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