Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  *
0004  *  Copyright (C) 2012 Thomas Langer <thomas.langer@lantiq.com>
0005  */
0006 
0007 #include <linux/module.h>
0008 #include <linux/device.h>
0009 #include <linux/platform_device.h>
0010 #include <linux/spi/spi.h>
0011 #include <linux/delay.h>
0012 #include <linux/of.h>
0013 #include <linux/of_platform.h>
0014 
0015 #include <lantiq_soc.h>
0016 
0017 #define DRV_NAME        "sflash-falcon"
0018 
0019 #define FALCON_SPI_XFER_BEGIN   (1 << 0)
0020 #define FALCON_SPI_XFER_END (1 << 1)
0021 
0022 /* Bus Read Configuration Register0 */
0023 #define BUSRCON0        0x00000010
0024 /* Bus Write Configuration Register0 */
0025 #define BUSWCON0        0x00000018
0026 /* Serial Flash Configuration Register */
0027 #define SFCON           0x00000080
0028 /* Serial Flash Time Register */
0029 #define SFTIME          0x00000084
0030 /* Serial Flash Status Register */
0031 #define SFSTAT          0x00000088
0032 /* Serial Flash Command Register */
0033 #define SFCMD           0x0000008C
0034 /* Serial Flash Address Register */
0035 #define SFADDR          0x00000090
0036 /* Serial Flash Data Register */
0037 #define SFDATA          0x00000094
0038 /* Serial Flash I/O Control Register */
0039 #define SFIO            0x00000098
0040 /* EBU Clock Control Register */
0041 #define EBUCC           0x000000C4
0042 
0043 /* Dummy Phase Length */
0044 #define SFCMD_DUMLEN_OFFSET 16
0045 #define SFCMD_DUMLEN_MASK   0x000F0000
0046 /* Chip Select */
0047 #define SFCMD_CS_OFFSET     24
0048 #define SFCMD_CS_MASK       0x07000000
0049 /* field offset */
0050 #define SFCMD_ALEN_OFFSET   20
0051 #define SFCMD_ALEN_MASK     0x00700000
0052 /* SCK Rise-edge Position */
0053 #define SFTIME_SCKR_POS_OFFSET  8
0054 #define SFTIME_SCKR_POS_MASK    0x00000F00
0055 /* SCK Period */
0056 #define SFTIME_SCK_PER_OFFSET   0
0057 #define SFTIME_SCK_PER_MASK 0x0000000F
0058 /* SCK Fall-edge Position */
0059 #define SFTIME_SCKF_POS_OFFSET  12
0060 #define SFTIME_SCKF_POS_MASK    0x0000F000
0061 /* Device Size */
0062 #define SFCON_DEV_SIZE_A23_0    0x03000000
0063 #define SFCON_DEV_SIZE_MASK 0x0F000000
0064 /* Read Data Position */
0065 #define SFTIME_RD_POS_MASK  0x000F0000
0066 /* Data Output */
0067 #define SFIO_UNUSED_WD_MASK 0x0000000F
0068 /* Command Opcode mask */
0069 #define SFCMD_OPC_MASK      0x000000FF
0070 /* dlen bytes of data to write */
0071 #define SFCMD_DIR_WRITE     0x00000100
0072 /* Data Length offset */
0073 #define SFCMD_DLEN_OFFSET   9
0074 /* Command Error */
0075 #define SFSTAT_CMD_ERR      0x20000000
0076 /* Access Command Pending */
0077 #define SFSTAT_CMD_PEND     0x00400000
0078 /* Frequency set to 100MHz. */
0079 #define EBUCC_EBUDIV_SELF100    0x00000001
0080 /* Serial Flash */
0081 #define BUSRCON0_AGEN_SERIAL_FLASH  0xF0000000
0082 /* 8-bit multiplexed */
0083 #define BUSRCON0_PORTW_8_BIT_MUX    0x00000000
0084 /* Serial Flash */
0085 #define BUSWCON0_AGEN_SERIAL_FLASH  0xF0000000
0086 /* Chip Select after opcode */
0087 #define SFCMD_KEEP_CS_KEEP_SELECTED 0x00008000
0088 
0089 #define CLOCK_100M  100000000
0090 #define CLOCK_50M   50000000
0091 
0092 struct falcon_sflash {
0093     u32 sfcmd; /* for caching of opcode, direction, ... */
0094     struct spi_master *master;
0095 };
0096 
0097 int falcon_sflash_xfer(struct spi_device *spi, struct spi_transfer *t,
0098         unsigned long flags)
0099 {
0100     struct device *dev = &spi->dev;
0101     struct falcon_sflash *priv = spi_master_get_devdata(spi->master);
0102     const u8 *txp = t->tx_buf;
0103     u8 *rxp = t->rx_buf;
0104     unsigned int bytelen = ((8 * t->len + 7) / 8);
0105     unsigned int len, alen, dumlen;
0106     u32 val;
0107     enum {
0108         state_init,
0109         state_command_prepare,
0110         state_write,
0111         state_read,
0112         state_disable_cs,
0113         state_end
0114     } state = state_init;
0115 
0116     do {
0117         switch (state) {
0118         case state_init: /* detect phase of upper layer sequence */
0119         {
0120             /* initial write ? */
0121             if (flags & FALCON_SPI_XFER_BEGIN) {
0122                 if (!txp) {
0123                     dev_err(dev,
0124                         "BEGIN without tx data!\n");
0125                     return -ENODATA;
0126                 }
0127                 /*
0128                  * Prepare the parts of the sfcmd register,
0129                  * which should not change during a sequence!
0130                  * Only exception are the length fields,
0131                  * especially alen and dumlen.
0132                  */
0133 
0134                 priv->sfcmd = ((spi->chip_select
0135                         << SFCMD_CS_OFFSET)
0136                            & SFCMD_CS_MASK);
0137                 priv->sfcmd |= SFCMD_KEEP_CS_KEEP_SELECTED;
0138                 priv->sfcmd |= *txp;
0139                 txp++;
0140                 bytelen--;
0141                 if (bytelen) {
0142                     /*
0143                      * more data:
0144                      * maybe address and/or dummy
0145                      */
0146                     state = state_command_prepare;
0147                     break;
0148                 } else {
0149                     dev_dbg(dev, "write cmd %02X\n",
0150                         priv->sfcmd & SFCMD_OPC_MASK);
0151                 }
0152             }
0153             /* continued write ? */
0154             if (txp && bytelen) {
0155                 state = state_write;
0156                 break;
0157             }
0158             /* read data? */
0159             if (rxp && bytelen) {
0160                 state = state_read;
0161                 break;
0162             }
0163             /* end of sequence? */
0164             if (flags & FALCON_SPI_XFER_END)
0165                 state = state_disable_cs;
0166             else
0167                 state = state_end;
0168             break;
0169         }
0170         /* collect tx data for address and dummy phase */
0171         case state_command_prepare:
0172         {
0173             /* txp is valid, already checked */
0174             val = 0;
0175             alen = 0;
0176             dumlen = 0;
0177             while (bytelen > 0) {
0178                 if (alen < 3) {
0179                     val = (val << 8) | (*txp++);
0180                     alen++;
0181                 } else if ((dumlen < 15) && (*txp == 0)) {
0182                     /*
0183                      * assume dummy bytes are set to 0
0184                      * from upper layer
0185                      */
0186                     dumlen++;
0187                     txp++;
0188                 } else {
0189                     break;
0190                 }
0191                 bytelen--;
0192             }
0193             priv->sfcmd &= ~(SFCMD_ALEN_MASK | SFCMD_DUMLEN_MASK);
0194             priv->sfcmd |= (alen << SFCMD_ALEN_OFFSET) |
0195                      (dumlen << SFCMD_DUMLEN_OFFSET);
0196             if (alen > 0)
0197                 ltq_ebu_w32(val, SFADDR);
0198 
0199             dev_dbg(dev, "wr %02X, alen=%d (addr=%06X) dlen=%d\n",
0200                 priv->sfcmd & SFCMD_OPC_MASK,
0201                 alen, val, dumlen);
0202 
0203             if (bytelen > 0) {
0204                 /* continue with write */
0205                 state = state_write;
0206             } else if (flags & FALCON_SPI_XFER_END) {
0207                 /* end of sequence? */
0208                 state = state_disable_cs;
0209             } else {
0210                 /*
0211                  * go to end and expect another
0212                  * call (read or write)
0213                  */
0214                 state = state_end;
0215             }
0216             break;
0217         }
0218         case state_write:
0219         {
0220             /* txp still valid */
0221             priv->sfcmd |= SFCMD_DIR_WRITE;
0222             len = 0;
0223             val = 0;
0224             do {
0225                 if (bytelen--)
0226                     val |= (*txp++) << (8 * len++);
0227                 if ((flags & FALCON_SPI_XFER_END)
0228                     && (bytelen == 0)) {
0229                     priv->sfcmd &=
0230                         ~SFCMD_KEEP_CS_KEEP_SELECTED;
0231                 }
0232                 if ((len == 4) || (bytelen == 0)) {
0233                     ltq_ebu_w32(val, SFDATA);
0234                     ltq_ebu_w32(priv->sfcmd
0235                         | (len<<SFCMD_DLEN_OFFSET),
0236                         SFCMD);
0237                     len = 0;
0238                     val = 0;
0239                     priv->sfcmd &= ~(SFCMD_ALEN_MASK
0240                              | SFCMD_DUMLEN_MASK);
0241                 }
0242             } while (bytelen);
0243             state = state_end;
0244             break;
0245         }
0246         case state_read:
0247         {
0248             /* read data */
0249             priv->sfcmd &= ~SFCMD_DIR_WRITE;
0250             do {
0251                 if ((flags & FALCON_SPI_XFER_END)
0252                     && (bytelen <= 4)) {
0253                     priv->sfcmd &=
0254                         ~SFCMD_KEEP_CS_KEEP_SELECTED;
0255                 }
0256                 len = (bytelen > 4) ? 4 : bytelen;
0257                 bytelen -= len;
0258                 ltq_ebu_w32(priv->sfcmd
0259                     | (len << SFCMD_DLEN_OFFSET), SFCMD);
0260                 priv->sfcmd &= ~(SFCMD_ALEN_MASK
0261                          | SFCMD_DUMLEN_MASK);
0262                 do {
0263                     val = ltq_ebu_r32(SFSTAT);
0264                     if (val & SFSTAT_CMD_ERR) {
0265                         /* reset error status */
0266                         dev_err(dev, "SFSTAT: CMD_ERR");
0267                         dev_err(dev, " (%x)\n", val);
0268                         ltq_ebu_w32(SFSTAT_CMD_ERR,
0269                             SFSTAT);
0270                         return -EBADE;
0271                     }
0272                 } while (val & SFSTAT_CMD_PEND);
0273                 val = ltq_ebu_r32(SFDATA);
0274                 do {
0275                     *rxp = (val & 0xFF);
0276                     rxp++;
0277                     val >>= 8;
0278                     len--;
0279                 } while (len);
0280             } while (bytelen);
0281             state = state_end;
0282             break;
0283         }
0284         case state_disable_cs:
0285         {
0286             priv->sfcmd &= ~SFCMD_KEEP_CS_KEEP_SELECTED;
0287             ltq_ebu_w32(priv->sfcmd | (0 << SFCMD_DLEN_OFFSET),
0288                 SFCMD);
0289             val = ltq_ebu_r32(SFSTAT);
0290             if (val & SFSTAT_CMD_ERR) {
0291                 /* reset error status */
0292                 dev_err(dev, "SFSTAT: CMD_ERR (%x)\n", val);
0293                 ltq_ebu_w32(SFSTAT_CMD_ERR, SFSTAT);
0294                 return -EBADE;
0295             }
0296             state = state_end;
0297             break;
0298         }
0299         case state_end:
0300             break;
0301         }
0302     } while (state != state_end);
0303 
0304     return 0;
0305 }
0306 
0307 static int falcon_sflash_setup(struct spi_device *spi)
0308 {
0309     unsigned int i;
0310     unsigned long flags;
0311 
0312     spin_lock_irqsave(&ebu_lock, flags);
0313 
0314     if (spi->max_speed_hz >= CLOCK_100M) {
0315         /* set EBU clock to 100 MHz */
0316         ltq_sys1_w32_mask(0, EBUCC_EBUDIV_SELF100, EBUCC);
0317         i = 1; /* divider */
0318     } else {
0319         /* set EBU clock to 50 MHz */
0320         ltq_sys1_w32_mask(EBUCC_EBUDIV_SELF100, 0, EBUCC);
0321 
0322         /* search for suitable divider */
0323         for (i = 1; i < 7; i++) {
0324             if (CLOCK_50M / i <= spi->max_speed_hz)
0325                 break;
0326         }
0327     }
0328 
0329     /* setup period of serial clock */
0330     ltq_ebu_w32_mask(SFTIME_SCKF_POS_MASK
0331              | SFTIME_SCKR_POS_MASK
0332              | SFTIME_SCK_PER_MASK,
0333              (i << SFTIME_SCKR_POS_OFFSET)
0334              | (i << (SFTIME_SCK_PER_OFFSET + 1)),
0335              SFTIME);
0336 
0337     /*
0338      * set some bits of unused_wd, to not trigger HOLD/WP
0339      * signals on non QUAD flashes
0340      */
0341     ltq_ebu_w32((SFIO_UNUSED_WD_MASK & (0x8 | 0x4)), SFIO);
0342 
0343     ltq_ebu_w32(BUSRCON0_AGEN_SERIAL_FLASH | BUSRCON0_PORTW_8_BIT_MUX,
0344             BUSRCON0);
0345     ltq_ebu_w32(BUSWCON0_AGEN_SERIAL_FLASH, BUSWCON0);
0346     /* set address wrap around to maximum for 24-bit addresses */
0347     ltq_ebu_w32_mask(SFCON_DEV_SIZE_MASK, SFCON_DEV_SIZE_A23_0, SFCON);
0348 
0349     spin_unlock_irqrestore(&ebu_lock, flags);
0350 
0351     return 0;
0352 }
0353 
0354 static int falcon_sflash_xfer_one(struct spi_master *master,
0355                     struct spi_message *m)
0356 {
0357     struct falcon_sflash *priv = spi_master_get_devdata(master);
0358     struct spi_transfer *t;
0359     unsigned long spi_flags;
0360     unsigned long flags;
0361     int ret = 0;
0362 
0363     priv->sfcmd = 0;
0364     m->actual_length = 0;
0365 
0366     spi_flags = FALCON_SPI_XFER_BEGIN;
0367     list_for_each_entry(t, &m->transfers, transfer_list) {
0368         if (list_is_last(&t->transfer_list, &m->transfers))
0369             spi_flags |= FALCON_SPI_XFER_END;
0370 
0371         spin_lock_irqsave(&ebu_lock, flags);
0372         ret = falcon_sflash_xfer(m->spi, t, spi_flags);
0373         spin_unlock_irqrestore(&ebu_lock, flags);
0374 
0375         if (ret)
0376             break;
0377 
0378         m->actual_length += t->len;
0379 
0380         WARN_ON(t->delay.value || t->cs_change);
0381         spi_flags = 0;
0382     }
0383 
0384     m->status = ret;
0385     spi_finalize_current_message(master);
0386 
0387     return 0;
0388 }
0389 
0390 static int falcon_sflash_probe(struct platform_device *pdev)
0391 {
0392     struct falcon_sflash *priv;
0393     struct spi_master *master;
0394     int ret;
0395 
0396     master = spi_alloc_master(&pdev->dev, sizeof(*priv));
0397     if (!master)
0398         return -ENOMEM;
0399 
0400     priv = spi_master_get_devdata(master);
0401     priv->master = master;
0402 
0403     master->mode_bits = SPI_MODE_3;
0404     master->flags = SPI_MASTER_HALF_DUPLEX;
0405     master->setup = falcon_sflash_setup;
0406     master->transfer_one_message = falcon_sflash_xfer_one;
0407     master->dev.of_node = pdev->dev.of_node;
0408 
0409     ret = devm_spi_register_master(&pdev->dev, master);
0410     if (ret)
0411         spi_master_put(master);
0412     return ret;
0413 }
0414 
0415 static const struct of_device_id falcon_sflash_match[] = {
0416     { .compatible = "lantiq,sflash-falcon" },
0417     {},
0418 };
0419 MODULE_DEVICE_TABLE(of, falcon_sflash_match);
0420 
0421 static struct platform_driver falcon_sflash_driver = {
0422     .probe  = falcon_sflash_probe,
0423     .driver = {
0424         .name   = DRV_NAME,
0425         .of_match_table = falcon_sflash_match,
0426     }
0427 };
0428 
0429 module_platform_driver(falcon_sflash_driver);
0430 
0431 MODULE_LICENSE("GPL");
0432 MODULE_DESCRIPTION("Lantiq Falcon SPI/SFLASH controller driver");