root/drivers/spi/spi-npcm-fiu.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. npcm_fiu_set_drd
  2. npcm_fiu_direct_read
  3. npcm_fiu_direct_write
  4. npcm_fiu_uma_read
  5. npcm_fiu_uma_write
  6. npcm_fiu_manualwrite
  7. npcm_fiu_read
  8. npcm_fiux_set_direct_wr
  9. npcm_fiux_set_direct_rd
  10. npcm_fiu_exec_op
  11. npcm_fiu_dirmap_create
  12. npcm_fiu_setup
  13. npcm_fiu_probe
  14. npcm_fiu_remove

   1 // SPDX-License-Identifier: GPL-2.0
   2 // Copyright (c) 2019 Nuvoton Technology corporation.
   3 
   4 #include <linux/init.h>
   5 #include <linux/kernel.h>
   6 #include <linux/device.h>
   7 #include <linux/module.h>
   8 #include <linux/ioport.h>
   9 #include <linux/clk.h>
  10 #include <linux/platform_device.h>
  11 #include <linux/io.h>
  12 #include <linux/vmalloc.h>
  13 #include <linux/regmap.h>
  14 #include <linux/of_device.h>
  15 #include <linux/spi/spi-mem.h>
  16 #include <linux/mfd/syscon.h>
  17 
  18 /* NPCM7xx GCR module */
  19 #define NPCM7XX_INTCR3_OFFSET           0x9C
  20 #define NPCM7XX_INTCR3_FIU_FIX          BIT(6)
  21 
  22 /* Flash Interface Unit (FIU) Registers */
  23 #define NPCM_FIU_DRD_CFG                0x00
  24 #define NPCM_FIU_DWR_CFG                0x04
  25 #define NPCM_FIU_UMA_CFG                0x08
  26 #define NPCM_FIU_UMA_CTS                0x0C
  27 #define NPCM_FIU_UMA_CMD                0x10
  28 #define NPCM_FIU_UMA_ADDR               0x14
  29 #define NPCM_FIU_PRT_CFG                0x18
  30 #define NPCM_FIU_UMA_DW0                0x20
  31 #define NPCM_FIU_UMA_DW1                0x24
  32 #define NPCM_FIU_UMA_DW2                0x28
  33 #define NPCM_FIU_UMA_DW3                0x2C
  34 #define NPCM_FIU_UMA_DR0                0x30
  35 #define NPCM_FIU_UMA_DR1                0x34
  36 #define NPCM_FIU_UMA_DR2                0x38
  37 #define NPCM_FIU_UMA_DR3                0x3C
  38 #define NPCM_FIU_MAX_REG_LIMIT          0x80
  39 
  40 /* FIU Direct Read Configuration Register */
  41 #define NPCM_FIU_DRD_CFG_LCK            BIT(31)
  42 #define NPCM_FIU_DRD_CFG_R_BURST        GENMASK(25, 24)
  43 #define NPCM_FIU_DRD_CFG_ADDSIZ         GENMASK(17, 16)
  44 #define NPCM_FIU_DRD_CFG_DBW            GENMASK(13, 12)
  45 #define NPCM_FIU_DRD_CFG_ACCTYPE        GENMASK(9, 8)
  46 #define NPCM_FIU_DRD_CFG_RDCMD          GENMASK(7, 0)
  47 #define NPCM_FIU_DRD_ADDSIZ_SHIFT       16
  48 #define NPCM_FIU_DRD_DBW_SHIFT          12
  49 #define NPCM_FIU_DRD_ACCTYPE_SHIFT      8
  50 
  51 /* FIU Direct Write Configuration Register */
  52 #define NPCM_FIU_DWR_CFG_LCK            BIT(31)
  53 #define NPCM_FIU_DWR_CFG_W_BURST        GENMASK(25, 24)
  54 #define NPCM_FIU_DWR_CFG_ADDSIZ         GENMASK(17, 16)
  55 #define NPCM_FIU_DWR_CFG_ABPCK          GENMASK(11, 10)
  56 #define NPCM_FIU_DWR_CFG_DBPCK          GENMASK(9, 8)
  57 #define NPCM_FIU_DWR_CFG_WRCMD          GENMASK(7, 0)
  58 #define NPCM_FIU_DWR_ADDSIZ_SHIFT       16
  59 #define NPCM_FIU_DWR_ABPCK_SHIFT        10
  60 #define NPCM_FIU_DWR_DBPCK_SHIFT        8
  61 
  62 /* FIU UMA Configuration Register */
  63 #define NPCM_FIU_UMA_CFG_LCK            BIT(31)
  64 #define NPCM_FIU_UMA_CFG_CMMLCK         BIT(30)
  65 #define NPCM_FIU_UMA_CFG_RDATSIZ        GENMASK(28, 24)
  66 #define NPCM_FIU_UMA_CFG_DBSIZ          GENMASK(23, 21)
  67 #define NPCM_FIU_UMA_CFG_WDATSIZ        GENMASK(20, 16)
  68 #define NPCM_FIU_UMA_CFG_ADDSIZ         GENMASK(13, 11)
  69 #define NPCM_FIU_UMA_CFG_CMDSIZ         BIT(10)
  70 #define NPCM_FIU_UMA_CFG_RDBPCK         GENMASK(9, 8)
  71 #define NPCM_FIU_UMA_CFG_DBPCK          GENMASK(7, 6)
  72 #define NPCM_FIU_UMA_CFG_WDBPCK         GENMASK(5, 4)
  73 #define NPCM_FIU_UMA_CFG_ADBPCK         GENMASK(3, 2)
  74 #define NPCM_FIU_UMA_CFG_CMBPCK         GENMASK(1, 0)
  75 #define NPCM_FIU_UMA_CFG_ADBPCK_SHIFT   2
  76 #define NPCM_FIU_UMA_CFG_WDBPCK_SHIFT   4
  77 #define NPCM_FIU_UMA_CFG_DBPCK_SHIFT    6
  78 #define NPCM_FIU_UMA_CFG_RDBPCK_SHIFT   8
  79 #define NPCM_FIU_UMA_CFG_ADDSIZ_SHIFT   11
  80 #define NPCM_FIU_UMA_CFG_WDATSIZ_SHIFT  16
  81 #define NPCM_FIU_UMA_CFG_DBSIZ_SHIFT    21
  82 #define NPCM_FIU_UMA_CFG_RDATSIZ_SHIFT  24
  83 
  84 /* FIU UMA Control and Status Register */
  85 #define NPCM_FIU_UMA_CTS_RDYIE          BIT(25)
  86 #define NPCM_FIU_UMA_CTS_RDYST          BIT(24)
  87 #define NPCM_FIU_UMA_CTS_SW_CS          BIT(16)
  88 #define NPCM_FIU_UMA_CTS_DEV_NUM        GENMASK(9, 8)
  89 #define NPCM_FIU_UMA_CTS_EXEC_DONE      BIT(0)
  90 #define NPCM_FIU_UMA_CTS_DEV_NUM_SHIFT  8
  91 
  92 /* FIU UMA Command Register */
  93 #define NPCM_FIU_UMA_CMD_DUM3           GENMASK(31, 24)
  94 #define NPCM_FIU_UMA_CMD_DUM2           GENMASK(23, 16)
  95 #define NPCM_FIU_UMA_CMD_DUM1           GENMASK(15, 8)
  96 #define NPCM_FIU_UMA_CMD_CMD            GENMASK(7, 0)
  97 
  98 /* FIU UMA Address Register */
  99 #define NPCM_FIU_UMA_ADDR_UMA_ADDR      GENMASK(31, 0)
 100 #define NPCM_FIU_UMA_ADDR_AB3           GENMASK(31, 24)
 101 #define NPCM_FIU_UMA_ADDR_AB2           GENMASK(23, 16)
 102 #define NPCM_FIU_UMA_ADDR_AB1           GENMASK(15, 8)
 103 #define NPCM_FIU_UMA_ADDR_AB0           GENMASK(7, 0)
 104 
 105 /* FIU UMA Write Data Bytes 0-3 Register */
 106 #define NPCM_FIU_UMA_DW0_WB3            GENMASK(31, 24)
 107 #define NPCM_FIU_UMA_DW0_WB2            GENMASK(23, 16)
 108 #define NPCM_FIU_UMA_DW0_WB1            GENMASK(15, 8)
 109 #define NPCM_FIU_UMA_DW0_WB0            GENMASK(7, 0)
 110 
 111 /* FIU UMA Write Data Bytes 4-7 Register */
 112 #define NPCM_FIU_UMA_DW1_WB7            GENMASK(31, 24)
 113 #define NPCM_FIU_UMA_DW1_WB6            GENMASK(23, 16)
 114 #define NPCM_FIU_UMA_DW1_WB5            GENMASK(15, 8)
 115 #define NPCM_FIU_UMA_DW1_WB4            GENMASK(7, 0)
 116 
 117 /* FIU UMA Write Data Bytes 8-11 Register */
 118 #define NPCM_FIU_UMA_DW2_WB11           GENMASK(31, 24)
 119 #define NPCM_FIU_UMA_DW2_WB10           GENMASK(23, 16)
 120 #define NPCM_FIU_UMA_DW2_WB9            GENMASK(15, 8)
 121 #define NPCM_FIU_UMA_DW2_WB8            GENMASK(7, 0)
 122 
 123 /* FIU UMA Write Data Bytes 12-15 Register */
 124 #define NPCM_FIU_UMA_DW3_WB15           GENMASK(31, 24)
 125 #define NPCM_FIU_UMA_DW3_WB14           GENMASK(23, 16)
 126 #define NPCM_FIU_UMA_DW3_WB13           GENMASK(15, 8)
 127 #define NPCM_FIU_UMA_DW3_WB12           GENMASK(7, 0)
 128 
 129 /* FIU UMA Read Data Bytes 0-3 Register */
 130 #define NPCM_FIU_UMA_DR0_RB3            GENMASK(31, 24)
 131 #define NPCM_FIU_UMA_DR0_RB2            GENMASK(23, 16)
 132 #define NPCM_FIU_UMA_DR0_RB1            GENMASK(15, 8)
 133 #define NPCM_FIU_UMA_DR0_RB0            GENMASK(7, 0)
 134 
 135 /* FIU UMA Read Data Bytes 4-7 Register */
 136 #define NPCM_FIU_UMA_DR1_RB15           GENMASK(31, 24)
 137 #define NPCM_FIU_UMA_DR1_RB14           GENMASK(23, 16)
 138 #define NPCM_FIU_UMA_DR1_RB13           GENMASK(15, 8)
 139 #define NPCM_FIU_UMA_DR1_RB12           GENMASK(7, 0)
 140 
 141 /* FIU UMA Read Data Bytes 8-11 Register */
 142 #define NPCM_FIU_UMA_DR2_RB15           GENMASK(31, 24)
 143 #define NPCM_FIU_UMA_DR2_RB14           GENMASK(23, 16)
 144 #define NPCM_FIU_UMA_DR2_RB13           GENMASK(15, 8)
 145 #define NPCM_FIU_UMA_DR2_RB12           GENMASK(7, 0)
 146 
 147 /* FIU UMA Read Data Bytes 12-15 Register */
 148 #define NPCM_FIU_UMA_DR3_RB15           GENMASK(31, 24)
 149 #define NPCM_FIU_UMA_DR3_RB14           GENMASK(23, 16)
 150 #define NPCM_FIU_UMA_DR3_RB13           GENMASK(15, 8)
 151 #define NPCM_FIU_UMA_DR3_RB12           GENMASK(7, 0)
 152 
 153 /* FIU Read Mode */
 154 enum {
 155         DRD_SINGLE_WIRE_MODE    = 0,
 156         DRD_DUAL_IO_MODE        = 1,
 157         DRD_QUAD_IO_MODE        = 2,
 158         DRD_SPI_X_MODE          = 3,
 159 };
 160 
 161 enum {
 162         DWR_ABPCK_BIT_PER_CLK   = 0,
 163         DWR_ABPCK_2_BIT_PER_CLK = 1,
 164         DWR_ABPCK_4_BIT_PER_CLK = 2,
 165 };
 166 
 167 enum {
 168         DWR_DBPCK_BIT_PER_CLK   = 0,
 169         DWR_DBPCK_2_BIT_PER_CLK = 1,
 170         DWR_DBPCK_4_BIT_PER_CLK = 2,
 171 };
 172 
 173 #define NPCM_FIU_DRD_16_BYTE_BURST      0x3000000
 174 #define NPCM_FIU_DWR_16_BYTE_BURST      0x3000000
 175 
 176 #define MAP_SIZE_128MB                  0x8000000
 177 #define MAP_SIZE_16MB                   0x1000000
 178 #define MAP_SIZE_8MB                    0x800000
 179 
 180 #define NUM_BITS_IN_BYTE                8
 181 #define FIU_DRD_MAX_DUMMY_NUMBER        3
 182 #define NPCM_MAX_CHIP_NUM               4
 183 #define CHUNK_SIZE                      16
 184 #define UMA_MICRO_SEC_TIMEOUT           150
 185 
 186 enum {
 187         FIU0 = 0,
 188         FIU3,
 189         FIUX,
 190 };
 191 
 192 struct npcm_fiu_info {
 193         char *name;
 194         u32 fiu_id;
 195         u32 max_map_size;
 196         u32 max_cs;
 197 };
 198 
 199 struct fiu_data {
 200         const struct npcm_fiu_info *npcm_fiu_data_info;
 201         int fiu_max;
 202 };
 203 
 204 static const struct npcm_fiu_info npxm7xx_fiu_info[] = {
 205         {.name = "FIU0", .fiu_id = FIU0,
 206                 .max_map_size = MAP_SIZE_128MB, .max_cs = 2},
 207         {.name = "FIU3", .fiu_id = FIU3,
 208                 .max_map_size = MAP_SIZE_128MB, .max_cs = 4},
 209         {.name = "FIUX", .fiu_id = FIUX,
 210                 .max_map_size = MAP_SIZE_16MB, .max_cs = 2} };
 211 
 212 static const struct fiu_data npxm7xx_fiu_data = {
 213         .npcm_fiu_data_info = npxm7xx_fiu_info,
 214         .fiu_max = 3,
 215 };
 216 
 217 struct npcm_fiu_spi;
 218 
 219 struct npcm_fiu_chip {
 220         void __iomem *flash_region_mapped_ptr;
 221         struct npcm_fiu_spi *fiu;
 222         unsigned long clkrate;
 223         u32 chipselect;
 224 };
 225 
 226 struct npcm_fiu_spi {
 227         struct npcm_fiu_chip chip[NPCM_MAX_CHIP_NUM];
 228         const struct npcm_fiu_info *info;
 229         struct spi_mem_op drd_op;
 230         struct resource *res_mem;
 231         struct regmap *regmap;
 232         unsigned long clkrate;
 233         struct device *dev;
 234         struct clk *clk;
 235         bool spix_mode;
 236 };
 237 
 238 static const struct regmap_config npcm_mtd_regmap_config = {
 239         .reg_bits = 32,
 240         .val_bits = 32,
 241         .reg_stride = 4,
 242         .max_register = NPCM_FIU_MAX_REG_LIMIT,
 243 };
 244 
 245 static void npcm_fiu_set_drd(struct npcm_fiu_spi *fiu,
 246                              const struct spi_mem_op *op)
 247 {
 248         regmap_update_bits(fiu->regmap, NPCM_FIU_DRD_CFG,
 249                            NPCM_FIU_DRD_CFG_ACCTYPE,
 250                            ilog2(op->addr.buswidth) <<
 251                            NPCM_FIU_DRD_ACCTYPE_SHIFT);
 252         fiu->drd_op.addr.buswidth = op->addr.buswidth;
 253         regmap_update_bits(fiu->regmap, NPCM_FIU_DRD_CFG,
 254                            NPCM_FIU_DRD_CFG_DBW,
 255                            ((op->dummy.nbytes * ilog2(op->addr.buswidth))
 256                             / NUM_BITS_IN_BYTE) << NPCM_FIU_DRD_DBW_SHIFT);
 257         fiu->drd_op.dummy.nbytes = op->dummy.nbytes;
 258         regmap_update_bits(fiu->regmap, NPCM_FIU_DRD_CFG,
 259                            NPCM_FIU_DRD_CFG_RDCMD, op->cmd.opcode);
 260         fiu->drd_op.cmd.opcode = op->cmd.opcode;
 261         regmap_update_bits(fiu->regmap, NPCM_FIU_DRD_CFG,
 262                            NPCM_FIU_DRD_CFG_ADDSIZ,
 263                            (op->addr.nbytes - 3) << NPCM_FIU_DRD_ADDSIZ_SHIFT);
 264         fiu->drd_op.addr.nbytes = op->addr.nbytes;
 265 }
 266 
 267 static ssize_t npcm_fiu_direct_read(struct spi_mem_dirmap_desc *desc,
 268                                     u64 offs, size_t len, void *buf)
 269 {
 270         struct npcm_fiu_spi *fiu =
 271                 spi_controller_get_devdata(desc->mem->spi->master);
 272         struct npcm_fiu_chip *chip = &fiu->chip[desc->mem->spi->chip_select];
 273         void __iomem *src = (void __iomem *)(chip->flash_region_mapped_ptr +
 274                                              offs);
 275         u8 *buf_rx = buf;
 276         u32 i;
 277 
 278         if (fiu->spix_mode) {
 279                 for (i = 0 ; i < len ; i++)
 280                         *(buf_rx + i) = ioread8(src + i);
 281         } else {
 282                 if (desc->info.op_tmpl.addr.buswidth != fiu->drd_op.addr.buswidth ||
 283                     desc->info.op_tmpl.dummy.nbytes != fiu->drd_op.dummy.nbytes ||
 284                     desc->info.op_tmpl.cmd.opcode != fiu->drd_op.cmd.opcode ||
 285                     desc->info.op_tmpl.addr.nbytes != fiu->drd_op.addr.nbytes)
 286                         npcm_fiu_set_drd(fiu, &desc->info.op_tmpl);
 287 
 288                 memcpy_fromio(buf_rx, src, len);
 289         }
 290 
 291         return len;
 292 }
 293 
 294 static ssize_t npcm_fiu_direct_write(struct spi_mem_dirmap_desc *desc,
 295                                      u64 offs, size_t len, const void *buf)
 296 {
 297         struct npcm_fiu_spi *fiu =
 298                 spi_controller_get_devdata(desc->mem->spi->master);
 299         struct npcm_fiu_chip *chip = &fiu->chip[desc->mem->spi->chip_select];
 300         void __iomem *dst = (void __iomem *)(chip->flash_region_mapped_ptr +
 301                                              offs);
 302         const u8 *buf_tx = buf;
 303         u32 i;
 304 
 305         if (fiu->spix_mode)
 306                 for (i = 0 ; i < len ; i++)
 307                         iowrite8(*(buf_tx + i), dst + i);
 308         else
 309                 memcpy_toio(dst, buf_tx, len);
 310 
 311         return len;
 312 }
 313 
 314 static int npcm_fiu_uma_read(struct spi_mem *mem,
 315                              const struct spi_mem_op *op, u32 addr,
 316                               bool is_address_size, u8 *data, u32 data_size)
 317 {
 318         struct npcm_fiu_spi *fiu =
 319                 spi_controller_get_devdata(mem->spi->master);
 320         u32 uma_cfg = BIT(10);
 321         u32 data_reg[4];
 322         int ret;
 323         u32 val;
 324         u32 i;
 325 
 326         regmap_update_bits(fiu->regmap, NPCM_FIU_UMA_CTS,
 327                            NPCM_FIU_UMA_CTS_DEV_NUM,
 328                            (mem->spi->chip_select <<
 329                             NPCM_FIU_UMA_CTS_DEV_NUM_SHIFT));
 330         regmap_update_bits(fiu->regmap, NPCM_FIU_UMA_CMD,
 331                            NPCM_FIU_UMA_CMD_CMD, op->cmd.opcode);
 332 
 333         if (is_address_size) {
 334                 uma_cfg |= ilog2(op->cmd.buswidth);
 335                 uma_cfg |= ilog2(op->addr.buswidth)
 336                         << NPCM_FIU_UMA_CFG_ADBPCK_SHIFT;
 337                 uma_cfg |= ilog2(op->dummy.buswidth)
 338                         << NPCM_FIU_UMA_CFG_DBPCK_SHIFT;
 339                 uma_cfg |= ilog2(op->data.buswidth)
 340                         << NPCM_FIU_UMA_CFG_RDBPCK_SHIFT;
 341                 uma_cfg |= op->dummy.nbytes << NPCM_FIU_UMA_CFG_DBSIZ_SHIFT;
 342                 uma_cfg |= op->addr.nbytes << NPCM_FIU_UMA_CFG_ADDSIZ_SHIFT;
 343                 regmap_write(fiu->regmap, NPCM_FIU_UMA_ADDR, addr);
 344         } else {
 345                 regmap_write(fiu->regmap, NPCM_FIU_UMA_ADDR, 0x0);
 346         }
 347 
 348         uma_cfg |= data_size << NPCM_FIU_UMA_CFG_RDATSIZ_SHIFT;
 349         regmap_write(fiu->regmap, NPCM_FIU_UMA_CFG, uma_cfg);
 350         regmap_write_bits(fiu->regmap, NPCM_FIU_UMA_CTS,
 351                           NPCM_FIU_UMA_CTS_EXEC_DONE,
 352                           NPCM_FIU_UMA_CTS_EXEC_DONE);
 353         ret = regmap_read_poll_timeout(fiu->regmap, NPCM_FIU_UMA_CTS, val,
 354                                        (!(val & NPCM_FIU_UMA_CTS_EXEC_DONE)), 0,
 355                                        UMA_MICRO_SEC_TIMEOUT);
 356         if (ret)
 357                 return ret;
 358 
 359         if (data_size) {
 360                 for (i = 0; i < DIV_ROUND_UP(data_size, 4); i++)
 361                         regmap_read(fiu->regmap, NPCM_FIU_UMA_DR0 + (i * 4),
 362                                     &data_reg[i]);
 363                 memcpy(data, data_reg, data_size);
 364         }
 365 
 366         return 0;
 367 }
 368 
 369 static int npcm_fiu_uma_write(struct spi_mem *mem,
 370                               const struct spi_mem_op *op, u8 cmd,
 371                               bool is_address_size, u8 *data, u32 data_size)
 372 {
 373         struct npcm_fiu_spi *fiu =
 374                 spi_controller_get_devdata(mem->spi->master);
 375         u32 uma_cfg = BIT(10);
 376         u32 data_reg[4] = {0};
 377         u32 val;
 378         u32 i;
 379 
 380         regmap_update_bits(fiu->regmap, NPCM_FIU_UMA_CTS,
 381                            NPCM_FIU_UMA_CTS_DEV_NUM,
 382                            (mem->spi->chip_select <<
 383                             NPCM_FIU_UMA_CTS_DEV_NUM_SHIFT));
 384 
 385         regmap_update_bits(fiu->regmap, NPCM_FIU_UMA_CMD,
 386                            NPCM_FIU_UMA_CMD_CMD, cmd);
 387 
 388         if (data_size) {
 389                 memcpy(data_reg, data, data_size);
 390                 for (i = 0; i < DIV_ROUND_UP(data_size, 4); i++)
 391                         regmap_write(fiu->regmap, NPCM_FIU_UMA_DW0 + (i * 4),
 392                                      data_reg[i]);
 393         }
 394 
 395         if (is_address_size) {
 396                 uma_cfg |= ilog2(op->cmd.buswidth);
 397                 uma_cfg |= ilog2(op->addr.buswidth) <<
 398                         NPCM_FIU_UMA_CFG_ADBPCK_SHIFT;
 399                 uma_cfg |= ilog2(op->data.buswidth) <<
 400                         NPCM_FIU_UMA_CFG_WDBPCK_SHIFT;
 401                 uma_cfg |= op->addr.nbytes << NPCM_FIU_UMA_CFG_ADDSIZ_SHIFT;
 402                 regmap_write(fiu->regmap, NPCM_FIU_UMA_ADDR, op->addr.val);
 403         } else {
 404                 regmap_write(fiu->regmap, NPCM_FIU_UMA_ADDR, 0x0);
 405         }
 406 
 407         uma_cfg |= (data_size << NPCM_FIU_UMA_CFG_WDATSIZ_SHIFT);
 408         regmap_write(fiu->regmap, NPCM_FIU_UMA_CFG, uma_cfg);
 409 
 410         regmap_write_bits(fiu->regmap, NPCM_FIU_UMA_CTS,
 411                           NPCM_FIU_UMA_CTS_EXEC_DONE,
 412                           NPCM_FIU_UMA_CTS_EXEC_DONE);
 413 
 414         return regmap_read_poll_timeout(fiu->regmap, NPCM_FIU_UMA_CTS, val,
 415                                        (!(val & NPCM_FIU_UMA_CTS_EXEC_DONE)), 0,
 416                                         UMA_MICRO_SEC_TIMEOUT);
 417 }
 418 
 419 static int npcm_fiu_manualwrite(struct spi_mem *mem,
 420                                 const struct spi_mem_op *op)
 421 {
 422         struct npcm_fiu_spi *fiu =
 423                 spi_controller_get_devdata(mem->spi->master);
 424         u8 *data = (u8 *)op->data.buf.out;
 425         u32 num_data_chunks;
 426         u32 remain_data;
 427         u32 idx = 0;
 428         int ret;
 429 
 430         num_data_chunks  = op->data.nbytes / CHUNK_SIZE;
 431         remain_data  = op->data.nbytes % CHUNK_SIZE;
 432 
 433         regmap_update_bits(fiu->regmap, NPCM_FIU_UMA_CTS,
 434                            NPCM_FIU_UMA_CTS_DEV_NUM,
 435                            (mem->spi->chip_select <<
 436                             NPCM_FIU_UMA_CTS_DEV_NUM_SHIFT));
 437         regmap_update_bits(fiu->regmap, NPCM_FIU_UMA_CTS,
 438                            NPCM_FIU_UMA_CTS_SW_CS, 0);
 439 
 440         ret = npcm_fiu_uma_write(mem, op, op->cmd.opcode, true, NULL, 0);
 441         if (ret)
 442                 return ret;
 443 
 444         /* Starting the data writing loop in multiples of 8 */
 445         for (idx = 0; idx < num_data_chunks; ++idx) {
 446                 ret = npcm_fiu_uma_write(mem, op, data[0], false,
 447                                          &data[1], CHUNK_SIZE - 1);
 448                 if (ret)
 449                         return ret;
 450 
 451                 data += CHUNK_SIZE;
 452         }
 453 
 454         /* Handling chunk remains */
 455         if (remain_data > 0) {
 456                 ret = npcm_fiu_uma_write(mem, op, data[0], false,
 457                                          &data[1], remain_data - 1);
 458                 if (ret)
 459                         return ret;
 460         }
 461 
 462         regmap_update_bits(fiu->regmap, NPCM_FIU_UMA_CTS,
 463                            NPCM_FIU_UMA_CTS_SW_CS, NPCM_FIU_UMA_CTS_SW_CS);
 464 
 465         return 0;
 466 }
 467 
 468 static int npcm_fiu_read(struct spi_mem *mem, const struct spi_mem_op *op)
 469 {
 470         u8 *data = op->data.buf.in;
 471         int i, readlen, currlen;
 472         u8 *buf_ptr;
 473         u32 addr;
 474         int ret;
 475 
 476         i = 0;
 477         currlen = op->data.nbytes;
 478 
 479         do {
 480                 addr = ((u32)op->addr.val + i);
 481                 if (currlen < 16)
 482                         readlen = currlen;
 483                 else
 484                         readlen = 16;
 485 
 486                 buf_ptr = data + i;
 487                 ret = npcm_fiu_uma_read(mem, op, addr, true, buf_ptr,
 488                                         readlen);
 489                 if (ret)
 490                         return ret;
 491 
 492                 i += readlen;
 493                 currlen -= 16;
 494         } while (currlen > 0);
 495 
 496         return 0;
 497 }
 498 
 499 static void npcm_fiux_set_direct_wr(struct npcm_fiu_spi *fiu)
 500 {
 501         regmap_write(fiu->regmap, NPCM_FIU_DWR_CFG,
 502                      NPCM_FIU_DWR_16_BYTE_BURST);
 503         regmap_update_bits(fiu->regmap, NPCM_FIU_DWR_CFG,
 504                            NPCM_FIU_DWR_CFG_ABPCK,
 505                            DWR_ABPCK_4_BIT_PER_CLK << NPCM_FIU_DWR_ABPCK_SHIFT);
 506         regmap_update_bits(fiu->regmap, NPCM_FIU_DWR_CFG,
 507                            NPCM_FIU_DWR_CFG_DBPCK,
 508                            DWR_DBPCK_4_BIT_PER_CLK << NPCM_FIU_DWR_DBPCK_SHIFT);
 509 }
 510 
 511 static void npcm_fiux_set_direct_rd(struct npcm_fiu_spi *fiu)
 512 {
 513         u32 rx_dummy = 0;
 514 
 515         regmap_write(fiu->regmap, NPCM_FIU_DRD_CFG,
 516                      NPCM_FIU_DRD_16_BYTE_BURST);
 517         regmap_update_bits(fiu->regmap, NPCM_FIU_DRD_CFG,
 518                            NPCM_FIU_DRD_CFG_ACCTYPE,
 519                            DRD_SPI_X_MODE << NPCM_FIU_DRD_ACCTYPE_SHIFT);
 520         regmap_update_bits(fiu->regmap, NPCM_FIU_DRD_CFG,
 521                            NPCM_FIU_DRD_CFG_DBW,
 522                            rx_dummy << NPCM_FIU_DRD_DBW_SHIFT);
 523 }
 524 
 525 static int npcm_fiu_exec_op(struct spi_mem *mem, const struct spi_mem_op *op)
 526 {
 527         struct npcm_fiu_spi *fiu =
 528                 spi_controller_get_devdata(mem->spi->master);
 529         struct npcm_fiu_chip *chip = &fiu->chip[mem->spi->chip_select];
 530         int ret = 0;
 531         u8 *buf;
 532 
 533         dev_dbg(fiu->dev, "cmd:%#x mode:%d.%d.%d.%d addr:%#llx len:%#x\n",
 534                 op->cmd.opcode, op->cmd.buswidth, op->addr.buswidth,
 535                 op->dummy.buswidth, op->data.buswidth, op->addr.val,
 536                 op->data.nbytes);
 537 
 538         if (fiu->spix_mode || op->addr.nbytes > 4)
 539                 return -ENOTSUPP;
 540 
 541         if (fiu->clkrate != chip->clkrate) {
 542                 ret = clk_set_rate(fiu->clk, chip->clkrate);
 543                 if (ret < 0)
 544                         dev_warn(fiu->dev, "Failed setting %lu frequency, stay at %lu frequency\n",
 545                                  chip->clkrate, fiu->clkrate);
 546                 else
 547                         fiu->clkrate = chip->clkrate;
 548         }
 549 
 550         if (op->data.dir == SPI_MEM_DATA_IN) {
 551                 if (!op->addr.nbytes) {
 552                         buf = op->data.buf.in;
 553                         ret = npcm_fiu_uma_read(mem, op, op->addr.val, false,
 554                                                 buf, op->data.nbytes);
 555                 } else {
 556                         ret = npcm_fiu_read(mem, op);
 557                 }
 558         } else  {
 559                 if (!op->addr.nbytes && !op->data.nbytes)
 560                         ret = npcm_fiu_uma_write(mem, op, op->cmd.opcode, false,
 561                                                  NULL, 0);
 562                 if (op->addr.nbytes && !op->data.nbytes) {
 563                         int i;
 564                         u8 buf_addr[4];
 565                         u32 addr = op->addr.val;
 566 
 567                         for (i = op->addr.nbytes - 1; i >= 0; i--) {
 568                                 buf_addr[i] = addr & 0xff;
 569                                 addr >>= 8;
 570                         }
 571                         ret = npcm_fiu_uma_write(mem, op, op->cmd.opcode, false,
 572                                                  buf_addr, op->addr.nbytes);
 573                 }
 574                 if (!op->addr.nbytes && op->data.nbytes)
 575                         ret = npcm_fiu_uma_write(mem, op, op->cmd.opcode, false,
 576                                                  (u8 *)op->data.buf.out,
 577                                                  op->data.nbytes);
 578                 if (op->addr.nbytes && op->data.nbytes)
 579                         ret = npcm_fiu_manualwrite(mem, op);
 580         }
 581 
 582         return ret;
 583 }
 584 
 585 static int npcm_fiu_dirmap_create(struct spi_mem_dirmap_desc *desc)
 586 {
 587         struct npcm_fiu_spi *fiu =
 588                 spi_controller_get_devdata(desc->mem->spi->master);
 589         struct npcm_fiu_chip *chip = &fiu->chip[desc->mem->spi->chip_select];
 590         struct regmap *gcr_regmap;
 591 
 592         if (!fiu->res_mem) {
 593                 dev_warn(fiu->dev, "Reserved memory not defined, direct read disabled\n");
 594                 desc->nodirmap = true;
 595                 return 0;
 596         }
 597 
 598         if (!fiu->spix_mode &&
 599             desc->info.op_tmpl.data.dir == SPI_MEM_DATA_OUT) {
 600                 desc->nodirmap = true;
 601                 return 0;
 602         }
 603 
 604         if (!chip->flash_region_mapped_ptr) {
 605                 chip->flash_region_mapped_ptr =
 606                         devm_ioremap_nocache(fiu->dev, (fiu->res_mem->start +
 607                                                         (fiu->info->max_map_size *
 608                                                     desc->mem->spi->chip_select)),
 609                                              (u32)desc->info.length);
 610                 if (!chip->flash_region_mapped_ptr) {
 611                         dev_warn(fiu->dev, "Error mapping memory region, direct read disabled\n");
 612                         desc->nodirmap = true;
 613                         return 0;
 614                 }
 615         }
 616 
 617         if (of_device_is_compatible(fiu->dev->of_node, "nuvoton,npcm750-fiu")) {
 618                 gcr_regmap =
 619                         syscon_regmap_lookup_by_compatible("nuvoton,npcm750-gcr");
 620                 if (IS_ERR(gcr_regmap)) {
 621                         dev_warn(fiu->dev, "Didn't find nuvoton,npcm750-gcr, direct read disabled\n");
 622                         desc->nodirmap = true;
 623                         return 0;
 624                 }
 625                 regmap_update_bits(gcr_regmap, NPCM7XX_INTCR3_OFFSET,
 626                                    NPCM7XX_INTCR3_FIU_FIX,
 627                                    NPCM7XX_INTCR3_FIU_FIX);
 628         }
 629 
 630         if (desc->info.op_tmpl.data.dir == SPI_MEM_DATA_IN) {
 631                 if (!fiu->spix_mode)
 632                         npcm_fiu_set_drd(fiu, &desc->info.op_tmpl);
 633                 else
 634                         npcm_fiux_set_direct_rd(fiu);
 635 
 636         } else {
 637                 npcm_fiux_set_direct_wr(fiu);
 638         }
 639 
 640         return 0;
 641 }
 642 
 643 static int npcm_fiu_setup(struct spi_device *spi)
 644 {
 645         struct spi_controller *ctrl = spi->master;
 646         struct npcm_fiu_spi *fiu = spi_controller_get_devdata(ctrl);
 647         struct npcm_fiu_chip *chip;
 648 
 649         chip = &fiu->chip[spi->chip_select];
 650         chip->fiu = fiu;
 651         chip->chipselect = spi->chip_select;
 652         chip->clkrate = spi->max_speed_hz;
 653 
 654         fiu->clkrate = clk_get_rate(fiu->clk);
 655 
 656         return 0;
 657 }
 658 
 659 static const struct spi_controller_mem_ops npcm_fiu_mem_ops = {
 660         .exec_op = npcm_fiu_exec_op,
 661         .dirmap_create = npcm_fiu_dirmap_create,
 662         .dirmap_read = npcm_fiu_direct_read,
 663         .dirmap_write = npcm_fiu_direct_write,
 664 };
 665 
 666 static const struct of_device_id npcm_fiu_dt_ids[] = {
 667         { .compatible = "nuvoton,npcm750-fiu", .data = &npxm7xx_fiu_data  },
 668         { /* sentinel */ }
 669 };
 670 
 671 static int npcm_fiu_probe(struct platform_device *pdev)
 672 {
 673         const struct fiu_data *fiu_data_match;
 674         const struct of_device_id *match;
 675         struct device *dev = &pdev->dev;
 676         struct spi_controller *ctrl;
 677         struct npcm_fiu_spi *fiu;
 678         void __iomem *regbase;
 679         struct resource *res;
 680         int ret;
 681         int id;
 682 
 683         ctrl = spi_alloc_master(dev, sizeof(*fiu));
 684         if (!ctrl)
 685                 return -ENOMEM;
 686 
 687         fiu = spi_controller_get_devdata(ctrl);
 688 
 689         match = of_match_device(npcm_fiu_dt_ids, dev);
 690         if (!match || !match->data) {
 691                 dev_err(dev, "No compatible OF match\n");
 692                 return -ENODEV;
 693         }
 694 
 695         fiu_data_match = match->data;
 696         id = of_alias_get_id(dev->of_node, "fiu");
 697         if (id < 0 || id >= fiu_data_match->fiu_max) {
 698                 dev_err(dev, "Invalid platform device id: %d\n", id);
 699                 return -EINVAL;
 700         }
 701 
 702         fiu->info = &fiu_data_match->npcm_fiu_data_info[id];
 703 
 704         platform_set_drvdata(pdev, fiu);
 705         fiu->dev = dev;
 706 
 707         res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "control");
 708         regbase = devm_ioremap_resource(dev, res);
 709         if (IS_ERR(regbase))
 710                 return PTR_ERR(regbase);
 711 
 712         fiu->regmap = devm_regmap_init_mmio(dev, regbase,
 713                                             &npcm_mtd_regmap_config);
 714         if (IS_ERR(fiu->regmap)) {
 715                 dev_err(dev, "Failed to create regmap\n");
 716                 return PTR_ERR(fiu->regmap);
 717         }
 718 
 719         fiu->res_mem = platform_get_resource_byname(pdev, IORESOURCE_MEM,
 720                                                     "memory");
 721         fiu->clk = devm_clk_get(dev, NULL);
 722         if (IS_ERR(fiu->clk))
 723                 return PTR_ERR(fiu->clk);
 724 
 725         fiu->spix_mode = of_property_read_bool(dev->of_node,
 726                                                "nuvoton,spix-mode");
 727 
 728         platform_set_drvdata(pdev, fiu);
 729         clk_prepare_enable(fiu->clk);
 730 
 731         ctrl->mode_bits = SPI_RX_DUAL | SPI_RX_QUAD
 732                 | SPI_TX_DUAL | SPI_TX_QUAD;
 733         ctrl->setup = npcm_fiu_setup;
 734         ctrl->bus_num = -1;
 735         ctrl->mem_ops = &npcm_fiu_mem_ops;
 736         ctrl->num_chipselect = fiu->info->max_cs;
 737         ctrl->dev.of_node = dev->of_node;
 738 
 739         ret = devm_spi_register_master(dev, ctrl);
 740         if (ret)
 741                 return ret;
 742 
 743         return 0;
 744 }
 745 
 746 static int npcm_fiu_remove(struct platform_device *pdev)
 747 {
 748         struct npcm_fiu_spi *fiu = platform_get_drvdata(pdev);
 749 
 750         clk_disable_unprepare(fiu->clk);
 751         return 0;
 752 }
 753 
 754 MODULE_DEVICE_TABLE(of, npcm_fiu_dt_ids);
 755 
 756 static struct platform_driver npcm_fiu_driver = {
 757         .driver = {
 758                 .name   = "NPCM-FIU",
 759                 .bus    = &platform_bus_type,
 760                 .of_match_table = npcm_fiu_dt_ids,
 761         },
 762         .probe      = npcm_fiu_probe,
 763         .remove     = npcm_fiu_remove,
 764 };
 765 module_platform_driver(npcm_fiu_driver);
 766 
 767 MODULE_DESCRIPTION("Nuvoton FLASH Interface Unit SPI Controller Driver");
 768 MODULE_AUTHOR("Tomer Maimon <tomer.maimon@nuvoton.com>");
 769 MODULE_LICENSE("GPL v2");

/* [<][>][^][v][top][bottom][index][help] */