linux/drivers/memory/renesas-rpc-if.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Renesas RPC-IF core driver
   4 *
   5 * Copyright (C) 2018-2019 Renesas Solutions Corp.
   6 * Copyright (C) 2019 Macronix International Co., Ltd.
   7 * Copyright (C) 2019-2020 Cogent Embedded, Inc.
   8 */
   9
  10#include <linux/clk.h>
  11#include <linux/io.h>
  12#include <linux/module.h>
  13#include <linux/platform_device.h>
  14#include <linux/of.h>
  15#include <linux/regmap.h>
  16#include <linux/reset.h>
  17
  18#include <memory/renesas-rpc-if.h>
  19
  20#define RPCIF_CMNCR             0x0000  /* R/W */
  21#define RPCIF_CMNCR_MD          BIT(31)
  22#define RPCIF_CMNCR_SFDE        BIT(24) /* undocumented but must be set */
  23#define RPCIF_CMNCR_MOIIO3(val) (((val) & 0x3) << 22)
  24#define RPCIF_CMNCR_MOIIO2(val) (((val) & 0x3) << 20)
  25#define RPCIF_CMNCR_MOIIO1(val) (((val) & 0x3) << 18)
  26#define RPCIF_CMNCR_MOIIO0(val) (((val) & 0x3) << 16)
  27#define RPCIF_CMNCR_MOIIO_HIZ   (RPCIF_CMNCR_MOIIO0(3) | \
  28                                 RPCIF_CMNCR_MOIIO1(3) | \
  29                                 RPCIF_CMNCR_MOIIO2(3) | RPCIF_CMNCR_MOIIO3(3))
  30#define RPCIF_CMNCR_IO3FV(val)  (((val) & 0x3) << 14) /* undocumented */
  31#define RPCIF_CMNCR_IO2FV(val)  (((val) & 0x3) << 12) /* undocumented */
  32#define RPCIF_CMNCR_IO0FV(val)  (((val) & 0x3) << 8)
  33#define RPCIF_CMNCR_IOFV_HIZ    (RPCIF_CMNCR_IO0FV(3) | RPCIF_CMNCR_IO2FV(3) | \
  34                                 RPCIF_CMNCR_IO3FV(3))
  35#define RPCIF_CMNCR_BSZ(val)    (((val) & 0x3) << 0)
  36
  37#define RPCIF_SSLDR             0x0004  /* R/W */
  38#define RPCIF_SSLDR_SPNDL(d)    (((d) & 0x7) << 16)
  39#define RPCIF_SSLDR_SLNDL(d)    (((d) & 0x7) << 8)
  40#define RPCIF_SSLDR_SCKDL(d)    (((d) & 0x7) << 0)
  41
  42#define RPCIF_DRCR              0x000C  /* R/W */
  43#define RPCIF_DRCR_SSLN         BIT(24)
  44#define RPCIF_DRCR_RBURST(v)    ((((v) - 1) & 0x1F) << 16)
  45#define RPCIF_DRCR_RCF          BIT(9)
  46#define RPCIF_DRCR_RBE          BIT(8)
  47#define RPCIF_DRCR_SSLE         BIT(0)
  48
  49#define RPCIF_DRCMR             0x0010  /* R/W */
  50#define RPCIF_DRCMR_CMD(c)      (((c) & 0xFF) << 16)
  51#define RPCIF_DRCMR_OCMD(c)     (((c) & 0xFF) << 0)
  52
  53#define RPCIF_DREAR             0x0014  /* R/W */
  54#define RPCIF_DREAR_EAV(c)      (((c) & 0xF) << 16)
  55#define RPCIF_DREAR_EAC(c)      (((c) & 0x7) << 0)
  56
  57#define RPCIF_DROPR             0x0018  /* R/W */
  58
  59#define RPCIF_DRENR             0x001C  /* R/W */
  60#define RPCIF_DRENR_CDB(o)      (u32)((((o) & 0x3) << 30))
  61#define RPCIF_DRENR_OCDB(o)     (((o) & 0x3) << 28)
  62#define RPCIF_DRENR_ADB(o)      (((o) & 0x3) << 24)
  63#define RPCIF_DRENR_OPDB(o)     (((o) & 0x3) << 20)
  64#define RPCIF_DRENR_DRDB(o)     (((o) & 0x3) << 16)
  65#define RPCIF_DRENR_DME         BIT(15)
  66#define RPCIF_DRENR_CDE         BIT(14)
  67#define RPCIF_DRENR_OCDE        BIT(12)
  68#define RPCIF_DRENR_ADE(v)      (((v) & 0xF) << 8)
  69#define RPCIF_DRENR_OPDE(v)     (((v) & 0xF) << 4)
  70
  71#define RPCIF_SMCR              0x0020  /* R/W */
  72#define RPCIF_SMCR_SSLKP        BIT(8)
  73#define RPCIF_SMCR_SPIRE        BIT(2)
  74#define RPCIF_SMCR_SPIWE        BIT(1)
  75#define RPCIF_SMCR_SPIE         BIT(0)
  76
  77#define RPCIF_SMCMR             0x0024  /* R/W */
  78#define RPCIF_SMCMR_CMD(c)      (((c) & 0xFF) << 16)
  79#define RPCIF_SMCMR_OCMD(c)     (((c) & 0xFF) << 0)
  80
  81#define RPCIF_SMADR             0x0028  /* R/W */
  82
  83#define RPCIF_SMOPR             0x002C  /* R/W */
  84#define RPCIF_SMOPR_OPD3(o)     (((o) & 0xFF) << 24)
  85#define RPCIF_SMOPR_OPD2(o)     (((o) & 0xFF) << 16)
  86#define RPCIF_SMOPR_OPD1(o)     (((o) & 0xFF) << 8)
  87#define RPCIF_SMOPR_OPD0(o)     (((o) & 0xFF) << 0)
  88
  89#define RPCIF_SMENR             0x0030  /* R/W */
  90#define RPCIF_SMENR_CDB(o)      (((o) & 0x3) << 30)
  91#define RPCIF_SMENR_OCDB(o)     (((o) & 0x3) << 28)
  92#define RPCIF_SMENR_ADB(o)      (((o) & 0x3) << 24)
  93#define RPCIF_SMENR_OPDB(o)     (((o) & 0x3) << 20)
  94#define RPCIF_SMENR_SPIDB(o)    (((o) & 0x3) << 16)
  95#define RPCIF_SMENR_DME         BIT(15)
  96#define RPCIF_SMENR_CDE         BIT(14)
  97#define RPCIF_SMENR_OCDE        BIT(12)
  98#define RPCIF_SMENR_ADE(v)      (((v) & 0xF) << 8)
  99#define RPCIF_SMENR_OPDE(v)     (((v) & 0xF) << 4)
 100#define RPCIF_SMENR_SPIDE(v)    (((v) & 0xF) << 0)
 101
 102#define RPCIF_SMRDR0            0x0038  /* R */
 103#define RPCIF_SMRDR1            0x003C  /* R */
 104#define RPCIF_SMWDR0            0x0040  /* W */
 105#define RPCIF_SMWDR1            0x0044  /* W */
 106
 107#define RPCIF_CMNSR             0x0048  /* R */
 108#define RPCIF_CMNSR_SSLF        BIT(1)
 109#define RPCIF_CMNSR_TEND        BIT(0)
 110
 111#define RPCIF_DRDMCR            0x0058  /* R/W */
 112#define RPCIF_DMDMCR_DMCYC(v)   ((((v) - 1) & 0x1F) << 0)
 113
 114#define RPCIF_DRDRENR           0x005C  /* R/W */
 115#define RPCIF_DRDRENR_HYPE(v)   (((v) & 0x7) << 12)
 116#define RPCIF_DRDRENR_ADDRE     BIT(8)
 117#define RPCIF_DRDRENR_OPDRE     BIT(4)
 118#define RPCIF_DRDRENR_DRDRE     BIT(0)
 119
 120#define RPCIF_SMDMCR            0x0060  /* R/W */
 121#define RPCIF_SMDMCR_DMCYC(v)   ((((v) - 1) & 0x1F) << 0)
 122
 123#define RPCIF_SMDRENR           0x0064  /* R/W */
 124#define RPCIF_SMDRENR_HYPE(v)   (((v) & 0x7) << 12)
 125#define RPCIF_SMDRENR_ADDRE     BIT(8)
 126#define RPCIF_SMDRENR_OPDRE     BIT(4)
 127#define RPCIF_SMDRENR_SPIDRE    BIT(0)
 128
 129#define RPCIF_PHYCNT            0x007C  /* R/W */
 130#define RPCIF_PHYCNT_CAL        BIT(31)
 131#define RPCIF_PHYCNT_OCTA(v)    (((v) & 0x3) << 22)
 132#define RPCIF_PHYCNT_EXDS       BIT(21)
 133#define RPCIF_PHYCNT_OCT        BIT(20)
 134#define RPCIF_PHYCNT_DDRCAL     BIT(19)
 135#define RPCIF_PHYCNT_HS         BIT(18)
 136#define RPCIF_PHYCNT_STRTIM(v)  (((v) & 0x7) << 15)
 137#define RPCIF_PHYCNT_WBUF2      BIT(4)
 138#define RPCIF_PHYCNT_WBUF       BIT(2)
 139#define RPCIF_PHYCNT_PHYMEM(v)  (((v) & 0x3) << 0)
 140
 141#define RPCIF_PHYOFFSET1        0x0080  /* R/W */
 142#define RPCIF_PHYOFFSET1_DDRTMG(v) (((v) & 0x3) << 28)
 143
 144#define RPCIF_PHYOFFSET2        0x0084  /* R/W */
 145#define RPCIF_PHYOFFSET2_OCTTMG(v) (((v) & 0x7) << 8)
 146
 147#define RPCIF_PHYINT            0x0088  /* R/W */
 148#define RPCIF_PHYINT_WPVAL      BIT(1)
 149
 150#define RPCIF_DIRMAP_SIZE       0x4000000
 151
 152static const struct regmap_range rpcif_volatile_ranges[] = {
 153        regmap_reg_range(RPCIF_SMRDR0, RPCIF_SMRDR1),
 154        regmap_reg_range(RPCIF_SMWDR0, RPCIF_SMWDR1),
 155        regmap_reg_range(RPCIF_CMNSR, RPCIF_CMNSR),
 156};
 157
 158static const struct regmap_access_table rpcif_volatile_table = {
 159        .yes_ranges     = rpcif_volatile_ranges,
 160        .n_yes_ranges   = ARRAY_SIZE(rpcif_volatile_ranges),
 161};
 162
 163static const struct regmap_config rpcif_regmap_config = {
 164        .reg_bits       = 32,
 165        .val_bits       = 32,
 166        .reg_stride     = 4,
 167        .fast_io        = true,
 168        .max_register   = RPCIF_PHYINT,
 169        .volatile_table = &rpcif_volatile_table,
 170};
 171
 172int rpcif_sw_init(struct rpcif *rpc, struct device *dev)
 173{
 174        struct platform_device *pdev = to_platform_device(dev);
 175        struct resource *res;
 176        void __iomem *base;
 177
 178        rpc->dev = dev;
 179
 180        res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs");
 181        base = devm_ioremap_resource(&pdev->dev, res);
 182        if (IS_ERR(base))
 183                return PTR_ERR(base);
 184
 185        rpc->regmap = devm_regmap_init_mmio(&pdev->dev, base,
 186                                            &rpcif_regmap_config);
 187        if (IS_ERR(rpc->regmap)) {
 188                dev_err(&pdev->dev,
 189                        "failed to init regmap for rpcif, error %ld\n",
 190                        PTR_ERR(rpc->regmap));
 191                return  PTR_ERR(rpc->regmap);
 192        }
 193
 194        res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dirmap");
 195        rpc->dirmap = devm_ioremap_resource(&pdev->dev, res);
 196        if (IS_ERR(rpc->dirmap))
 197                rpc->dirmap = NULL;
 198        rpc->size = resource_size(res);
 199
 200        rpc->rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL);
 201
 202        return PTR_ERR_OR_ZERO(rpc->rstc);
 203}
 204EXPORT_SYMBOL(rpcif_sw_init);
 205
 206void rpcif_hw_init(struct rpcif *rpc, bool hyperflash)
 207{
 208        u32 dummy;
 209
 210        pm_runtime_get_sync(rpc->dev);
 211
 212        /*
 213         * NOTE: The 0x260 are undocumented bits, but they must be set.
 214         *       RPCIF_PHYCNT_STRTIM is strobe timing adjustment bits,
 215         *       0x0 : the delay is biggest,
 216         *       0x1 : the delay is 2nd biggest,
 217         *       On H3 ES1.x, the value should be 0, while on others,
 218         *       the value should be 7.
 219         */
 220        regmap_write(rpc->regmap, RPCIF_PHYCNT, RPCIF_PHYCNT_STRTIM(7) |
 221                     RPCIF_PHYCNT_PHYMEM(hyperflash ? 3 : 0) | 0x260);
 222
 223        /*
 224         * NOTE: The 0x1511144 are undocumented bits, but they must be set
 225         *       for RPCIF_PHYOFFSET1.
 226         *       The 0x31 are undocumented bits, but they must be set
 227         *       for RPCIF_PHYOFFSET2.
 228         */
 229        regmap_write(rpc->regmap, RPCIF_PHYOFFSET1, 0x1511144 |
 230                     RPCIF_PHYOFFSET1_DDRTMG(3));
 231        regmap_write(rpc->regmap, RPCIF_PHYOFFSET2, 0x31 |
 232                     RPCIF_PHYOFFSET2_OCTTMG(4));
 233
 234        if (hyperflash)
 235                regmap_update_bits(rpc->regmap, RPCIF_PHYINT,
 236                                   RPCIF_PHYINT_WPVAL, 0);
 237
 238        regmap_write(rpc->regmap, RPCIF_CMNCR, RPCIF_CMNCR_SFDE |
 239                     RPCIF_CMNCR_MOIIO_HIZ | RPCIF_CMNCR_IOFV_HIZ |
 240                     RPCIF_CMNCR_BSZ(hyperflash ? 1 : 0));
 241        /* Set RCF after BSZ update */
 242        regmap_write(rpc->regmap, RPCIF_DRCR, RPCIF_DRCR_RCF);
 243        /* Dummy read according to spec */
 244        regmap_read(rpc->regmap, RPCIF_DRCR, &dummy);
 245        regmap_write(rpc->regmap, RPCIF_SSLDR, RPCIF_SSLDR_SPNDL(7) |
 246                     RPCIF_SSLDR_SLNDL(7) | RPCIF_SSLDR_SCKDL(7));
 247
 248        pm_runtime_put(rpc->dev);
 249
 250        rpc->bus_size = hyperflash ? 2 : 1;
 251}
 252EXPORT_SYMBOL(rpcif_hw_init);
 253
 254static int wait_msg_xfer_end(struct rpcif *rpc)
 255{
 256        u32 sts;
 257
 258        return regmap_read_poll_timeout(rpc->regmap, RPCIF_CMNSR, sts,
 259                                        sts & RPCIF_CMNSR_TEND, 0,
 260                                        USEC_PER_SEC);
 261}
 262
 263static u8 rpcif_bits_set(struct rpcif *rpc, u32 nbytes)
 264{
 265        if (rpc->bus_size == 2)
 266                nbytes /= 2;
 267        nbytes = clamp(nbytes, 1U, 4U);
 268        return GENMASK(3, 4 - nbytes);
 269}
 270
 271static u8 rpcif_bit_size(u8 buswidth)
 272{
 273        return buswidth > 4 ? 2 : ilog2(buswidth);
 274}
 275
 276void rpcif_prepare(struct rpcif *rpc, const struct rpcif_op *op, u64 *offs,
 277                   size_t *len)
 278{
 279        rpc->smcr = 0;
 280        rpc->smadr = 0;
 281        rpc->enable = 0;
 282        rpc->command = 0;
 283        rpc->option = 0;
 284        rpc->dummy = 0;
 285        rpc->ddr = 0;
 286        rpc->xferlen = 0;
 287
 288        if (op->cmd.buswidth) {
 289                rpc->enable  = RPCIF_SMENR_CDE |
 290                        RPCIF_SMENR_CDB(rpcif_bit_size(op->cmd.buswidth));
 291                rpc->command = RPCIF_SMCMR_CMD(op->cmd.opcode);
 292                if (op->cmd.ddr)
 293                        rpc->ddr = RPCIF_SMDRENR_HYPE(0x5);
 294        }
 295        if (op->ocmd.buswidth) {
 296                rpc->enable  |= RPCIF_SMENR_OCDE |
 297                        RPCIF_SMENR_OCDB(rpcif_bit_size(op->ocmd.buswidth));
 298                rpc->command |= RPCIF_SMCMR_OCMD(op->ocmd.opcode);
 299        }
 300
 301        if (op->addr.buswidth) {
 302                rpc->enable |=
 303                        RPCIF_SMENR_ADB(rpcif_bit_size(op->addr.buswidth));
 304                if (op->addr.nbytes == 4)
 305                        rpc->enable |= RPCIF_SMENR_ADE(0xF);
 306                else
 307                        rpc->enable |= RPCIF_SMENR_ADE(GENMASK(
 308                                                2, 3 - op->addr.nbytes));
 309                if (op->addr.ddr)
 310                        rpc->ddr |= RPCIF_SMDRENR_ADDRE;
 311
 312                if (offs && len)
 313                        rpc->smadr = *offs;
 314                else
 315                        rpc->smadr = op->addr.val;
 316        }
 317
 318        if (op->dummy.buswidth) {
 319                rpc->enable |= RPCIF_SMENR_DME;
 320                rpc->dummy = RPCIF_SMDMCR_DMCYC(op->dummy.ncycles /
 321                                                op->dummy.buswidth);
 322        }
 323
 324        if (op->option.buswidth) {
 325                rpc->enable |= RPCIF_SMENR_OPDE(
 326                        rpcif_bits_set(rpc, op->option.nbytes)) |
 327                        RPCIF_SMENR_OPDB(rpcif_bit_size(op->option.buswidth));
 328                if (op->option.ddr)
 329                        rpc->ddr |= RPCIF_SMDRENR_OPDRE;
 330                rpc->option = op->option.val;
 331        }
 332
 333        rpc->dir = op->data.dir;
 334        if (op->data.buswidth) {
 335                u32 nbytes;
 336
 337                rpc->buffer = op->data.buf.in;
 338                switch (op->data.dir) {
 339                case RPCIF_DATA_IN:
 340                        rpc->smcr = RPCIF_SMCR_SPIRE;
 341                        break;
 342                case RPCIF_DATA_OUT:
 343                        rpc->smcr = RPCIF_SMCR_SPIWE;
 344                        break;
 345                default:
 346                        break;
 347                }
 348                if (op->data.ddr)
 349                        rpc->ddr |= RPCIF_SMDRENR_SPIDRE;
 350
 351                if (offs && len)
 352                        nbytes = *len;
 353                else
 354                        nbytes = op->data.nbytes;
 355                rpc->xferlen = nbytes;
 356
 357                rpc->enable |= RPCIF_SMENR_SPIDE(rpcif_bits_set(rpc, nbytes)) |
 358                        RPCIF_SMENR_SPIDB(rpcif_bit_size(op->data.buswidth));
 359        }
 360}
 361EXPORT_SYMBOL(rpcif_prepare);
 362
 363int rpcif_manual_xfer(struct rpcif *rpc)
 364{
 365        u32 smenr, smcr, pos = 0, max = 4;
 366        int ret = 0;
 367
 368        if (rpc->bus_size == 2)
 369                max = 8;
 370
 371        pm_runtime_get_sync(rpc->dev);
 372
 373        regmap_update_bits(rpc->regmap, RPCIF_PHYCNT,
 374                           RPCIF_PHYCNT_CAL, RPCIF_PHYCNT_CAL);
 375        regmap_update_bits(rpc->regmap, RPCIF_CMNCR,
 376                           RPCIF_CMNCR_MD, RPCIF_CMNCR_MD);
 377        regmap_write(rpc->regmap, RPCIF_SMCMR, rpc->command);
 378        regmap_write(rpc->regmap, RPCIF_SMOPR, rpc->option);
 379        regmap_write(rpc->regmap, RPCIF_SMDMCR, rpc->dummy);
 380        regmap_write(rpc->regmap, RPCIF_SMDRENR, rpc->ddr);
 381        smenr = rpc->enable;
 382
 383        switch (rpc->dir) {
 384        case RPCIF_DATA_OUT:
 385                while (pos < rpc->xferlen) {
 386                        u32 nbytes = rpc->xferlen - pos;
 387                        u32 data[2];
 388
 389                        smcr = rpc->smcr | RPCIF_SMCR_SPIE;
 390                        if (nbytes > max) {
 391                                nbytes = max;
 392                                smcr |= RPCIF_SMCR_SSLKP;
 393                        }
 394
 395                        memcpy(data, rpc->buffer + pos, nbytes);
 396                        if (nbytes > 4) {
 397                                regmap_write(rpc->regmap, RPCIF_SMWDR1,
 398                                             data[0]);
 399                                regmap_write(rpc->regmap, RPCIF_SMWDR0,
 400                                             data[1]);
 401                        } else if (nbytes > 2) {
 402                                regmap_write(rpc->regmap, RPCIF_SMWDR0,
 403                                             data[0]);
 404                        } else  {
 405                                regmap_write(rpc->regmap, RPCIF_SMWDR0,
 406                                             data[0] << 16);
 407                        }
 408
 409                        regmap_write(rpc->regmap, RPCIF_SMADR,
 410                                     rpc->smadr + pos);
 411                        regmap_write(rpc->regmap, RPCIF_SMENR, smenr);
 412                        regmap_write(rpc->regmap, RPCIF_SMCR, smcr);
 413                        ret = wait_msg_xfer_end(rpc);
 414                        if (ret)
 415                                goto err_out;
 416
 417                        pos += nbytes;
 418                        smenr = rpc->enable &
 419                                ~RPCIF_SMENR_CDE & ~RPCIF_SMENR_ADE(0xF);
 420                }
 421                break;
 422        case RPCIF_DATA_IN:
 423                /*
 424                 * RPC-IF spoils the data for the commands without an address
 425                 * phase (like RDID) in the manual mode, so we'll have to work
 426                 * around this issue by using the external address space read
 427                 * mode instead.
 428                 */
 429                if (!(smenr & RPCIF_SMENR_ADE(0xF)) && rpc->dirmap) {
 430                        u32 dummy;
 431
 432                        regmap_update_bits(rpc->regmap, RPCIF_CMNCR,
 433                                           RPCIF_CMNCR_MD, 0);
 434                        regmap_write(rpc->regmap, RPCIF_DRCR,
 435                                     RPCIF_DRCR_RBURST(32) | RPCIF_DRCR_RBE);
 436                        regmap_write(rpc->regmap, RPCIF_DRCMR, rpc->command);
 437                        regmap_write(rpc->regmap, RPCIF_DREAR,
 438                                     RPCIF_DREAR_EAC(1));
 439                        regmap_write(rpc->regmap, RPCIF_DROPR, rpc->option);
 440                        regmap_write(rpc->regmap, RPCIF_DRENR,
 441                                     smenr & ~RPCIF_SMENR_SPIDE(0xF));
 442                        regmap_write(rpc->regmap, RPCIF_DRDMCR,  rpc->dummy);
 443                        regmap_write(rpc->regmap, RPCIF_DRDRENR, rpc->ddr);
 444                        memcpy_fromio(rpc->buffer, rpc->dirmap, rpc->xferlen);
 445                        regmap_write(rpc->regmap, RPCIF_DRCR, RPCIF_DRCR_RCF);
 446                        /* Dummy read according to spec */
 447                        regmap_read(rpc->regmap, RPCIF_DRCR, &dummy);
 448                        break;
 449                }
 450                while (pos < rpc->xferlen) {
 451                        u32 nbytes = rpc->xferlen - pos;
 452                        u32 data[2];
 453
 454                        if (nbytes > max)
 455                                nbytes = max;
 456
 457                        regmap_write(rpc->regmap, RPCIF_SMADR,
 458                                     rpc->smadr + pos);
 459                        regmap_write(rpc->regmap, RPCIF_SMENR, smenr);
 460                        regmap_write(rpc->regmap, RPCIF_SMCR,
 461                                     rpc->smcr | RPCIF_SMCR_SPIE);
 462                        ret = wait_msg_xfer_end(rpc);
 463                        if (ret)
 464                                goto err_out;
 465
 466                        if (nbytes > 4) {
 467                                regmap_read(rpc->regmap, RPCIF_SMRDR1,
 468                                            &data[0]);
 469                                regmap_read(rpc->regmap, RPCIF_SMRDR0,
 470                                            &data[1]);
 471                        } else if (nbytes > 2) {
 472                                regmap_read(rpc->regmap, RPCIF_SMRDR0,
 473                                            &data[0]);
 474                        } else  {
 475                                regmap_read(rpc->regmap, RPCIF_SMRDR0,
 476                                            &data[0]);
 477                                data[0] >>= 16;
 478                        }
 479                        memcpy(rpc->buffer + pos, data, nbytes);
 480
 481                        pos += nbytes;
 482                }
 483                break;
 484        default:
 485                regmap_write(rpc->regmap, RPCIF_SMENR, rpc->enable);
 486                regmap_write(rpc->regmap, RPCIF_SMCR,
 487                             rpc->smcr | RPCIF_SMCR_SPIE);
 488                ret = wait_msg_xfer_end(rpc);
 489                if (ret)
 490                        goto err_out;
 491        }
 492
 493exit:
 494        pm_runtime_put(rpc->dev);
 495        return ret;
 496
 497err_out:
 498        if (reset_control_reset(rpc->rstc))
 499                dev_err(rpc->dev, "Failed to reset HW\n");
 500        rpcif_hw_init(rpc, rpc->bus_size == 2);
 501        goto exit;
 502}
 503EXPORT_SYMBOL(rpcif_manual_xfer);
 504
 505ssize_t rpcif_dirmap_read(struct rpcif *rpc, u64 offs, size_t len, void *buf)
 506{
 507        loff_t from = offs & (RPCIF_DIRMAP_SIZE - 1);
 508        size_t size = RPCIF_DIRMAP_SIZE - from;
 509
 510        if (len > size)
 511                len = size;
 512
 513        pm_runtime_get_sync(rpc->dev);
 514
 515        regmap_update_bits(rpc->regmap, RPCIF_CMNCR, RPCIF_CMNCR_MD, 0);
 516        regmap_write(rpc->regmap, RPCIF_DRCR, 0);
 517        regmap_write(rpc->regmap, RPCIF_DRCMR, rpc->command);
 518        regmap_write(rpc->regmap, RPCIF_DREAR,
 519                     RPCIF_DREAR_EAV(offs >> 25) | RPCIF_DREAR_EAC(1));
 520        regmap_write(rpc->regmap, RPCIF_DROPR, rpc->option);
 521        regmap_write(rpc->regmap, RPCIF_DRENR,
 522                     rpc->enable & ~RPCIF_SMENR_SPIDE(0xF));
 523        regmap_write(rpc->regmap, RPCIF_DRDMCR, rpc->dummy);
 524        regmap_write(rpc->regmap, RPCIF_DRDRENR, rpc->ddr);
 525
 526        memcpy_fromio(buf, rpc->dirmap + from, len);
 527
 528        pm_runtime_put(rpc->dev);
 529
 530        return len;
 531}
 532EXPORT_SYMBOL(rpcif_dirmap_read);
 533
 534static int rpcif_probe(struct platform_device *pdev)
 535{
 536        struct platform_device *vdev;
 537        struct device_node *flash;
 538        const char *name;
 539
 540        flash = of_get_next_child(pdev->dev.of_node, NULL);
 541        if (!flash) {
 542                dev_warn(&pdev->dev, "no flash node found\n");
 543                return -ENODEV;
 544        }
 545
 546        if (of_device_is_compatible(flash, "jedec,spi-nor")) {
 547                name = "rpc-if-spi";
 548        } else if (of_device_is_compatible(flash, "cfi-flash")) {
 549                name = "rpc-if-hyperflash";
 550        } else  {
 551                of_node_put(flash);
 552                dev_warn(&pdev->dev, "unknown flash type\n");
 553                return -ENODEV;
 554        }
 555        of_node_put(flash);
 556
 557        vdev = platform_device_alloc(name, pdev->id);
 558        if (!vdev)
 559                return -ENOMEM;
 560        vdev->dev.parent = &pdev->dev;
 561        platform_set_drvdata(pdev, vdev);
 562        return platform_device_add(vdev);
 563}
 564
 565static int rpcif_remove(struct platform_device *pdev)
 566{
 567        struct platform_device *vdev = platform_get_drvdata(pdev);
 568
 569        platform_device_unregister(vdev);
 570
 571        return 0;
 572}
 573
 574static const struct of_device_id rpcif_of_match[] = {
 575        { .compatible = "renesas,rcar-gen3-rpc-if", },
 576        {},
 577};
 578MODULE_DEVICE_TABLE(of, rpcif_of_match);
 579
 580static struct platform_driver rpcif_driver = {
 581        .probe  = rpcif_probe,
 582        .remove = rpcif_remove,
 583        .driver = {
 584                .name = "rpc-if",
 585                .of_match_table = rpcif_of_match,
 586        },
 587};
 588module_platform_driver(rpcif_driver);
 589
 590MODULE_DESCRIPTION("Renesas RPC-IF core driver");
 591MODULE_LICENSE("GPL v2");
 592