uboot/drivers/spi/renesas_rpc_spi.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Renesas RCar Gen3 RPC QSPI driver
   4 *
   5 * Copyright (C) 2018 Marek Vasut <marek.vasut@gmail.com>
   6 */
   7
   8#include <common.h>
   9#include <asm/io.h>
  10#include <clk.h>
  11#include <dm.h>
  12#include <dm/of_access.h>
  13#include <dt-structs.h>
  14#include <errno.h>
  15#include <linux/errno.h>
  16#include <spi.h>
  17#include <wait_bit.h>
  18
  19#define RPC_CMNCR               0x0000  /* R/W */
  20#define RPC_CMNCR_MD            BIT(31)
  21#define RPC_CMNCR_SFDE          BIT(24)
  22#define RPC_CMNCR_MOIIO3(val)   (((val) & 0x3) << 22)
  23#define RPC_CMNCR_MOIIO2(val)   (((val) & 0x3) << 20)
  24#define RPC_CMNCR_MOIIO1(val)   (((val) & 0x3) << 18)
  25#define RPC_CMNCR_MOIIO0(val)   (((val) & 0x3) << 16)
  26#define RPC_CMNCR_MOIIO_HIZ     (RPC_CMNCR_MOIIO0(3) | RPC_CMNCR_MOIIO1(3) | \
  27                                 RPC_CMNCR_MOIIO2(3) | RPC_CMNCR_MOIIO3(3))
  28#define RPC_CMNCR_IO3FV(val)    (((val) & 0x3) << 14)
  29#define RPC_CMNCR_IO2FV(val)    (((val) & 0x3) << 12)
  30#define RPC_CMNCR_IO0FV(val)    (((val) & 0x3) << 8)
  31#define RPC_CMNCR_IOFV_HIZ      (RPC_CMNCR_IO0FV(3) | RPC_CMNCR_IO2FV(3) | \
  32                                 RPC_CMNCR_IO3FV(3))
  33#define RPC_CMNCR_CPHAT         BIT(6)
  34#define RPC_CMNCR_CPHAR         BIT(5)
  35#define RPC_CMNCR_SSLP          BIT(4)
  36#define RPC_CMNCR_CPOL          BIT(3)
  37#define RPC_CMNCR_BSZ(val)      (((val) & 0x3) << 0)
  38
  39#define RPC_SSLDR               0x0004  /* R/W */
  40#define RPC_SSLDR_SPNDL(d)      (((d) & 0x7) << 16)
  41#define RPC_SSLDR_SLNDL(d)      (((d) & 0x7) << 8)
  42#define RPC_SSLDR_SCKDL(d)      (((d) & 0x7) << 0)
  43
  44#define RPC_DRCR                0x000C  /* R/W */
  45#define RPC_DRCR_SSLN           BIT(24)
  46#define RPC_DRCR_RBURST(v)      (((v) & 0x1F) << 16)
  47#define RPC_DRCR_RCF            BIT(9)
  48#define RPC_DRCR_RBE            BIT(8)
  49#define RPC_DRCR_SSLE           BIT(0)
  50
  51#define RPC_DRCMR               0x0010  /* R/W */
  52#define RPC_DRCMR_CMD(c)        (((c) & 0xFF) << 16)
  53#define RPC_DRCMR_OCMD(c)       (((c) & 0xFF) << 0)
  54
  55#define RPC_DREAR               0x0014  /* R/W */
  56#define RPC_DREAR_EAV(v)        (((v) & 0xFF) << 16)
  57#define RPC_DREAR_EAC(v)        (((v) & 0x7) << 0)
  58
  59#define RPC_DROPR               0x0018  /* R/W */
  60#define RPC_DROPR_OPD3(o)       (((o) & 0xFF) << 24)
  61#define RPC_DROPR_OPD2(o)       (((o) & 0xFF) << 16)
  62#define RPC_DROPR_OPD1(o)       (((o) & 0xFF) << 8)
  63#define RPC_DROPR_OPD0(o)       (((o) & 0xFF) << 0)
  64
  65#define RPC_DRENR               0x001C  /* R/W */
  66#define RPC_DRENR_CDB(o)        (u32)((((o) & 0x3) << 30))
  67#define RPC_DRENR_OCDB(o)       (((o) & 0x3) << 28)
  68#define RPC_DRENR_ADB(o)        (((o) & 0x3) << 24)
  69#define RPC_DRENR_OPDB(o)       (((o) & 0x3) << 20)
  70#define RPC_DRENR_SPIDB(o)      (((o) & 0x3) << 16)
  71#define RPC_DRENR_DME           BIT(15)
  72#define RPC_DRENR_CDE           BIT(14)
  73#define RPC_DRENR_OCDE          BIT(12)
  74#define RPC_DRENR_ADE(v)        (((v) & 0xF) << 8)
  75#define RPC_DRENR_OPDE(v)       (((v) & 0xF) << 4)
  76
  77#define RPC_SMCR                0x0020  /* R/W */
  78#define RPC_SMCR_SSLKP          BIT(8)
  79#define RPC_SMCR_SPIRE          BIT(2)
  80#define RPC_SMCR_SPIWE          BIT(1)
  81#define RPC_SMCR_SPIE           BIT(0)
  82
  83#define RPC_SMCMR               0x0024  /* R/W */
  84#define RPC_SMCMR_CMD(c)        (((c) & 0xFF) << 16)
  85#define RPC_SMCMR_OCMD(c)       (((c) & 0xFF) << 0)
  86
  87#define RPC_SMADR               0x0028  /* R/W */
  88#define RPC_SMOPR               0x002C  /* R/W */
  89#define RPC_SMOPR_OPD0(o)       (((o) & 0xFF) << 0)
  90#define RPC_SMOPR_OPD1(o)       (((o) & 0xFF) << 8)
  91#define RPC_SMOPR_OPD2(o)       (((o) & 0xFF) << 16)
  92#define RPC_SMOPR_OPD3(o)       (((o) & 0xFF) << 24)
  93
  94#define RPC_SMENR               0x0030  /* R/W */
  95#define RPC_SMENR_CDB(o)        (((o) & 0x3) << 30)
  96#define RPC_SMENR_OCDB(o)       (((o) & 0x3) << 28)
  97#define RPC_SMENR_ADB(o)        (((o) & 0x3) << 24)
  98#define RPC_SMENR_OPDB(o)       (((o) & 0x3) << 20)
  99#define RPC_SMENR_SPIDB(o)      (((o) & 0x3) << 16)
 100#define RPC_SMENR_DME           BIT(15)
 101#define RPC_SMENR_CDE           BIT(14)
 102#define RPC_SMENR_OCDE          BIT(12)
 103#define RPC_SMENR_ADE(v)        (((v) & 0xF) << 8)
 104#define RPC_SMENR_OPDE(v)       (((v) & 0xF) << 4)
 105#define RPC_SMENR_SPIDE(v)      (((v) & 0xF) << 0)
 106
 107#define RPC_SMRDR0              0x0038  /* R */
 108#define RPC_SMRDR1              0x003C  /* R */
 109#define RPC_SMWDR0              0x0040  /* R/W */
 110#define RPC_SMWDR1              0x0044  /* R/W */
 111#define RPC_CMNSR               0x0048  /* R */
 112#define RPC_CMNSR_SSLF          BIT(1)
 113#define RPC_CMNSR_TEND          BIT(0)
 114
 115#define RPC_DRDMCR              0x0058  /* R/W */
 116#define RPC_DRDMCR_DMCYC(v)     (((v) & 0xF) << 0)
 117
 118#define RPC_DRDRENR             0x005C  /* R/W */
 119#define RPC_DRDRENR_HYPE        (0x5 << 12)
 120#define RPC_DRDRENR_ADDRE       BIT(8)
 121#define RPC_DRDRENR_OPDRE       BIT(4)
 122#define RPC_DRDRENR_DRDRE       BIT(0)
 123
 124#define RPC_SMDMCR              0x0060  /* R/W */
 125#define RPC_SMDMCR_DMCYC(v)     (((v) & 0xF) << 0)
 126
 127#define RPC_SMDRENR             0x0064  /* R/W */
 128#define RPC_SMDRENR_HYPE        (0x5 << 12)
 129#define RPC_SMDRENR_ADDRE       BIT(8)
 130#define RPC_SMDRENR_OPDRE       BIT(4)
 131#define RPC_SMDRENR_SPIDRE      BIT(0)
 132
 133#define RPC_PHYCNT              0x007C  /* R/W */
 134#define RPC_PHYCNT_CAL          BIT(31)
 135#define PRC_PHYCNT_OCTA_AA      BIT(22)
 136#define PRC_PHYCNT_OCTA_SA      BIT(23)
 137#define PRC_PHYCNT_EXDS         BIT(21)
 138#define RPC_PHYCNT_OCT          BIT(20)
 139#define RPC_PHYCNT_STRTIM(v)    (((v) & 0x7) << 15)
 140#define RPC_PHYCNT_WBUF2        BIT(4)
 141#define RPC_PHYCNT_WBUF         BIT(2)
 142#define RPC_PHYCNT_MEM(v)       (((v) & 0x3) << 0)
 143
 144#define RPC_PHYINT              0x0088  /* R/W */
 145#define RPC_PHYINT_RSTEN        BIT(18)
 146#define RPC_PHYINT_WPEN         BIT(17)
 147#define RPC_PHYINT_INTEN        BIT(16)
 148#define RPC_PHYINT_RST          BIT(2)
 149#define RPC_PHYINT_WP           BIT(1)
 150#define RPC_PHYINT_INT          BIT(0)
 151
 152#define RPC_WBUF                0x8000  /* R/W size=4/8/16/32/64Bytes */
 153#define RPC_WBUF_SIZE           0x100
 154
 155DECLARE_GLOBAL_DATA_PTR;
 156
 157struct rpc_spi_platdata {
 158        fdt_addr_t      regs;
 159        fdt_addr_t      extr;
 160        s32             freq;   /* Default clock freq, -1 for none */
 161};
 162
 163struct rpc_spi_priv {
 164        fdt_addr_t      regs;
 165        fdt_addr_t      extr;
 166        struct clk      clk;
 167
 168        u8              cmdcopy[8];
 169        u32             cmdlen;
 170        bool            cmdstarted;
 171};
 172
 173static int rpc_spi_wait_sslf(struct udevice *dev)
 174{
 175        struct rpc_spi_priv *priv = dev_get_priv(dev->parent);
 176
 177        return wait_for_bit_le32((void *)priv->regs + RPC_CMNSR, RPC_CMNSR_SSLF,
 178                                 false, 1000, false);
 179}
 180
 181static int rpc_spi_wait_tend(struct udevice *dev)
 182{
 183        struct rpc_spi_priv *priv = dev_get_priv(dev->parent);
 184
 185        return wait_for_bit_le32((void *)priv->regs + RPC_CMNSR, RPC_CMNSR_TEND,
 186                                 true, 1000, false);
 187}
 188
 189static void rpc_spi_flush_read_cache(struct udevice *dev)
 190{
 191        struct udevice *bus = dev->parent;
 192        struct rpc_spi_priv *priv = dev_get_priv(bus);
 193
 194        /* Flush read cache */
 195        writel(RPC_DRCR_SSLN | RPC_DRCR_RBURST(0x1f) |
 196               RPC_DRCR_RCF | RPC_DRCR_RBE | RPC_DRCR_SSLE,
 197               priv->regs + RPC_DRCR);
 198        readl(priv->regs + RPC_DRCR);
 199
 200}
 201
 202static int rpc_spi_claim_bus(struct udevice *dev, bool manual)
 203{
 204        struct udevice *bus = dev->parent;
 205        struct rpc_spi_priv *priv = dev_get_priv(bus);
 206
 207        /*
 208         * NOTE: The 0x260 are undocumented bits, but they must be set.
 209         * NOTE: On H3 ES1.x (not supported in mainline U-Boot), the
 210         *       RPC_PHYCNT_STRTIM shall be 0, while on newer parts, the
 211         *       RPC_PHYCNT_STRTIM shall be 6.
 212         */
 213        writel(RPC_PHYCNT_CAL | RPC_PHYCNT_STRTIM(6) | 0x260,
 214               priv->regs + RPC_PHYCNT);
 215        writel((manual ? RPC_CMNCR_MD : 0) | RPC_CMNCR_SFDE |
 216                 RPC_CMNCR_MOIIO_HIZ | RPC_CMNCR_IOFV_HIZ | RPC_CMNCR_BSZ(0),
 217                 priv->regs + RPC_CMNCR);
 218
 219        writel(RPC_SSLDR_SPNDL(7) | RPC_SSLDR_SLNDL(7) |
 220               RPC_SSLDR_SCKDL(7), priv->regs + RPC_SSLDR);
 221
 222        rpc_spi_flush_read_cache(dev);
 223
 224        return 0;
 225}
 226
 227static int rpc_spi_release_bus(struct udevice *dev)
 228{
 229        struct udevice *bus = dev->parent;
 230        struct rpc_spi_priv *priv = dev_get_priv(bus);
 231
 232        /* NOTE: The 0x260 are undocumented bits, but they must be set. */
 233        writel(RPC_PHYCNT_STRTIM(6) | 0x260, priv->regs + RPC_PHYCNT);
 234
 235        rpc_spi_flush_read_cache(dev);
 236
 237        return 0;
 238}
 239
 240static int rpc_spi_xfer(struct udevice *dev, unsigned int bitlen,
 241                        const void *dout, void *din, unsigned long flags)
 242{
 243        struct udevice *bus = dev->parent;
 244        struct rpc_spi_priv *priv = dev_get_priv(bus);
 245        u32 wlen = dout ? (bitlen / 8) : 0;
 246        u32 rlen = din ? (bitlen / 8) : 0;
 247        u32 wloop = DIV_ROUND_UP(wlen, 4);
 248        u32 smenr, smcr, offset;
 249        int ret = 0;
 250
 251        if (!priv->cmdstarted) {
 252                if (!wlen || rlen)
 253                        BUG();
 254
 255                memcpy(priv->cmdcopy, dout, wlen);
 256                priv->cmdlen = wlen;
 257
 258                /* Command transfer start */
 259                priv->cmdstarted = true;
 260                if (!(flags & SPI_XFER_END))
 261                        return 0;
 262        }
 263
 264        offset = (priv->cmdcopy[1] << 16) | (priv->cmdcopy[2] << 8) |
 265                 (priv->cmdcopy[3] << 0);
 266
 267        smenr = 0;
 268
 269        if (wlen || (!rlen && !wlen) || flags == SPI_XFER_ONCE) {
 270                if (wlen && flags == SPI_XFER_END)
 271                        smenr = RPC_SMENR_SPIDE(0xf);
 272
 273                rpc_spi_claim_bus(dev, true);
 274
 275                writel(0, priv->regs + RPC_SMCR);
 276
 277                if (priv->cmdlen >= 1) {        /* Command(1) */
 278                        writel(RPC_SMCMR_CMD(priv->cmdcopy[0]),
 279                               priv->regs + RPC_SMCMR);
 280                        smenr |= RPC_SMENR_CDE;
 281                } else {
 282                        writel(0, priv->regs + RPC_SMCMR);
 283                }
 284
 285                if (priv->cmdlen >= 4) {        /* Address(3) */
 286                        writel(offset, priv->regs + RPC_SMADR);
 287                        smenr |= RPC_SMENR_ADE(7);
 288                } else {
 289                        writel(0, priv->regs + RPC_SMADR);
 290                }
 291
 292                if (priv->cmdlen >= 5) {        /* Dummy(n) */
 293                        writel(8 * (priv->cmdlen - 4) - 1,
 294                               priv->regs + RPC_SMDMCR);
 295                        smenr |= RPC_SMENR_DME;
 296                } else {
 297                        writel(0, priv->regs + RPC_SMDMCR);
 298                }
 299
 300                writel(0, priv->regs + RPC_SMOPR);
 301
 302                writel(0, priv->regs + RPC_SMDRENR);
 303
 304                if (wlen && flags == SPI_XFER_END) {
 305                        u32 *datout = (u32 *)dout;
 306
 307                        while (wloop--) {
 308                                smcr = RPC_SMCR_SPIWE | RPC_SMCR_SPIE;
 309                                if (wloop >= 1)
 310                                        smcr |= RPC_SMCR_SSLKP;
 311                                writel(smenr, priv->regs + RPC_SMENR);
 312                                writel(*datout, priv->regs + RPC_SMWDR0);
 313                                writel(smcr, priv->regs + RPC_SMCR);
 314                                ret = rpc_spi_wait_tend(dev);
 315                                if (ret)
 316                                        goto err;
 317                                datout++;
 318                                smenr = RPC_SMENR_SPIDE(0xf);
 319                        }
 320
 321                        ret = rpc_spi_wait_sslf(dev);
 322
 323                } else {
 324                        writel(smenr, priv->regs + RPC_SMENR);
 325                        writel(RPC_SMCR_SPIE, priv->regs + RPC_SMCR);
 326                        ret = rpc_spi_wait_tend(dev);
 327                }
 328        } else {        /* Read data only, using DRx ext access */
 329                rpc_spi_claim_bus(dev, false);
 330
 331                if (priv->cmdlen >= 1) {        /* Command(1) */
 332                        writel(RPC_DRCMR_CMD(priv->cmdcopy[0]),
 333                               priv->regs + RPC_DRCMR);
 334                        smenr |= RPC_DRENR_CDE;
 335                } else {
 336                        writel(0, priv->regs + RPC_DRCMR);
 337                }
 338
 339                if (priv->cmdlen >= 4)          /* Address(3) */
 340                        smenr |= RPC_DRENR_ADE(7);
 341
 342                if (priv->cmdlen >= 5) {        /* Dummy(n) */
 343                        writel(8 * (priv->cmdlen - 4) - 1,
 344                               priv->regs + RPC_DRDMCR);
 345                        smenr |= RPC_DRENR_DME;
 346                } else {
 347                        writel(0, priv->regs + RPC_DRDMCR);
 348                }
 349
 350                writel(0, priv->regs + RPC_DROPR);
 351
 352                writel(smenr, priv->regs + RPC_DRENR);
 353
 354                if (rlen)
 355                        memcpy_fromio(din, (void *)(priv->extr + offset), rlen);
 356                else
 357                        readl(priv->extr);      /* Dummy read */
 358        }
 359
 360err:
 361        priv->cmdstarted = false;
 362
 363        rpc_spi_release_bus(dev);
 364
 365        return ret;
 366}
 367
 368static int rpc_spi_set_speed(struct udevice *bus, uint speed)
 369{
 370        /* This is a SPI NOR controller, do nothing. */
 371        return 0;
 372}
 373
 374static int rpc_spi_set_mode(struct udevice *bus, uint mode)
 375{
 376        /* This is a SPI NOR controller, do nothing. */
 377        return 0;
 378}
 379
 380static int rpc_spi_bind(struct udevice *parent)
 381{
 382        const void *fdt = gd->fdt_blob;
 383        ofnode node;
 384        int ret, off;
 385
 386        /*
 387         * Check if there are any SPI NOR child nodes, if so, bind as
 388         * this controller will be operated in SPI mode.
 389         */
 390        dev_for_each_subnode(node, parent) {
 391                off = ofnode_to_offset(node);
 392
 393                ret = fdt_node_check_compatible(fdt, off, "spi-flash");
 394                if (!ret)
 395                        return 0;
 396
 397                ret = fdt_node_check_compatible(fdt, off, "jedec,spi-nor");
 398                if (!ret)
 399                        return 0;
 400        }
 401
 402        return -ENODEV;
 403}
 404
 405static int rpc_spi_probe(struct udevice *dev)
 406{
 407        struct rpc_spi_platdata *plat = dev_get_platdata(dev);
 408        struct rpc_spi_priv *priv = dev_get_priv(dev);
 409
 410        priv->regs = plat->regs;
 411        priv->extr = plat->extr;
 412
 413        clk_enable(&priv->clk);
 414
 415        return 0;
 416}
 417
 418static int rpc_spi_ofdata_to_platdata(struct udevice *bus)
 419{
 420        struct rpc_spi_platdata *plat = dev_get_platdata(bus);
 421        struct rpc_spi_priv *priv = dev_get_priv(bus);
 422        int ret;
 423
 424        plat->regs = dev_read_addr_index(bus, 0);
 425        plat->extr = dev_read_addr_index(bus, 1);
 426
 427        ret = clk_get_by_index(bus, 0, &priv->clk);
 428        if (ret < 0) {
 429                printf("%s: Could not get clock for %s: %d\n",
 430                       __func__, bus->name, ret);
 431                return ret;
 432        }
 433
 434        plat->freq = dev_read_u32_default(bus, "spi-max-freq", 50000000);
 435
 436        return 0;
 437}
 438
 439static const struct dm_spi_ops rpc_spi_ops = {
 440        .xfer           = rpc_spi_xfer,
 441        .set_speed      = rpc_spi_set_speed,
 442        .set_mode       = rpc_spi_set_mode,
 443};
 444
 445static const struct udevice_id rpc_spi_ids[] = {
 446        { .compatible = "renesas,rpc-r8a7795" },
 447        { .compatible = "renesas,rpc-r8a7796" },
 448        { .compatible = "renesas,rpc-r8a77965" },
 449        { .compatible = "renesas,rpc-r8a77970" },
 450        { .compatible = "renesas,rpc-r8a77995" },
 451        { }
 452};
 453
 454U_BOOT_DRIVER(rpc_spi) = {
 455        .name           = "rpc_spi",
 456        .id             = UCLASS_SPI,
 457        .of_match       = rpc_spi_ids,
 458        .ops            = &rpc_spi_ops,
 459        .ofdata_to_platdata = rpc_spi_ofdata_to_platdata,
 460        .platdata_auto_alloc_size = sizeof(struct rpc_spi_platdata),
 461        .priv_auto_alloc_size = sizeof(struct rpc_spi_priv),
 462        .bind           = rpc_spi_bind,
 463        .probe          = rpc_spi_probe,
 464};
 465