uboot/drivers/spi/stm32_qspi.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2016
   3 *
   4 * Michael Kurz, <michi.kurz@gmail.com>
   5 *
   6 * STM32 QSPI driver
   7 *
   8 * SPDX-License-Identifier:     GPL-2.0+
   9 */
  10
  11#include <common.h>
  12#include <malloc.h>
  13#include <spi.h>
  14#include <spi_flash.h>
  15#include <asm/io.h>
  16#include <dm.h>
  17#include <errno.h>
  18#include <asm/arch/stm32.h>
  19#include <asm/arch/stm32_defs.h>
  20
  21DECLARE_GLOBAL_DATA_PTR;
  22
  23struct stm32_qspi_regs {
  24        u32 cr;         /* 0x00 */
  25        u32 dcr;        /* 0x04 */
  26        u32 sr;         /* 0x08 */
  27        u32 fcr;        /* 0x0C */
  28        u32 dlr;        /* 0x10 */
  29        u32 ccr;        /* 0x14 */
  30        u32 ar;         /* 0x18 */
  31        u32 abr;        /* 0x1C */
  32        u32 dr;         /* 0x20 */
  33        u32 psmkr;      /* 0x24 */
  34        u32 psmar;      /* 0x28 */
  35        u32 pir;        /* 0x2C */
  36        u32 lptr;       /* 0x30 */
  37};
  38
  39/*
  40 * QUADSPI control register
  41 */
  42#define STM32_QSPI_CR_EN                BIT(0)
  43#define STM32_QSPI_CR_ABORT             BIT(1)
  44#define STM32_QSPI_CR_DMAEN             BIT(2)
  45#define STM32_QSPI_CR_TCEN              BIT(3)
  46#define STM32_QSPI_CR_SSHIFT            BIT(4)
  47#define STM32_QSPI_CR_DFM               BIT(6)
  48#define STM32_QSPI_CR_FSEL              BIT(7)
  49#define STM32_QSPI_CR_FTHRES_MASK       GENMASK(4, 0)
  50#define STM32_QSPI_CR_FTHRES_SHIFT      (8)
  51#define STM32_QSPI_CR_TEIE              BIT(16)
  52#define STM32_QSPI_CR_TCIE              BIT(17)
  53#define STM32_QSPI_CR_FTIE              BIT(18)
  54#define STM32_QSPI_CR_SMIE              BIT(19)
  55#define STM32_QSPI_CR_TOIE              BIT(20)
  56#define STM32_QSPI_CR_APMS              BIT(22)
  57#define STM32_QSPI_CR_PMM               BIT(23)
  58#define STM32_QSPI_CR_PRESCALER_MASK    GENMASK(7, 0)
  59#define STM32_QSPI_CR_PRESCALER_SHIFT   (24)
  60
  61/*
  62 * QUADSPI device configuration register
  63 */
  64#define STM32_QSPI_DCR_CKMODE           BIT(0)
  65#define STM32_QSPI_DCR_CSHT_MASK        GENMASK(2, 0)
  66#define STM32_QSPI_DCR_CSHT_SHIFT       (8)
  67#define STM32_QSPI_DCR_FSIZE_MASK       GENMASK(4, 0)
  68#define STM32_QSPI_DCR_FSIZE_SHIFT      (16)
  69
  70/*
  71 * QUADSPI status register
  72 */
  73#define STM32_QSPI_SR_TEF               BIT(0)
  74#define STM32_QSPI_SR_TCF               BIT(1)
  75#define STM32_QSPI_SR_FTF               BIT(2)
  76#define STM32_QSPI_SR_SMF               BIT(3)
  77#define STM32_QSPI_SR_TOF               BIT(4)
  78#define STM32_QSPI_SR_BUSY              BIT(5)
  79#define STM32_QSPI_SR_FLEVEL_MASK       GENMASK(5, 0)
  80#define STM32_QSPI_SR_FLEVEL_SHIFT      (8)
  81
  82/*
  83 * QUADSPI flag clear register
  84 */
  85#define STM32_QSPI_FCR_CTEF             BIT(0)
  86#define STM32_QSPI_FCR_CTCF             BIT(1)
  87#define STM32_QSPI_FCR_CSMF             BIT(3)
  88#define STM32_QSPI_FCR_CTOF             BIT(4)
  89
  90/*
  91 * QUADSPI communication configuration register
  92 */
  93#define STM32_QSPI_CCR_DDRM             BIT(31)
  94#define STM32_QSPI_CCR_DHHC             BIT(30)
  95#define STM32_QSPI_CCR_SIOO             BIT(28)
  96#define STM32_QSPI_CCR_FMODE_SHIFT      (26)
  97#define STM32_QSPI_CCR_DMODE_SHIFT      (24)
  98#define STM32_QSPI_CCR_DCYC_SHIFT       (18)
  99#define STM32_QSPI_CCR_DCYC_MASK        GENMASK(4, 0)
 100#define STM32_QSPI_CCR_ABSIZE_SHIFT     (16)
 101#define STM32_QSPI_CCR_ABMODE_SHIFT     (14)
 102#define STM32_QSPI_CCR_ADSIZE_SHIFT     (12)
 103#define STM32_QSPI_CCR_ADMODE_SHIFT     (10)
 104#define STM32_QSPI_CCR_IMODE_SHIFT      (8)
 105#define STM32_QSPI_CCR_INSTRUCTION_MASK GENMASK(7, 0)
 106
 107enum STM32_QSPI_CCR_IMODE {
 108        STM32_QSPI_CCR_IMODE_NONE = 0,
 109        STM32_QSPI_CCR_IMODE_ONE_LINE = 1,
 110        STM32_QSPI_CCR_IMODE_TWO_LINE = 2,
 111        STM32_QSPI_CCR_IMODE_FOUR_LINE = 3,
 112};
 113
 114enum STM32_QSPI_CCR_ADMODE {
 115        STM32_QSPI_CCR_ADMODE_NONE = 0,
 116        STM32_QSPI_CCR_ADMODE_ONE_LINE = 1,
 117        STM32_QSPI_CCR_ADMODE_TWO_LINE = 2,
 118        STM32_QSPI_CCR_ADMODE_FOUR_LINE = 3,
 119};
 120
 121enum STM32_QSPI_CCR_ADSIZE {
 122        STM32_QSPI_CCR_ADSIZE_8BIT = 0,
 123        STM32_QSPI_CCR_ADSIZE_16BIT = 1,
 124        STM32_QSPI_CCR_ADSIZE_24BIT = 2,
 125        STM32_QSPI_CCR_ADSIZE_32BIT = 3,
 126};
 127
 128enum STM32_QSPI_CCR_ABMODE {
 129        STM32_QSPI_CCR_ABMODE_NONE = 0,
 130        STM32_QSPI_CCR_ABMODE_ONE_LINE = 1,
 131        STM32_QSPI_CCR_ABMODE_TWO_LINE = 2,
 132        STM32_QSPI_CCR_ABMODE_FOUR_LINE = 3,
 133};
 134
 135enum STM32_QSPI_CCR_ABSIZE {
 136        STM32_QSPI_CCR_ABSIZE_8BIT = 0,
 137        STM32_QSPI_CCR_ABSIZE_16BIT = 1,
 138        STM32_QSPI_CCR_ABSIZE_24BIT = 2,
 139        STM32_QSPI_CCR_ABSIZE_32BIT = 3,
 140};
 141
 142enum STM32_QSPI_CCR_DMODE {
 143        STM32_QSPI_CCR_DMODE_NONE = 0,
 144        STM32_QSPI_CCR_DMODE_ONE_LINE = 1,
 145        STM32_QSPI_CCR_DMODE_TWO_LINE = 2,
 146        STM32_QSPI_CCR_DMODE_FOUR_LINE = 3,
 147};
 148
 149enum STM32_QSPI_CCR_FMODE {
 150        STM32_QSPI_CCR_IND_WRITE = 0,
 151        STM32_QSPI_CCR_IND_READ = 1,
 152        STM32_QSPI_CCR_AUTO_POLL = 2,
 153        STM32_QSPI_CCR_MEM_MAP = 3,
 154};
 155
 156/* default SCK frequency, unit: HZ */
 157#define STM32_QSPI_DEFAULT_SCK_FREQ 108000000
 158
 159struct stm32_qspi_platdata {
 160        u32 base;
 161        u32 memory_map;
 162        u32 max_hz;
 163};
 164
 165struct stm32_qspi_priv {
 166        struct stm32_qspi_regs *regs;
 167        u32 max_hz;
 168        u32 mode;
 169
 170        u32 command;
 171        u32 address;
 172        u32 dummycycles;
 173#define CMD_HAS_ADR     BIT(24)
 174#define CMD_HAS_DUMMY   BIT(25)
 175#define CMD_HAS_DATA    BIT(26)
 176};
 177
 178static void _stm32_qspi_disable(struct stm32_qspi_priv *priv)
 179{
 180        clrbits_le32(&priv->regs->cr, STM32_QSPI_CR_EN);
 181}
 182
 183static void _stm32_qspi_enable(struct stm32_qspi_priv *priv)
 184{
 185        setbits_le32(&priv->regs->cr, STM32_QSPI_CR_EN);
 186}
 187
 188static void _stm32_qspi_wait_for_not_busy(struct stm32_qspi_priv *priv)
 189{
 190        while (readl(&priv->regs->sr) & STM32_QSPI_SR_BUSY)
 191                ;
 192}
 193
 194static void _stm32_qspi_wait_for_complete(struct stm32_qspi_priv *priv)
 195{
 196        while (!(readl(&priv->regs->sr) & STM32_QSPI_SR_TCF))
 197                ;
 198}
 199
 200static void _stm32_qspi_wait_for_ftf(struct stm32_qspi_priv *priv)
 201{
 202        while (!(readl(&priv->regs->sr) & STM32_QSPI_SR_FTF))
 203                ;
 204}
 205
 206static void _stm32_qspi_set_flash_size(struct stm32_qspi_priv *priv, u32 size)
 207{
 208        u32 fsize = fls(size) - 1;
 209        clrsetbits_le32(&priv->regs->dcr,
 210                        STM32_QSPI_DCR_FSIZE_MASK << STM32_QSPI_DCR_FSIZE_SHIFT,
 211                        fsize << STM32_QSPI_DCR_FSIZE_SHIFT);
 212}
 213
 214static unsigned int _stm32_qspi_gen_ccr(struct stm32_qspi_priv *priv)
 215{
 216        unsigned int ccr_reg = 0;
 217        u8 imode, admode, dmode;
 218        u32 mode = priv->mode;
 219        u32 cmd = (priv->command & STM32_QSPI_CCR_INSTRUCTION_MASK);
 220
 221        imode = STM32_QSPI_CCR_IMODE_ONE_LINE;
 222        admode = STM32_QSPI_CCR_ADMODE_ONE_LINE;
 223
 224        if (mode & SPI_RX_QUAD) {
 225                dmode = STM32_QSPI_CCR_DMODE_FOUR_LINE;
 226                if (mode & SPI_TX_QUAD) {
 227                        imode = STM32_QSPI_CCR_IMODE_FOUR_LINE;
 228                        admode = STM32_QSPI_CCR_ADMODE_FOUR_LINE;
 229                }
 230        } else if (mode & SPI_RX_DUAL) {
 231                dmode = STM32_QSPI_CCR_DMODE_TWO_LINE;
 232                if (mode & SPI_TX_DUAL) {
 233                        imode = STM32_QSPI_CCR_IMODE_TWO_LINE;
 234                        admode = STM32_QSPI_CCR_ADMODE_TWO_LINE;
 235                }
 236        } else {
 237                dmode = STM32_QSPI_CCR_DMODE_ONE_LINE;
 238        }
 239
 240        if (priv->command & CMD_HAS_DATA)
 241                ccr_reg |= (dmode << STM32_QSPI_CCR_DMODE_SHIFT);
 242
 243        if (priv->command & CMD_HAS_DUMMY)
 244                ccr_reg |= ((priv->dummycycles & STM32_QSPI_CCR_DCYC_MASK)
 245                                << STM32_QSPI_CCR_DCYC_SHIFT);
 246
 247        if (priv->command & CMD_HAS_ADR) {
 248                ccr_reg |= (STM32_QSPI_CCR_ADSIZE_24BIT
 249                                << STM32_QSPI_CCR_ADSIZE_SHIFT);
 250                ccr_reg |= (admode << STM32_QSPI_CCR_ADMODE_SHIFT);
 251        }
 252        ccr_reg |= (imode << STM32_QSPI_CCR_IMODE_SHIFT);
 253        ccr_reg |= cmd;
 254        return ccr_reg;
 255}
 256
 257static void _stm32_qspi_enable_mmap(struct stm32_qspi_priv *priv,
 258                struct spi_flash *flash)
 259{
 260        priv->command = flash->read_cmd | CMD_HAS_ADR | CMD_HAS_DATA
 261                        | CMD_HAS_DUMMY;
 262        priv->dummycycles = flash->dummy_byte * 8;
 263
 264        unsigned int ccr_reg = _stm32_qspi_gen_ccr(priv);
 265        ccr_reg |= (STM32_QSPI_CCR_MEM_MAP << STM32_QSPI_CCR_FMODE_SHIFT);
 266
 267        _stm32_qspi_wait_for_not_busy(priv);
 268
 269        writel(ccr_reg, &priv->regs->ccr);
 270
 271        priv->dummycycles = 0;
 272}
 273
 274static void _stm32_qspi_disable_mmap(struct stm32_qspi_priv *priv)
 275{
 276        setbits_le32(&priv->regs->cr, STM32_QSPI_CR_ABORT);
 277}
 278
 279static void _stm32_qspi_set_xfer_length(struct stm32_qspi_priv *priv,
 280                                        u32 length)
 281{
 282        writel(length - 1, &priv->regs->dlr);
 283}
 284
 285static void _stm32_qspi_start_xfer(struct stm32_qspi_priv *priv, u32 cr_reg)
 286{
 287        writel(cr_reg, &priv->regs->ccr);
 288
 289        if (priv->command & CMD_HAS_ADR)
 290                writel(priv->address, &priv->regs->ar);
 291}
 292
 293static int _stm32_qspi_xfer(struct stm32_qspi_priv *priv,
 294                struct spi_flash *flash, unsigned int bitlen,
 295                const u8 *dout, u8 *din, unsigned long flags)
 296{
 297        unsigned int words = bitlen / 8;
 298
 299        if (flags & SPI_XFER_MMAP) {
 300                _stm32_qspi_enable_mmap(priv, flash);
 301                return 0;
 302        } else if (flags & SPI_XFER_MMAP_END) {
 303                _stm32_qspi_disable_mmap(priv);
 304                return 0;
 305        }
 306
 307        if (bitlen == 0)
 308                return -1;
 309
 310        if (bitlen % 8) {
 311                debug("spi_xfer: Non byte aligned SPI transfer\n");
 312                return -1;
 313        }
 314
 315        if (dout && din) {
 316                debug("spi_xfer: QSPI cannot have data in and data out set\n");
 317                return -1;
 318        }
 319
 320        if (!dout && (flags & SPI_XFER_BEGIN)) {
 321                debug("spi_xfer: QSPI transfer must begin with command\n");
 322                return -1;
 323        }
 324
 325        if (dout) {
 326                if (flags & SPI_XFER_BEGIN) {
 327                        /* data is command */
 328                        priv->command = dout[0] | CMD_HAS_DATA;
 329                        if (words >= 4) {
 330                                /* address is here too */
 331                                priv->address = (dout[1] << 16) |
 332                                                (dout[2] << 8) | dout[3];
 333                                priv->command |= CMD_HAS_ADR;
 334                        }
 335
 336                        if (words > 4) {
 337                                /* rest is dummy bytes */
 338                                priv->dummycycles = (words - 4) * 8;
 339                                priv->command |= CMD_HAS_DUMMY;
 340                        }
 341
 342                        if (flags & SPI_XFER_END) {
 343                                /* command without data */
 344                                priv->command &= ~(CMD_HAS_DATA);
 345                        }
 346                }
 347
 348                if (flags & SPI_XFER_END) {
 349                        u32 ccr_reg = _stm32_qspi_gen_ccr(priv);
 350                        ccr_reg |= STM32_QSPI_CCR_IND_WRITE
 351                                        << STM32_QSPI_CCR_FMODE_SHIFT;
 352
 353                        _stm32_qspi_wait_for_not_busy(priv);
 354
 355                        if (priv->command & CMD_HAS_DATA)
 356                                _stm32_qspi_set_xfer_length(priv, words);
 357
 358                        _stm32_qspi_start_xfer(priv, ccr_reg);
 359
 360                        debug("%s: write: ccr:0x%08x adr:0x%08x\n",
 361                              __func__, priv->regs->ccr, priv->regs->ar);
 362
 363                        if (priv->command & CMD_HAS_DATA) {
 364                                _stm32_qspi_wait_for_ftf(priv);
 365
 366                                debug("%s: words:%d data:", __func__, words);
 367
 368                                int i = 0;
 369                                while (words > i) {
 370                                        writeb(dout[i], &priv->regs->dr);
 371                                        debug("%02x ", dout[i]);
 372                                        i++;
 373                                }
 374                                debug("\n");
 375
 376                                _stm32_qspi_wait_for_complete(priv);
 377                        } else {
 378                                _stm32_qspi_wait_for_not_busy(priv);
 379                        }
 380                }
 381        } else if (din) {
 382                u32 ccr_reg = _stm32_qspi_gen_ccr(priv);
 383                ccr_reg |= STM32_QSPI_CCR_IND_READ
 384                                << STM32_QSPI_CCR_FMODE_SHIFT;
 385
 386                _stm32_qspi_wait_for_not_busy(priv);
 387
 388                _stm32_qspi_set_xfer_length(priv, words);
 389
 390                _stm32_qspi_start_xfer(priv, ccr_reg);
 391
 392                debug("%s: read: ccr:0x%08x adr:0x%08x len:%d\n", __func__,
 393                      priv->regs->ccr, priv->regs->ar, priv->regs->dlr);
 394
 395                debug("%s: data:", __func__);
 396
 397                int i = 0;
 398                while (words > i) {
 399                        din[i] = readb(&priv->regs->dr);
 400                        debug("%02x ", din[i]);
 401                        i++;
 402                }
 403                debug("\n");
 404        }
 405
 406        return 0;
 407}
 408
 409static int stm32_qspi_ofdata_to_platdata(struct udevice *bus)
 410{
 411        struct fdt_resource res_regs, res_mem;
 412        struct stm32_qspi_platdata *plat = bus->platdata;
 413        const void *blob = gd->fdt_blob;
 414        int node = dev_of_offset(bus);
 415        int ret;
 416
 417        ret = fdt_get_named_resource(blob, node, "reg", "reg-names",
 418                                     "QuadSPI", &res_regs);
 419        if (ret) {
 420                debug("Error: can't get regs base addresses(ret = %d)!\n", ret);
 421                return -ENOMEM;
 422        }
 423        ret = fdt_get_named_resource(blob, node, "reg", "reg-names",
 424                                     "QuadSPI-memory", &res_mem);
 425        if (ret) {
 426                debug("Error: can't get mmap base address(ret = %d)!\n", ret);
 427                return -ENOMEM;
 428        }
 429
 430        plat->max_hz = fdtdec_get_int(blob, node, "spi-max-frequency",
 431                                        STM32_QSPI_DEFAULT_SCK_FREQ);
 432
 433        plat->base = res_regs.start;
 434        plat->memory_map = res_mem.start;
 435
 436        debug("%s: regs=<0x%x> mapped=<0x%x>, max-frequency=%d\n",
 437              __func__,
 438              plat->base,
 439              plat->memory_map,
 440              plat->max_hz
 441              );
 442
 443        return 0;
 444}
 445
 446static int stm32_qspi_probe(struct udevice *bus)
 447{
 448        struct stm32_qspi_platdata *plat = dev_get_platdata(bus);
 449        struct stm32_qspi_priv *priv = dev_get_priv(bus);
 450        struct dm_spi_bus *dm_spi_bus;
 451
 452        dm_spi_bus = bus->uclass_priv;
 453
 454        dm_spi_bus->max_hz = plat->max_hz;
 455
 456        priv->regs = (struct stm32_qspi_regs *)(uintptr_t)plat->base;
 457
 458        priv->max_hz = plat->max_hz;
 459
 460        clock_setup(QSPI_CLOCK_CFG);
 461
 462        setbits_le32(&priv->regs->cr, STM32_QSPI_CR_SSHIFT);
 463
 464        return 0;
 465}
 466
 467static int stm32_qspi_remove(struct udevice *bus)
 468{
 469        return 0;
 470}
 471
 472static int stm32_qspi_claim_bus(struct udevice *dev)
 473{
 474        struct stm32_qspi_priv *priv;
 475        struct udevice *bus;
 476        struct spi_flash *flash;
 477
 478        bus = dev->parent;
 479        priv = dev_get_priv(bus);
 480        flash = dev_get_uclass_priv(dev);
 481
 482        _stm32_qspi_set_flash_size(priv, flash->size);
 483
 484        _stm32_qspi_enable(priv);
 485
 486        return 0;
 487}
 488
 489static int stm32_qspi_release_bus(struct udevice *dev)
 490{
 491        struct stm32_qspi_priv *priv;
 492        struct udevice *bus;
 493
 494        bus = dev->parent;
 495        priv = dev_get_priv(bus);
 496
 497        _stm32_qspi_disable(priv);
 498
 499        return 0;
 500}
 501
 502static int stm32_qspi_xfer(struct udevice *dev, unsigned int bitlen,
 503                const void *dout, void *din, unsigned long flags)
 504{
 505        struct stm32_qspi_priv *priv;
 506        struct udevice *bus;
 507        struct spi_flash *flash;
 508
 509        bus = dev->parent;
 510        priv = dev_get_priv(bus);
 511        flash = dev_get_uclass_priv(dev);
 512
 513        return _stm32_qspi_xfer(priv, flash, bitlen, (const u8 *)dout,
 514                                (u8 *)din, flags);
 515}
 516
 517static int stm32_qspi_set_speed(struct udevice *bus, uint speed)
 518{
 519        struct stm32_qspi_platdata *plat = bus->platdata;
 520        struct stm32_qspi_priv *priv = dev_get_priv(bus);
 521
 522        if (speed > plat->max_hz)
 523                speed = plat->max_hz;
 524
 525        u32 qspi_clk = clock_get(CLOCK_AHB);
 526        u32 prescaler = 255;
 527        if (speed > 0) {
 528                prescaler = DIV_ROUND_UP(qspi_clk, speed) - 1;
 529                if (prescaler > 255)
 530                        prescaler = 255;
 531                else if (prescaler < 0)
 532                        prescaler = 0;
 533        }
 534
 535        u32 csht = DIV_ROUND_UP((5 * qspi_clk) / (prescaler + 1), 100000000);
 536        csht = (csht - 1) & STM32_QSPI_DCR_CSHT_MASK;
 537
 538        _stm32_qspi_wait_for_not_busy(priv);
 539
 540        clrsetbits_le32(&priv->regs->cr,
 541                        STM32_QSPI_CR_PRESCALER_MASK <<
 542                        STM32_QSPI_CR_PRESCALER_SHIFT,
 543                        prescaler << STM32_QSPI_CR_PRESCALER_SHIFT);
 544
 545
 546        clrsetbits_le32(&priv->regs->dcr,
 547                        STM32_QSPI_DCR_CSHT_MASK << STM32_QSPI_DCR_CSHT_SHIFT,
 548                        csht << STM32_QSPI_DCR_CSHT_SHIFT);
 549
 550        debug("%s: regs=%p, speed=%d\n", __func__, priv->regs,
 551              (qspi_clk / (prescaler + 1)));
 552
 553        return 0;
 554}
 555
 556static int stm32_qspi_set_mode(struct udevice *bus, uint mode)
 557{
 558        struct stm32_qspi_priv *priv = dev_get_priv(bus);
 559
 560        _stm32_qspi_wait_for_not_busy(priv);
 561
 562        if ((mode & SPI_CPHA) && (mode & SPI_CPOL))
 563                setbits_le32(&priv->regs->dcr, STM32_QSPI_DCR_CKMODE);
 564        else if (!(mode & SPI_CPHA) && !(mode & SPI_CPOL))
 565                clrbits_le32(&priv->regs->dcr, STM32_QSPI_DCR_CKMODE);
 566        else
 567                return -ENODEV;
 568
 569        if (mode & SPI_CS_HIGH)
 570                return -ENODEV;
 571
 572        if (mode & SPI_RX_QUAD)
 573                priv->mode |= SPI_RX_QUAD;
 574        else if (mode & SPI_RX_DUAL)
 575                priv->mode |= SPI_RX_DUAL;
 576        else
 577                priv->mode &= ~(SPI_RX_QUAD | SPI_RX_DUAL);
 578
 579        if (mode & SPI_TX_QUAD)
 580                priv->mode |= SPI_TX_QUAD;
 581        else if (mode & SPI_TX_DUAL)
 582                priv->mode |= SPI_TX_DUAL;
 583        else
 584                priv->mode &= ~(SPI_TX_QUAD | SPI_TX_DUAL);
 585
 586        debug("%s: regs=%p, mode=%d rx: ", __func__, priv->regs, mode);
 587
 588        if (mode & SPI_RX_QUAD)
 589                debug("quad, tx: ");
 590        else if (mode & SPI_RX_DUAL)
 591                debug("dual, tx: ");
 592        else
 593                debug("single, tx: ");
 594
 595        if (mode & SPI_TX_QUAD)
 596                debug("quad\n");
 597        else if (mode & SPI_TX_DUAL)
 598                debug("dual\n");
 599        else
 600                debug("single\n");
 601
 602        return 0;
 603}
 604
 605static const struct dm_spi_ops stm32_qspi_ops = {
 606        .claim_bus      = stm32_qspi_claim_bus,
 607        .release_bus    = stm32_qspi_release_bus,
 608        .xfer           = stm32_qspi_xfer,
 609        .set_speed      = stm32_qspi_set_speed,
 610        .set_mode       = stm32_qspi_set_mode,
 611};
 612
 613static const struct udevice_id stm32_qspi_ids[] = {
 614        { .compatible = "st,stm32-qspi" },
 615        { }
 616};
 617
 618U_BOOT_DRIVER(stm32_qspi) = {
 619        .name   = "stm32_qspi",
 620        .id     = UCLASS_SPI,
 621        .of_match = stm32_qspi_ids,
 622        .ops    = &stm32_qspi_ops,
 623        .ofdata_to_platdata = stm32_qspi_ofdata_to_platdata,
 624        .platdata_auto_alloc_size = sizeof(struct stm32_qspi_platdata),
 625        .priv_auto_alloc_size = sizeof(struct stm32_qspi_priv),
 626        .probe  = stm32_qspi_probe,
 627        .remove = stm32_qspi_remove,
 628};
 629