linux/drivers/spi/spi-npcm-fiu.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2// Copyright (c) 2019 Nuvoton Technology corporation.
   3
   4#include <linux/bits.h>
   5#include <linux/init.h>
   6#include <linux/kernel.h>
   7#include <linux/device.h>
   8#include <linux/module.h>
   9#include <linux/ioport.h>
  10#include <linux/clk.h>
  11#include <linux/platform_device.h>
  12#include <linux/io.h>
  13#include <linux/vmalloc.h>
  14#include <linux/regmap.h>
  15#include <linux/of_device.h>
  16#include <linux/spi/spi-mem.h>
  17#include <linux/mfd/syscon.h>
  18
  19/* NPCM7xx GCR module */
  20#define NPCM7XX_INTCR3_OFFSET           0x9C
  21#define NPCM7XX_INTCR3_FIU_FIX          BIT(6)
  22
  23/* Flash Interface Unit (FIU) Registers */
  24#define NPCM_FIU_DRD_CFG                0x00
  25#define NPCM_FIU_DWR_CFG                0x04
  26#define NPCM_FIU_UMA_CFG                0x08
  27#define NPCM_FIU_UMA_CTS                0x0C
  28#define NPCM_FIU_UMA_CMD                0x10
  29#define NPCM_FIU_UMA_ADDR               0x14
  30#define NPCM_FIU_PRT_CFG                0x18
  31#define NPCM_FIU_UMA_DW0                0x20
  32#define NPCM_FIU_UMA_DW1                0x24
  33#define NPCM_FIU_UMA_DW2                0x28
  34#define NPCM_FIU_UMA_DW3                0x2C
  35#define NPCM_FIU_UMA_DR0                0x30
  36#define NPCM_FIU_UMA_DR1                0x34
  37#define NPCM_FIU_UMA_DR2                0x38
  38#define NPCM_FIU_UMA_DR3                0x3C
  39#define NPCM_FIU_MAX_REG_LIMIT          0x80
  40
  41/* FIU Direct Read Configuration Register */
  42#define NPCM_FIU_DRD_CFG_LCK            BIT(31)
  43#define NPCM_FIU_DRD_CFG_R_BURST        GENMASK(25, 24)
  44#define NPCM_FIU_DRD_CFG_ADDSIZ         GENMASK(17, 16)
  45#define NPCM_FIU_DRD_CFG_DBW            GENMASK(13, 12)
  46#define NPCM_FIU_DRD_CFG_ACCTYPE        GENMASK(9, 8)
  47#define NPCM_FIU_DRD_CFG_RDCMD          GENMASK(7, 0)
  48#define NPCM_FIU_DRD_ADDSIZ_SHIFT       16
  49#define NPCM_FIU_DRD_DBW_SHIFT          12
  50#define NPCM_FIU_DRD_ACCTYPE_SHIFT      8
  51
  52/* FIU Direct Write Configuration Register */
  53#define NPCM_FIU_DWR_CFG_LCK            BIT(31)
  54#define NPCM_FIU_DWR_CFG_W_BURST        GENMASK(25, 24)
  55#define NPCM_FIU_DWR_CFG_ADDSIZ         GENMASK(17, 16)
  56#define NPCM_FIU_DWR_CFG_ABPCK          GENMASK(11, 10)
  57#define NPCM_FIU_DWR_CFG_DBPCK          GENMASK(9, 8)
  58#define NPCM_FIU_DWR_CFG_WRCMD          GENMASK(7, 0)
  59#define NPCM_FIU_DWR_ADDSIZ_SHIFT       16
  60#define NPCM_FIU_DWR_ABPCK_SHIFT        10
  61#define NPCM_FIU_DWR_DBPCK_SHIFT        8
  62
  63/* FIU UMA Configuration Register */
  64#define NPCM_FIU_UMA_CFG_LCK            BIT(31)
  65#define NPCM_FIU_UMA_CFG_CMMLCK         BIT(30)
  66#define NPCM_FIU_UMA_CFG_RDATSIZ        GENMASK(28, 24)
  67#define NPCM_FIU_UMA_CFG_DBSIZ          GENMASK(23, 21)
  68#define NPCM_FIU_UMA_CFG_WDATSIZ        GENMASK(20, 16)
  69#define NPCM_FIU_UMA_CFG_ADDSIZ         GENMASK(13, 11)
  70#define NPCM_FIU_UMA_CFG_CMDSIZ         BIT(10)
  71#define NPCM_FIU_UMA_CFG_RDBPCK         GENMASK(9, 8)
  72#define NPCM_FIU_UMA_CFG_DBPCK          GENMASK(7, 6)
  73#define NPCM_FIU_UMA_CFG_WDBPCK         GENMASK(5, 4)
  74#define NPCM_FIU_UMA_CFG_ADBPCK         GENMASK(3, 2)
  75#define NPCM_FIU_UMA_CFG_CMBPCK         GENMASK(1, 0)
  76#define NPCM_FIU_UMA_CFG_ADBPCK_SHIFT   2
  77#define NPCM_FIU_UMA_CFG_WDBPCK_SHIFT   4
  78#define NPCM_FIU_UMA_CFG_DBPCK_SHIFT    6
  79#define NPCM_FIU_UMA_CFG_RDBPCK_SHIFT   8
  80#define NPCM_FIU_UMA_CFG_ADDSIZ_SHIFT   11
  81#define NPCM_FIU_UMA_CFG_WDATSIZ_SHIFT  16
  82#define NPCM_FIU_UMA_CFG_DBSIZ_SHIFT    21
  83#define NPCM_FIU_UMA_CFG_RDATSIZ_SHIFT  24
  84
  85/* FIU UMA Control and Status Register */
  86#define NPCM_FIU_UMA_CTS_RDYIE          BIT(25)
  87#define NPCM_FIU_UMA_CTS_RDYST          BIT(24)
  88#define NPCM_FIU_UMA_CTS_SW_CS          BIT(16)
  89#define NPCM_FIU_UMA_CTS_DEV_NUM        GENMASK(9, 8)
  90#define NPCM_FIU_UMA_CTS_EXEC_DONE      BIT(0)
  91#define NPCM_FIU_UMA_CTS_DEV_NUM_SHIFT  8
  92
  93/* FIU UMA Command Register */
  94#define NPCM_FIU_UMA_CMD_DUM3           GENMASK(31, 24)
  95#define NPCM_FIU_UMA_CMD_DUM2           GENMASK(23, 16)
  96#define NPCM_FIU_UMA_CMD_DUM1           GENMASK(15, 8)
  97#define NPCM_FIU_UMA_CMD_CMD            GENMASK(7, 0)
  98
  99/* FIU UMA Address Register */
 100#define NPCM_FIU_UMA_ADDR_UMA_ADDR      GENMASK(31, 0)
 101#define NPCM_FIU_UMA_ADDR_AB3           GENMASK(31, 24)
 102#define NPCM_FIU_UMA_ADDR_AB2           GENMASK(23, 16)
 103#define NPCM_FIU_UMA_ADDR_AB1           GENMASK(15, 8)
 104#define NPCM_FIU_UMA_ADDR_AB0           GENMASK(7, 0)
 105
 106/* FIU UMA Write Data Bytes 0-3 Register */
 107#define NPCM_FIU_UMA_DW0_WB3            GENMASK(31, 24)
 108#define NPCM_FIU_UMA_DW0_WB2            GENMASK(23, 16)
 109#define NPCM_FIU_UMA_DW0_WB1            GENMASK(15, 8)
 110#define NPCM_FIU_UMA_DW0_WB0            GENMASK(7, 0)
 111
 112/* FIU UMA Write Data Bytes 4-7 Register */
 113#define NPCM_FIU_UMA_DW1_WB7            GENMASK(31, 24)
 114#define NPCM_FIU_UMA_DW1_WB6            GENMASK(23, 16)
 115#define NPCM_FIU_UMA_DW1_WB5            GENMASK(15, 8)
 116#define NPCM_FIU_UMA_DW1_WB4            GENMASK(7, 0)
 117
 118/* FIU UMA Write Data Bytes 8-11 Register */
 119#define NPCM_FIU_UMA_DW2_WB11           GENMASK(31, 24)
 120#define NPCM_FIU_UMA_DW2_WB10           GENMASK(23, 16)
 121#define NPCM_FIU_UMA_DW2_WB9            GENMASK(15, 8)
 122#define NPCM_FIU_UMA_DW2_WB8            GENMASK(7, 0)
 123
 124/* FIU UMA Write Data Bytes 12-15 Register */
 125#define NPCM_FIU_UMA_DW3_WB15           GENMASK(31, 24)
 126#define NPCM_FIU_UMA_DW3_WB14           GENMASK(23, 16)
 127#define NPCM_FIU_UMA_DW3_WB13           GENMASK(15, 8)
 128#define NPCM_FIU_UMA_DW3_WB12           GENMASK(7, 0)
 129
 130/* FIU UMA Read Data Bytes 0-3 Register */
 131#define NPCM_FIU_UMA_DR0_RB3            GENMASK(31, 24)
 132#define NPCM_FIU_UMA_DR0_RB2            GENMASK(23, 16)
 133#define NPCM_FIU_UMA_DR0_RB1            GENMASK(15, 8)
 134#define NPCM_FIU_UMA_DR0_RB0            GENMASK(7, 0)
 135
 136/* FIU UMA Read Data Bytes 4-7 Register */
 137#define NPCM_FIU_UMA_DR1_RB15           GENMASK(31, 24)
 138#define NPCM_FIU_UMA_DR1_RB14           GENMASK(23, 16)
 139#define NPCM_FIU_UMA_DR1_RB13           GENMASK(15, 8)
 140#define NPCM_FIU_UMA_DR1_RB12           GENMASK(7, 0)
 141
 142/* FIU UMA Read Data Bytes 8-11 Register */
 143#define NPCM_FIU_UMA_DR2_RB15           GENMASK(31, 24)
 144#define NPCM_FIU_UMA_DR2_RB14           GENMASK(23, 16)
 145#define NPCM_FIU_UMA_DR2_RB13           GENMASK(15, 8)
 146#define NPCM_FIU_UMA_DR2_RB12           GENMASK(7, 0)
 147
 148/* FIU UMA Read Data Bytes 12-15 Register */
 149#define NPCM_FIU_UMA_DR3_RB15           GENMASK(31, 24)
 150#define NPCM_FIU_UMA_DR3_RB14           GENMASK(23, 16)
 151#define NPCM_FIU_UMA_DR3_RB13           GENMASK(15, 8)
 152#define NPCM_FIU_UMA_DR3_RB12           GENMASK(7, 0)
 153
 154/* FIU Read Mode */
 155enum {
 156        DRD_SINGLE_WIRE_MODE    = 0,
 157        DRD_DUAL_IO_MODE        = 1,
 158        DRD_QUAD_IO_MODE        = 2,
 159        DRD_SPI_X_MODE          = 3,
 160};
 161
 162enum {
 163        DWR_ABPCK_BIT_PER_CLK   = 0,
 164        DWR_ABPCK_2_BIT_PER_CLK = 1,
 165        DWR_ABPCK_4_BIT_PER_CLK = 2,
 166};
 167
 168enum {
 169        DWR_DBPCK_BIT_PER_CLK   = 0,
 170        DWR_DBPCK_2_BIT_PER_CLK = 1,
 171        DWR_DBPCK_4_BIT_PER_CLK = 2,
 172};
 173
 174#define NPCM_FIU_DRD_16_BYTE_BURST      0x3000000
 175#define NPCM_FIU_DWR_16_BYTE_BURST      0x3000000
 176
 177#define MAP_SIZE_128MB                  0x8000000
 178#define MAP_SIZE_16MB                   0x1000000
 179#define MAP_SIZE_8MB                    0x800000
 180
 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
 186enum {
 187        FIU0 = 0,
 188        FIU3,
 189        FIUX,
 190};
 191
 192struct npcm_fiu_info {
 193        char *name;
 194        u32 fiu_id;
 195        u32 max_map_size;
 196        u32 max_cs;
 197};
 198
 199struct fiu_data {
 200        const struct npcm_fiu_info *npcm_fiu_data_info;
 201        int fiu_max;
 202};
 203
 204static 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
 212static const struct fiu_data npxm7xx_fiu_data = {
 213        .npcm_fiu_data_info = npxm7xx_fiu_info,
 214        .fiu_max = 3,
 215};
 216
 217struct npcm_fiu_spi;
 218
 219struct 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
 226struct 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
 238static 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
 245static 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)) / BITS_PER_BYTE)
 256                           << 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
 267static 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
 294static 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
 314static 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
 369static 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
 419static 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
 468static 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
 499static 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
 511static 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
 525static 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
 585static 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(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
 643static 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
 659static 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
 666static const struct of_device_id npcm_fiu_dt_ids[] = {
 667        { .compatible = "nuvoton,npcm750-fiu", .data = &npxm7xx_fiu_data  },
 668        { /* sentinel */ }
 669};
 670
 671static 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 id, ret;
 681
 682        ctrl = devm_spi_alloc_master(dev, sizeof(*fiu));
 683        if (!ctrl)
 684                return -ENOMEM;
 685
 686        fiu = spi_controller_get_devdata(ctrl);
 687
 688        match = of_match_device(npcm_fiu_dt_ids, dev);
 689        if (!match || !match->data) {
 690                dev_err(dev, "No compatible OF match\n");
 691                return -ENODEV;
 692        }
 693
 694        fiu_data_match = match->data;
 695        id = of_alias_get_id(dev->of_node, "fiu");
 696        if (id < 0 || id >= fiu_data_match->fiu_max) {
 697                dev_err(dev, "Invalid platform device id: %d\n", id);
 698                return -EINVAL;
 699        }
 700
 701        fiu->info = &fiu_data_match->npcm_fiu_data_info[id];
 702
 703        platform_set_drvdata(pdev, fiu);
 704        fiu->dev = dev;
 705
 706        res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "control");
 707        regbase = devm_ioremap_resource(dev, res);
 708        if (IS_ERR(regbase))
 709                return PTR_ERR(regbase);
 710
 711        fiu->regmap = devm_regmap_init_mmio(dev, regbase,
 712                                            &npcm_mtd_regmap_config);
 713        if (IS_ERR(fiu->regmap)) {
 714                dev_err(dev, "Failed to create regmap\n");
 715                return PTR_ERR(fiu->regmap);
 716        }
 717
 718        fiu->res_mem = platform_get_resource_byname(pdev, IORESOURCE_MEM,
 719                                                    "memory");
 720        fiu->clk = devm_clk_get(dev, NULL);
 721        if (IS_ERR(fiu->clk))
 722                return PTR_ERR(fiu->clk);
 723
 724        fiu->spix_mode = of_property_read_bool(dev->of_node,
 725                                               "nuvoton,spix-mode");
 726
 727        platform_set_drvdata(pdev, fiu);
 728        clk_prepare_enable(fiu->clk);
 729
 730        ctrl->mode_bits = SPI_RX_DUAL | SPI_RX_QUAD
 731                | SPI_TX_DUAL | SPI_TX_QUAD;
 732        ctrl->setup = npcm_fiu_setup;
 733        ctrl->bus_num = -1;
 734        ctrl->mem_ops = &npcm_fiu_mem_ops;
 735        ctrl->num_chipselect = fiu->info->max_cs;
 736        ctrl->dev.of_node = dev->of_node;
 737
 738        ret = devm_spi_register_master(dev, ctrl);
 739        if (ret)
 740                clk_disable_unprepare(fiu->clk);
 741
 742        return ret;
 743}
 744
 745static int npcm_fiu_remove(struct platform_device *pdev)
 746{
 747        struct npcm_fiu_spi *fiu = platform_get_drvdata(pdev);
 748
 749        clk_disable_unprepare(fiu->clk);
 750        return 0;
 751}
 752
 753MODULE_DEVICE_TABLE(of, npcm_fiu_dt_ids);
 754
 755static struct platform_driver npcm_fiu_driver = {
 756        .driver = {
 757                .name   = "NPCM-FIU",
 758                .bus    = &platform_bus_type,
 759                .of_match_table = npcm_fiu_dt_ids,
 760        },
 761        .probe      = npcm_fiu_probe,
 762        .remove     = npcm_fiu_remove,
 763};
 764module_platform_driver(npcm_fiu_driver);
 765
 766MODULE_DESCRIPTION("Nuvoton FLASH Interface Unit SPI Controller Driver");
 767MODULE_AUTHOR("Tomer Maimon <tomer.maimon@nuvoton.com>");
 768MODULE_LICENSE("GPL v2");
 769