Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 // Copyright (c) 2019 Nuvoton Technology corporation.
0003 
0004 #include <linux/bits.h>
0005 #include <linux/init.h>
0006 #include <linux/kernel.h>
0007 #include <linux/device.h>
0008 #include <linux/module.h>
0009 #include <linux/ioport.h>
0010 #include <linux/clk.h>
0011 #include <linux/platform_device.h>
0012 #include <linux/io.h>
0013 #include <linux/vmalloc.h>
0014 #include <linux/regmap.h>
0015 #include <linux/of_device.h>
0016 #include <linux/spi/spi-mem.h>
0017 #include <linux/mfd/syscon.h>
0018 
0019 /* NPCM7xx GCR module */
0020 #define NPCM7XX_INTCR3_OFFSET       0x9C
0021 #define NPCM7XX_INTCR3_FIU_FIX      BIT(6)
0022 
0023 /* Flash Interface Unit (FIU) Registers */
0024 #define NPCM_FIU_DRD_CFG        0x00
0025 #define NPCM_FIU_DWR_CFG        0x04
0026 #define NPCM_FIU_UMA_CFG        0x08
0027 #define NPCM_FIU_UMA_CTS        0x0C
0028 #define NPCM_FIU_UMA_CMD        0x10
0029 #define NPCM_FIU_UMA_ADDR       0x14
0030 #define NPCM_FIU_PRT_CFG        0x18
0031 #define NPCM_FIU_UMA_DW0        0x20
0032 #define NPCM_FIU_UMA_DW1        0x24
0033 #define NPCM_FIU_UMA_DW2        0x28
0034 #define NPCM_FIU_UMA_DW3        0x2C
0035 #define NPCM_FIU_UMA_DR0        0x30
0036 #define NPCM_FIU_UMA_DR1        0x34
0037 #define NPCM_FIU_UMA_DR2        0x38
0038 #define NPCM_FIU_UMA_DR3        0x3C
0039 #define NPCM_FIU_CFG            0x78
0040 #define NPCM_FIU_MAX_REG_LIMIT      0x80
0041 
0042 /* FIU Direct Read Configuration Register */
0043 #define NPCM_FIU_DRD_CFG_LCK        BIT(31)
0044 #define NPCM_FIU_DRD_CFG_R_BURST    GENMASK(25, 24)
0045 #define NPCM_FIU_DRD_CFG_ADDSIZ     GENMASK(17, 16)
0046 #define NPCM_FIU_DRD_CFG_DBW        GENMASK(13, 12)
0047 #define NPCM_FIU_DRD_CFG_ACCTYPE    GENMASK(9, 8)
0048 #define NPCM_FIU_DRD_CFG_RDCMD      GENMASK(7, 0)
0049 #define NPCM_FIU_DRD_ADDSIZ_SHIFT   16
0050 #define NPCM_FIU_DRD_DBW_SHIFT      12
0051 #define NPCM_FIU_DRD_ACCTYPE_SHIFT  8
0052 
0053 /* FIU Direct Write Configuration Register */
0054 #define NPCM_FIU_DWR_CFG_LCK        BIT(31)
0055 #define NPCM_FIU_DWR_CFG_W_BURST    GENMASK(25, 24)
0056 #define NPCM_FIU_DWR_CFG_ADDSIZ     GENMASK(17, 16)
0057 #define NPCM_FIU_DWR_CFG_ABPCK      GENMASK(11, 10)
0058 #define NPCM_FIU_DWR_CFG_DBPCK      GENMASK(9, 8)
0059 #define NPCM_FIU_DWR_CFG_WRCMD      GENMASK(7, 0)
0060 #define NPCM_FIU_DWR_ADDSIZ_SHIFT   16
0061 #define NPCM_FIU_DWR_ABPCK_SHIFT    10
0062 #define NPCM_FIU_DWR_DBPCK_SHIFT    8
0063 
0064 /* FIU UMA Configuration Register */
0065 #define NPCM_FIU_UMA_CFG_LCK        BIT(31)
0066 #define NPCM_FIU_UMA_CFG_CMMLCK     BIT(30)
0067 #define NPCM_FIU_UMA_CFG_RDATSIZ    GENMASK(28, 24)
0068 #define NPCM_FIU_UMA_CFG_DBSIZ      GENMASK(23, 21)
0069 #define NPCM_FIU_UMA_CFG_WDATSIZ    GENMASK(20, 16)
0070 #define NPCM_FIU_UMA_CFG_ADDSIZ     GENMASK(13, 11)
0071 #define NPCM_FIU_UMA_CFG_CMDSIZ     BIT(10)
0072 #define NPCM_FIU_UMA_CFG_RDBPCK     GENMASK(9, 8)
0073 #define NPCM_FIU_UMA_CFG_DBPCK      GENMASK(7, 6)
0074 #define NPCM_FIU_UMA_CFG_WDBPCK     GENMASK(5, 4)
0075 #define NPCM_FIU_UMA_CFG_ADBPCK     GENMASK(3, 2)
0076 #define NPCM_FIU_UMA_CFG_CMBPCK     GENMASK(1, 0)
0077 #define NPCM_FIU_UMA_CFG_ADBPCK_SHIFT   2
0078 #define NPCM_FIU_UMA_CFG_WDBPCK_SHIFT   4
0079 #define NPCM_FIU_UMA_CFG_DBPCK_SHIFT    6
0080 #define NPCM_FIU_UMA_CFG_RDBPCK_SHIFT   8
0081 #define NPCM_FIU_UMA_CFG_ADDSIZ_SHIFT   11
0082 #define NPCM_FIU_UMA_CFG_WDATSIZ_SHIFT  16
0083 #define NPCM_FIU_UMA_CFG_DBSIZ_SHIFT    21
0084 #define NPCM_FIU_UMA_CFG_RDATSIZ_SHIFT  24
0085 
0086 /* FIU UMA Control and Status Register */
0087 #define NPCM_FIU_UMA_CTS_RDYIE      BIT(25)
0088 #define NPCM_FIU_UMA_CTS_RDYST      BIT(24)
0089 #define NPCM_FIU_UMA_CTS_SW_CS      BIT(16)
0090 #define NPCM_FIU_UMA_CTS_DEV_NUM    GENMASK(9, 8)
0091 #define NPCM_FIU_UMA_CTS_EXEC_DONE  BIT(0)
0092 #define NPCM_FIU_UMA_CTS_DEV_NUM_SHIFT  8
0093 
0094 /* FIU UMA Command Register */
0095 #define NPCM_FIU_UMA_CMD_DUM3       GENMASK(31, 24)
0096 #define NPCM_FIU_UMA_CMD_DUM2       GENMASK(23, 16)
0097 #define NPCM_FIU_UMA_CMD_DUM1       GENMASK(15, 8)
0098 #define NPCM_FIU_UMA_CMD_CMD        GENMASK(7, 0)
0099 
0100 /* FIU UMA Address Register */
0101 #define NPCM_FIU_UMA_ADDR_UMA_ADDR  GENMASK(31, 0)
0102 #define NPCM_FIU_UMA_ADDR_AB3       GENMASK(31, 24)
0103 #define NPCM_FIU_UMA_ADDR_AB2       GENMASK(23, 16)
0104 #define NPCM_FIU_UMA_ADDR_AB1       GENMASK(15, 8)
0105 #define NPCM_FIU_UMA_ADDR_AB0       GENMASK(7, 0)
0106 
0107 /* FIU UMA Write Data Bytes 0-3 Register */
0108 #define NPCM_FIU_UMA_DW0_WB3        GENMASK(31, 24)
0109 #define NPCM_FIU_UMA_DW0_WB2        GENMASK(23, 16)
0110 #define NPCM_FIU_UMA_DW0_WB1        GENMASK(15, 8)
0111 #define NPCM_FIU_UMA_DW0_WB0        GENMASK(7, 0)
0112 
0113 /* FIU UMA Write Data Bytes 4-7 Register */
0114 #define NPCM_FIU_UMA_DW1_WB7        GENMASK(31, 24)
0115 #define NPCM_FIU_UMA_DW1_WB6        GENMASK(23, 16)
0116 #define NPCM_FIU_UMA_DW1_WB5        GENMASK(15, 8)
0117 #define NPCM_FIU_UMA_DW1_WB4        GENMASK(7, 0)
0118 
0119 /* FIU UMA Write Data Bytes 8-11 Register */
0120 #define NPCM_FIU_UMA_DW2_WB11       GENMASK(31, 24)
0121 #define NPCM_FIU_UMA_DW2_WB10       GENMASK(23, 16)
0122 #define NPCM_FIU_UMA_DW2_WB9        GENMASK(15, 8)
0123 #define NPCM_FIU_UMA_DW2_WB8        GENMASK(7, 0)
0124 
0125 /* FIU UMA Write Data Bytes 12-15 Register */
0126 #define NPCM_FIU_UMA_DW3_WB15       GENMASK(31, 24)
0127 #define NPCM_FIU_UMA_DW3_WB14       GENMASK(23, 16)
0128 #define NPCM_FIU_UMA_DW3_WB13       GENMASK(15, 8)
0129 #define NPCM_FIU_UMA_DW3_WB12       GENMASK(7, 0)
0130 
0131 /* FIU UMA Read Data Bytes 0-3 Register */
0132 #define NPCM_FIU_UMA_DR0_RB3        GENMASK(31, 24)
0133 #define NPCM_FIU_UMA_DR0_RB2        GENMASK(23, 16)
0134 #define NPCM_FIU_UMA_DR0_RB1        GENMASK(15, 8)
0135 #define NPCM_FIU_UMA_DR0_RB0        GENMASK(7, 0)
0136 
0137 /* FIU UMA Read Data Bytes 4-7 Register */
0138 #define NPCM_FIU_UMA_DR1_RB15       GENMASK(31, 24)
0139 #define NPCM_FIU_UMA_DR1_RB14       GENMASK(23, 16)
0140 #define NPCM_FIU_UMA_DR1_RB13       GENMASK(15, 8)
0141 #define NPCM_FIU_UMA_DR1_RB12       GENMASK(7, 0)
0142 
0143 /* FIU UMA Read Data Bytes 8-11 Register */
0144 #define NPCM_FIU_UMA_DR2_RB15       GENMASK(31, 24)
0145 #define NPCM_FIU_UMA_DR2_RB14       GENMASK(23, 16)
0146 #define NPCM_FIU_UMA_DR2_RB13       GENMASK(15, 8)
0147 #define NPCM_FIU_UMA_DR2_RB12       GENMASK(7, 0)
0148 
0149 /* FIU UMA Read Data Bytes 12-15 Register */
0150 #define NPCM_FIU_UMA_DR3_RB15       GENMASK(31, 24)
0151 #define NPCM_FIU_UMA_DR3_RB14       GENMASK(23, 16)
0152 #define NPCM_FIU_UMA_DR3_RB13       GENMASK(15, 8)
0153 #define NPCM_FIU_UMA_DR3_RB12       GENMASK(7, 0)
0154 
0155 /* FIU Configuration Register */
0156 #define NPCM_FIU_CFG_FIU_FIX        BIT(31)
0157 
0158 /* FIU Read Mode */
0159 enum {
0160     DRD_SINGLE_WIRE_MODE    = 0,
0161     DRD_DUAL_IO_MODE    = 1,
0162     DRD_QUAD_IO_MODE    = 2,
0163     DRD_SPI_X_MODE      = 3,
0164 };
0165 
0166 enum {
0167     DWR_ABPCK_BIT_PER_CLK   = 0,
0168     DWR_ABPCK_2_BIT_PER_CLK = 1,
0169     DWR_ABPCK_4_BIT_PER_CLK = 2,
0170 };
0171 
0172 enum {
0173     DWR_DBPCK_BIT_PER_CLK   = 0,
0174     DWR_DBPCK_2_BIT_PER_CLK = 1,
0175     DWR_DBPCK_4_BIT_PER_CLK = 2,
0176 };
0177 
0178 #define NPCM_FIU_DRD_16_BYTE_BURST  0x3000000
0179 #define NPCM_FIU_DWR_16_BYTE_BURST  0x3000000
0180 
0181 #define MAP_SIZE_128MB          0x8000000
0182 #define MAP_SIZE_16MB           0x1000000
0183 #define MAP_SIZE_8MB            0x800000
0184 
0185 #define FIU_DRD_MAX_DUMMY_NUMBER    3
0186 #define NPCM_MAX_CHIP_NUM       4
0187 #define CHUNK_SIZE          16
0188 #define UMA_MICRO_SEC_TIMEOUT       150
0189 
0190 enum {
0191     FIU0 = 0,
0192     FIU3,
0193     FIUX,
0194     FIU1,
0195 };
0196 
0197 struct npcm_fiu_info {
0198     char *name;
0199     u32 fiu_id;
0200     u32 max_map_size;
0201     u32 max_cs;
0202 };
0203 
0204 struct fiu_data {
0205     const struct npcm_fiu_info *npcm_fiu_data_info;
0206     int fiu_max;
0207 };
0208 
0209 static const struct npcm_fiu_info npcm7xx_fiu_info[] = {
0210     {.name = "FIU0", .fiu_id = FIU0,
0211         .max_map_size = MAP_SIZE_128MB, .max_cs = 2},
0212     {.name = "FIU3", .fiu_id = FIU3,
0213         .max_map_size = MAP_SIZE_128MB, .max_cs = 4},
0214     {.name = "FIUX", .fiu_id = FIUX,
0215         .max_map_size = MAP_SIZE_16MB, .max_cs = 2} };
0216 
0217 static const struct fiu_data npcm7xx_fiu_data = {
0218     .npcm_fiu_data_info = npcm7xx_fiu_info,
0219     .fiu_max = 3,
0220 };
0221 
0222 static const struct npcm_fiu_info npxm8xx_fiu_info[] = {
0223     {.name = "FIU0", .fiu_id = FIU0,
0224         .max_map_size = MAP_SIZE_128MB, .max_cs = 2},
0225     {.name = "FIU3", .fiu_id = FIU3,
0226         .max_map_size = MAP_SIZE_128MB, .max_cs = 4},
0227     {.name = "FIUX", .fiu_id = FIUX,
0228         .max_map_size = MAP_SIZE_16MB, .max_cs = 2},
0229     {.name = "FIU1", .fiu_id = FIU1,
0230         .max_map_size = MAP_SIZE_16MB, .max_cs = 4} };
0231 
0232 static const struct fiu_data npxm8xx_fiu_data = {
0233     .npcm_fiu_data_info = npxm8xx_fiu_info,
0234     .fiu_max = 4,
0235 };
0236 
0237 struct npcm_fiu_spi;
0238 
0239 struct npcm_fiu_chip {
0240     void __iomem *flash_region_mapped_ptr;
0241     struct npcm_fiu_spi *fiu;
0242     unsigned long clkrate;
0243     u32 chipselect;
0244 };
0245 
0246 struct npcm_fiu_spi {
0247     struct npcm_fiu_chip chip[NPCM_MAX_CHIP_NUM];
0248     const struct npcm_fiu_info *info;
0249     struct spi_mem_op drd_op;
0250     struct resource *res_mem;
0251     struct regmap *regmap;
0252     unsigned long clkrate;
0253     struct device *dev;
0254     struct clk *clk;
0255     bool spix_mode;
0256 };
0257 
0258 static const struct regmap_config npcm_mtd_regmap_config = {
0259     .reg_bits = 32,
0260     .val_bits = 32,
0261     .reg_stride = 4,
0262     .max_register = NPCM_FIU_MAX_REG_LIMIT,
0263 };
0264 
0265 static void npcm_fiu_set_drd(struct npcm_fiu_spi *fiu,
0266                  const struct spi_mem_op *op)
0267 {
0268     regmap_update_bits(fiu->regmap, NPCM_FIU_DRD_CFG,
0269                NPCM_FIU_DRD_CFG_ACCTYPE,
0270                ilog2(op->addr.buswidth) <<
0271                NPCM_FIU_DRD_ACCTYPE_SHIFT);
0272     fiu->drd_op.addr.buswidth = op->addr.buswidth;
0273     regmap_update_bits(fiu->regmap, NPCM_FIU_DRD_CFG,
0274                NPCM_FIU_DRD_CFG_DBW,
0275                op->dummy.nbytes << NPCM_FIU_DRD_DBW_SHIFT);
0276     fiu->drd_op.dummy.nbytes = op->dummy.nbytes;
0277     regmap_update_bits(fiu->regmap, NPCM_FIU_DRD_CFG,
0278                NPCM_FIU_DRD_CFG_RDCMD, op->cmd.opcode);
0279     fiu->drd_op.cmd.opcode = op->cmd.opcode;
0280     regmap_update_bits(fiu->regmap, NPCM_FIU_DRD_CFG,
0281                NPCM_FIU_DRD_CFG_ADDSIZ,
0282                (op->addr.nbytes - 3) << NPCM_FIU_DRD_ADDSIZ_SHIFT);
0283     fiu->drd_op.addr.nbytes = op->addr.nbytes;
0284 }
0285 
0286 static ssize_t npcm_fiu_direct_read(struct spi_mem_dirmap_desc *desc,
0287                     u64 offs, size_t len, void *buf)
0288 {
0289     struct npcm_fiu_spi *fiu =
0290         spi_controller_get_devdata(desc->mem->spi->master);
0291     struct npcm_fiu_chip *chip = &fiu->chip[desc->mem->spi->chip_select];
0292     void __iomem *src = (void __iomem *)(chip->flash_region_mapped_ptr +
0293                          offs);
0294     u8 *buf_rx = buf;
0295     u32 i;
0296 
0297     if (fiu->spix_mode) {
0298         for (i = 0 ; i < len ; i++)
0299             *(buf_rx + i) = ioread8(src + i);
0300     } else {
0301         if (desc->info.op_tmpl.addr.buswidth != fiu->drd_op.addr.buswidth ||
0302             desc->info.op_tmpl.dummy.nbytes != fiu->drd_op.dummy.nbytes ||
0303             desc->info.op_tmpl.cmd.opcode != fiu->drd_op.cmd.opcode ||
0304             desc->info.op_tmpl.addr.nbytes != fiu->drd_op.addr.nbytes)
0305             npcm_fiu_set_drd(fiu, &desc->info.op_tmpl);
0306 
0307         memcpy_fromio(buf_rx, src, len);
0308     }
0309 
0310     return len;
0311 }
0312 
0313 static ssize_t npcm_fiu_direct_write(struct spi_mem_dirmap_desc *desc,
0314                      u64 offs, size_t len, const void *buf)
0315 {
0316     struct npcm_fiu_spi *fiu =
0317         spi_controller_get_devdata(desc->mem->spi->master);
0318     struct npcm_fiu_chip *chip = &fiu->chip[desc->mem->spi->chip_select];
0319     void __iomem *dst = (void __iomem *)(chip->flash_region_mapped_ptr +
0320                          offs);
0321     const u8 *buf_tx = buf;
0322     u32 i;
0323 
0324     if (fiu->spix_mode)
0325         for (i = 0 ; i < len ; i++)
0326             iowrite8(*(buf_tx + i), dst + i);
0327     else
0328         memcpy_toio(dst, buf_tx, len);
0329 
0330     return len;
0331 }
0332 
0333 static int npcm_fiu_uma_read(struct spi_mem *mem,
0334                  const struct spi_mem_op *op, u32 addr,
0335                   bool is_address_size, u8 *data, u32 data_size)
0336 {
0337     struct npcm_fiu_spi *fiu =
0338         spi_controller_get_devdata(mem->spi->master);
0339     u32 uma_cfg = BIT(10);
0340     u32 data_reg[4];
0341     int ret;
0342     u32 val;
0343     u32 i;
0344 
0345     regmap_update_bits(fiu->regmap, NPCM_FIU_UMA_CTS,
0346                NPCM_FIU_UMA_CTS_DEV_NUM,
0347                (mem->spi->chip_select <<
0348                 NPCM_FIU_UMA_CTS_DEV_NUM_SHIFT));
0349     regmap_update_bits(fiu->regmap, NPCM_FIU_UMA_CMD,
0350                NPCM_FIU_UMA_CMD_CMD, op->cmd.opcode);
0351 
0352     if (is_address_size) {
0353         uma_cfg |= ilog2(op->cmd.buswidth);
0354         uma_cfg |= ilog2(op->addr.buswidth)
0355             << NPCM_FIU_UMA_CFG_ADBPCK_SHIFT;
0356         uma_cfg |= ilog2(op->dummy.buswidth)
0357             << NPCM_FIU_UMA_CFG_DBPCK_SHIFT;
0358         uma_cfg |= ilog2(op->data.buswidth)
0359             << NPCM_FIU_UMA_CFG_RDBPCK_SHIFT;
0360         uma_cfg |= op->dummy.nbytes << NPCM_FIU_UMA_CFG_DBSIZ_SHIFT;
0361         uma_cfg |= op->addr.nbytes << NPCM_FIU_UMA_CFG_ADDSIZ_SHIFT;
0362         regmap_write(fiu->regmap, NPCM_FIU_UMA_ADDR, addr);
0363     } else {
0364         regmap_write(fiu->regmap, NPCM_FIU_UMA_ADDR, 0x0);
0365     }
0366 
0367     uma_cfg |= data_size << NPCM_FIU_UMA_CFG_RDATSIZ_SHIFT;
0368     regmap_write(fiu->regmap, NPCM_FIU_UMA_CFG, uma_cfg);
0369     regmap_write_bits(fiu->regmap, NPCM_FIU_UMA_CTS,
0370               NPCM_FIU_UMA_CTS_EXEC_DONE,
0371               NPCM_FIU_UMA_CTS_EXEC_DONE);
0372     ret = regmap_read_poll_timeout(fiu->regmap, NPCM_FIU_UMA_CTS, val,
0373                        (!(val & NPCM_FIU_UMA_CTS_EXEC_DONE)), 0,
0374                        UMA_MICRO_SEC_TIMEOUT);
0375     if (ret)
0376         return ret;
0377 
0378     if (data_size) {
0379         for (i = 0; i < DIV_ROUND_UP(data_size, 4); i++)
0380             regmap_read(fiu->regmap, NPCM_FIU_UMA_DR0 + (i * 4),
0381                     &data_reg[i]);
0382         memcpy(data, data_reg, data_size);
0383     }
0384 
0385     return 0;
0386 }
0387 
0388 static int npcm_fiu_uma_write(struct spi_mem *mem,
0389                   const struct spi_mem_op *op, u8 cmd,
0390                   bool is_address_size, u8 *data, u32 data_size)
0391 {
0392     struct npcm_fiu_spi *fiu =
0393         spi_controller_get_devdata(mem->spi->master);
0394     u32 uma_cfg = BIT(10);
0395     u32 data_reg[4] = {0};
0396     u32 val;
0397     u32 i;
0398 
0399     regmap_update_bits(fiu->regmap, NPCM_FIU_UMA_CTS,
0400                NPCM_FIU_UMA_CTS_DEV_NUM,
0401                (mem->spi->chip_select <<
0402                 NPCM_FIU_UMA_CTS_DEV_NUM_SHIFT));
0403 
0404     regmap_update_bits(fiu->regmap, NPCM_FIU_UMA_CMD,
0405                NPCM_FIU_UMA_CMD_CMD, cmd);
0406 
0407     if (data_size) {
0408         memcpy(data_reg, data, data_size);
0409         for (i = 0; i < DIV_ROUND_UP(data_size, 4); i++)
0410             regmap_write(fiu->regmap, NPCM_FIU_UMA_DW0 + (i * 4),
0411                      data_reg[i]);
0412     }
0413 
0414     if (is_address_size) {
0415         uma_cfg |= ilog2(op->cmd.buswidth);
0416         uma_cfg |= ilog2(op->addr.buswidth) <<
0417             NPCM_FIU_UMA_CFG_ADBPCK_SHIFT;
0418         uma_cfg |= ilog2(op->data.buswidth) <<
0419             NPCM_FIU_UMA_CFG_WDBPCK_SHIFT;
0420         uma_cfg |= op->addr.nbytes << NPCM_FIU_UMA_CFG_ADDSIZ_SHIFT;
0421         regmap_write(fiu->regmap, NPCM_FIU_UMA_ADDR, op->addr.val);
0422     } else {
0423         regmap_write(fiu->regmap, NPCM_FIU_UMA_ADDR, 0x0);
0424     }
0425 
0426     uma_cfg |= (data_size << NPCM_FIU_UMA_CFG_WDATSIZ_SHIFT);
0427     regmap_write(fiu->regmap, NPCM_FIU_UMA_CFG, uma_cfg);
0428 
0429     regmap_write_bits(fiu->regmap, NPCM_FIU_UMA_CTS,
0430               NPCM_FIU_UMA_CTS_EXEC_DONE,
0431               NPCM_FIU_UMA_CTS_EXEC_DONE);
0432 
0433     return regmap_read_poll_timeout(fiu->regmap, NPCM_FIU_UMA_CTS, val,
0434                        (!(val & NPCM_FIU_UMA_CTS_EXEC_DONE)), 0,
0435                     UMA_MICRO_SEC_TIMEOUT);
0436 }
0437 
0438 static int npcm_fiu_manualwrite(struct spi_mem *mem,
0439                 const struct spi_mem_op *op)
0440 {
0441     struct npcm_fiu_spi *fiu =
0442         spi_controller_get_devdata(mem->spi->master);
0443     u8 *data = (u8 *)op->data.buf.out;
0444     u32 num_data_chunks;
0445     u32 remain_data;
0446     u32 idx = 0;
0447     int ret;
0448 
0449     num_data_chunks  = op->data.nbytes / CHUNK_SIZE;
0450     remain_data  = op->data.nbytes % CHUNK_SIZE;
0451 
0452     regmap_update_bits(fiu->regmap, NPCM_FIU_UMA_CTS,
0453                NPCM_FIU_UMA_CTS_DEV_NUM,
0454                (mem->spi->chip_select <<
0455                 NPCM_FIU_UMA_CTS_DEV_NUM_SHIFT));
0456     regmap_update_bits(fiu->regmap, NPCM_FIU_UMA_CTS,
0457                NPCM_FIU_UMA_CTS_SW_CS, 0);
0458 
0459     ret = npcm_fiu_uma_write(mem, op, op->cmd.opcode, true, NULL, 0);
0460     if (ret)
0461         return ret;
0462 
0463     /* Starting the data writing loop in multiples of 8 */
0464     for (idx = 0; idx < num_data_chunks; ++idx) {
0465         ret = npcm_fiu_uma_write(mem, op, data[0], false,
0466                      &data[1], CHUNK_SIZE - 1);
0467         if (ret)
0468             return ret;
0469 
0470         data += CHUNK_SIZE;
0471     }
0472 
0473     /* Handling chunk remains */
0474     if (remain_data > 0) {
0475         ret = npcm_fiu_uma_write(mem, op, data[0], false,
0476                      &data[1], remain_data - 1);
0477         if (ret)
0478             return ret;
0479     }
0480 
0481     regmap_update_bits(fiu->regmap, NPCM_FIU_UMA_CTS,
0482                NPCM_FIU_UMA_CTS_SW_CS, NPCM_FIU_UMA_CTS_SW_CS);
0483 
0484     return 0;
0485 }
0486 
0487 static int npcm_fiu_read(struct spi_mem *mem, const struct spi_mem_op *op)
0488 {
0489     u8 *data = op->data.buf.in;
0490     int i, readlen, currlen;
0491     u8 *buf_ptr;
0492     u32 addr;
0493     int ret;
0494 
0495     i = 0;
0496     currlen = op->data.nbytes;
0497 
0498     do {
0499         addr = ((u32)op->addr.val + i);
0500         if (currlen < 16)
0501             readlen = currlen;
0502         else
0503             readlen = 16;
0504 
0505         buf_ptr = data + i;
0506         ret = npcm_fiu_uma_read(mem, op, addr, true, buf_ptr,
0507                     readlen);
0508         if (ret)
0509             return ret;
0510 
0511         i += readlen;
0512         currlen -= 16;
0513     } while (currlen > 0);
0514 
0515     return 0;
0516 }
0517 
0518 static void npcm_fiux_set_direct_wr(struct npcm_fiu_spi *fiu)
0519 {
0520     regmap_write(fiu->regmap, NPCM_FIU_DWR_CFG,
0521              NPCM_FIU_DWR_16_BYTE_BURST);
0522     regmap_update_bits(fiu->regmap, NPCM_FIU_DWR_CFG,
0523                NPCM_FIU_DWR_CFG_ABPCK,
0524                DWR_ABPCK_4_BIT_PER_CLK << NPCM_FIU_DWR_ABPCK_SHIFT);
0525     regmap_update_bits(fiu->regmap, NPCM_FIU_DWR_CFG,
0526                NPCM_FIU_DWR_CFG_DBPCK,
0527                DWR_DBPCK_4_BIT_PER_CLK << NPCM_FIU_DWR_DBPCK_SHIFT);
0528 }
0529 
0530 static void npcm_fiux_set_direct_rd(struct npcm_fiu_spi *fiu)
0531 {
0532     u32 rx_dummy = 0;
0533 
0534     regmap_write(fiu->regmap, NPCM_FIU_DRD_CFG,
0535              NPCM_FIU_DRD_16_BYTE_BURST);
0536     regmap_update_bits(fiu->regmap, NPCM_FIU_DRD_CFG,
0537                NPCM_FIU_DRD_CFG_ACCTYPE,
0538                DRD_SPI_X_MODE << NPCM_FIU_DRD_ACCTYPE_SHIFT);
0539     regmap_update_bits(fiu->regmap, NPCM_FIU_DRD_CFG,
0540                NPCM_FIU_DRD_CFG_DBW,
0541                rx_dummy << NPCM_FIU_DRD_DBW_SHIFT);
0542 }
0543 
0544 static int npcm_fiu_exec_op(struct spi_mem *mem, const struct spi_mem_op *op)
0545 {
0546     struct npcm_fiu_spi *fiu =
0547         spi_controller_get_devdata(mem->spi->master);
0548     struct npcm_fiu_chip *chip = &fiu->chip[mem->spi->chip_select];
0549     int ret = 0;
0550     u8 *buf;
0551 
0552     dev_dbg(fiu->dev, "cmd:%#x mode:%d.%d.%d.%d addr:%#llx len:%#x\n",
0553         op->cmd.opcode, op->cmd.buswidth, op->addr.buswidth,
0554         op->dummy.buswidth, op->data.buswidth, op->addr.val,
0555         op->data.nbytes);
0556 
0557     if (fiu->spix_mode || op->addr.nbytes > 4)
0558         return -ENOTSUPP;
0559 
0560     if (fiu->clkrate != chip->clkrate) {
0561         ret = clk_set_rate(fiu->clk, chip->clkrate);
0562         if (ret < 0)
0563             dev_warn(fiu->dev, "Failed setting %lu frequency, stay at %lu frequency\n",
0564                  chip->clkrate, fiu->clkrate);
0565         else
0566             fiu->clkrate = chip->clkrate;
0567     }
0568 
0569     if (op->data.dir == SPI_MEM_DATA_IN) {
0570         if (!op->addr.nbytes) {
0571             buf = op->data.buf.in;
0572             ret = npcm_fiu_uma_read(mem, op, op->addr.val, false,
0573                         buf, op->data.nbytes);
0574         } else {
0575             ret = npcm_fiu_read(mem, op);
0576         }
0577     } else  {
0578         if (!op->addr.nbytes && !op->data.nbytes)
0579             ret = npcm_fiu_uma_write(mem, op, op->cmd.opcode, false,
0580                          NULL, 0);
0581         if (op->addr.nbytes && !op->data.nbytes) {
0582             int i;
0583             u8 buf_addr[4];
0584             u32 addr = op->addr.val;
0585 
0586             for (i = op->addr.nbytes - 1; i >= 0; i--) {
0587                 buf_addr[i] = addr & 0xff;
0588                 addr >>= 8;
0589             }
0590             ret = npcm_fiu_uma_write(mem, op, op->cmd.opcode, false,
0591                          buf_addr, op->addr.nbytes);
0592         }
0593         if (!op->addr.nbytes && op->data.nbytes)
0594             ret = npcm_fiu_uma_write(mem, op, op->cmd.opcode, false,
0595                          (u8 *)op->data.buf.out,
0596                          op->data.nbytes);
0597         if (op->addr.nbytes && op->data.nbytes)
0598             ret = npcm_fiu_manualwrite(mem, op);
0599     }
0600 
0601     return ret;
0602 }
0603 
0604 static int npcm_fiu_dirmap_create(struct spi_mem_dirmap_desc *desc)
0605 {
0606     struct npcm_fiu_spi *fiu =
0607         spi_controller_get_devdata(desc->mem->spi->master);
0608     struct npcm_fiu_chip *chip = &fiu->chip[desc->mem->spi->chip_select];
0609     struct regmap *gcr_regmap;
0610 
0611     if (!fiu->res_mem) {
0612         dev_warn(fiu->dev, "Reserved memory not defined, direct read disabled\n");
0613         desc->nodirmap = true;
0614         return 0;
0615     }
0616 
0617     if (!fiu->spix_mode &&
0618         desc->info.op_tmpl.data.dir == SPI_MEM_DATA_OUT) {
0619         desc->nodirmap = true;
0620         return 0;
0621     }
0622 
0623     if (!chip->flash_region_mapped_ptr) {
0624         chip->flash_region_mapped_ptr =
0625             devm_ioremap(fiu->dev, (fiu->res_mem->start +
0626                             (fiu->info->max_map_size *
0627                             desc->mem->spi->chip_select)),
0628                          (u32)desc->info.length);
0629         if (!chip->flash_region_mapped_ptr) {
0630             dev_warn(fiu->dev, "Error mapping memory region, direct read disabled\n");
0631             desc->nodirmap = true;
0632             return 0;
0633         }
0634     }
0635 
0636     if (of_device_is_compatible(fiu->dev->of_node, "nuvoton,npcm750-fiu")) {
0637         gcr_regmap =
0638             syscon_regmap_lookup_by_compatible("nuvoton,npcm750-gcr");
0639         if (IS_ERR(gcr_regmap)) {
0640             dev_warn(fiu->dev, "Didn't find nuvoton,npcm750-gcr, direct read disabled\n");
0641             desc->nodirmap = true;
0642             return 0;
0643         }
0644         regmap_update_bits(gcr_regmap, NPCM7XX_INTCR3_OFFSET,
0645                    NPCM7XX_INTCR3_FIU_FIX,
0646                    NPCM7XX_INTCR3_FIU_FIX);
0647     } else {
0648         regmap_update_bits(fiu->regmap, NPCM_FIU_CFG,
0649                    NPCM_FIU_CFG_FIU_FIX,
0650                    NPCM_FIU_CFG_FIU_FIX);
0651     }
0652 
0653     if (desc->info.op_tmpl.data.dir == SPI_MEM_DATA_IN) {
0654         if (!fiu->spix_mode)
0655             npcm_fiu_set_drd(fiu, &desc->info.op_tmpl);
0656         else
0657             npcm_fiux_set_direct_rd(fiu);
0658 
0659     } else {
0660         npcm_fiux_set_direct_wr(fiu);
0661     }
0662 
0663     return 0;
0664 }
0665 
0666 static int npcm_fiu_setup(struct spi_device *spi)
0667 {
0668     struct spi_controller *ctrl = spi->master;
0669     struct npcm_fiu_spi *fiu = spi_controller_get_devdata(ctrl);
0670     struct npcm_fiu_chip *chip;
0671 
0672     chip = &fiu->chip[spi->chip_select];
0673     chip->fiu = fiu;
0674     chip->chipselect = spi->chip_select;
0675     chip->clkrate = spi->max_speed_hz;
0676 
0677     fiu->clkrate = clk_get_rate(fiu->clk);
0678 
0679     return 0;
0680 }
0681 
0682 static const struct spi_controller_mem_ops npcm_fiu_mem_ops = {
0683     .exec_op = npcm_fiu_exec_op,
0684     .dirmap_create = npcm_fiu_dirmap_create,
0685     .dirmap_read = npcm_fiu_direct_read,
0686     .dirmap_write = npcm_fiu_direct_write,
0687 };
0688 
0689 static const struct of_device_id npcm_fiu_dt_ids[] = {
0690     { .compatible = "nuvoton,npcm750-fiu", .data = &npcm7xx_fiu_data  },
0691     { .compatible = "nuvoton,npcm845-fiu", .data = &npxm8xx_fiu_data  },
0692     { /* sentinel */ }
0693 };
0694 
0695 static int npcm_fiu_probe(struct platform_device *pdev)
0696 {
0697     const struct fiu_data *fiu_data_match;
0698     struct device *dev = &pdev->dev;
0699     struct spi_controller *ctrl;
0700     struct npcm_fiu_spi *fiu;
0701     void __iomem *regbase;
0702     struct resource *res;
0703     int id, ret;
0704 
0705     ctrl = devm_spi_alloc_master(dev, sizeof(*fiu));
0706     if (!ctrl)
0707         return -ENOMEM;
0708 
0709     fiu = spi_controller_get_devdata(ctrl);
0710 
0711     fiu_data_match = of_device_get_match_data(dev);
0712     if (!fiu_data_match) {
0713         dev_err(dev, "No compatible OF match\n");
0714         return -ENODEV;
0715     }
0716 
0717     id = of_alias_get_id(dev->of_node, "fiu");
0718     if (id < 0 || id >= fiu_data_match->fiu_max) {
0719         dev_err(dev, "Invalid platform device id: %d\n", id);
0720         return -EINVAL;
0721     }
0722 
0723     fiu->info = &fiu_data_match->npcm_fiu_data_info[id];
0724 
0725     platform_set_drvdata(pdev, fiu);
0726     fiu->dev = dev;
0727 
0728     res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "control");
0729     regbase = devm_ioremap_resource(dev, res);
0730     if (IS_ERR(regbase))
0731         return PTR_ERR(regbase);
0732 
0733     fiu->regmap = devm_regmap_init_mmio(dev, regbase,
0734                         &npcm_mtd_regmap_config);
0735     if (IS_ERR(fiu->regmap)) {
0736         dev_err(dev, "Failed to create regmap\n");
0737         return PTR_ERR(fiu->regmap);
0738     }
0739 
0740     fiu->res_mem = platform_get_resource_byname(pdev, IORESOURCE_MEM,
0741                             "memory");
0742     fiu->clk = devm_clk_get(dev, NULL);
0743     if (IS_ERR(fiu->clk))
0744         return PTR_ERR(fiu->clk);
0745 
0746     fiu->spix_mode = of_property_read_bool(dev->of_node,
0747                            "nuvoton,spix-mode");
0748 
0749     platform_set_drvdata(pdev, fiu);
0750     clk_prepare_enable(fiu->clk);
0751 
0752     ctrl->mode_bits = SPI_RX_DUAL | SPI_RX_QUAD
0753         | SPI_TX_DUAL | SPI_TX_QUAD;
0754     ctrl->setup = npcm_fiu_setup;
0755     ctrl->bus_num = -1;
0756     ctrl->mem_ops = &npcm_fiu_mem_ops;
0757     ctrl->num_chipselect = fiu->info->max_cs;
0758     ctrl->dev.of_node = dev->of_node;
0759 
0760     ret = devm_spi_register_master(dev, ctrl);
0761     if (ret)
0762         clk_disable_unprepare(fiu->clk);
0763 
0764     return ret;
0765 }
0766 
0767 static int npcm_fiu_remove(struct platform_device *pdev)
0768 {
0769     struct npcm_fiu_spi *fiu = platform_get_drvdata(pdev);
0770 
0771     clk_disable_unprepare(fiu->clk);
0772     return 0;
0773 }
0774 
0775 MODULE_DEVICE_TABLE(of, npcm_fiu_dt_ids);
0776 
0777 static struct platform_driver npcm_fiu_driver = {
0778     .driver = {
0779         .name   = "NPCM-FIU",
0780         .bus    = &platform_bus_type,
0781         .of_match_table = npcm_fiu_dt_ids,
0782     },
0783     .probe      = npcm_fiu_probe,
0784     .remove     = npcm_fiu_remove,
0785 };
0786 module_platform_driver(npcm_fiu_driver);
0787 
0788 MODULE_DESCRIPTION("Nuvoton FLASH Interface Unit SPI Controller Driver");
0789 MODULE_AUTHOR("Tomer Maimon <tomer.maimon@nuvoton.com>");
0790 MODULE_LICENSE("GPL v2");