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

Introduce Socionext F_OSPI SPI flash controller

Merge series from Kunihiko Hayashi <hayashi.kunihiko@socionext.com>:

This series adds dt-bindings and a driver for Socionext F_OSPI controller
for connecting an SPI Flash memory over up to 8-bit wide bus.
The controller supports up to 4 chip selects.

+770
+57
Documentation/devicetree/bindings/spi/socionext,f-ospi.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/socionext,f-ospi.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Socionext F_OSPI controller 8 + 9 + description: | 10 + The Socionext F_OSPI is a controller used to interface with flash 11 + memories using the SPI communication interface. 12 + 13 + maintainers: 14 + - Kunihiko Hayashi <hayashi.kunihiko@socionext.com> 15 + 16 + allOf: 17 + - $ref: spi-controller.yaml# 18 + 19 + properties: 20 + compatible: 21 + const: socionext,f-ospi 22 + 23 + reg: 24 + maxItems: 1 25 + 26 + clocks: 27 + maxItems: 1 28 + 29 + num-cs: 30 + minimum: 1 31 + maximum: 4 32 + 33 + required: 34 + - compatible 35 + - reg 36 + - clocks 37 + - "#address-cells" 38 + - "#size-cells" 39 + 40 + unevaluatedProperties: false 41 + 42 + examples: 43 + - | 44 + ospi0: spi@80000000 { 45 + compatible = "socionext,f-ospi"; 46 + reg = <0x80000000 0x1000>; 47 + clocks = <&clks 0>; 48 + num-cs = <1>; 49 + #address-cells = <1>; 50 + #size-cells = <0>; 51 + 52 + flash@0 { 53 + compatible = "spansion,s25fl128s", "jedec,spi-nor"; 54 + reg = <0>; 55 + spi-max-frequency = <50000000>; 56 + }; 57 + };
+9
drivers/spi/Kconfig
··· 906 906 say Y or M here.If you are not sure, say N. 907 907 SPI slave drivers for Mediatek MT27XX series ARM SoCs. 908 908 909 + config SPI_SN_F_OSPI 910 + tristate "Socionext F_OSPI SPI flash controller" 911 + depends on OF && HAS_IOMEM 912 + depends on SPI_MEM 913 + help 914 + This enables support for the Socionext F_OSPI controller 915 + for connecting an SPI Flash memory over up to 8-bit wide bus. 916 + It supports indirect access mode only. 917 + 909 918 config SPI_SPRD 910 919 tristate "Spreadtrum SPI controller" 911 920 depends on ARCH_SPRD || COMPILE_TEST
+1
drivers/spi/Makefile
··· 121 121 obj-$(CONFIG_SPI_SH_SCI) += spi-sh-sci.o 122 122 obj-$(CONFIG_SPI_SIFIVE) += spi-sifive.o 123 123 obj-$(CONFIG_SPI_SLAVE_MT27XX) += spi-slave-mt27xx.o 124 + obj-$(CONFIG_SPI_SN_F_OSPI) += spi-sn-f-ospi.o 124 125 obj-$(CONFIG_SPI_SPRD) += spi-sprd.o 125 126 obj-$(CONFIG_SPI_SPRD_ADI) += spi-sprd-adi.o 126 127 obj-$(CONFIG_SPI_STM32) += spi-stm32.o
+703
drivers/spi/spi-sn-f-ospi.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Socionext SPI flash controller F_OSPI driver 4 + * Copyright (C) 2021 Socionext Inc. 5 + */ 6 + 7 + #include <linux/bitfield.h> 8 + #include <linux/clk.h> 9 + #include <linux/io.h> 10 + #include <linux/iopoll.h> 11 + #include <linux/module.h> 12 + #include <linux/mutex.h> 13 + #include <linux/of_device.h> 14 + #include <linux/platform_device.h> 15 + #include <linux/spi/spi.h> 16 + #include <linux/spi/spi-mem.h> 17 + 18 + /* Registers */ 19 + #define OSPI_PROT_CTL_INDIR 0x00 20 + #define OSPI_PROT_MODE_DATA_MASK GENMASK(31, 30) 21 + #define OSPI_PROT_MODE_ALT_MASK GENMASK(29, 28) 22 + #define OSPI_PROT_MODE_ADDR_MASK GENMASK(27, 26) 23 + #define OSPI_PROT_MODE_CODE_MASK GENMASK(25, 24) 24 + #define OSPI_PROT_MODE_SINGLE 0 25 + #define OSPI_PROT_MODE_DUAL 1 26 + #define OSPI_PROT_MODE_QUAD 2 27 + #define OSPI_PROT_MODE_OCTAL 3 28 + #define OSPI_PROT_DATA_RATE_DATA BIT(23) 29 + #define OSPI_PROT_DATA_RATE_ALT BIT(22) 30 + #define OSPI_PROT_DATA_RATE_ADDR BIT(21) 31 + #define OSPI_PROT_DATA_RATE_CODE BIT(20) 32 + #define OSPI_PROT_SDR 0 33 + #define OSPI_PROT_DDR 1 34 + #define OSPI_PROT_BIT_POS_DATA BIT(19) 35 + #define OSPI_PROT_BIT_POS_ALT BIT(18) 36 + #define OSPI_PROT_BIT_POS_ADDR BIT(17) 37 + #define OSPI_PROT_BIT_POS_CODE BIT(16) 38 + #define OSPI_PROT_SAMP_EDGE BIT(12) 39 + #define OSPI_PROT_DATA_UNIT_MASK GENMASK(11, 10) 40 + #define OSPI_PROT_DATA_UNIT_1B 0 41 + #define OSPI_PROT_DATA_UNIT_2B 1 42 + #define OSPI_PROT_DATA_UNIT_4B 3 43 + #define OSPI_PROT_TRANS_DIR_WRITE BIT(9) 44 + #define OSPI_PROT_DATA_EN BIT(8) 45 + #define OSPI_PROT_ALT_SIZE_MASK GENMASK(7, 5) 46 + #define OSPI_PROT_ADDR_SIZE_MASK GENMASK(4, 2) 47 + #define OSPI_PROT_CODE_SIZE_MASK GENMASK(1, 0) 48 + 49 + #define OSPI_CLK_CTL 0x10 50 + #define OSPI_CLK_CTL_BOOT_INT_CLK_EN BIT(16) 51 + #define OSPI_CLK_CTL_PHA BIT(12) 52 + #define OSPI_CLK_CTL_PHA_180 0 53 + #define OSPI_CLK_CTL_PHA_90 1 54 + #define OSPI_CLK_CTL_DIV GENMASK(9, 8) 55 + #define OSPI_CLK_CTL_DIV_1 0 56 + #define OSPI_CLK_CTL_DIV_2 1 57 + #define OSPI_CLK_CTL_DIV_4 2 58 + #define OSPI_CLK_CTL_DIV_8 3 59 + #define OSPI_CLK_CTL_INT_CLK_EN BIT(0) 60 + 61 + #define OSPI_CS_CTL1 0x14 62 + #define OSPI_CS_CTL2 0x18 63 + #define OSPI_SSEL 0x20 64 + #define OSPI_CMD_IDX_INDIR 0x40 65 + #define OSPI_ADDR 0x50 66 + #define OSPI_ALT_INDIR 0x60 67 + #define OSPI_DMY_INDIR 0x70 68 + #define OSPI_DAT 0x80 69 + #define OSPI_DAT_SWP_INDIR 0x90 70 + 71 + #define OSPI_DAT_SIZE_INDIR 0xA0 72 + #define OSPI_DAT_SIZE_EN BIT(15) 73 + #define OSPI_DAT_SIZE_MASK GENMASK(10, 0) 74 + #define OSPI_DAT_SIZE_MAX (OSPI_DAT_SIZE_MASK + 1) 75 + 76 + #define OSPI_TRANS_CTL 0xC0 77 + #define OSPI_TRANS_CTL_STOP_REQ BIT(1) /* RW1AC */ 78 + #define OSPI_TRANS_CTL_START_REQ BIT(0) /* RW1AC */ 79 + 80 + #define OSPI_ACC_MODE 0xC4 81 + #define OSPI_ACC_MODE_BOOT_DISABLE BIT(0) 82 + 83 + #define OSPI_SWRST 0xD0 84 + #define OSPI_SWRST_INDIR_WRITE_FIFO BIT(9) /* RW1AC */ 85 + #define OSPI_SWRST_INDIR_READ_FIFO BIT(8) /* RW1AC */ 86 + 87 + #define OSPI_STAT 0xE0 88 + #define OSPI_STAT_IS_AXI_WRITING BIT(10) 89 + #define OSPI_STAT_IS_AXI_READING BIT(9) 90 + #define OSPI_STAT_IS_SPI_INT_CLK_STOP BIT(4) 91 + #define OSPI_STAT_IS_SPI_IDLE BIT(3) 92 + 93 + #define OSPI_IRQ 0xF0 94 + #define OSPI_IRQ_CS_DEASSERT BIT(8) 95 + #define OSPI_IRQ_WRITE_BUF_READY BIT(2) 96 + #define OSPI_IRQ_READ_BUF_READY BIT(1) 97 + #define OSPI_IRQ_CS_TRANS_COMP BIT(0) 98 + #define OSPI_IRQ_ALL \ 99 + (OSPI_IRQ_CS_DEASSERT | OSPI_IRQ_WRITE_BUF_READY \ 100 + | OSPI_IRQ_READ_BUF_READY | OSPI_IRQ_CS_TRANS_COMP) 101 + 102 + #define OSPI_IRQ_STAT_EN 0xF4 103 + #define OSPI_IRQ_SIG_EN 0xF8 104 + 105 + /* Parameters */ 106 + #define OSPI_NUM_CS 4 107 + #define OSPI_DUMMY_CYCLE_MAX 255 108 + #define OSPI_WAIT_MAX_MSEC 100 109 + 110 + struct f_ospi { 111 + void __iomem *base; 112 + struct device *dev; 113 + struct clk *clk; 114 + struct mutex mlock; 115 + }; 116 + 117 + static u32 f_ospi_get_dummy_cycle(const struct spi_mem_op *op) 118 + { 119 + return (op->dummy.nbytes * 8) / op->dummy.buswidth; 120 + } 121 + 122 + static void f_ospi_clear_irq(struct f_ospi *ospi) 123 + { 124 + writel(OSPI_IRQ_CS_DEASSERT | OSPI_IRQ_CS_TRANS_COMP, 125 + ospi->base + OSPI_IRQ); 126 + } 127 + 128 + static void f_ospi_enable_irq_status(struct f_ospi *ospi, u32 irq_bits) 129 + { 130 + u32 val; 131 + 132 + val = readl(ospi->base + OSPI_IRQ_STAT_EN); 133 + val |= irq_bits; 134 + writel(val, ospi->base + OSPI_IRQ_STAT_EN); 135 + } 136 + 137 + static void f_ospi_disable_irq_status(struct f_ospi *ospi, u32 irq_bits) 138 + { 139 + u32 val; 140 + 141 + val = readl(ospi->base + OSPI_IRQ_STAT_EN); 142 + val &= ~irq_bits; 143 + writel(val, ospi->base + OSPI_IRQ_STAT_EN); 144 + } 145 + 146 + static void f_ospi_disable_irq_output(struct f_ospi *ospi, u32 irq_bits) 147 + { 148 + u32 val; 149 + 150 + val = readl(ospi->base + OSPI_IRQ_SIG_EN); 151 + val &= ~irq_bits; 152 + writel(val, ospi->base + OSPI_IRQ_SIG_EN); 153 + } 154 + 155 + static int f_ospi_prepare_config(struct f_ospi *ospi) 156 + { 157 + u32 val, stat0, stat1; 158 + 159 + /* G4: Disable internal clock */ 160 + val = readl(ospi->base + OSPI_CLK_CTL); 161 + val &= ~(OSPI_CLK_CTL_BOOT_INT_CLK_EN | OSPI_CLK_CTL_INT_CLK_EN); 162 + writel(val, ospi->base + OSPI_CLK_CTL); 163 + 164 + /* G5: Wait for stop */ 165 + stat0 = OSPI_STAT_IS_AXI_WRITING | OSPI_STAT_IS_AXI_READING; 166 + stat1 = OSPI_STAT_IS_SPI_IDLE | OSPI_STAT_IS_SPI_INT_CLK_STOP; 167 + 168 + return readl_poll_timeout(ospi->base + OSPI_STAT, 169 + val, (val & (stat0 | stat1)) == stat1, 170 + 0, OSPI_WAIT_MAX_MSEC); 171 + } 172 + 173 + static int f_ospi_unprepare_config(struct f_ospi *ospi) 174 + { 175 + u32 val; 176 + 177 + /* G11: Enable internal clock */ 178 + val = readl(ospi->base + OSPI_CLK_CTL); 179 + val |= OSPI_CLK_CTL_BOOT_INT_CLK_EN | OSPI_CLK_CTL_INT_CLK_EN; 180 + writel(val, ospi->base + OSPI_CLK_CTL); 181 + 182 + /* G12: Wait for clock to start */ 183 + return readl_poll_timeout(ospi->base + OSPI_STAT, 184 + val, !(val & OSPI_STAT_IS_SPI_INT_CLK_STOP), 185 + 0, OSPI_WAIT_MAX_MSEC); 186 + } 187 + 188 + static void f_ospi_config_clk(struct f_ospi *ospi, u32 device_hz) 189 + { 190 + long rate_hz = clk_get_rate(ospi->clk); 191 + u32 div = DIV_ROUND_UP(rate_hz, device_hz); 192 + u32 div_reg; 193 + u32 val; 194 + 195 + if (rate_hz < device_hz) { 196 + dev_warn(ospi->dev, "Device frequency too large: %d\n", 197 + device_hz); 198 + div_reg = OSPI_CLK_CTL_DIV_1; 199 + } else { 200 + if (div == 1) { 201 + div_reg = OSPI_CLK_CTL_DIV_1; 202 + } else if (div == 2) { 203 + div_reg = OSPI_CLK_CTL_DIV_2; 204 + } else if (div <= 4) { 205 + div_reg = OSPI_CLK_CTL_DIV_4; 206 + } else if (div <= 8) { 207 + div_reg = OSPI_CLK_CTL_DIV_8; 208 + } else { 209 + dev_warn(ospi->dev, "Device frequency too small: %d\n", 210 + device_hz); 211 + div_reg = OSPI_CLK_CTL_DIV_8; 212 + } 213 + } 214 + 215 + /* 216 + * G7: Set clock mode 217 + * clock phase is fixed at 180 degrees and configure edge direction 218 + * instead. 219 + */ 220 + val = readl(ospi->base + OSPI_CLK_CTL); 221 + 222 + val &= ~(OSPI_CLK_CTL_PHA | OSPI_CLK_CTL_DIV); 223 + val |= FIELD_PREP(OSPI_CLK_CTL_PHA, OSPI_CLK_CTL_PHA_180) 224 + | FIELD_PREP(OSPI_CLK_CTL_DIV, div_reg); 225 + 226 + writel(val, ospi->base + OSPI_CLK_CTL); 227 + } 228 + 229 + static void f_ospi_config_dll(struct f_ospi *ospi) 230 + { 231 + /* G8: Configure DLL, nothing */ 232 + } 233 + 234 + static u8 f_ospi_get_mode(struct f_ospi *ospi, int width, int data_size) 235 + { 236 + u8 mode = OSPI_PROT_MODE_SINGLE; 237 + 238 + switch (width) { 239 + case 1: 240 + mode = OSPI_PROT_MODE_SINGLE; 241 + break; 242 + case 2: 243 + mode = OSPI_PROT_MODE_DUAL; 244 + break; 245 + case 4: 246 + mode = OSPI_PROT_MODE_QUAD; 247 + break; 248 + case 8: 249 + mode = OSPI_PROT_MODE_OCTAL; 250 + break; 251 + default: 252 + if (data_size) 253 + dev_err(ospi->dev, "Invalid buswidth: %d\n", width); 254 + break; 255 + } 256 + 257 + return mode; 258 + } 259 + 260 + static void f_ospi_config_indir_protocol(struct f_ospi *ospi, 261 + struct spi_mem *mem, 262 + const struct spi_mem_op *op) 263 + { 264 + struct spi_device *spi = mem->spi; 265 + u8 mode; 266 + u32 prot = 0, val; 267 + int unit; 268 + 269 + /* Set one chip select */ 270 + writel(BIT(spi->chip_select), ospi->base + OSPI_SSEL); 271 + 272 + mode = f_ospi_get_mode(ospi, op->cmd.buswidth, 1); 273 + prot |= FIELD_PREP(OSPI_PROT_MODE_CODE_MASK, mode); 274 + 275 + mode = f_ospi_get_mode(ospi, op->addr.buswidth, op->addr.nbytes); 276 + prot |= FIELD_PREP(OSPI_PROT_MODE_ADDR_MASK, mode); 277 + 278 + mode = f_ospi_get_mode(ospi, op->data.buswidth, op->data.nbytes); 279 + prot |= FIELD_PREP(OSPI_PROT_MODE_DATA_MASK, mode); 280 + 281 + prot |= FIELD_PREP(OSPI_PROT_DATA_RATE_DATA, OSPI_PROT_SDR); 282 + prot |= FIELD_PREP(OSPI_PROT_DATA_RATE_ALT, OSPI_PROT_SDR); 283 + prot |= FIELD_PREP(OSPI_PROT_DATA_RATE_ADDR, OSPI_PROT_SDR); 284 + prot |= FIELD_PREP(OSPI_PROT_DATA_RATE_CODE, OSPI_PROT_SDR); 285 + 286 + if (spi->mode & SPI_LSB_FIRST) 287 + prot |= OSPI_PROT_BIT_POS_DATA | OSPI_PROT_BIT_POS_ALT 288 + | OSPI_PROT_BIT_POS_ADDR | OSPI_PROT_BIT_POS_CODE; 289 + 290 + if (spi->mode & SPI_CPHA) 291 + prot |= OSPI_PROT_SAMP_EDGE; 292 + 293 + /* Examine nbytes % 4 */ 294 + switch (op->data.nbytes & 0x3) { 295 + case 0: 296 + unit = OSPI_PROT_DATA_UNIT_4B; 297 + val = 0; 298 + break; 299 + case 2: 300 + unit = OSPI_PROT_DATA_UNIT_2B; 301 + val = OSPI_DAT_SIZE_EN | (op->data.nbytes - 1); 302 + break; 303 + default: 304 + unit = OSPI_PROT_DATA_UNIT_1B; 305 + val = OSPI_DAT_SIZE_EN | (op->data.nbytes - 1); 306 + break; 307 + } 308 + prot |= FIELD_PREP(OSPI_PROT_DATA_UNIT_MASK, unit); 309 + 310 + switch (op->data.dir) { 311 + case SPI_MEM_DATA_IN: 312 + prot |= OSPI_PROT_DATA_EN; 313 + break; 314 + 315 + case SPI_MEM_DATA_OUT: 316 + prot |= OSPI_PROT_TRANS_DIR_WRITE | OSPI_PROT_DATA_EN; 317 + break; 318 + 319 + case SPI_MEM_NO_DATA: 320 + prot |= OSPI_PROT_TRANS_DIR_WRITE; 321 + break; 322 + 323 + default: 324 + dev_warn(ospi->dev, "Unsupported direction"); 325 + break; 326 + } 327 + 328 + prot |= FIELD_PREP(OSPI_PROT_ADDR_SIZE_MASK, op->addr.nbytes); 329 + prot |= FIELD_PREP(OSPI_PROT_CODE_SIZE_MASK, 1); /* 1byte */ 330 + 331 + writel(prot, ospi->base + OSPI_PROT_CTL_INDIR); 332 + writel(val, ospi->base + OSPI_DAT_SIZE_INDIR); 333 + } 334 + 335 + static int f_ospi_indir_prepare_op(struct f_ospi *ospi, struct spi_mem *mem, 336 + const struct spi_mem_op *op) 337 + { 338 + struct spi_device *spi = mem->spi; 339 + u32 irq_stat_en; 340 + int ret; 341 + 342 + ret = f_ospi_prepare_config(ospi); 343 + if (ret) 344 + return ret; 345 + 346 + f_ospi_config_clk(ospi, spi->max_speed_hz); 347 + 348 + f_ospi_config_indir_protocol(ospi, mem, op); 349 + 350 + writel(f_ospi_get_dummy_cycle(op), ospi->base + OSPI_DMY_INDIR); 351 + writel(op->addr.val, ospi->base + OSPI_ADDR); 352 + writel(op->cmd.opcode, ospi->base + OSPI_CMD_IDX_INDIR); 353 + 354 + f_ospi_clear_irq(ospi); 355 + 356 + switch (op->data.dir) { 357 + case SPI_MEM_DATA_IN: 358 + irq_stat_en = OSPI_IRQ_READ_BUF_READY | OSPI_IRQ_CS_TRANS_COMP; 359 + break; 360 + 361 + case SPI_MEM_DATA_OUT: 362 + irq_stat_en = OSPI_IRQ_WRITE_BUF_READY | OSPI_IRQ_CS_TRANS_COMP; 363 + break; 364 + 365 + case SPI_MEM_NO_DATA: 366 + irq_stat_en = OSPI_IRQ_CS_TRANS_COMP; 367 + break; 368 + 369 + default: 370 + dev_warn(ospi->dev, "Unsupported direction"); 371 + irq_stat_en = 0; 372 + } 373 + 374 + f_ospi_disable_irq_status(ospi, ~irq_stat_en); 375 + f_ospi_enable_irq_status(ospi, irq_stat_en); 376 + 377 + return f_ospi_unprepare_config(ospi); 378 + } 379 + 380 + static void f_ospi_indir_start_xfer(struct f_ospi *ospi) 381 + { 382 + /* Write only 1, auto cleared */ 383 + writel(OSPI_TRANS_CTL_START_REQ, ospi->base + OSPI_TRANS_CTL); 384 + } 385 + 386 + static void f_ospi_indir_stop_xfer(struct f_ospi *ospi) 387 + { 388 + /* Write only 1, auto cleared */ 389 + writel(OSPI_TRANS_CTL_STOP_REQ, ospi->base + OSPI_TRANS_CTL); 390 + } 391 + 392 + static int f_ospi_indir_wait_xfer_complete(struct f_ospi *ospi) 393 + { 394 + u32 val; 395 + 396 + return readl_poll_timeout(ospi->base + OSPI_IRQ, val, 397 + val & OSPI_IRQ_CS_TRANS_COMP, 398 + 0, OSPI_WAIT_MAX_MSEC); 399 + } 400 + 401 + static int f_ospi_indir_read(struct f_ospi *ospi, struct spi_mem *mem, 402 + const struct spi_mem_op *op) 403 + { 404 + u8 *buf = op->data.buf.in; 405 + u32 val; 406 + int i, ret; 407 + 408 + mutex_lock(&ospi->mlock); 409 + 410 + /* E1-2: Prepare transfer operation */ 411 + ret = f_ospi_indir_prepare_op(ospi, mem, op); 412 + if (ret) 413 + goto out; 414 + 415 + f_ospi_indir_start_xfer(ospi); 416 + 417 + /* E3-4: Wait for ready and read data */ 418 + for (i = 0; i < op->data.nbytes; i++) { 419 + ret = readl_poll_timeout(ospi->base + OSPI_IRQ, val, 420 + val & OSPI_IRQ_READ_BUF_READY, 421 + 0, OSPI_WAIT_MAX_MSEC); 422 + if (ret) 423 + goto out; 424 + 425 + buf[i] = readl(ospi->base + OSPI_DAT) & 0xFF; 426 + } 427 + 428 + /* E5-6: Stop transfer if data size is nothing */ 429 + if (!(readl(ospi->base + OSPI_DAT_SIZE_INDIR) & OSPI_DAT_SIZE_EN)) 430 + f_ospi_indir_stop_xfer(ospi); 431 + 432 + /* E7-8: Wait for completion and clear */ 433 + ret = f_ospi_indir_wait_xfer_complete(ospi); 434 + if (ret) 435 + goto out; 436 + 437 + writel(OSPI_IRQ_CS_TRANS_COMP, ospi->base + OSPI_IRQ); 438 + 439 + /* E9: Do nothing if data size is valid */ 440 + if (readl(ospi->base + OSPI_DAT_SIZE_INDIR) & OSPI_DAT_SIZE_EN) 441 + goto out; 442 + 443 + /* E10-11: Reset and check read fifo */ 444 + writel(OSPI_SWRST_INDIR_READ_FIFO, ospi->base + OSPI_SWRST); 445 + 446 + ret = readl_poll_timeout(ospi->base + OSPI_SWRST, val, 447 + !(val & OSPI_SWRST_INDIR_READ_FIFO), 448 + 0, OSPI_WAIT_MAX_MSEC); 449 + out: 450 + mutex_unlock(&ospi->mlock); 451 + 452 + return ret; 453 + } 454 + 455 + static int f_ospi_indir_write(struct f_ospi *ospi, struct spi_mem *mem, 456 + const struct spi_mem_op *op) 457 + { 458 + u8 *buf = (u8 *)op->data.buf.out; 459 + u32 val; 460 + int i, ret; 461 + 462 + mutex_lock(&ospi->mlock); 463 + 464 + /* F1-3: Prepare transfer operation */ 465 + ret = f_ospi_indir_prepare_op(ospi, mem, op); 466 + if (ret) 467 + goto out; 468 + 469 + f_ospi_indir_start_xfer(ospi); 470 + 471 + if (!(readl(ospi->base + OSPI_PROT_CTL_INDIR) & OSPI_PROT_DATA_EN)) 472 + goto nodata; 473 + 474 + /* F4-5: Wait for buffer ready and write data */ 475 + for (i = 0; i < op->data.nbytes; i++) { 476 + ret = readl_poll_timeout(ospi->base + OSPI_IRQ, val, 477 + val & OSPI_IRQ_WRITE_BUF_READY, 478 + 0, OSPI_WAIT_MAX_MSEC); 479 + if (ret) 480 + goto out; 481 + 482 + writel(buf[i], ospi->base + OSPI_DAT); 483 + } 484 + 485 + /* F6-7: Stop transfer if data size is nothing */ 486 + if (!(readl(ospi->base + OSPI_DAT_SIZE_INDIR) & OSPI_DAT_SIZE_EN)) 487 + f_ospi_indir_stop_xfer(ospi); 488 + 489 + nodata: 490 + /* F8-9: Wait for completion and clear */ 491 + ret = f_ospi_indir_wait_xfer_complete(ospi); 492 + if (ret) 493 + goto out; 494 + 495 + writel(OSPI_IRQ_CS_TRANS_COMP, ospi->base + OSPI_IRQ); 496 + out: 497 + mutex_unlock(&ospi->mlock); 498 + 499 + return ret; 500 + } 501 + 502 + static int f_ospi_exec_op(struct spi_mem *mem, const struct spi_mem_op *op) 503 + { 504 + struct f_ospi *ospi = spi_controller_get_devdata(mem->spi->master); 505 + int err = 0; 506 + 507 + switch (op->data.dir) { 508 + case SPI_MEM_DATA_IN: 509 + err = f_ospi_indir_read(ospi, mem, op); 510 + break; 511 + 512 + case SPI_MEM_DATA_OUT: 513 + fallthrough; 514 + case SPI_MEM_NO_DATA: 515 + err = f_ospi_indir_write(ospi, mem, op); 516 + break; 517 + 518 + default: 519 + dev_warn(ospi->dev, "Unsupported direction"); 520 + err = -EOPNOTSUPP; 521 + } 522 + 523 + return err; 524 + } 525 + 526 + static bool f_ospi_supports_op_width(struct spi_mem *mem, 527 + const struct spi_mem_op *op) 528 + { 529 + u8 width_available[] = { 0, 1, 2, 4, 8 }; 530 + u8 width_op[] = { op->cmd.buswidth, op->addr.buswidth, 531 + op->dummy.buswidth, op->data.buswidth }; 532 + bool is_match_found; 533 + int i, j; 534 + 535 + for (i = 0; i < ARRAY_SIZE(width_op); i++) { 536 + is_match_found = false; 537 + 538 + for (j = 0; j < ARRAY_SIZE(width_available); j++) { 539 + if (width_op[i] == width_available[j]) { 540 + is_match_found = true; 541 + break; 542 + } 543 + } 544 + 545 + if (!is_match_found) 546 + return false; 547 + } 548 + 549 + return true; 550 + } 551 + 552 + static bool f_ospi_supports_op(struct spi_mem *mem, 553 + const struct spi_mem_op *op) 554 + { 555 + if (f_ospi_get_dummy_cycle(op) > OSPI_DUMMY_CYCLE_MAX) 556 + return false; 557 + 558 + if (op->addr.nbytes > 4) 559 + return false; 560 + 561 + if (!f_ospi_supports_op_width(mem, op)) 562 + return false; 563 + 564 + return true; 565 + } 566 + 567 + static int f_ospi_adjust_op_size(struct spi_mem *mem, struct spi_mem_op *op) 568 + { 569 + op->data.nbytes = min((int)op->data.nbytes, (int)(OSPI_DAT_SIZE_MAX)); 570 + 571 + return 0; 572 + } 573 + 574 + static const struct spi_controller_mem_ops f_ospi_mem_ops = { 575 + .adjust_op_size = f_ospi_adjust_op_size, 576 + .supports_op = f_ospi_supports_op, 577 + .exec_op = f_ospi_exec_op, 578 + }; 579 + 580 + static int f_ospi_init(struct f_ospi *ospi) 581 + { 582 + int ret; 583 + 584 + ret = f_ospi_prepare_config(ospi); 585 + if (ret) 586 + return ret; 587 + 588 + /* Disable boot signal */ 589 + writel(OSPI_ACC_MODE_BOOT_DISABLE, ospi->base + OSPI_ACC_MODE); 590 + 591 + f_ospi_config_dll(ospi); 592 + 593 + /* Disable IRQ */ 594 + f_ospi_clear_irq(ospi); 595 + f_ospi_disable_irq_status(ospi, OSPI_IRQ_ALL); 596 + f_ospi_disable_irq_output(ospi, OSPI_IRQ_ALL); 597 + 598 + return f_ospi_unprepare_config(ospi); 599 + } 600 + 601 + static int f_ospi_probe(struct platform_device *pdev) 602 + { 603 + struct spi_controller *ctlr; 604 + struct device *dev = &pdev->dev; 605 + struct f_ospi *ospi; 606 + u32 num_cs = OSPI_NUM_CS; 607 + int ret; 608 + 609 + ctlr = spi_alloc_master(dev, sizeof(*ospi)); 610 + if (!ctlr) 611 + return -ENOMEM; 612 + 613 + ctlr->mode_bits = SPI_TX_DUAL | SPI_TX_QUAD | SPI_TX_OCTAL 614 + | SPI_RX_DUAL | SPI_RX_QUAD | SPI_TX_OCTAL 615 + | SPI_MODE_0 | SPI_MODE_1 | SPI_LSB_FIRST; 616 + ctlr->mem_ops = &f_ospi_mem_ops; 617 + ctlr->bus_num = -1; 618 + of_property_read_u32(dev->of_node, "num-cs", &num_cs); 619 + if (num_cs > OSPI_NUM_CS) { 620 + dev_err(dev, "num-cs too large: %d\n", num_cs); 621 + return -ENOMEM; 622 + } 623 + ctlr->num_chipselect = num_cs; 624 + ctlr->dev.of_node = dev->of_node; 625 + 626 + ospi = spi_controller_get_devdata(ctlr); 627 + ospi->dev = dev; 628 + 629 + platform_set_drvdata(pdev, ospi); 630 + 631 + ospi->base = devm_platform_ioremap_resource(pdev, 0); 632 + if (IS_ERR(ospi->base)) { 633 + ret = PTR_ERR(ospi->base); 634 + goto err_put_ctlr; 635 + } 636 + 637 + ospi->clk = devm_clk_get(dev, NULL); 638 + if (IS_ERR(ospi->clk)) { 639 + ret = PTR_ERR(ospi->clk); 640 + goto err_put_ctlr; 641 + } 642 + 643 + ret = clk_prepare_enable(ospi->clk); 644 + if (ret) { 645 + dev_err(dev, "Failed to enable the clock\n"); 646 + goto err_disable_clk; 647 + } 648 + 649 + mutex_init(&ospi->mlock); 650 + 651 + ret = f_ospi_init(ospi); 652 + if (ret) 653 + goto err_destroy_mutex; 654 + 655 + ret = devm_spi_register_controller(dev, ctlr); 656 + if (ret) 657 + goto err_destroy_mutex; 658 + 659 + return 0; 660 + 661 + err_destroy_mutex: 662 + mutex_destroy(&ospi->mlock); 663 + 664 + err_disable_clk: 665 + clk_disable_unprepare(ospi->clk); 666 + 667 + err_put_ctlr: 668 + spi_controller_put(ctlr); 669 + 670 + return ret; 671 + } 672 + 673 + static int f_ospi_remove(struct platform_device *pdev) 674 + { 675 + struct f_ospi *ospi = platform_get_drvdata(pdev); 676 + 677 + clk_disable_unprepare(ospi->clk); 678 + 679 + mutex_destroy(&ospi->mlock); 680 + 681 + return 0; 682 + } 683 + 684 + static const struct of_device_id f_ospi_dt_ids[] = { 685 + { .compatible = "socionext,f-ospi" }, 686 + {} 687 + }; 688 + MODULE_DEVICE_TABLE(of, f_ospi_dt_ids); 689 + 690 + static struct platform_driver f_ospi_driver = { 691 + .driver = { 692 + .name = "socionext,f-ospi", 693 + .of_match_table = f_ospi_dt_ids, 694 + }, 695 + .probe = f_ospi_probe, 696 + .remove = f_ospi_remove, 697 + }; 698 + module_platform_driver(f_ospi_driver); 699 + 700 + MODULE_DESCRIPTION("Socionext F_OSPI controller driver"); 701 + MODULE_AUTHOR("Socionext Inc."); 702 + MODULE_AUTHOR("Kunihiko Hayashi <hayashi.kunihiko@socionext.com>"); 703 + MODULE_LICENSE("GPL");