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: spi-nxp-fspi: add DTR mode support

Merge series from Haibo Chen <haibo.chen@nxp.com>:

this patch set add DTR mode support for flexspi.
For DTR mode, flexspi only support 8D-8D-8D mode.

Patch 1~2 extract nxp_fspi_dll_override(), prepare for adding the DTR mode.
in nor suspend, it will disable DTR mode, and enable DTR mode back
in nor resume. this require the flexspi driver has the ability to
set back to dll override mode in STR mode when clock rate < 100MHz.
Patch 3 Add the DDR LUT command support. flexspi use LUT command to handle
the dtr/str mode.
Patch 4 add the logic of sample clock source selection for STR/DTR mode
STR use the default mode 0, sample based on the internal dummy pad.
DTR use the mode 3, sample based on the external DQS pad, so this
board and device connect the DQS pad.
adjust the clock rate for DTR mode, when detect the DDR LUT command,
flexspi will automatically div 2 of the root clock and output to device.
Patch 5 finally add the DTR support in default after the upper 4 patches's
prepareation. Since lx2160a do not implement DQS pad, so can't support
this DTR mode.

+98 -17
+98 -17
drivers/spi/spi-nxp-fspi.c
··· 330 330 331 331 /* Access flash memory using IP bus only */ 332 332 #define FSPI_QUIRK_USE_IP_ONLY BIT(0) 333 + /* Disable DTR */ 334 + #define FSPI_QUIRK_DISABLE_DTR BIT(1) 333 335 334 336 struct nxp_fspi_devtype_data { 335 337 unsigned int rxfifo; ··· 346 344 .rxfifo = SZ_512, /* (64 * 64 bits) */ 347 345 .txfifo = SZ_1K, /* (128 * 64 bits) */ 348 346 .ahb_buf_size = SZ_2K, /* (256 * 64 bits) */ 349 - .quirks = 0, 347 + .quirks = FSPI_QUIRK_DISABLE_DTR, 350 348 .lut_num = 32, 351 349 .little_endian = true, /* little-endian */ 352 350 }; ··· 401 399 struct mutex lock; 402 400 struct pm_qos_request pm_qos_req; 403 401 int selected; 404 - #define FSPI_NEED_INIT (1 << 0) 402 + #define FSPI_NEED_INIT BIT(0) 403 + #define FSPI_DTR_MODE BIT(1) 405 404 int flags; 406 405 }; 407 406 ··· 562 559 u32 target_lut_reg; 563 560 564 561 /* cmd */ 565 - lutval[0] |= LUT_DEF(0, LUT_CMD, LUT_PAD(op->cmd.buswidth), 566 - op->cmd.opcode); 562 + if (op->cmd.dtr) { 563 + lutval[0] |= LUT_DEF(0, LUT_CMD_DDR, LUT_PAD(op->cmd.buswidth), 564 + op->cmd.opcode >> 8); 565 + lutval[lutidx / 2] |= LUT_DEF(lutidx, LUT_CMD_DDR, 566 + LUT_PAD(op->cmd.buswidth), 567 + op->cmd.opcode & 0xFF); 568 + lutidx++; 569 + } else { 570 + lutval[0] |= LUT_DEF(0, LUT_CMD, LUT_PAD(op->cmd.buswidth), 571 + op->cmd.opcode); 572 + } 567 573 568 574 /* addr bytes */ 569 575 if (op->addr.nbytes) { 570 - lutval[lutidx / 2] |= LUT_DEF(lutidx, LUT_ADDR, 576 + lutval[lutidx / 2] |= LUT_DEF(lutidx, op->addr.dtr ? LUT_ADDR_DDR : LUT_ADDR, 571 577 LUT_PAD(op->addr.buswidth), 572 578 op->addr.nbytes * 8); 573 579 lutidx++; ··· 584 572 585 573 /* dummy bytes, if needed */ 586 574 if (op->dummy.nbytes) { 587 - lutval[lutidx / 2] |= LUT_DEF(lutidx, LUT_DUMMY, 575 + lutval[lutidx / 2] |= LUT_DEF(lutidx, op->dummy.dtr ? LUT_DUMMY_DDR : LUT_DUMMY, 588 576 /* 589 577 * Due to FlexSPI controller limitation number of PAD for dummy 590 578 * buswidth needs to be programmed as equal to data buswidth. ··· 599 587 if (op->data.nbytes) { 600 588 lutval[lutidx / 2] |= LUT_DEF(lutidx, 601 589 op->data.dir == SPI_MEM_DATA_IN ? 602 - LUT_NXP_READ : LUT_NXP_WRITE, 590 + (op->data.dtr ? LUT_READ_DDR : LUT_NXP_READ) : 591 + (op->data.dtr ? LUT_WRITE_DDR : LUT_NXP_WRITE), 603 592 LUT_PAD(op->data.buswidth), 604 593 0); 605 594 lutidx++; ··· 658 645 return; 659 646 } 660 647 648 + /* 649 + * Sample Clock source selection for Flash Reading 650 + * Four modes defined by fspi: 651 + * mode 0: Dummy Read strobe generated by FlexSPI Controller 652 + * and loopback internally 653 + * mode 1: Dummy Read strobe generated by FlexSPI Controller 654 + * and loopback from DQS pad 655 + * mode 2: Reserved 656 + * mode 3: Flash provided Read strobe and input from DQS pad 657 + * 658 + * fspi default use mode 0 after reset 659 + */ 660 + static void nxp_fspi_select_rx_sample_clk_source(struct nxp_fspi *f, 661 + bool op_is_dtr) 662 + { 663 + u32 reg; 664 + 665 + /* 666 + * For 8D-8D-8D mode, need to use mode 3 (Flash provided Read 667 + * strobe and input from DQS pad), otherwise read operaton may 668 + * meet issue. 669 + * This mode require flash device connect the DQS pad on board. 670 + * For other modes, still use mode 0, keep align with before. 671 + * spi_nor_suspend will disable 8D-8D-8D mode, also need to 672 + * change the mode back to mode 0. 673 + */ 674 + reg = fspi_readl(f, f->iobase + FSPI_MCR0); 675 + if (op_is_dtr) 676 + reg |= FSPI_MCR0_RXCLKSRC(3); 677 + else /*select mode 0 */ 678 + reg &= ~FSPI_MCR0_RXCLKSRC(3); 679 + fspi_writel(f, reg, f->iobase + FSPI_MCR0); 680 + } 681 + 661 682 static void nxp_fspi_dll_calibration(struct nxp_fspi *f) 662 683 { 663 684 int ret; ··· 719 672 0, POLL_TOUT, true); 720 673 if (ret) 721 674 dev_warn(f->dev, "DLL lock failed, please fix it!\n"); 675 + } 676 + 677 + /* 678 + * Config the DLL register to default value, enable the target clock delay 679 + * line delay cell override mode, and use 1 fixed delay cell in DLL delay 680 + * chain, this is the suggested setting when clock rate < 100MHz. 681 + */ 682 + static void nxp_fspi_dll_override(struct nxp_fspi *f) 683 + { 684 + fspi_writel(f, FSPI_DLLACR_OVRDEN, f->iobase + FSPI_DLLACR); 685 + fspi_writel(f, FSPI_DLLBCR_OVRDEN, f->iobase + FSPI_DLLBCR); 722 686 } 723 687 724 688 /* ··· 773 715 static void nxp_fspi_select_mem(struct nxp_fspi *f, struct spi_device *spi, 774 716 const struct spi_mem_op *op) 775 717 { 718 + /* flexspi only support one DTR mode: 8D-8D-8D */ 719 + bool op_is_dtr = op->cmd.dtr && op->addr.dtr && op->dummy.dtr && op->data.dtr; 776 720 unsigned long rate = op->max_freq; 777 721 int ret; 778 722 uint64_t size_kb; 779 723 780 724 /* 781 725 * Return, if previously selected target device is same as current 782 - * requested target device. 726 + * requested target device. Also the DTR or STR mode do not change. 783 727 */ 784 - if (f->selected == spi_get_chipselect(spi, 0)) 728 + if ((f->selected == spi_get_chipselect(spi, 0)) && 729 + (!!(f->flags & FSPI_DTR_MODE) == op_is_dtr)) 785 730 return; 786 731 787 732 /* Reset FLSHxxCR0 registers */ ··· 800 739 4 * spi_get_chipselect(spi, 0)); 801 740 802 741 dev_dbg(f->dev, "Target device [CS:%x] selected\n", spi_get_chipselect(spi, 0)); 742 + 743 + nxp_fspi_select_rx_sample_clk_source(f, op_is_dtr); 744 + 745 + if (op_is_dtr) { 746 + f->flags |= FSPI_DTR_MODE; 747 + /* For DTR mode, flexspi will default div 2 and output to device. 748 + * so here to config the root clock to 2 * device rate. 749 + */ 750 + rate = rate * 2; 751 + } else { 752 + f->flags &= ~FSPI_DTR_MODE; 753 + } 803 754 804 755 nxp_fspi_clk_disable_unprep(f); 805 756 ··· 829 756 */ 830 757 if (rate > 100000000) 831 758 nxp_fspi_dll_calibration(f); 759 + else 760 + nxp_fspi_dll_override(f); 832 761 833 762 f->selected = spi_get_chipselect(spi, 0); 834 763 } ··· 1146 1071 /* Disable the module */ 1147 1072 fspi_writel(f, FSPI_MCR0_MDIS, base + FSPI_MCR0); 1148 1073 1149 - /* 1150 - * Config the DLL register to default value, enable the target clock delay 1151 - * line delay cell override mode, and use 1 fixed delay cell in DLL delay 1152 - * chain, this is the suggested setting when clock rate < 100MHz. 1153 - */ 1154 - fspi_writel(f, FSPI_DLLACR_OVRDEN, base + FSPI_DLLACR); 1155 - fspi_writel(f, FSPI_DLLBCR_OVRDEN, base + FSPI_DLLBCR); 1074 + nxp_fspi_dll_override(f); 1156 1075 1157 1076 /* enable module */ 1158 1077 fspi_writel(f, FSPI_MCR0_AHB_TIMEOUT(0xFF) | ··· 1233 1164 }; 1234 1165 1235 1166 static const struct spi_controller_mem_caps nxp_fspi_mem_caps = { 1167 + .dtr = true, 1168 + .swap16 = false, 1169 + .per_op_freq = true, 1170 + }; 1171 + 1172 + static const struct spi_controller_mem_caps nxp_fspi_mem_caps_disable_dtr = { 1173 + .dtr = false, 1236 1174 .per_op_freq = true, 1237 1175 }; 1238 1176 ··· 1355 1279 ctlr->bus_num = -1; 1356 1280 ctlr->num_chipselect = NXP_FSPI_MAX_CHIPSELECT; 1357 1281 ctlr->mem_ops = &nxp_fspi_mem_ops; 1358 - ctlr->mem_caps = &nxp_fspi_mem_caps; 1282 + 1283 + if (f->devtype_data->quirks & FSPI_QUIRK_DISABLE_DTR) 1284 + ctlr->mem_caps = &nxp_fspi_mem_caps_disable_dtr; 1285 + else 1286 + ctlr->mem_caps = &nxp_fspi_mem_caps; 1287 + 1359 1288 ctlr->dev.of_node = np; 1360 1289 1361 1290 ret = devm_add_action_or_reset(dev, nxp_fspi_cleanup, f);