Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

spi: atcspi200: Add support for Andes ATCSPI200 SPI

Merge series from CL Wang <cl634@andestech.com>:

This series adds support for the Andes ATCSPI200 SPI controller.

+781
+85
Documentation/devicetree/bindings/spi/andestech,ae350-spi.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/spi/andestech,ae350-spi.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Andes ATCSPI200 SPI controller 8 + 9 + maintainers: 10 + - CL Wang <cl634@andestech.com> 11 + 12 + properties: 13 + compatible: 14 + oneOf: 15 + - items: 16 + - enum: 17 + - andestech,qilai-spi 18 + - const: andestech,ae350-spi 19 + - const: andestech,ae350-spi 20 + 21 + reg: 22 + maxItems: 1 23 + 24 + clocks: 25 + maxItems: 1 26 + 27 + num-cs: 28 + description: Number of chip selects supported 29 + maxItems: 1 30 + 31 + dmas: 32 + items: 33 + - description: Transmit FIFO DMA channel 34 + - description: Receive FIFO DMA channel 35 + 36 + dma-names: 37 + items: 38 + - const: tx 39 + - const: rx 40 + 41 + patternProperties: 42 + "@[0-9a-f]+$": 43 + type: object 44 + additionalProperties: true 45 + 46 + properties: 47 + spi-rx-bus-width: 48 + enum: [1, 4] 49 + 50 + spi-tx-bus-width: 51 + enum: [1, 4] 52 + 53 + allOf: 54 + - $ref: spi-controller.yaml# 55 + 56 + required: 57 + - compatible 58 + - reg 59 + - clocks 60 + - dmas 61 + - dma-names 62 + 63 + unevaluatedProperties: false 64 + 65 + examples: 66 + - | 67 + spi@f0b00000 { 68 + compatible = "andestech,ae350-spi"; 69 + reg = <0xf0b00000 0x100>; 70 + clocks = <&clk_spi>; 71 + dmas = <&dma0 0>, <&dma0 1>; 72 + dma-names = "tx", "rx"; 73 + 74 + #address-cells = <1>; 75 + #size-cells = <0>; 76 + 77 + flash@0 { 78 + compatible = "jedec,spi-nor"; 79 + reg = <0>; 80 + spi-tx-bus-width = <4>; 81 + spi-rx-bus-width = <4>; 82 + spi-cpol; 83 + spi-cpha; 84 + }; 85 + };
+6
MAINTAINERS
··· 1817 1817 F: drivers/clk/analogbits/* 1818 1818 F: include/linux/clk/analogbits* 1819 1819 1820 + ANDES ATCSPI200 SPI DRIVER 1821 + M: CL Wang <cl634@andestech.com> 1822 + S: Supported 1823 + F: Documentation/devicetree/bindings/spi/andestech,ae350-spi.yaml 1824 + F: drivers/spi/spi-atcspi200.c 1825 + 1820 1826 ANDROID DRIVERS 1821 1827 M: Greg Kroah-Hartman <gregkh@linuxfoundation.org> 1822 1828 M: Arve Hjønnevåg <arve@android.com>
+9
drivers/spi/Kconfig
··· 136 136 This enables support for the SPI controller present on the 137 137 Qualcomm Atheros AR934X/QCA95XX SoCs. 138 138 139 + config SPI_ATCSPI200 140 + tristate "Andes ATCSPI200 SPI controller" 141 + depends on ARCH_ANDES 142 + help 143 + SPI driver for Andes ATCSPI200 SPI controller. 144 + ATCSPI200 controller supports DMA and PIO modes. When DMA 145 + is not available, the driver automatically falls back to 146 + PIO mode. 147 + 139 148 config SPI_ATH79 140 149 tristate "Atheros AR71XX/AR724X/AR913X SPI controller driver" 141 150 depends on ATH79 || COMPILE_TEST
+1
drivers/spi/Makefile
··· 26 26 obj-$(CONFIG_SPI_AR934X) += spi-ar934x.o 27 27 obj-$(CONFIG_SPI_ARMADA_3700) += spi-armada-3700.o 28 28 obj-$(CONFIG_SPI_ASPEED_SMC) += spi-aspeed-smc.o 29 + obj-$(CONFIG_SPI_ATCSPI200) += spi-atcspi200.o 29 30 obj-$(CONFIG_SPI_ATMEL) += spi-atmel.o 30 31 obj-$(CONFIG_SPI_ATMEL_QUADSPI) += atmel-quadspi.o 31 32 obj-$(CONFIG_SPI_AT91_USART) += spi-at91-usart.o
+680
drivers/spi/spi-atcspi200.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-or-later 2 + /* 3 + * Driver for Andes ATCSPI200 SPI Controller 4 + * 5 + * Copyright (C) 2025 Andes Technology Corporation. 6 + */ 7 + 8 + #include <linux/bitfield.h> 9 + #include <linux/clk.h> 10 + #include <linux/completion.h> 11 + #include <linux/dev_printk.h> 12 + #include <linux/dmaengine.h> 13 + #include <linux/err.h> 14 + #include <linux/errno.h> 15 + #include <linux/jiffies.h> 16 + #include <linux/minmax.h> 17 + #include <linux/module.h> 18 + #include <linux/mod_devicetable.h> 19 + #include <linux/mutex.h> 20 + #include <linux/platform_device.h> 21 + #include <linux/regmap.h> 22 + #include <linux/spi/spi.h> 23 + #include <linux/spi/spi-mem.h> 24 + 25 + /* Register definitions */ 26 + #define ATCSPI_TRANS_FMT 0x10 /* SPI transfer format register */ 27 + #define ATCSPI_TRANS_CTRL 0x20 /* SPI transfer control register */ 28 + #define ATCSPI_CMD 0x24 /* SPI command register */ 29 + #define ATCSPI_ADDR 0x28 /* SPI address register */ 30 + #define ATCSPI_DATA 0x2C /* SPI data register */ 31 + #define ATCSPI_CTRL 0x30 /* SPI control register */ 32 + #define ATCSPI_STATUS 0x34 /* SPI status register */ 33 + #define ATCSPI_TIMING 0x40 /* SPI interface timing register */ 34 + #define ATCSPI_CONFIG 0x7C /* SPI configuration register */ 35 + 36 + /* Transfer format register */ 37 + #define TRANS_FMT_CPHA BIT(0) 38 + #define TRANS_FMT_CPOL BIT(1) 39 + #define TRANS_FMT_DATA_MERGE_EN BIT(7) 40 + #define TRANS_FMT_DATA_LEN_MASK GENMASK(12, 8) 41 + #define TRANS_FMT_ADDR_LEN_MASK GENMASK(17, 16) 42 + #define TRANS_FMT_DATA_LEN(x) FIELD_PREP(TRANS_FMT_DATA_LEN_MASK, (x) - 1) 43 + #define TRANS_FMT_ADDR_LEN(x) FIELD_PREP(TRANS_FMT_ADDR_LEN_MASK, (x) - 1) 44 + 45 + /* Transfer control register */ 46 + #define TRANS_MODE_MASK GENMASK(27, 24) 47 + #define TRANS_MODE_W_ONLY FIELD_PREP(TRANS_MODE_MASK, 1) 48 + #define TRANS_MODE_R_ONLY FIELD_PREP(TRANS_MODE_MASK, 2) 49 + #define TRANS_MODE_NONE_DATA FIELD_PREP(TRANS_MODE_MASK, 7) 50 + #define TRANS_MODE_DMY_READ FIELD_PREP(TRANS_MODE_MASK, 9) 51 + #define TRANS_FIELD_DECNZ(m, x) ((x) ? FIELD_PREP(m, (x) - 1) : 0) 52 + #define TRANS_RD_TRANS_CNT(x) TRANS_FIELD_DECNZ(GENMASK(8, 0), x) 53 + #define TRANS_DUMMY_CNT(x) TRANS_FIELD_DECNZ(GENMASK(10, 9), x) 54 + #define TRANS_WR_TRANS_CNT(x) TRANS_FIELD_DECNZ(GENMASK(20, 12), x) 55 + #define TRANS_DUAL_QUAD(x) FIELD_PREP(GENMASK(23, 22), (x)) 56 + #define TRANS_ADDR_FMT BIT(28) 57 + #define TRANS_ADDR_EN BIT(29) 58 + #define TRANS_CMD_EN BIT(30) 59 + 60 + /* Control register */ 61 + #define CTRL_SPI_RST BIT(0) 62 + #define CTRL_RX_FIFO_RST BIT(1) 63 + #define CTRL_TX_FIFO_RST BIT(2) 64 + #define CTRL_RX_DMA_EN BIT(3) 65 + #define CTRL_TX_DMA_EN BIT(4) 66 + 67 + /* Status register */ 68 + #define ATCSPI_ACTIVE BIT(0) 69 + #define ATCSPI_RX_EMPTY BIT(14) 70 + #define ATCSPI_TX_FULL BIT(23) 71 + 72 + /* Interface timing setting */ 73 + #define TIMING_SCLK_DIV_MASK GENMASK(7, 0) 74 + #define TIMING_SCLK_DIV_MAX 0xFE 75 + 76 + /* Configuration register */ 77 + #define RXFIFO_SIZE(x) FIELD_GET(GENMASK(3, 0), (x)) 78 + #define TXFIFO_SIZE(x) FIELD_GET(GENMASK(7, 4), (x)) 79 + 80 + /* driver configurations */ 81 + #define ATCSPI_MAX_TRANS_LEN 512 82 + #define ATCSPI_MAX_SPEED_HZ 50000000 83 + #define ATCSPI_RDY_TIMEOUT_US 1000000 84 + #define ATCSPI_XFER_TIMEOUT(n) ((n) * 10) 85 + #define ATCSPI_MAX_CS_NUM 1 86 + #define ATCSPI_DMA_THRESHOLD 256 87 + #define ATCSPI_BITS_PER_UINT 8 88 + #define ATCSPI_DATA_MERGE_EN 1 89 + #define ATCSPI_DMA_SUPPORT 1 90 + 91 + /** 92 + * struct atcspi_dev - Andes ATCSPI200 SPI controller private data 93 + * @host: Pointer to the SPI controller structure. 94 + * @mutex_lock: A mutex to protect concurrent access to the controller. 95 + * @dma_completion: A completion to signal the end of a DMA transfer. 96 + * @dev: Pointer to the device structure. 97 + * @regmap: Register map for accessing controller registers. 98 + * @clk: Pointer to the controller's functional clock. 99 + * @dma_addr: The physical address of the SPI data register for DMA. 100 + * @clk_rate: The cached frequency of the functional clock. 101 + * @sclk_rate: The target frequency for the SPI clock (SCLK). 102 + * @txfifo_size: The size of the transmit FIFO in bytes. 103 + * @rxfifo_size: The size of the receive FIFO in bytes. 104 + * @data_merge: A flag indicating if the data merge mode is enabled for 105 + * the current transfer. 106 + * @use_dma: Enable DMA mode if ATCSPI_DMA_SUPPORT is set and DMA is 107 + * successfully configured. 108 + */ 109 + struct atcspi_dev { 110 + struct spi_controller *host; 111 + struct mutex mutex_lock; 112 + struct completion dma_completion; 113 + struct device *dev; 114 + struct regmap *regmap; 115 + struct clk *clk; 116 + dma_addr_t dma_addr; 117 + unsigned int clk_rate; 118 + unsigned int sclk_rate; 119 + unsigned int txfifo_size; 120 + unsigned int rxfifo_size; 121 + bool data_merge; 122 + bool use_dma; 123 + }; 124 + 125 + static int atcspi_wait_fifo_ready(struct atcspi_dev *spi, 126 + enum spi_mem_data_dir dir) 127 + { 128 + unsigned int val; 129 + unsigned int mask; 130 + int ret; 131 + 132 + mask = (dir == SPI_MEM_DATA_OUT) ? ATCSPI_TX_FULL : ATCSPI_RX_EMPTY; 133 + ret = regmap_read_poll_timeout(spi->regmap, 134 + ATCSPI_STATUS, 135 + val, 136 + !(val & mask), 137 + 0, 138 + ATCSPI_RDY_TIMEOUT_US); 139 + if (ret) 140 + dev_info(spi->dev, "Timed out waiting for FIFO ready\n"); 141 + 142 + return ret; 143 + } 144 + 145 + static int atcspi_xfer_data_poll(struct atcspi_dev *spi, 146 + const struct spi_mem_op *op) 147 + { 148 + void *rx_buf = op->data.buf.in; 149 + const void *tx_buf = op->data.buf.out; 150 + unsigned int val; 151 + int trans_bytes = op->data.nbytes; 152 + int num_byte; 153 + int ret = 0; 154 + 155 + num_byte = spi->data_merge ? 4 : 1; 156 + while (trans_bytes) { 157 + if (op->data.dir == SPI_MEM_DATA_OUT) { 158 + ret = atcspi_wait_fifo_ready(spi, SPI_MEM_DATA_OUT); 159 + if (ret) 160 + return ret; 161 + 162 + if (spi->data_merge) 163 + val = *(unsigned int *)tx_buf; 164 + else 165 + val = *(unsigned char *)tx_buf; 166 + regmap_write(spi->regmap, ATCSPI_DATA, val); 167 + tx_buf = (unsigned char *)tx_buf + num_byte; 168 + } else { 169 + ret = atcspi_wait_fifo_ready(spi, SPI_MEM_DATA_IN); 170 + if (ret) 171 + return ret; 172 + 173 + regmap_read(spi->regmap, ATCSPI_DATA, &val); 174 + if (spi->data_merge) 175 + *(unsigned int *)rx_buf = val; 176 + else 177 + *(unsigned char *)rx_buf = (unsigned char)val; 178 + rx_buf = (unsigned char *)rx_buf + num_byte; 179 + } 180 + trans_bytes -= num_byte; 181 + } 182 + 183 + return ret; 184 + } 185 + 186 + static void atcspi_set_trans_ctl(struct atcspi_dev *spi, 187 + const struct spi_mem_op *op) 188 + { 189 + unsigned int tc = 0; 190 + 191 + if (op->cmd.nbytes) 192 + tc |= TRANS_CMD_EN; 193 + if (op->addr.nbytes) 194 + tc |= TRANS_ADDR_EN; 195 + if (op->addr.buswidth > 1) 196 + tc |= TRANS_ADDR_FMT; 197 + if (op->data.nbytes) { 198 + tc |= TRANS_DUAL_QUAD(ffs(op->data.buswidth) - 1); 199 + if (op->data.dir == SPI_MEM_DATA_IN) { 200 + if (op->dummy.nbytes) 201 + tc |= TRANS_MODE_DMY_READ | 202 + TRANS_DUMMY_CNT(op->dummy.nbytes); 203 + else 204 + tc |= TRANS_MODE_R_ONLY; 205 + tc |= TRANS_RD_TRANS_CNT(op->data.nbytes); 206 + } else { 207 + tc |= TRANS_MODE_W_ONLY | 208 + TRANS_WR_TRANS_CNT(op->data.nbytes); 209 + } 210 + } else { 211 + tc |= TRANS_MODE_NONE_DATA; 212 + } 213 + regmap_write(spi->regmap, ATCSPI_TRANS_CTRL, tc); 214 + } 215 + 216 + static void atcspi_set_trans_fmt(struct atcspi_dev *spi, 217 + const struct spi_mem_op *op) 218 + { 219 + unsigned int val; 220 + 221 + regmap_read(spi->regmap, ATCSPI_TRANS_FMT, &val); 222 + if (op->data.nbytes) { 223 + if (ATCSPI_DATA_MERGE_EN && ATCSPI_BITS_PER_UINT == 8 && 224 + !(op->data.nbytes % 4)) { 225 + val |= TRANS_FMT_DATA_MERGE_EN; 226 + spi->data_merge = true; 227 + } else { 228 + val &= ~TRANS_FMT_DATA_MERGE_EN; 229 + spi->data_merge = false; 230 + } 231 + } 232 + 233 + val = (val & ~TRANS_FMT_ADDR_LEN_MASK) | 234 + TRANS_FMT_ADDR_LEN(op->addr.nbytes); 235 + regmap_write(spi->regmap, ATCSPI_TRANS_FMT, val); 236 + } 237 + 238 + static void atcspi_prepare_trans(struct atcspi_dev *spi, 239 + const struct spi_mem_op *op) 240 + { 241 + atcspi_set_trans_fmt(spi, op); 242 + atcspi_set_trans_ctl(spi, op); 243 + if (op->addr.nbytes) 244 + regmap_write(spi->regmap, ATCSPI_ADDR, op->addr.val); 245 + regmap_write(spi->regmap, ATCSPI_CMD, op->cmd.opcode); 246 + } 247 + 248 + static int atcspi_adjust_op_size(struct spi_mem *mem, struct spi_mem_op *op) 249 + { 250 + struct atcspi_dev *spi; 251 + 252 + spi = spi_controller_get_devdata(mem->spi->controller); 253 + op->data.nbytes = min(op->data.nbytes, ATCSPI_MAX_TRANS_LEN); 254 + 255 + /* DMA needs to be aligned to 4 byte */ 256 + if (spi->use_dma && op->data.nbytes >= ATCSPI_DMA_THRESHOLD) 257 + op->data.nbytes = ALIGN_DOWN(op->data.nbytes, 4); 258 + 259 + return 0; 260 + } 261 + 262 + static int atcspi_dma_config(struct atcspi_dev *spi, bool is_rx) 263 + { 264 + struct dma_slave_config conf = { 0 }; 265 + struct dma_chan *chan; 266 + 267 + if (is_rx) { 268 + chan = spi->host->dma_rx; 269 + conf.direction = DMA_DEV_TO_MEM; 270 + conf.src_addr = spi->dma_addr; 271 + } else { 272 + chan = spi->host->dma_tx; 273 + conf.direction = DMA_MEM_TO_DEV; 274 + conf.dst_addr = spi->dma_addr; 275 + } 276 + conf.dst_maxburst = spi->rxfifo_size / 2; 277 + conf.src_maxburst = spi->txfifo_size / 2; 278 + 279 + if (spi->data_merge) { 280 + conf.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; 281 + conf.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; 282 + } else { 283 + conf.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; 284 + conf.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; 285 + } 286 + 287 + return dmaengine_slave_config(chan, &conf); 288 + } 289 + 290 + static void atcspi_dma_callback(void *arg) 291 + { 292 + struct completion *dma_completion = arg; 293 + 294 + complete(dma_completion); 295 + } 296 + 297 + static int atcspi_dma_trans(struct atcspi_dev *spi, 298 + const struct spi_mem_op *op) 299 + { 300 + struct dma_async_tx_descriptor *desc; 301 + struct dma_chan *dma_ch; 302 + struct sg_table sgt; 303 + enum dma_transfer_direction dma_dir; 304 + dma_cookie_t cookie; 305 + unsigned int ctrl; 306 + int timeout; 307 + int ret; 308 + 309 + regmap_read(spi->regmap, ATCSPI_CTRL, &ctrl); 310 + ctrl |= CTRL_TX_DMA_EN | CTRL_RX_DMA_EN; 311 + regmap_write(spi->regmap, ATCSPI_CTRL, ctrl); 312 + if (op->data.dir == SPI_MEM_DATA_IN) { 313 + ret = atcspi_dma_config(spi, TRUE); 314 + dma_dir = DMA_DEV_TO_MEM; 315 + dma_ch = spi->host->dma_rx; 316 + } else { 317 + ret = atcspi_dma_config(spi, FALSE); 318 + dma_dir = DMA_MEM_TO_DEV; 319 + dma_ch = spi->host->dma_tx; 320 + } 321 + if (ret) 322 + return ret; 323 + 324 + ret = spi_controller_dma_map_mem_op_data(spi->host, op, &sgt); 325 + if (ret) 326 + return ret; 327 + 328 + desc = dmaengine_prep_slave_sg(dma_ch, sgt.sgl, sgt.nents, dma_dir, 329 + DMA_PREP_INTERRUPT | DMA_CTRL_ACK); 330 + if (!desc) { 331 + ret = -ENOMEM; 332 + goto exit_unmap; 333 + } 334 + 335 + reinit_completion(&spi->dma_completion); 336 + desc->callback = atcspi_dma_callback; 337 + desc->callback_param = &spi->dma_completion; 338 + cookie = dmaengine_submit(desc); 339 + ret = dma_submit_error(cookie); 340 + if (ret) 341 + goto exit_unmap; 342 + 343 + dma_async_issue_pending(dma_ch); 344 + timeout = msecs_to_jiffies(ATCSPI_XFER_TIMEOUT(op->data.nbytes)); 345 + if (!wait_for_completion_timeout(&spi->dma_completion, timeout)) { 346 + ret = -ETIMEDOUT; 347 + dmaengine_terminate_all(dma_ch); 348 + } 349 + 350 + exit_unmap: 351 + spi_controller_dma_unmap_mem_op_data(spi->host, op, &sgt); 352 + 353 + return ret; 354 + } 355 + 356 + static int atcspi_exec_mem_op(struct spi_mem *mem, const struct spi_mem_op *op) 357 + { 358 + struct spi_device *spi_dev = mem->spi; 359 + struct atcspi_dev *spi; 360 + unsigned int val; 361 + int ret; 362 + 363 + spi = spi_controller_get_devdata(spi_dev->controller); 364 + mutex_lock(&spi->mutex_lock); 365 + atcspi_prepare_trans(spi, op); 366 + if (op->data.nbytes) { 367 + if (spi->use_dma && op->data.nbytes >= ATCSPI_DMA_THRESHOLD) 368 + ret = atcspi_dma_trans(spi, op); 369 + else 370 + ret = atcspi_xfer_data_poll(spi, op); 371 + if (ret) { 372 + dev_info(spi->dev, "SPI transmission failed\n"); 373 + goto exec_mem_exit; 374 + } 375 + } 376 + 377 + ret = regmap_read_poll_timeout(spi->regmap, 378 + ATCSPI_STATUS, 379 + val, 380 + !(val & ATCSPI_ACTIVE), 381 + 0, 382 + ATCSPI_RDY_TIMEOUT_US); 383 + if (ret) 384 + dev_info(spi->dev, "Timed out waiting for ATCSPI_ACTIVE\n"); 385 + 386 + exec_mem_exit: 387 + mutex_unlock(&spi->mutex_lock); 388 + 389 + return ret; 390 + } 391 + 392 + static const struct spi_controller_mem_ops atcspi_mem_ops = { 393 + .exec_op = atcspi_exec_mem_op, 394 + .adjust_op_size = atcspi_adjust_op_size, 395 + }; 396 + 397 + static int atcspi_setup(struct atcspi_dev *spi) 398 + { 399 + unsigned int ctrl_val; 400 + unsigned int val; 401 + int actual_spi_sclk_f; 402 + int ret; 403 + unsigned char div; 404 + 405 + ctrl_val = CTRL_TX_FIFO_RST | CTRL_RX_FIFO_RST | CTRL_SPI_RST; 406 + regmap_write(spi->regmap, ATCSPI_CTRL, ctrl_val); 407 + ret = regmap_read_poll_timeout(spi->regmap, 408 + ATCSPI_CTRL, 409 + val, 410 + !(val & ctrl_val), 411 + 0, 412 + ATCSPI_RDY_TIMEOUT_US); 413 + if (ret) 414 + return dev_err_probe(spi->dev, ret, 415 + "Timed out waiting for ATCSPI_CTRL\n"); 416 + 417 + val = TRANS_FMT_DATA_LEN(ATCSPI_BITS_PER_UINT) | 418 + TRANS_FMT_CPHA | TRANS_FMT_CPOL; 419 + regmap_write(spi->regmap, ATCSPI_TRANS_FMT, val); 420 + 421 + regmap_read(spi->regmap, ATCSPI_CONFIG, &val); 422 + spi->txfifo_size = BIT(TXFIFO_SIZE(val) + 1); 423 + spi->rxfifo_size = BIT(RXFIFO_SIZE(val) + 1); 424 + 425 + regmap_read(spi->regmap, ATCSPI_TIMING, &val); 426 + val &= ~TIMING_SCLK_DIV_MASK; 427 + 428 + /* 429 + * The SCLK_DIV value 0xFF is special and indicates that the 430 + * SCLK rate should be the same as the SPI clock rate. 431 + */ 432 + if (spi->sclk_rate >= spi->clk_rate) { 433 + div = TIMING_SCLK_DIV_MASK; 434 + } else { 435 + /* 436 + * The divider value is determined as follows: 437 + * 1. If the divider can generate the exact target frequency, 438 + * use that setting. 439 + * 2. If an exact match is not possible, select the closest 440 + * available setting that is lower than the target frequency. 441 + */ 442 + div = (spi->clk_rate + (spi->sclk_rate * 2 - 1)) / 443 + (spi->sclk_rate * 2) - 1; 444 + 445 + /* Check if the actual SPI clock is lower than the target */ 446 + actual_spi_sclk_f = spi->clk_rate / ((div + 1) * 2); 447 + if (actual_spi_sclk_f < spi->sclk_rate) 448 + dev_info(spi->dev, 449 + "Clock adjusted %d to %d due to divider limitation", 450 + spi->sclk_rate, actual_spi_sclk_f); 451 + 452 + if (div > TIMING_SCLK_DIV_MAX) 453 + return dev_err_probe(spi->dev, -EINVAL, 454 + "Unsupported SPI clock %d\n", 455 + spi->sclk_rate); 456 + } 457 + val |= div; 458 + regmap_write(spi->regmap, ATCSPI_TIMING, val); 459 + 460 + return ret; 461 + } 462 + 463 + static int atcspi_init_resources(struct platform_device *pdev, 464 + struct atcspi_dev *spi, 465 + struct resource **mem_res) 466 + { 467 + void __iomem *base; 468 + const struct regmap_config atcspi_regmap_cfg = { 469 + .name = "atcspi", 470 + .reg_bits = 32, 471 + .val_bits = 32, 472 + .cache_type = REGCACHE_NONE, 473 + .reg_stride = 4, 474 + .pad_bits = 0, 475 + .max_register = ATCSPI_CONFIG 476 + }; 477 + 478 + base = devm_platform_get_and_ioremap_resource(pdev, 0, mem_res); 479 + if (IS_ERR(base)) 480 + return dev_err_probe(spi->dev, PTR_ERR(base), 481 + "Failed to get ioremap resource\n"); 482 + 483 + spi->regmap = devm_regmap_init_mmio(spi->dev, base, 484 + &atcspi_regmap_cfg); 485 + if (IS_ERR(spi->regmap)) 486 + return dev_err_probe(spi->dev, PTR_ERR(spi->regmap), 487 + "Failed to init regmap\n"); 488 + 489 + spi->clk = devm_clk_get(spi->dev, NULL); 490 + if (IS_ERR(spi->clk)) 491 + return dev_err_probe(spi->dev, PTR_ERR(spi->clk), 492 + "Failed to get SPI clock\n"); 493 + 494 + spi->sclk_rate = ATCSPI_MAX_SPEED_HZ; 495 + return 0; 496 + } 497 + 498 + static int atcspi_configure_dma(struct atcspi_dev *spi) 499 + { 500 + struct dma_chan *dma_chan; 501 + int ret = 0; 502 + 503 + dma_chan = devm_dma_request_chan(spi->dev, "rx"); 504 + if (IS_ERR(dma_chan)) { 505 + ret = PTR_ERR(dma_chan); 506 + goto err_exit; 507 + } 508 + spi->host->dma_rx = dma_chan; 509 + 510 + dma_chan = devm_dma_request_chan(spi->dev, "tx"); 511 + if (IS_ERR(dma_chan)) { 512 + ret = PTR_ERR(dma_chan); 513 + goto free_rx; 514 + } 515 + spi->host->dma_tx = dma_chan; 516 + init_completion(&spi->dma_completion); 517 + 518 + return ret; 519 + 520 + free_rx: 521 + dma_release_channel(spi->host->dma_rx); 522 + spi->host->dma_rx = NULL; 523 + err_exit: 524 + return ret; 525 + } 526 + 527 + static int atcspi_enable_clk(struct atcspi_dev *spi) 528 + { 529 + int ret; 530 + 531 + ret = clk_prepare_enable(spi->clk); 532 + if (ret) 533 + return dev_err_probe(spi->dev, ret, 534 + "Failed to enable clock\n"); 535 + 536 + spi->clk_rate = clk_get_rate(spi->clk); 537 + if (!spi->clk_rate) 538 + return dev_err_probe(spi->dev, -EINVAL, 539 + "Failed to get SPI clock rate\n"); 540 + 541 + return 0; 542 + } 543 + 544 + static void atcspi_init_controller(struct platform_device *pdev, 545 + struct atcspi_dev *spi, 546 + struct spi_controller *host, 547 + struct resource *mem_res) 548 + { 549 + /* Get the physical address of the data register for DMA transfers. */ 550 + spi->dma_addr = (dma_addr_t)(mem_res->start + ATCSPI_DATA); 551 + 552 + /* Initialize controller properties */ 553 + host->bus_num = pdev->id; 554 + host->mode_bits = SPI_CPOL | SPI_CPHA | SPI_RX_QUAD | SPI_TX_QUAD; 555 + host->dev.of_node = pdev->dev.of_node; 556 + host->num_chipselect = ATCSPI_MAX_CS_NUM; 557 + host->mem_ops = &atcspi_mem_ops; 558 + host->max_speed_hz = spi->sclk_rate; 559 + } 560 + 561 + static int atcspi_probe(struct platform_device *pdev) 562 + { 563 + struct spi_controller *host; 564 + struct atcspi_dev *spi; 565 + struct resource *mem_res; 566 + int ret; 567 + 568 + host = spi_alloc_host(&pdev->dev, sizeof(*spi)); 569 + if (!host) 570 + return -ENOMEM; 571 + 572 + spi = spi_controller_get_devdata(host); 573 + spi->host = host; 574 + spi->dev = &pdev->dev; 575 + dev_set_drvdata(&pdev->dev, host); 576 + 577 + ret = atcspi_init_resources(pdev, spi, &mem_res); 578 + if (ret) 579 + goto free_controller; 580 + 581 + ret = atcspi_enable_clk(spi); 582 + if (ret) 583 + goto free_controller; 584 + 585 + atcspi_init_controller(pdev, spi, host, mem_res); 586 + 587 + ret = atcspi_setup(spi); 588 + if (ret) 589 + goto disable_clk; 590 + 591 + ret = devm_spi_register_controller(&pdev->dev, host); 592 + if (ret) { 593 + dev_err_probe(spi->dev, ret, 594 + "Failed to register SPI controller\n"); 595 + goto disable_clk; 596 + } 597 + 598 + spi->use_dma = false; 599 + if (ATCSPI_DMA_SUPPORT) { 600 + ret = atcspi_configure_dma(spi); 601 + if (ret) 602 + dev_info(spi->dev, 603 + "Failed to init DMA, fallback to PIO mode\n"); 604 + else 605 + spi->use_dma = true; 606 + } 607 + mutex_init(&spi->mutex_lock); 608 + 609 + return 0; 610 + 611 + disable_clk: 612 + clk_disable_unprepare(spi->clk); 613 + 614 + free_controller: 615 + spi_controller_put(host); 616 + return ret; 617 + } 618 + 619 + static int atcspi_suspend(struct device *dev) 620 + { 621 + struct spi_controller *host = dev_get_drvdata(dev); 622 + struct atcspi_dev *spi = spi_controller_get_devdata(host); 623 + 624 + spi_controller_suspend(host); 625 + 626 + clk_disable_unprepare(spi->clk); 627 + 628 + return 0; 629 + } 630 + 631 + static int atcspi_resume(struct device *dev) 632 + { 633 + struct spi_controller *host = dev_get_drvdata(dev); 634 + struct atcspi_dev *spi = spi_controller_get_devdata(host); 635 + int ret; 636 + 637 + ret = clk_prepare_enable(spi->clk); 638 + if (ret) 639 + return ret; 640 + 641 + ret = atcspi_setup(spi); 642 + if (ret) 643 + goto disable_clk; 644 + 645 + ret = spi_controller_resume(host); 646 + if (ret) 647 + goto disable_clk; 648 + 649 + return ret; 650 + 651 + disable_clk: 652 + clk_disable_unprepare(spi->clk); 653 + 654 + return ret; 655 + } 656 + 657 + static DEFINE_SIMPLE_DEV_PM_OPS(atcspi_pm_ops, atcspi_suspend, atcspi_resume); 658 + 659 + static const struct of_device_id atcspi_of_match[] = { 660 + { .compatible = "andestech,qilai-spi", }, 661 + { .compatible = "andestech,ae350-spi", }, 662 + { /* sentinel */ } 663 + }; 664 + 665 + MODULE_DEVICE_TABLE(of, atcspi_of_match); 666 + 667 + static struct platform_driver atcspi_driver = { 668 + .probe = atcspi_probe, 669 + .driver = { 670 + .name = "atcspi200", 671 + .owner = THIS_MODULE, 672 + .of_match_table = atcspi_of_match, 673 + .pm = pm_sleep_ptr(&atcspi_pm_ops) 674 + } 675 + }; 676 + module_platform_driver(atcspi_driver); 677 + 678 + MODULE_AUTHOR("CL Wang <cl634@andestech.com>"); 679 + MODULE_DESCRIPTION("Andes ATCSPI200 SPI controller driver"); 680 + MODULE_LICENSE("GPL");