1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * SG2044 SPI NOR controller driver 4 * 5 * Copyright (c) 2025 Longbin Li <looong.bin@gmail.com> 6 */ 7 8 #include <linux/bitfield.h> 9 #include <linux/clk.h> 10 #include <linux/iopoll.h> 11 #include <linux/module.h> 12 #include <linux/of.h> 13 #include <linux/platform_device.h> 14 #include <linux/spi/spi-mem.h> 15 16 /* Hardware register definitions */ 17 #define SPIFMC_CTRL 0x00 18 #define SPIFMC_CTRL_CPHA BIT(12) 19 #define SPIFMC_CTRL_CPOL BIT(13) 20 #define SPIFMC_CTRL_HOLD_OL BIT(14) 21 #define SPIFMC_CTRL_WP_OL BIT(15) 22 #define SPIFMC_CTRL_LSBF BIT(20) 23 #define SPIFMC_CTRL_SRST BIT(21) 24 #define SPIFMC_CTRL_SCK_DIV_SHIFT 0 25 #define SPIFMC_CTRL_FRAME_LEN_SHIFT 16 26 #define SPIFMC_CTRL_SCK_DIV_MASK 0x7FF 27 28 #define SPIFMC_CE_CTRL 0x04 29 #define SPIFMC_CE_CTRL_CEMANUAL BIT(0) 30 #define SPIFMC_CE_CTRL_CEMANUAL_EN BIT(1) 31 32 #define SPIFMC_DLY_CTRL 0x08 33 #define SPIFMC_CTRL_FM_INTVL_MASK 0x000f 34 #define SPIFMC_CTRL_FM_INTVL BIT(0) 35 #define SPIFMC_CTRL_CET_MASK 0x0f00 36 #define SPIFMC_CTRL_CET BIT(8) 37 38 #define SPIFMC_DMMR 0x0c 39 40 #define SPIFMC_TRAN_CSR 0x10 41 #define SPIFMC_TRAN_CSR_TRAN_MODE_MASK GENMASK(1, 0) 42 #define SPIFMC_TRAN_CSR_TRAN_MODE_RX BIT(0) 43 #define SPIFMC_TRAN_CSR_TRAN_MODE_TX BIT(1) 44 #define SPIFMC_TRAN_CSR_FAST_MODE BIT(3) 45 #define SPIFMC_TRAN_CSR_BUS_WIDTH_1_BIT (0x00 << 4) 46 #define SPIFMC_TRAN_CSR_BUS_WIDTH_2_BIT (0x01 << 4) 47 #define SPIFMC_TRAN_CSR_BUS_WIDTH_4_BIT (0x02 << 4) 48 #define SPIFMC_TRAN_CSR_DMA_EN BIT(6) 49 #define SPIFMC_TRAN_CSR_MISO_LEVEL BIT(7) 50 #define SPIFMC_TRAN_CSR_ADDR_BYTES_MASK GENMASK(10, 8) 51 #define SPIFMC_TRAN_CSR_ADDR_BYTES_SHIFT 8 52 #define SPIFMC_TRAN_CSR_WITH_CMD BIT(11) 53 #define SPIFMC_TRAN_CSR_FIFO_TRG_LVL_MASK GENMASK(13, 12) 54 #define SPIFMC_TRAN_CSR_FIFO_TRG_LVL_1_BYTE (0x00 << 12) 55 #define SPIFMC_TRAN_CSR_FIFO_TRG_LVL_2_BYTE (0x01 << 12) 56 #define SPIFMC_TRAN_CSR_FIFO_TRG_LVL_4_BYTE (0x02 << 12) 57 #define SPIFMC_TRAN_CSR_FIFO_TRG_LVL_8_BYTE (0x03 << 12) 58 #define SPIFMC_TRAN_CSR_GO_BUSY BIT(15) 59 #define SPIFMC_TRAN_CSR_ADDR4B_SHIFT 20 60 #define SPIFMC_TRAN_CSR_CMD4B_SHIFT 21 61 62 #define SPIFMC_TRAN_NUM 0x14 63 #define SPIFMC_FIFO_PORT 0x18 64 #define SPIFMC_FIFO_PT 0x20 65 66 #define SPIFMC_INT_STS 0x28 67 #define SPIFMC_INT_TRAN_DONE BIT(0) 68 #define SPIFMC_INT_RD_FIFO BIT(2) 69 #define SPIFMC_INT_WR_FIFO BIT(3) 70 #define SPIFMC_INT_RX_FRAME BIT(4) 71 #define SPIFMC_INT_TX_FRAME BIT(5) 72 73 #define SPIFMC_INT_EN 0x2c 74 #define SPIFMC_INT_TRAN_DONE_EN BIT(0) 75 #define SPIFMC_INT_RD_FIFO_EN BIT(2) 76 #define SPIFMC_INT_WR_FIFO_EN BIT(3) 77 #define SPIFMC_INT_RX_FRAME_EN BIT(4) 78 #define SPIFMC_INT_TX_FRAME_EN BIT(5) 79 80 #define SPIFMC_OPT 0x030 81 #define SPIFMC_OPT_DISABLE_FIFO_FLUSH BIT(1) 82 83 #define SPIFMC_MAX_FIFO_DEPTH 8 84 85 #define SPIFMC_MAX_READ_SIZE 0x10000 86 87 struct sg2044_spifmc { 88 struct spi_controller *ctrl; 89 void __iomem *io_base; 90 struct device *dev; 91 struct mutex lock; 92 struct clk *clk; 93 }; 94 95 static int sg2044_spifmc_wait_int(struct sg2044_spifmc *spifmc, u8 int_type) 96 { 97 u32 stat; 98 99 return readl_poll_timeout(spifmc->io_base + SPIFMC_INT_STS, stat, 100 (stat & int_type), 0, 1000000); 101 } 102 103 static int sg2044_spifmc_wait_xfer_size(struct sg2044_spifmc *spifmc, 104 int xfer_size) 105 { 106 u8 stat; 107 108 return readl_poll_timeout(spifmc->io_base + SPIFMC_FIFO_PT, stat, 109 ((stat & 0xf) == xfer_size), 1, 1000000); 110 } 111 112 static u32 sg2044_spifmc_init_reg(struct sg2044_spifmc *spifmc) 113 { 114 u32 reg; 115 116 reg = readl(spifmc->io_base + SPIFMC_TRAN_CSR); 117 reg &= ~(SPIFMC_TRAN_CSR_TRAN_MODE_MASK | 118 SPIFMC_TRAN_CSR_FAST_MODE | 119 SPIFMC_TRAN_CSR_BUS_WIDTH_2_BIT | 120 SPIFMC_TRAN_CSR_BUS_WIDTH_4_BIT | 121 SPIFMC_TRAN_CSR_DMA_EN | 122 SPIFMC_TRAN_CSR_ADDR_BYTES_MASK | 123 SPIFMC_TRAN_CSR_WITH_CMD | 124 SPIFMC_TRAN_CSR_FIFO_TRG_LVL_MASK); 125 126 writel(reg, spifmc->io_base + SPIFMC_TRAN_CSR); 127 128 return reg; 129 } 130 131 static ssize_t sg2044_spifmc_read_64k(struct sg2044_spifmc *spifmc, 132 const struct spi_mem_op *op, loff_t from, 133 size_t len, u_char *buf) 134 { 135 int xfer_size, offset; 136 u32 reg; 137 int ret; 138 int i; 139 140 reg = sg2044_spifmc_init_reg(spifmc); 141 reg |= (op->addr.nbytes + op->dummy.nbytes) << SPIFMC_TRAN_CSR_ADDR_BYTES_SHIFT; 142 reg |= SPIFMC_TRAN_CSR_FIFO_TRG_LVL_8_BYTE; 143 reg |= SPIFMC_TRAN_CSR_WITH_CMD; 144 reg |= SPIFMC_TRAN_CSR_TRAN_MODE_RX; 145 146 writel(0, spifmc->io_base + SPIFMC_FIFO_PT); 147 writeb(op->cmd.opcode, spifmc->io_base + SPIFMC_FIFO_PORT); 148 149 for (i = op->addr.nbytes - 1; i >= 0; i--) 150 writeb((from >> i * 8) & 0xff, spifmc->io_base + SPIFMC_FIFO_PORT); 151 152 for (i = 0; i < op->dummy.nbytes; i++) 153 writeb(0xff, spifmc->io_base + SPIFMC_FIFO_PORT); 154 155 writel(len, spifmc->io_base + SPIFMC_TRAN_NUM); 156 writel(0, spifmc->io_base + SPIFMC_INT_STS); 157 reg |= SPIFMC_TRAN_CSR_GO_BUSY; 158 writel(reg, spifmc->io_base + SPIFMC_TRAN_CSR); 159 160 ret = sg2044_spifmc_wait_int(spifmc, SPIFMC_INT_RD_FIFO); 161 if (ret < 0) 162 return ret; 163 164 offset = 0; 165 while (offset < len) { 166 xfer_size = min_t(size_t, SPIFMC_MAX_FIFO_DEPTH, len - offset); 167 168 ret = sg2044_spifmc_wait_xfer_size(spifmc, xfer_size); 169 if (ret < 0) 170 return ret; 171 172 for (i = 0; i < xfer_size; i++) 173 buf[i + offset] = readb(spifmc->io_base + SPIFMC_FIFO_PORT); 174 175 offset += xfer_size; 176 } 177 178 ret = sg2044_spifmc_wait_int(spifmc, SPIFMC_INT_TRAN_DONE); 179 if (ret < 0) 180 return ret; 181 182 writel(0, spifmc->io_base + SPIFMC_FIFO_PT); 183 184 return len; 185 } 186 187 static ssize_t sg2044_spifmc_read(struct sg2044_spifmc *spifmc, 188 const struct spi_mem_op *op) 189 { 190 size_t xfer_size; 191 size_t offset; 192 loff_t from = op->addr.val; 193 size_t len = op->data.nbytes; 194 int ret; 195 u8 *din = op->data.buf.in; 196 197 offset = 0; 198 while (offset < len) { 199 xfer_size = min_t(size_t, SPIFMC_MAX_READ_SIZE, len - offset); 200 201 ret = sg2044_spifmc_read_64k(spifmc, op, from, xfer_size, din); 202 if (ret < 0) 203 return ret; 204 205 offset += xfer_size; 206 din += xfer_size; 207 from += xfer_size; 208 } 209 210 return 0; 211 } 212 213 static ssize_t sg2044_spifmc_write(struct sg2044_spifmc *spifmc, 214 const struct spi_mem_op *op) 215 { 216 size_t xfer_size; 217 const u8 *dout = op->data.buf.out; 218 int i, offset; 219 int ret; 220 u32 reg; 221 222 reg = sg2044_spifmc_init_reg(spifmc); 223 reg |= (op->addr.nbytes + op->dummy.nbytes) << SPIFMC_TRAN_CSR_ADDR_BYTES_SHIFT; 224 reg |= SPIFMC_TRAN_CSR_FIFO_TRG_LVL_8_BYTE; 225 reg |= SPIFMC_TRAN_CSR_WITH_CMD; 226 reg |= SPIFMC_TRAN_CSR_TRAN_MODE_TX; 227 228 writel(0, spifmc->io_base + SPIFMC_FIFO_PT); 229 writeb(op->cmd.opcode, spifmc->io_base + SPIFMC_FIFO_PORT); 230 231 for (i = op->addr.nbytes - 1; i >= 0; i--) 232 writeb((op->addr.val >> i * 8) & 0xff, spifmc->io_base + SPIFMC_FIFO_PORT); 233 234 for (i = 0; i < op->dummy.nbytes; i++) 235 writeb(0xff, spifmc->io_base + SPIFMC_FIFO_PORT); 236 237 writel(0, spifmc->io_base + SPIFMC_INT_STS); 238 writel(op->data.nbytes, spifmc->io_base + SPIFMC_TRAN_NUM); 239 reg |= SPIFMC_TRAN_CSR_GO_BUSY; 240 writel(reg, spifmc->io_base + SPIFMC_TRAN_CSR); 241 242 ret = sg2044_spifmc_wait_xfer_size(spifmc, 0); 243 if (ret < 0) 244 return ret; 245 246 writel(0, spifmc->io_base + SPIFMC_FIFO_PT); 247 248 offset = 0; 249 while (offset < op->data.nbytes) { 250 xfer_size = min_t(size_t, SPIFMC_MAX_FIFO_DEPTH, op->data.nbytes - offset); 251 252 ret = sg2044_spifmc_wait_xfer_size(spifmc, 0); 253 if (ret < 0) 254 return ret; 255 256 for (i = 0; i < xfer_size; i++) 257 writeb(dout[i + offset], spifmc->io_base + SPIFMC_FIFO_PORT); 258 259 offset += xfer_size; 260 } 261 262 ret = sg2044_spifmc_wait_int(spifmc, SPIFMC_INT_TRAN_DONE); 263 if (ret < 0) 264 return ret; 265 266 writel(0, spifmc->io_base + SPIFMC_FIFO_PT); 267 268 return 0; 269 } 270 271 static ssize_t sg2044_spifmc_tran_cmd(struct sg2044_spifmc *spifmc, 272 const struct spi_mem_op *op) 273 { 274 int i, ret; 275 u32 reg; 276 277 reg = sg2044_spifmc_init_reg(spifmc); 278 reg |= (op->addr.nbytes + op->dummy.nbytes) << SPIFMC_TRAN_CSR_ADDR_BYTES_SHIFT; 279 reg |= SPIFMC_TRAN_CSR_FIFO_TRG_LVL_1_BYTE; 280 reg |= SPIFMC_TRAN_CSR_WITH_CMD; 281 282 writel(0, spifmc->io_base + SPIFMC_FIFO_PT); 283 writeb(op->cmd.opcode, spifmc->io_base + SPIFMC_FIFO_PORT); 284 285 for (i = op->addr.nbytes - 1; i >= 0; i--) 286 writeb((op->addr.val >> i * 8) & 0xff, spifmc->io_base + SPIFMC_FIFO_PORT); 287 288 for (i = 0; i < op->dummy.nbytes; i++) 289 writeb(0xff, spifmc->io_base + SPIFMC_FIFO_PORT); 290 291 writel(0, spifmc->io_base + SPIFMC_INT_STS); 292 reg |= SPIFMC_TRAN_CSR_GO_BUSY; 293 writel(reg, spifmc->io_base + SPIFMC_TRAN_CSR); 294 295 ret = sg2044_spifmc_wait_int(spifmc, SPIFMC_INT_TRAN_DONE); 296 if (ret < 0) 297 return ret; 298 299 writel(0, spifmc->io_base + SPIFMC_FIFO_PT); 300 301 return 0; 302 } 303 304 static void sg2044_spifmc_trans(struct sg2044_spifmc *spifmc, 305 const struct spi_mem_op *op) 306 { 307 if (op->data.dir == SPI_MEM_DATA_IN) 308 sg2044_spifmc_read(spifmc, op); 309 else if (op->data.dir == SPI_MEM_DATA_OUT) 310 sg2044_spifmc_write(spifmc, op); 311 else 312 sg2044_spifmc_tran_cmd(spifmc, op); 313 } 314 315 static ssize_t sg2044_spifmc_trans_reg(struct sg2044_spifmc *spifmc, 316 const struct spi_mem_op *op) 317 { 318 const u8 *dout = NULL; 319 u8 *din = NULL; 320 size_t len = op->data.nbytes; 321 int ret, i; 322 u32 reg; 323 324 if (op->data.dir == SPI_MEM_DATA_IN) 325 din = op->data.buf.in; 326 else 327 dout = op->data.buf.out; 328 329 reg = sg2044_spifmc_init_reg(spifmc); 330 reg |= SPIFMC_TRAN_CSR_FIFO_TRG_LVL_1_BYTE; 331 reg |= SPIFMC_TRAN_CSR_WITH_CMD; 332 333 if (din) { 334 reg |= SPIFMC_TRAN_CSR_BUS_WIDTH_1_BIT; 335 reg |= SPIFMC_TRAN_CSR_TRAN_MODE_RX; 336 reg |= SPIFMC_TRAN_CSR_TRAN_MODE_TX; 337 338 writel(SPIFMC_OPT_DISABLE_FIFO_FLUSH, spifmc->io_base + SPIFMC_OPT); 339 } else { 340 /* 341 * If write values to the Status Register, 342 * configure TRAN_CSR register as the same as 343 * sg2044_spifmc_read_reg. 344 */ 345 if (op->cmd.opcode == 0x01) { 346 reg |= SPIFMC_TRAN_CSR_TRAN_MODE_RX; 347 reg |= SPIFMC_TRAN_CSR_TRAN_MODE_TX; 348 writel(len, spifmc->io_base + SPIFMC_TRAN_NUM); 349 } 350 } 351 352 writel(0, spifmc->io_base + SPIFMC_FIFO_PT); 353 writeb(op->cmd.opcode, spifmc->io_base + SPIFMC_FIFO_PORT); 354 355 for (i = 0; i < len; i++) { 356 if (din) 357 writeb(0xff, spifmc->io_base + SPIFMC_FIFO_PORT); 358 else 359 writeb(dout[i], spifmc->io_base + SPIFMC_FIFO_PORT); 360 } 361 362 writel(0, spifmc->io_base + SPIFMC_INT_STS); 363 writel(len, spifmc->io_base + SPIFMC_TRAN_NUM); 364 reg |= SPIFMC_TRAN_CSR_GO_BUSY; 365 writel(reg, spifmc->io_base + SPIFMC_TRAN_CSR); 366 367 ret = sg2044_spifmc_wait_int(spifmc, SPIFMC_INT_TRAN_DONE); 368 if (ret < 0) 369 return ret; 370 371 if (din) { 372 while (len--) 373 *din++ = readb(spifmc->io_base + SPIFMC_FIFO_PORT); 374 } 375 376 writel(0, spifmc->io_base + SPIFMC_FIFO_PT); 377 378 return 0; 379 } 380 381 static int sg2044_spifmc_exec_op(struct spi_mem *mem, 382 const struct spi_mem_op *op) 383 { 384 struct sg2044_spifmc *spifmc; 385 386 spifmc = spi_controller_get_devdata(mem->spi->controller); 387 388 mutex_lock(&spifmc->lock); 389 390 if (op->addr.nbytes == 0) 391 sg2044_spifmc_trans_reg(spifmc, op); 392 else 393 sg2044_spifmc_trans(spifmc, op); 394 395 mutex_unlock(&spifmc->lock); 396 397 return 0; 398 } 399 400 static const struct spi_controller_mem_ops sg2044_spifmc_mem_ops = { 401 .exec_op = sg2044_spifmc_exec_op, 402 }; 403 404 static void sg2044_spifmc_init(struct sg2044_spifmc *spifmc) 405 { 406 u32 tran_csr; 407 u32 reg; 408 409 writel(0, spifmc->io_base + SPIFMC_DMMR); 410 411 reg = readl(spifmc->io_base + SPIFMC_CTRL); 412 reg |= SPIFMC_CTRL_SRST; 413 reg &= ~(SPIFMC_CTRL_SCK_DIV_MASK); 414 reg |= 1; 415 writel(reg, spifmc->io_base + SPIFMC_CTRL); 416 417 writel(0, spifmc->io_base + SPIFMC_CE_CTRL); 418 419 tran_csr = readl(spifmc->io_base + SPIFMC_TRAN_CSR); 420 tran_csr |= (0 << SPIFMC_TRAN_CSR_ADDR_BYTES_SHIFT); 421 tran_csr |= SPIFMC_TRAN_CSR_FIFO_TRG_LVL_4_BYTE; 422 tran_csr |= SPIFMC_TRAN_CSR_WITH_CMD; 423 writel(tran_csr, spifmc->io_base + SPIFMC_TRAN_CSR); 424 } 425 426 static int sg2044_spifmc_probe(struct platform_device *pdev) 427 { 428 struct device *dev = &pdev->dev; 429 struct spi_controller *ctrl; 430 struct sg2044_spifmc *spifmc; 431 int ret; 432 433 ctrl = devm_spi_alloc_host(&pdev->dev, sizeof(*spifmc)); 434 if (!ctrl) 435 return -ENOMEM; 436 437 spifmc = spi_controller_get_devdata(ctrl); 438 439 spifmc->clk = devm_clk_get_enabled(&pdev->dev, NULL); 440 if (IS_ERR(spifmc->clk)) 441 return dev_err_probe(dev, PTR_ERR(spifmc->clk), "Cannot get and enable AHB clock\n"); 442 443 spifmc->dev = &pdev->dev; 444 spifmc->ctrl = ctrl; 445 446 spifmc->io_base = devm_platform_ioremap_resource(pdev, 0); 447 if (IS_ERR(spifmc->io_base)) 448 return PTR_ERR(spifmc->io_base); 449 450 ctrl->num_chipselect = 1; 451 ctrl->dev.of_node = pdev->dev.of_node; 452 ctrl->bits_per_word_mask = SPI_BPW_MASK(8); 453 ctrl->auto_runtime_pm = false; 454 ctrl->mem_ops = &sg2044_spifmc_mem_ops; 455 ctrl->mode_bits = SPI_RX_DUAL | SPI_TX_DUAL | SPI_RX_QUAD | SPI_TX_QUAD; 456 457 ret = devm_mutex_init(dev, &spifmc->lock); 458 if (ret) 459 return ret; 460 461 sg2044_spifmc_init(spifmc); 462 sg2044_spifmc_init_reg(spifmc); 463 464 ret = devm_spi_register_controller(&pdev->dev, ctrl); 465 if (ret) 466 return dev_err_probe(dev, ret, "spi_register_controller failed\n"); 467 468 return 0; 469 } 470 471 static const struct of_device_id sg2044_spifmc_match[] = { 472 { .compatible = "sophgo,sg2044-spifmc-nor" }, 473 { /* sentinel */ } 474 }; 475 MODULE_DEVICE_TABLE(of, sg2044_spifmc_match); 476 477 static struct platform_driver sg2044_nor_driver = { 478 .driver = { 479 .name = "sg2044,spifmc-nor", 480 .of_match_table = sg2044_spifmc_match, 481 }, 482 .probe = sg2044_spifmc_probe, 483 }; 484 module_platform_driver(sg2044_nor_driver); 485 486 MODULE_DESCRIPTION("SG2044 SPI NOR controller driver"); 487 MODULE_AUTHOR("Longbin Li <looong.bin@gmail.com>"); 488 MODULE_LICENSE("GPL"); 489