1119 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Copyright (c) 2024 AIROHA Inc4 * Author: Lorenzo Bianconi <lorenzo@kernel.org>5 * Author: Ray Liu <ray.liu@airoha.com>6 */7 8#include <linux/bitfield.h>9#include <linux/clk.h>10#include <linux/delay.h>11#include <linux/device.h>12#include <linux/dma-mapping.h>13#include <linux/errno.h>14#include <linux/limits.h>15#include <linux/math.h>16#include <linux/minmax.h>17#include <linux/module.h>18#include <linux/mutex.h>19#include <linux/platform_device.h>20#include <linux/property.h>21#include <linux/regmap.h>22#include <linux/sizes.h>23#include <linux/spi/spi.h>24#include <linux/spi/spi-mem.h>25#include <linux/types.h>26#include <linux/unaligned.h>27 28/* SPI */29#define REG_SPI_CTRL_BASE 0x1FA1000030 31#define REG_SPI_CTRL_READ_MODE 0x000032#define REG_SPI_CTRL_READ_IDLE_EN 0x000433#define REG_SPI_CTRL_SIDLY 0x000834#define REG_SPI_CTRL_CSHEXT 0x000c35#define REG_SPI_CTRL_CSLEXT 0x001036 37#define REG_SPI_CTRL_MTX_MODE_TOG 0x001438#define SPI_CTRL_MTX_MODE_TOG GENMASK(3, 0)39 40#define REG_SPI_CTRL_RDCTL_FSM 0x001841#define SPI_CTRL_RDCTL_FSM GENMASK(3, 0)42 43#define REG_SPI_CTRL_MACMUX_SEL 0x001c44 45#define REG_SPI_CTRL_MANUAL_EN 0x002046#define SPI_CTRL_MANUAL_EN BIT(0)47 48#define REG_SPI_CTRL_OPFIFO_EMPTY 0x002449#define SPI_CTRL_OPFIFO_EMPTY BIT(0)50 51#define REG_SPI_CTRL_OPFIFO_WDATA 0x002852#define SPI_CTRL_OPFIFO_LEN GENMASK(8, 0)53#define SPI_CTRL_OPFIFO_OP GENMASK(13, 9)54 55#define REG_SPI_CTRL_OPFIFO_FULL 0x002c56#define SPI_CTRL_OPFIFO_FULL BIT(0)57 58#define REG_SPI_CTRL_OPFIFO_WR 0x003059#define SPI_CTRL_OPFIFO_WR BIT(0)60 61#define REG_SPI_CTRL_DFIFO_FULL 0x003462#define SPI_CTRL_DFIFO_FULL BIT(0)63 64#define REG_SPI_CTRL_DFIFO_WDATA 0x003865#define SPI_CTRL_DFIFO_WDATA GENMASK(7, 0)66 67#define REG_SPI_CTRL_DFIFO_EMPTY 0x003c68#define SPI_CTRL_DFIFO_EMPTY BIT(0)69 70#define REG_SPI_CTRL_DFIFO_RD 0x004071#define SPI_CTRL_DFIFO_RD BIT(0)72 73#define REG_SPI_CTRL_DFIFO_RDATA 0x004474#define SPI_CTRL_DFIFO_RDATA GENMASK(7, 0)75 76#define REG_SPI_CTRL_DUMMY 0x008077#define SPI_CTRL_CTRL_DUMMY GENMASK(3, 0)78 79#define REG_SPI_CTRL_PROBE_SEL 0x008880#define REG_SPI_CTRL_INTERRUPT 0x009081#define REG_SPI_CTRL_INTERRUPT_EN 0x009482#define REG_SPI_CTRL_SI_CK_SEL 0x009c83#define REG_SPI_CTRL_SW_CFGNANDADDR_VAL 0x010c84#define REG_SPI_CTRL_SW_CFGNANDADDR_EN 0x011085#define REG_SPI_CTRL_SFC_STRAP 0x011486 87#define REG_SPI_CTRL_NFI2SPI_EN 0x013088#define SPI_CTRL_NFI2SPI_EN BIT(0)89 90/* NFI2SPI */91#define REG_SPI_NFI_CNFG 0x000092#define SPI_NFI_DMA_MODE BIT(0)93#define SPI_NFI_READ_MODE BIT(1)94#define SPI_NFI_DMA_BURST_EN BIT(2)95#define SPI_NFI_HW_ECC_EN BIT(8)96#define SPI_NFI_AUTO_FDM_EN BIT(9)97#define SPI_NFI_OPMODE GENMASK(14, 12)98 99#define REG_SPI_NFI_PAGEFMT 0x0004100#define SPI_NFI_PAGE_SIZE GENMASK(1, 0)101#define SPI_NFI_SPARE_SIZE GENMASK(5, 4)102 103#define REG_SPI_NFI_CON 0x0008104#define SPI_NFI_FIFO_FLUSH BIT(0)105#define SPI_NFI_RST BIT(1)106#define SPI_NFI_RD_TRIG BIT(8)107#define SPI_NFI_WR_TRIG BIT(9)108#define SPI_NFI_SEC_NUM GENMASK(15, 12)109 110#define REG_SPI_NFI_INTR_EN 0x0010111#define SPI_NFI_RD_DONE_EN BIT(0)112#define SPI_NFI_WR_DONE_EN BIT(1)113#define SPI_NFI_RST_DONE_EN BIT(2)114#define SPI_NFI_ERASE_DONE_EN BIT(3)115#define SPI_NFI_BUSY_RETURN_EN BIT(4)116#define SPI_NFI_ACCESS_LOCK_EN BIT(5)117#define SPI_NFI_AHB_DONE_EN BIT(6)118#define SPI_NFI_ALL_IRQ_EN \119 (SPI_NFI_RD_DONE_EN | SPI_NFI_WR_DONE_EN | \120 SPI_NFI_RST_DONE_EN | SPI_NFI_ERASE_DONE_EN | \121 SPI_NFI_BUSY_RETURN_EN | SPI_NFI_ACCESS_LOCK_EN | \122 SPI_NFI_AHB_DONE_EN)123 124#define REG_SPI_NFI_INTR 0x0014125#define SPI_NFI_AHB_DONE BIT(6)126 127#define REG_SPI_NFI_CMD 0x0020128 129#define REG_SPI_NFI_ADDR_NOB 0x0030130#define SPI_NFI_ROW_ADDR_NOB GENMASK(6, 4)131 132#define REG_SPI_NFI_STA 0x0060133#define REG_SPI_NFI_FIFOSTA 0x0064134#define REG_SPI_NFI_STRADDR 0x0080135#define REG_SPI_NFI_FDM0L 0x00a0136#define REG_SPI_NFI_FDM0M 0x00a4137#define REG_SPI_NFI_FDM7L 0x00d8138#define REG_SPI_NFI_FDM7M 0x00dc139#define REG_SPI_NFI_FIFODATA0 0x0190140#define REG_SPI_NFI_FIFODATA1 0x0194141#define REG_SPI_NFI_FIFODATA2 0x0198142#define REG_SPI_NFI_FIFODATA3 0x019c143#define REG_SPI_NFI_MASTERSTA 0x0224144 145#define REG_SPI_NFI_SECCUS_SIZE 0x022c146#define SPI_NFI_CUS_SEC_SIZE GENMASK(12, 0)147#define SPI_NFI_CUS_SEC_SIZE_EN BIT(16)148 149#define REG_SPI_NFI_RD_CTL2 0x0510150#define REG_SPI_NFI_RD_CTL3 0x0514151 152#define REG_SPI_NFI_PG_CTL1 0x0524153#define SPI_NFI_PG_LOAD_CMD GENMASK(15, 8)154 155#define REG_SPI_NFI_PG_CTL2 0x0528156#define REG_SPI_NFI_NOR_PROG_ADDR 0x052c157#define REG_SPI_NFI_NOR_RD_ADDR 0x0534158 159#define REG_SPI_NFI_SNF_MISC_CTL 0x0538160#define SPI_NFI_DATA_READ_WR_MODE GENMASK(18, 16)161 162#define REG_SPI_NFI_SNF_MISC_CTL2 0x053c163#define SPI_NFI_READ_DATA_BYTE_NUM GENMASK(12, 0)164#define SPI_NFI_PROG_LOAD_BYTE_NUM GENMASK(28, 16)165 166#define REG_SPI_NFI_SNF_STA_CTL1 0x0550167#define SPI_NFI_READ_FROM_CACHE_DONE BIT(25)168#define SPI_NFI_LOAD_TO_CACHE_DONE BIT(26)169 170#define REG_SPI_NFI_SNF_STA_CTL2 0x0554171 172#define REG_SPI_NFI_SNF_NFI_CNFG 0x055c173#define SPI_NFI_SPI_MODE BIT(0)174 175/* SPI NAND Protocol OP */176#define SPI_NAND_OP_GET_FEATURE 0x0f177#define SPI_NAND_OP_SET_FEATURE 0x1f178#define SPI_NAND_OP_PAGE_READ 0x13179#define SPI_NAND_OP_READ_FROM_CACHE_SINGLE 0x03180#define SPI_NAND_OP_READ_FROM_CACHE_SINGLE_FAST 0x0b181#define SPI_NAND_OP_READ_FROM_CACHE_DUAL 0x3b182#define SPI_NAND_OP_READ_FROM_CACHE_QUAD 0x6b183#define SPI_NAND_OP_WRITE_ENABLE 0x06184#define SPI_NAND_OP_WRITE_DISABLE 0x04185#define SPI_NAND_OP_PROGRAM_LOAD_SINGLE 0x02186#define SPI_NAND_OP_PROGRAM_LOAD_QUAD 0x32187#define SPI_NAND_OP_PROGRAM_LOAD_RAMDOM_SINGLE 0x84188#define SPI_NAND_OP_PROGRAM_LOAD_RAMDON_QUAD 0x34189#define SPI_NAND_OP_PROGRAM_EXECUTE 0x10190#define SPI_NAND_OP_READ_ID 0x9f191#define SPI_NAND_OP_BLOCK_ERASE 0xd8192#define SPI_NAND_OP_RESET 0xff193#define SPI_NAND_OP_DIE_SELECT 0xc2194 195#define SPI_NAND_CACHE_SIZE (SZ_4K + SZ_256)196#define SPI_MAX_TRANSFER_SIZE 511197 198enum airoha_snand_mode {199 SPI_MODE_AUTO,200 SPI_MODE_MANUAL,201 SPI_MODE_DMA,202};203 204enum airoha_snand_cs {205 SPI_CHIP_SEL_HIGH,206 SPI_CHIP_SEL_LOW,207};208 209struct airoha_snand_dev {210 size_t buf_len;211 212 u8 *txrx_buf;213 dma_addr_t dma_addr;214};215 216struct airoha_snand_ctrl {217 struct device *dev;218 struct regmap *regmap_ctrl;219 struct regmap *regmap_nfi;220 struct clk *spi_clk;221 222 struct {223 size_t page_size;224 size_t sec_size;225 u8 sec_num;226 u8 spare_size;227 } nfi_cfg;228};229 230static int airoha_snand_set_fifo_op(struct airoha_snand_ctrl *as_ctrl,231 u8 op_cmd, int op_len)232{233 int err;234 u32 val;235 236 err = regmap_write(as_ctrl->regmap_ctrl, REG_SPI_CTRL_OPFIFO_WDATA,237 FIELD_PREP(SPI_CTRL_OPFIFO_LEN, op_len) |238 FIELD_PREP(SPI_CTRL_OPFIFO_OP, op_cmd));239 if (err)240 return err;241 242 err = regmap_read_poll_timeout(as_ctrl->regmap_ctrl,243 REG_SPI_CTRL_OPFIFO_FULL,244 val, !(val & SPI_CTRL_OPFIFO_FULL),245 0, 250 * USEC_PER_MSEC);246 if (err)247 return err;248 249 err = regmap_write(as_ctrl->regmap_ctrl, REG_SPI_CTRL_OPFIFO_WR,250 SPI_CTRL_OPFIFO_WR);251 if (err)252 return err;253 254 return regmap_read_poll_timeout(as_ctrl->regmap_ctrl,255 REG_SPI_CTRL_OPFIFO_EMPTY,256 val, (val & SPI_CTRL_OPFIFO_EMPTY),257 0, 250 * USEC_PER_MSEC);258}259 260static int airoha_snand_set_cs(struct airoha_snand_ctrl *as_ctrl, u8 cs)261{262 return airoha_snand_set_fifo_op(as_ctrl, cs, sizeof(cs));263}264 265static int airoha_snand_write_data_to_fifo(struct airoha_snand_ctrl *as_ctrl,266 const u8 *data, int len)267{268 int i;269 270 for (i = 0; i < len; i++) {271 int err;272 u32 val;273 274 /* 1. Wait until dfifo is not full */275 err = regmap_read_poll_timeout(as_ctrl->regmap_ctrl,276 REG_SPI_CTRL_DFIFO_FULL, val,277 !(val & SPI_CTRL_DFIFO_FULL),278 0, 250 * USEC_PER_MSEC);279 if (err)280 return err;281 282 /* 2. Write data to register DFIFO_WDATA */283 err = regmap_write(as_ctrl->regmap_ctrl,284 REG_SPI_CTRL_DFIFO_WDATA,285 FIELD_PREP(SPI_CTRL_DFIFO_WDATA, data[i]));286 if (err)287 return err;288 289 /* 3. Wait until dfifo is not full */290 err = regmap_read_poll_timeout(as_ctrl->regmap_ctrl,291 REG_SPI_CTRL_DFIFO_FULL, val,292 !(val & SPI_CTRL_DFIFO_FULL),293 0, 250 * USEC_PER_MSEC);294 if (err)295 return err;296 }297 298 return 0;299}300 301static int airoha_snand_read_data_from_fifo(struct airoha_snand_ctrl *as_ctrl,302 u8 *ptr, int len)303{304 int i;305 306 for (i = 0; i < len; i++) {307 int err;308 u32 val;309 310 /* 1. wait until dfifo is not empty */311 err = regmap_read_poll_timeout(as_ctrl->regmap_ctrl,312 REG_SPI_CTRL_DFIFO_EMPTY, val,313 !(val & SPI_CTRL_DFIFO_EMPTY),314 0, 250 * USEC_PER_MSEC);315 if (err)316 return err;317 318 /* 2. read from dfifo to register DFIFO_RDATA */319 err = regmap_read(as_ctrl->regmap_ctrl,320 REG_SPI_CTRL_DFIFO_RDATA, &val);321 if (err)322 return err;323 324 ptr[i] = FIELD_GET(SPI_CTRL_DFIFO_RDATA, val);325 /* 3. enable register DFIFO_RD to read next byte */326 err = regmap_write(as_ctrl->regmap_ctrl,327 REG_SPI_CTRL_DFIFO_RD, SPI_CTRL_DFIFO_RD);328 if (err)329 return err;330 }331 332 return 0;333}334 335static int airoha_snand_set_mode(struct airoha_snand_ctrl *as_ctrl,336 enum airoha_snand_mode mode)337{338 int err;339 340 switch (mode) {341 case SPI_MODE_MANUAL: {342 u32 val;343 344 err = regmap_write(as_ctrl->regmap_ctrl,345 REG_SPI_CTRL_NFI2SPI_EN, 0);346 if (err)347 return err;348 349 err = regmap_write(as_ctrl->regmap_ctrl,350 REG_SPI_CTRL_READ_IDLE_EN, 0);351 if (err)352 return err;353 354 err = regmap_read_poll_timeout(as_ctrl->regmap_ctrl,355 REG_SPI_CTRL_RDCTL_FSM, val,356 !(val & SPI_CTRL_RDCTL_FSM),357 0, 250 * USEC_PER_MSEC);358 if (err)359 return err;360 361 err = regmap_write(as_ctrl->regmap_ctrl,362 REG_SPI_CTRL_MTX_MODE_TOG, 9);363 if (err)364 return err;365 366 err = regmap_write(as_ctrl->regmap_ctrl,367 REG_SPI_CTRL_MANUAL_EN, SPI_CTRL_MANUAL_EN);368 if (err)369 return err;370 break;371 }372 case SPI_MODE_DMA:373 err = regmap_write(as_ctrl->regmap_ctrl,374 REG_SPI_CTRL_NFI2SPI_EN,375 SPI_CTRL_MANUAL_EN);376 if (err < 0)377 return err;378 379 err = regmap_write(as_ctrl->regmap_ctrl,380 REG_SPI_CTRL_MTX_MODE_TOG, 0x0);381 if (err < 0)382 return err;383 384 err = regmap_write(as_ctrl->regmap_ctrl,385 REG_SPI_CTRL_MANUAL_EN, 0x0);386 if (err < 0)387 return err;388 break;389 case SPI_MODE_AUTO:390 default:391 break;392 }393 394 return regmap_write(as_ctrl->regmap_ctrl, REG_SPI_CTRL_DUMMY, 0);395}396 397static int airoha_snand_write_data(struct airoha_snand_ctrl *as_ctrl, u8 cmd,398 const u8 *data, int len)399{400 int i, data_len;401 402 for (i = 0; i < len; i += data_len) {403 int err;404 405 data_len = min(len - i, SPI_MAX_TRANSFER_SIZE);406 err = airoha_snand_set_fifo_op(as_ctrl, cmd, data_len);407 if (err)408 return err;409 410 err = airoha_snand_write_data_to_fifo(as_ctrl, &data[i],411 data_len);412 if (err < 0)413 return err;414 }415 416 return 0;417}418 419static int airoha_snand_read_data(struct airoha_snand_ctrl *as_ctrl, u8 *data,420 int len)421{422 int i, data_len;423 424 for (i = 0; i < len; i += data_len) {425 int err;426 427 data_len = min(len - i, SPI_MAX_TRANSFER_SIZE);428 err = airoha_snand_set_fifo_op(as_ctrl, 0xc, data_len);429 if (err)430 return err;431 432 err = airoha_snand_read_data_from_fifo(as_ctrl, &data[i],433 data_len);434 if (err < 0)435 return err;436 }437 438 return 0;439}440 441static int airoha_snand_nfi_init(struct airoha_snand_ctrl *as_ctrl)442{443 int err;444 445 /* switch to SNFI mode */446 err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_SNF_NFI_CNFG,447 SPI_NFI_SPI_MODE);448 if (err)449 return err;450 451 /* Enable DMA */452 return regmap_update_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_INTR_EN,453 SPI_NFI_ALL_IRQ_EN, SPI_NFI_AHB_DONE_EN);454}455 456static int airoha_snand_nfi_config(struct airoha_snand_ctrl *as_ctrl)457{458 int err;459 u32 val;460 461 err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_CON,462 SPI_NFI_FIFO_FLUSH | SPI_NFI_RST);463 if (err)464 return err;465 466 /* auto FDM */467 err = regmap_clear_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CNFG,468 SPI_NFI_AUTO_FDM_EN);469 if (err)470 return err;471 472 /* HW ECC */473 err = regmap_clear_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CNFG,474 SPI_NFI_HW_ECC_EN);475 if (err)476 return err;477 478 /* DMA Burst */479 err = regmap_set_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CNFG,480 SPI_NFI_DMA_BURST_EN);481 if (err)482 return err;483 484 /* page format */485 switch (as_ctrl->nfi_cfg.spare_size) {486 case 26:487 val = FIELD_PREP(SPI_NFI_SPARE_SIZE, 0x1);488 break;489 case 27:490 val = FIELD_PREP(SPI_NFI_SPARE_SIZE, 0x2);491 break;492 case 28:493 val = FIELD_PREP(SPI_NFI_SPARE_SIZE, 0x3);494 break;495 default:496 val = FIELD_PREP(SPI_NFI_SPARE_SIZE, 0x0);497 break;498 }499 500 err = regmap_update_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_PAGEFMT,501 SPI_NFI_SPARE_SIZE, val);502 if (err)503 return err;504 505 switch (as_ctrl->nfi_cfg.page_size) {506 case 2048:507 val = FIELD_PREP(SPI_NFI_PAGE_SIZE, 0x1);508 break;509 case 4096:510 val = FIELD_PREP(SPI_NFI_PAGE_SIZE, 0x2);511 break;512 default:513 val = FIELD_PREP(SPI_NFI_PAGE_SIZE, 0x0);514 break;515 }516 517 err = regmap_update_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_PAGEFMT,518 SPI_NFI_PAGE_SIZE, val);519 if (err)520 return err;521 522 /* sec num */523 val = FIELD_PREP(SPI_NFI_SEC_NUM, as_ctrl->nfi_cfg.sec_num);524 err = regmap_update_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CON,525 SPI_NFI_SEC_NUM, val);526 if (err)527 return err;528 529 /* enable cust sec size */530 err = regmap_set_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_SECCUS_SIZE,531 SPI_NFI_CUS_SEC_SIZE_EN);532 if (err)533 return err;534 535 /* set cust sec size */536 val = FIELD_PREP(SPI_NFI_CUS_SEC_SIZE, as_ctrl->nfi_cfg.sec_size);537 return regmap_update_bits(as_ctrl->regmap_nfi,538 REG_SPI_NFI_SECCUS_SIZE,539 SPI_NFI_CUS_SEC_SIZE, val);540}541 542static bool airoha_snand_is_page_ops(const struct spi_mem_op *op)543{544 if (op->addr.nbytes != 2)545 return false;546 547 if (op->addr.buswidth != 1 && op->addr.buswidth != 2 &&548 op->addr.buswidth != 4)549 return false;550 551 switch (op->data.dir) {552 case SPI_MEM_DATA_IN:553 if (op->dummy.nbytes * BITS_PER_BYTE / op->dummy.buswidth > 0xf)554 return false;555 556 /* quad in / quad out */557 if (op->addr.buswidth == 4)558 return op->data.buswidth == 4;559 560 if (op->addr.buswidth == 2)561 return op->data.buswidth == 2;562 563 /* standard spi */564 return op->data.buswidth == 4 || op->data.buswidth == 2 ||565 op->data.buswidth == 1;566 case SPI_MEM_DATA_OUT:567 return !op->dummy.nbytes && op->addr.buswidth == 1 &&568 (op->data.buswidth == 4 || op->data.buswidth == 1);569 default:570 return false;571 }572}573 574static int airoha_snand_adjust_op_size(struct spi_mem *mem,575 struct spi_mem_op *op)576{577 size_t max_len;578 579 if (airoha_snand_is_page_ops(op)) {580 struct airoha_snand_ctrl *as_ctrl;581 582 as_ctrl = spi_controller_get_devdata(mem->spi->controller);583 max_len = as_ctrl->nfi_cfg.sec_size;584 max_len += as_ctrl->nfi_cfg.spare_size;585 max_len *= as_ctrl->nfi_cfg.sec_num;586 587 if (op->data.nbytes > max_len)588 op->data.nbytes = max_len;589 } else {590 max_len = 1 + op->addr.nbytes + op->dummy.nbytes;591 if (max_len >= 160)592 return -EOPNOTSUPP;593 594 if (op->data.nbytes > 160 - max_len)595 op->data.nbytes = 160 - max_len;596 }597 598 return 0;599}600 601static bool airoha_snand_supports_op(struct spi_mem *mem,602 const struct spi_mem_op *op)603{604 if (!spi_mem_default_supports_op(mem, op))605 return false;606 607 if (op->cmd.buswidth != 1)608 return false;609 610 if (airoha_snand_is_page_ops(op))611 return true;612 613 return (!op->addr.nbytes || op->addr.buswidth == 1) &&614 (!op->dummy.nbytes || op->dummy.buswidth == 1) &&615 (!op->data.nbytes || op->data.buswidth == 1);616}617 618static int airoha_snand_dirmap_create(struct spi_mem_dirmap_desc *desc)619{620 struct airoha_snand_dev *as_dev = spi_get_ctldata(desc->mem->spi);621 622 if (!as_dev->txrx_buf)623 return -EINVAL;624 625 if (desc->info.offset + desc->info.length > U32_MAX)626 return -EINVAL;627 628 if (!airoha_snand_supports_op(desc->mem, &desc->info.op_tmpl))629 return -EOPNOTSUPP;630 631 return 0;632}633 634static ssize_t airoha_snand_dirmap_read(struct spi_mem_dirmap_desc *desc,635 u64 offs, size_t len, void *buf)636{637 struct spi_device *spi = desc->mem->spi;638 struct airoha_snand_dev *as_dev = spi_get_ctldata(spi);639 struct spi_mem_op *op = &desc->info.op_tmpl;640 struct airoha_snand_ctrl *as_ctrl;641 u32 val, rd_mode;642 int err;643 644 switch (op->cmd.opcode) {645 case SPI_NAND_OP_READ_FROM_CACHE_DUAL:646 rd_mode = 1;647 break;648 case SPI_NAND_OP_READ_FROM_CACHE_QUAD:649 rd_mode = 2;650 break;651 default:652 rd_mode = 0;653 break;654 }655 656 as_ctrl = spi_controller_get_devdata(spi->controller);657 err = airoha_snand_set_mode(as_ctrl, SPI_MODE_DMA);658 if (err < 0)659 return err;660 661 err = airoha_snand_nfi_config(as_ctrl);662 if (err)663 return err;664 665 dma_sync_single_for_device(as_ctrl->dev, as_dev->dma_addr,666 as_dev->buf_len, DMA_BIDIRECTIONAL);667 668 /* set dma addr */669 err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_STRADDR,670 as_dev->dma_addr);671 if (err)672 return err;673 674 /* set cust sec size */675 val = as_ctrl->nfi_cfg.sec_size * as_ctrl->nfi_cfg.sec_num;676 val = FIELD_PREP(SPI_NFI_READ_DATA_BYTE_NUM, val);677 err = regmap_update_bits(as_ctrl->regmap_nfi,678 REG_SPI_NFI_SNF_MISC_CTL2,679 SPI_NFI_READ_DATA_BYTE_NUM, val);680 if (err)681 return err;682 683 /* set read command */684 err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_RD_CTL2,685 op->cmd.opcode);686 if (err)687 return err;688 689 /* set read mode */690 err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_SNF_MISC_CTL,691 FIELD_PREP(SPI_NFI_DATA_READ_WR_MODE, rd_mode));692 if (err)693 return err;694 695 /* set read addr */696 err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_RD_CTL3, 0x0);697 if (err)698 return err;699 700 /* set nfi read */701 err = regmap_update_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CNFG,702 SPI_NFI_OPMODE,703 FIELD_PREP(SPI_NFI_OPMODE, 6));704 if (err)705 return err;706 707 err = regmap_set_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CNFG,708 SPI_NFI_READ_MODE | SPI_NFI_DMA_MODE);709 if (err)710 return err;711 712 err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_CMD, 0x0);713 if (err)714 return err;715 716 /* trigger dma start read */717 err = regmap_clear_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CON,718 SPI_NFI_RD_TRIG);719 if (err)720 return err;721 722 err = regmap_set_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CON,723 SPI_NFI_RD_TRIG);724 if (err)725 return err;726 727 err = regmap_read_poll_timeout(as_ctrl->regmap_nfi,728 REG_SPI_NFI_SNF_STA_CTL1, val,729 (val & SPI_NFI_READ_FROM_CACHE_DONE),730 0, 1 * USEC_PER_SEC);731 if (err)732 return err;733 734 /*735 * SPI_NFI_READ_FROM_CACHE_DONE bit must be written at the end736 * of dirmap_read operation even if it is already set.737 */738 err = regmap_write_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_SNF_STA_CTL1,739 SPI_NFI_READ_FROM_CACHE_DONE,740 SPI_NFI_READ_FROM_CACHE_DONE);741 if (err)742 return err;743 744 err = regmap_read_poll_timeout(as_ctrl->regmap_nfi, REG_SPI_NFI_INTR,745 val, (val & SPI_NFI_AHB_DONE), 0,746 1 * USEC_PER_SEC);747 if (err)748 return err;749 750 /* DMA read need delay for data ready from controller to DRAM */751 udelay(1);752 753 dma_sync_single_for_cpu(as_ctrl->dev, as_dev->dma_addr,754 as_dev->buf_len, DMA_BIDIRECTIONAL);755 err = airoha_snand_set_mode(as_ctrl, SPI_MODE_MANUAL);756 if (err < 0)757 return err;758 759 memcpy(buf, as_dev->txrx_buf + offs, len);760 761 return len;762}763 764static ssize_t airoha_snand_dirmap_write(struct spi_mem_dirmap_desc *desc,765 u64 offs, size_t len, const void *buf)766{767 struct spi_device *spi = desc->mem->spi;768 struct airoha_snand_dev *as_dev = spi_get_ctldata(spi);769 struct spi_mem_op *op = &desc->info.op_tmpl;770 struct airoha_snand_ctrl *as_ctrl;771 u32 wr_mode, val;772 int err;773 774 as_ctrl = spi_controller_get_devdata(spi->controller);775 err = airoha_snand_set_mode(as_ctrl, SPI_MODE_MANUAL);776 if (err < 0)777 return err;778 779 dma_sync_single_for_cpu(as_ctrl->dev, as_dev->dma_addr,780 as_dev->buf_len, DMA_BIDIRECTIONAL);781 memcpy(as_dev->txrx_buf + offs, buf, len);782 dma_sync_single_for_device(as_ctrl->dev, as_dev->dma_addr,783 as_dev->buf_len, DMA_BIDIRECTIONAL);784 785 err = airoha_snand_set_mode(as_ctrl, SPI_MODE_DMA);786 if (err < 0)787 return err;788 789 err = airoha_snand_nfi_config(as_ctrl);790 if (err)791 return err;792 793 if (op->cmd.opcode == SPI_NAND_OP_PROGRAM_LOAD_QUAD ||794 op->cmd.opcode == SPI_NAND_OP_PROGRAM_LOAD_RAMDON_QUAD)795 wr_mode = BIT(1);796 else797 wr_mode = 0;798 799 err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_STRADDR,800 as_dev->dma_addr);801 if (err)802 return err;803 804 val = FIELD_PREP(SPI_NFI_PROG_LOAD_BYTE_NUM,805 as_ctrl->nfi_cfg.sec_size * as_ctrl->nfi_cfg.sec_num);806 err = regmap_update_bits(as_ctrl->regmap_nfi,807 REG_SPI_NFI_SNF_MISC_CTL2,808 SPI_NFI_PROG_LOAD_BYTE_NUM, val);809 if (err)810 return err;811 812 err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_PG_CTL1,813 FIELD_PREP(SPI_NFI_PG_LOAD_CMD,814 op->cmd.opcode));815 if (err)816 return err;817 818 err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_SNF_MISC_CTL,819 FIELD_PREP(SPI_NFI_DATA_READ_WR_MODE, wr_mode));820 if (err)821 return err;822 823 err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_PG_CTL2, 0x0);824 if (err)825 return err;826 827 err = regmap_clear_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CNFG,828 SPI_NFI_READ_MODE);829 if (err)830 return err;831 832 err = regmap_update_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CNFG,833 SPI_NFI_OPMODE,834 FIELD_PREP(SPI_NFI_OPMODE, 3));835 if (err)836 return err;837 838 err = regmap_set_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CNFG,839 SPI_NFI_DMA_MODE);840 if (err)841 return err;842 843 err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_CMD, 0x80);844 if (err)845 return err;846 847 err = regmap_clear_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CON,848 SPI_NFI_WR_TRIG);849 if (err)850 return err;851 852 err = regmap_set_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CON,853 SPI_NFI_WR_TRIG);854 if (err)855 return err;856 857 err = regmap_read_poll_timeout(as_ctrl->regmap_nfi, REG_SPI_NFI_INTR,858 val, (val & SPI_NFI_AHB_DONE), 0,859 1 * USEC_PER_SEC);860 if (err)861 return err;862 863 err = regmap_read_poll_timeout(as_ctrl->regmap_nfi,864 REG_SPI_NFI_SNF_STA_CTL1, val,865 (val & SPI_NFI_LOAD_TO_CACHE_DONE),866 0, 1 * USEC_PER_SEC);867 if (err)868 return err;869 870 /*871 * SPI_NFI_LOAD_TO_CACHE_DONE bit must be written at the end872 * of dirmap_write operation even if it is already set.873 */874 err = regmap_write_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_SNF_STA_CTL1,875 SPI_NFI_LOAD_TO_CACHE_DONE,876 SPI_NFI_LOAD_TO_CACHE_DONE);877 if (err)878 return err;879 880 err = airoha_snand_set_mode(as_ctrl, SPI_MODE_MANUAL);881 if (err < 0)882 return err;883 884 return len;885}886 887static int airoha_snand_exec_op(struct spi_mem *mem,888 const struct spi_mem_op *op)889{890 u8 data[8], cmd, opcode = op->cmd.opcode;891 struct airoha_snand_ctrl *as_ctrl;892 int i, err;893 894 as_ctrl = spi_controller_get_devdata(mem->spi->controller);895 896 /* switch to manual mode */897 err = airoha_snand_set_mode(as_ctrl, SPI_MODE_MANUAL);898 if (err < 0)899 return err;900 901 err = airoha_snand_set_cs(as_ctrl, SPI_CHIP_SEL_LOW);902 if (err < 0)903 return err;904 905 /* opcode */906 err = airoha_snand_write_data(as_ctrl, 0x8, &opcode, sizeof(opcode));907 if (err)908 return err;909 910 /* addr part */911 cmd = opcode == SPI_NAND_OP_GET_FEATURE ? 0x11 : 0x8;912 put_unaligned_be64(op->addr.val, data);913 914 for (i = ARRAY_SIZE(data) - op->addr.nbytes;915 i < ARRAY_SIZE(data); i++) {916 err = airoha_snand_write_data(as_ctrl, cmd, &data[i],917 sizeof(data[0]));918 if (err)919 return err;920 }921 922 /* dummy */923 data[0] = 0xff;924 for (i = 0; i < op->dummy.nbytes; i++) {925 err = airoha_snand_write_data(as_ctrl, 0x8, &data[0],926 sizeof(data[0]));927 if (err)928 return err;929 }930 931 /* data */932 if (op->data.dir == SPI_MEM_DATA_IN) {933 err = airoha_snand_read_data(as_ctrl, op->data.buf.in,934 op->data.nbytes);935 if (err)936 return err;937 } else {938 err = airoha_snand_write_data(as_ctrl, 0x8, op->data.buf.out,939 op->data.nbytes);940 if (err)941 return err;942 }943 944 return airoha_snand_set_cs(as_ctrl, SPI_CHIP_SEL_HIGH);945}946 947static const struct spi_controller_mem_ops airoha_snand_mem_ops = {948 .adjust_op_size = airoha_snand_adjust_op_size,949 .supports_op = airoha_snand_supports_op,950 .exec_op = airoha_snand_exec_op,951 .dirmap_create = airoha_snand_dirmap_create,952 .dirmap_read = airoha_snand_dirmap_read,953 .dirmap_write = airoha_snand_dirmap_write,954};955 956static int airoha_snand_setup(struct spi_device *spi)957{958 struct airoha_snand_ctrl *as_ctrl;959 struct airoha_snand_dev *as_dev;960 961 as_ctrl = spi_controller_get_devdata(spi->controller);962 963 as_dev = devm_kzalloc(as_ctrl->dev, sizeof(*as_dev), GFP_KERNEL);964 if (!as_dev)965 return -ENOMEM;966 967 /* prepare device buffer */968 as_dev->buf_len = SPI_NAND_CACHE_SIZE;969 as_dev->txrx_buf = devm_kzalloc(as_ctrl->dev, as_dev->buf_len,970 GFP_KERNEL);971 if (!as_dev->txrx_buf)972 return -ENOMEM;973 974 as_dev->dma_addr = dma_map_single(as_ctrl->dev, as_dev->txrx_buf,975 as_dev->buf_len, DMA_BIDIRECTIONAL);976 if (dma_mapping_error(as_ctrl->dev, as_dev->dma_addr))977 return -ENOMEM;978 979 spi_set_ctldata(spi, as_dev);980 981 return 0;982}983 984static void airoha_snand_cleanup(struct spi_device *spi)985{986 struct airoha_snand_dev *as_dev = spi_get_ctldata(spi);987 struct airoha_snand_ctrl *as_ctrl;988 989 as_ctrl = spi_controller_get_devdata(spi->controller);990 dma_unmap_single(as_ctrl->dev, as_dev->dma_addr,991 as_dev->buf_len, DMA_BIDIRECTIONAL);992 spi_set_ctldata(spi, NULL);993}994 995static int airoha_snand_nfi_setup(struct airoha_snand_ctrl *as_ctrl)996{997 u32 val, sec_size, sec_num;998 int err;999 1000 err = regmap_read(as_ctrl->regmap_nfi, REG_SPI_NFI_CON, &val);1001 if (err)1002 return err;1003 1004 sec_num = FIELD_GET(SPI_NFI_SEC_NUM, val);1005 1006 err = regmap_read(as_ctrl->regmap_nfi, REG_SPI_NFI_SECCUS_SIZE, &val);1007 if (err)1008 return err;1009 1010 sec_size = FIELD_GET(SPI_NFI_CUS_SEC_SIZE, val);1011 1012 /* init default value */1013 as_ctrl->nfi_cfg.sec_size = sec_size;1014 as_ctrl->nfi_cfg.sec_num = sec_num;1015 as_ctrl->nfi_cfg.page_size = round_down(sec_size * sec_num, 1024);1016 as_ctrl->nfi_cfg.spare_size = 16;1017 1018 err = airoha_snand_nfi_init(as_ctrl);1019 if (err)1020 return err;1021 1022 return airoha_snand_nfi_config(as_ctrl);1023}1024 1025static const struct regmap_config spi_ctrl_regmap_config = {1026 .name = "ctrl",1027 .reg_bits = 32,1028 .val_bits = 32,1029 .reg_stride = 4,1030 .max_register = REG_SPI_CTRL_NFI2SPI_EN,1031};1032 1033static const struct regmap_config spi_nfi_regmap_config = {1034 .name = "nfi",1035 .reg_bits = 32,1036 .val_bits = 32,1037 .reg_stride = 4,1038 .max_register = REG_SPI_NFI_SNF_NFI_CNFG,1039};1040 1041static const struct of_device_id airoha_snand_ids[] = {1042 { .compatible = "airoha,en7581-snand" },1043 { /* sentinel */ }1044};1045MODULE_DEVICE_TABLE(of, airoha_snand_ids);1046 1047static int airoha_snand_probe(struct platform_device *pdev)1048{1049 struct airoha_snand_ctrl *as_ctrl;1050 struct device *dev = &pdev->dev;1051 struct spi_controller *ctrl;1052 void __iomem *base;1053 int err;1054 1055 ctrl = devm_spi_alloc_host(dev, sizeof(*as_ctrl));1056 if (!ctrl)1057 return -ENOMEM;1058 1059 as_ctrl = spi_controller_get_devdata(ctrl);1060 as_ctrl->dev = dev;1061 1062 base = devm_platform_ioremap_resource(pdev, 0);1063 if (IS_ERR(base))1064 return PTR_ERR(base);1065 1066 as_ctrl->regmap_ctrl = devm_regmap_init_mmio(dev, base,1067 &spi_ctrl_regmap_config);1068 if (IS_ERR(as_ctrl->regmap_ctrl))1069 return dev_err_probe(dev, PTR_ERR(as_ctrl->regmap_ctrl),1070 "failed to init spi ctrl regmap\n");1071 1072 base = devm_platform_ioremap_resource(pdev, 1);1073 if (IS_ERR(base))1074 return PTR_ERR(base);1075 1076 as_ctrl->regmap_nfi = devm_regmap_init_mmio(dev, base,1077 &spi_nfi_regmap_config);1078 if (IS_ERR(as_ctrl->regmap_nfi))1079 return dev_err_probe(dev, PTR_ERR(as_ctrl->regmap_nfi),1080 "failed to init spi nfi regmap\n");1081 1082 as_ctrl->spi_clk = devm_clk_get_enabled(dev, "spi");1083 if (IS_ERR(as_ctrl->spi_clk))1084 return dev_err_probe(dev, PTR_ERR(as_ctrl->spi_clk),1085 "unable to get spi clk\n");1086 1087 err = dma_set_mask(as_ctrl->dev, DMA_BIT_MASK(32));1088 if (err)1089 return err;1090 1091 ctrl->num_chipselect = 2;1092 ctrl->mem_ops = &airoha_snand_mem_ops;1093 ctrl->bits_per_word_mask = SPI_BPW_MASK(8);1094 ctrl->mode_bits = SPI_RX_DUAL;1095 ctrl->setup = airoha_snand_setup;1096 ctrl->cleanup = airoha_snand_cleanup;1097 device_set_node(&ctrl->dev, dev_fwnode(dev));1098 1099 err = airoha_snand_nfi_setup(as_ctrl);1100 if (err)1101 return err;1102 1103 return devm_spi_register_controller(dev, ctrl);1104}1105 1106static struct platform_driver airoha_snand_driver = {1107 .driver = {1108 .name = "airoha-spi",1109 .of_match_table = airoha_snand_ids,1110 },1111 .probe = airoha_snand_probe,1112};1113module_platform_driver(airoha_snand_driver);1114 1115MODULE_DESCRIPTION("Airoha SPI-NAND Flash Controller Driver");1116MODULE_AUTHOR("Lorenzo Bianconi <lorenzo@kernel.org>");1117MODULE_AUTHOR("Ray Liu <ray.liu@airoha.com>");1118MODULE_LICENSE("GPL");1119