Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 //
0003 // Synquacer HSSPI controller driver
0004 //
0005 // Copyright (c) 2015-2018 Socionext Inc.
0006 // Copyright (c) 2018-2019 Linaro Ltd.
0007 //
0008 
0009 #include <linux/acpi.h>
0010 #include <linux/delay.h>
0011 #include <linux/interrupt.h>
0012 #include <linux/io.h>
0013 #include <linux/module.h>
0014 #include <linux/of.h>
0015 #include <linux/platform_device.h>
0016 #include <linux/pm_runtime.h>
0017 #include <linux/scatterlist.h>
0018 #include <linux/slab.h>
0019 #include <linux/spi/spi.h>
0020 #include <linux/spinlock.h>
0021 #include <linux/clk.h>
0022 
0023 /* HSSPI register address definitions */
0024 #define SYNQUACER_HSSPI_REG_MCTRL   0x00
0025 #define SYNQUACER_HSSPI_REG_PCC0    0x04
0026 #define SYNQUACER_HSSPI_REG_PCC(n)  (SYNQUACER_HSSPI_REG_PCC0 + (n) * 4)
0027 #define SYNQUACER_HSSPI_REG_TXF     0x14
0028 #define SYNQUACER_HSSPI_REG_TXE     0x18
0029 #define SYNQUACER_HSSPI_REG_TXC     0x1C
0030 #define SYNQUACER_HSSPI_REG_RXF     0x20
0031 #define SYNQUACER_HSSPI_REG_RXE     0x24
0032 #define SYNQUACER_HSSPI_REG_RXC     0x28
0033 #define SYNQUACER_HSSPI_REG_FAULTF  0x2C
0034 #define SYNQUACER_HSSPI_REG_FAULTC  0x30
0035 #define SYNQUACER_HSSPI_REG_DMCFG   0x34
0036 #define SYNQUACER_HSSPI_REG_DMSTART 0x38
0037 #define SYNQUACER_HSSPI_REG_DMBCC   0x3C
0038 #define SYNQUACER_HSSPI_REG_DMSTATUS    0x40
0039 #define SYNQUACER_HSSPI_REG_FIFOCFG 0x4C
0040 #define SYNQUACER_HSSPI_REG_TX_FIFO 0x50
0041 #define SYNQUACER_HSSPI_REG_RX_FIFO 0x90
0042 #define SYNQUACER_HSSPI_REG_MID     0xFC
0043 
0044 /* HSSPI register bit definitions */
0045 #define SYNQUACER_HSSPI_MCTRL_MEN           BIT(0)
0046 #define SYNQUACER_HSSPI_MCTRL_COMMAND_SEQUENCE_EN   BIT(1)
0047 #define SYNQUACER_HSSPI_MCTRL_CDSS          BIT(3)
0048 #define SYNQUACER_HSSPI_MCTRL_MES           BIT(4)
0049 #define SYNQUACER_HSSPI_MCTRL_SYNCON            BIT(5)
0050 
0051 #define SYNQUACER_HSSPI_PCC_CPHA        BIT(0)
0052 #define SYNQUACER_HSSPI_PCC_CPOL        BIT(1)
0053 #define SYNQUACER_HSSPI_PCC_ACES        BIT(2)
0054 #define SYNQUACER_HSSPI_PCC_RTM         BIT(3)
0055 #define SYNQUACER_HSSPI_PCC_SSPOL       BIT(4)
0056 #define SYNQUACER_HSSPI_PCC_SDIR        BIT(7)
0057 #define SYNQUACER_HSSPI_PCC_SENDIAN     BIT(8)
0058 #define SYNQUACER_HSSPI_PCC_SAFESYNC        BIT(16)
0059 #define SYNQUACER_HSSPI_PCC_SS2CD_SHIFT     5U
0060 #define SYNQUACER_HSSPI_PCC_CDRS_MASK       0x7f
0061 #define SYNQUACER_HSSPI_PCC_CDRS_SHIFT      9U
0062 
0063 #define SYNQUACER_HSSPI_TXF_FIFO_FULL       BIT(0)
0064 #define SYNQUACER_HSSPI_TXF_FIFO_EMPTY      BIT(1)
0065 #define SYNQUACER_HSSPI_TXF_SLAVE_RELEASED  BIT(6)
0066 
0067 #define SYNQUACER_HSSPI_TXE_FIFO_FULL       BIT(0)
0068 #define SYNQUACER_HSSPI_TXE_FIFO_EMPTY      BIT(1)
0069 #define SYNQUACER_HSSPI_TXE_SLAVE_RELEASED  BIT(6)
0070 
0071 #define SYNQUACER_HSSPI_RXF_FIFO_MORE_THAN_THRESHOLD        BIT(5)
0072 #define SYNQUACER_HSSPI_RXF_SLAVE_RELEASED          BIT(6)
0073 
0074 #define SYNQUACER_HSSPI_RXE_FIFO_MORE_THAN_THRESHOLD        BIT(5)
0075 #define SYNQUACER_HSSPI_RXE_SLAVE_RELEASED          BIT(6)
0076 
0077 #define SYNQUACER_HSSPI_DMCFG_SSDC      BIT(1)
0078 #define SYNQUACER_HSSPI_DMCFG_MSTARTEN      BIT(2)
0079 
0080 #define SYNQUACER_HSSPI_DMSTART_START       BIT(0)
0081 #define SYNQUACER_HSSPI_DMSTOP_STOP     BIT(8)
0082 #define SYNQUACER_HSSPI_DMPSEL_CS_MASK      0x3
0083 #define SYNQUACER_HSSPI_DMPSEL_CS_SHIFT     16U
0084 #define SYNQUACER_HSSPI_DMTRP_BUS_WIDTH_SHIFT   24U
0085 #define SYNQUACER_HSSPI_DMTRP_DATA_MASK     0x3
0086 #define SYNQUACER_HSSPI_DMTRP_DATA_SHIFT    26U
0087 #define SYNQUACER_HSSPI_DMTRP_DATA_TXRX     0
0088 #define SYNQUACER_HSSPI_DMTRP_DATA_RX       1
0089 #define SYNQUACER_HSSPI_DMTRP_DATA_TX       2
0090 
0091 #define SYNQUACER_HSSPI_DMSTATUS_RX_DATA_MASK   0x1f
0092 #define SYNQUACER_HSSPI_DMSTATUS_RX_DATA_SHIFT  8U
0093 #define SYNQUACER_HSSPI_DMSTATUS_TX_DATA_MASK   0x1f
0094 #define SYNQUACER_HSSPI_DMSTATUS_TX_DATA_SHIFT  16U
0095 
0096 #define SYNQUACER_HSSPI_FIFOCFG_RX_THRESHOLD_MASK   0xf
0097 #define SYNQUACER_HSSPI_FIFOCFG_RX_THRESHOLD_SHIFT  0U
0098 #define SYNQUACER_HSSPI_FIFOCFG_TX_THRESHOLD_MASK   0xf
0099 #define SYNQUACER_HSSPI_FIFOCFG_TX_THRESHOLD_SHIFT  4U
0100 #define SYNQUACER_HSSPI_FIFOCFG_FIFO_WIDTH_MASK     0x3
0101 #define SYNQUACER_HSSPI_FIFOCFG_FIFO_WIDTH_SHIFT    8U
0102 #define SYNQUACER_HSSPI_FIFOCFG_RX_FLUSH        BIT(11)
0103 #define SYNQUACER_HSSPI_FIFOCFG_TX_FLUSH        BIT(12)
0104 
0105 #define SYNQUACER_HSSPI_FIFO_DEPTH      16U
0106 #define SYNQUACER_HSSPI_FIFO_TX_THRESHOLD   4U
0107 #define SYNQUACER_HSSPI_FIFO_RX_THRESHOLD \
0108     (SYNQUACER_HSSPI_FIFO_DEPTH - SYNQUACER_HSSPI_FIFO_TX_THRESHOLD)
0109 
0110 #define SYNQUACER_HSSPI_TRANSFER_MODE_TX    BIT(1)
0111 #define SYNQUACER_HSSPI_TRANSFER_MODE_RX    BIT(2)
0112 #define SYNQUACER_HSSPI_TRANSFER_TMOUT_MSEC 2000U
0113 #define SYNQUACER_HSSPI_ENABLE_TMOUT_MSEC   1000U
0114 
0115 #define SYNQUACER_HSSPI_CLOCK_SRC_IHCLK     0
0116 #define SYNQUACER_HSSPI_CLOCK_SRC_IPCLK     1
0117 
0118 #define SYNQUACER_HSSPI_NUM_CHIP_SELECT     4U
0119 #define SYNQUACER_HSSPI_IRQ_NAME_MAX        32U
0120 
0121 struct synquacer_spi {
0122     struct device *dev;
0123     struct completion transfer_done;
0124     unsigned int cs;
0125     unsigned int bpw;
0126     unsigned int mode;
0127     unsigned int speed;
0128     bool aces, rtm;
0129     void *rx_buf;
0130     const void *tx_buf;
0131     struct clk *clk;
0132     int clk_src_type;
0133     void __iomem *regs;
0134     u32 tx_words, rx_words;
0135     unsigned int bus_width;
0136     unsigned int transfer_mode;
0137     char rx_irq_name[SYNQUACER_HSSPI_IRQ_NAME_MAX];
0138     char tx_irq_name[SYNQUACER_HSSPI_IRQ_NAME_MAX];
0139 };
0140 
0141 static int read_fifo(struct synquacer_spi *sspi)
0142 {
0143     u32 len = readl(sspi->regs + SYNQUACER_HSSPI_REG_DMSTATUS);
0144 
0145     len = (len >> SYNQUACER_HSSPI_DMSTATUS_RX_DATA_SHIFT) &
0146            SYNQUACER_HSSPI_DMSTATUS_RX_DATA_MASK;
0147     len = min(len, sspi->rx_words);
0148 
0149     switch (sspi->bpw) {
0150     case 8: {
0151         u8 *buf = sspi->rx_buf;
0152 
0153         ioread8_rep(sspi->regs + SYNQUACER_HSSPI_REG_RX_FIFO,
0154                 buf, len);
0155         sspi->rx_buf = buf + len;
0156         break;
0157     }
0158     case 16: {
0159         u16 *buf = sspi->rx_buf;
0160 
0161         ioread16_rep(sspi->regs + SYNQUACER_HSSPI_REG_RX_FIFO,
0162                  buf, len);
0163         sspi->rx_buf = buf + len;
0164         break;
0165     }
0166     case 24:
0167         /* fallthrough, should use 32-bits access */
0168     case 32: {
0169         u32 *buf = sspi->rx_buf;
0170 
0171         ioread32_rep(sspi->regs + SYNQUACER_HSSPI_REG_RX_FIFO,
0172                  buf, len);
0173         sspi->rx_buf = buf + len;
0174         break;
0175     }
0176     default:
0177         return -EINVAL;
0178     }
0179 
0180     sspi->rx_words -= len;
0181     return 0;
0182 }
0183 
0184 static int write_fifo(struct synquacer_spi *sspi)
0185 {
0186     u32 len = readl(sspi->regs + SYNQUACER_HSSPI_REG_DMSTATUS);
0187 
0188     len = (len >> SYNQUACER_HSSPI_DMSTATUS_TX_DATA_SHIFT) &
0189            SYNQUACER_HSSPI_DMSTATUS_TX_DATA_MASK;
0190     len = min(SYNQUACER_HSSPI_FIFO_DEPTH - len,
0191             sspi->tx_words);
0192 
0193     switch (sspi->bpw) {
0194     case 8: {
0195         const u8 *buf = sspi->tx_buf;
0196 
0197         iowrite8_rep(sspi->regs + SYNQUACER_HSSPI_REG_TX_FIFO,
0198                  buf, len);
0199         sspi->tx_buf = buf + len;
0200         break;
0201     }
0202     case 16: {
0203         const u16 *buf = sspi->tx_buf;
0204 
0205         iowrite16_rep(sspi->regs + SYNQUACER_HSSPI_REG_TX_FIFO,
0206                   buf, len);
0207         sspi->tx_buf = buf + len;
0208         break;
0209     }
0210     case 24:
0211         /* fallthrough, should use 32-bits access */
0212     case 32: {
0213         const u32 *buf = sspi->tx_buf;
0214 
0215         iowrite32_rep(sspi->regs + SYNQUACER_HSSPI_REG_TX_FIFO,
0216                   buf, len);
0217         sspi->tx_buf = buf + len;
0218         break;
0219     }
0220     default:
0221         return -EINVAL;
0222     }
0223 
0224     sspi->tx_words -= len;
0225     return 0;
0226 }
0227 
0228 static int synquacer_spi_config(struct spi_master *master,
0229                 struct spi_device *spi,
0230                 struct spi_transfer *xfer)
0231 {
0232     struct synquacer_spi *sspi = spi_master_get_devdata(master);
0233     unsigned int speed, mode, bpw, cs, bus_width, transfer_mode;
0234     u32 rate, val, div;
0235 
0236     /* Full Duplex only on 1-bit wide bus */
0237     if (xfer->rx_buf && xfer->tx_buf &&
0238         (xfer->rx_nbits != 1 || xfer->tx_nbits != 1)) {
0239         dev_err(sspi->dev,
0240             "RX and TX bus widths must be 1-bit for Full-Duplex!\n");
0241         return -EINVAL;
0242     }
0243 
0244     if (xfer->tx_buf) {
0245         bus_width = xfer->tx_nbits;
0246         transfer_mode = SYNQUACER_HSSPI_TRANSFER_MODE_TX;
0247     } else {
0248         bus_width = xfer->rx_nbits;
0249         transfer_mode = SYNQUACER_HSSPI_TRANSFER_MODE_RX;
0250     }
0251 
0252     mode = spi->mode;
0253     cs = spi->chip_select;
0254     speed = xfer->speed_hz;
0255     bpw = xfer->bits_per_word;
0256 
0257     /* return if nothing to change */
0258     if (speed == sspi->speed &&
0259         bus_width == sspi->bus_width && bpw == sspi->bpw &&
0260         mode == sspi->mode && cs == sspi->cs &&
0261         transfer_mode == sspi->transfer_mode) {
0262         return 0;
0263     }
0264 
0265     sspi->transfer_mode = transfer_mode;
0266     rate = master->max_speed_hz;
0267 
0268     div = DIV_ROUND_UP(rate, speed);
0269     if (div > 254) {
0270         dev_err(sspi->dev, "Requested rate too low (%u)\n",
0271             sspi->speed);
0272         return -EINVAL;
0273     }
0274 
0275     val = readl(sspi->regs + SYNQUACER_HSSPI_REG_PCC(cs));
0276     val &= ~SYNQUACER_HSSPI_PCC_SAFESYNC;
0277     if (bpw == 8 && (mode & (SPI_TX_DUAL | SPI_RX_DUAL)) && div < 3)
0278         val |= SYNQUACER_HSSPI_PCC_SAFESYNC;
0279     if (bpw == 8 && (mode & (SPI_TX_QUAD | SPI_RX_QUAD)) && div < 6)
0280         val |= SYNQUACER_HSSPI_PCC_SAFESYNC;
0281     if (bpw == 16 && (mode & (SPI_TX_QUAD | SPI_RX_QUAD)) && div < 3)
0282         val |= SYNQUACER_HSSPI_PCC_SAFESYNC;
0283 
0284     if (mode & SPI_CPHA)
0285         val |= SYNQUACER_HSSPI_PCC_CPHA;
0286     else
0287         val &= ~SYNQUACER_HSSPI_PCC_CPHA;
0288 
0289     if (mode & SPI_CPOL)
0290         val |= SYNQUACER_HSSPI_PCC_CPOL;
0291     else
0292         val &= ~SYNQUACER_HSSPI_PCC_CPOL;
0293 
0294     if (mode & SPI_CS_HIGH)
0295         val |= SYNQUACER_HSSPI_PCC_SSPOL;
0296     else
0297         val &= ~SYNQUACER_HSSPI_PCC_SSPOL;
0298 
0299     if (mode & SPI_LSB_FIRST)
0300         val |= SYNQUACER_HSSPI_PCC_SDIR;
0301     else
0302         val &= ~SYNQUACER_HSSPI_PCC_SDIR;
0303 
0304     if (sspi->aces)
0305         val |= SYNQUACER_HSSPI_PCC_ACES;
0306     else
0307         val &= ~SYNQUACER_HSSPI_PCC_ACES;
0308 
0309     if (sspi->rtm)
0310         val |= SYNQUACER_HSSPI_PCC_RTM;
0311     else
0312         val &= ~SYNQUACER_HSSPI_PCC_RTM;
0313 
0314     val |= (3 << SYNQUACER_HSSPI_PCC_SS2CD_SHIFT);
0315     val |= SYNQUACER_HSSPI_PCC_SENDIAN;
0316 
0317     val &= ~(SYNQUACER_HSSPI_PCC_CDRS_MASK <<
0318          SYNQUACER_HSSPI_PCC_CDRS_SHIFT);
0319     val |= ((div >> 1) << SYNQUACER_HSSPI_PCC_CDRS_SHIFT);
0320 
0321     writel(val, sspi->regs + SYNQUACER_HSSPI_REG_PCC(cs));
0322 
0323     val = readl(sspi->regs + SYNQUACER_HSSPI_REG_FIFOCFG);
0324     val &= ~(SYNQUACER_HSSPI_FIFOCFG_FIFO_WIDTH_MASK <<
0325          SYNQUACER_HSSPI_FIFOCFG_FIFO_WIDTH_SHIFT);
0326     val |= ((bpw / 8 - 1) << SYNQUACER_HSSPI_FIFOCFG_FIFO_WIDTH_SHIFT);
0327     writel(val, sspi->regs + SYNQUACER_HSSPI_REG_FIFOCFG);
0328 
0329     val = readl(sspi->regs + SYNQUACER_HSSPI_REG_DMSTART);
0330     val &= ~(SYNQUACER_HSSPI_DMTRP_DATA_MASK <<
0331          SYNQUACER_HSSPI_DMTRP_DATA_SHIFT);
0332 
0333     if (xfer->rx_buf)
0334         val |= (SYNQUACER_HSSPI_DMTRP_DATA_RX <<
0335             SYNQUACER_HSSPI_DMTRP_DATA_SHIFT);
0336     else
0337         val |= (SYNQUACER_HSSPI_DMTRP_DATA_TX <<
0338             SYNQUACER_HSSPI_DMTRP_DATA_SHIFT);
0339 
0340     val &= ~(3 << SYNQUACER_HSSPI_DMTRP_BUS_WIDTH_SHIFT);
0341     val |= ((bus_width >> 1) << SYNQUACER_HSSPI_DMTRP_BUS_WIDTH_SHIFT);
0342     writel(val, sspi->regs + SYNQUACER_HSSPI_REG_DMSTART);
0343 
0344     sspi->bpw = bpw;
0345     sspi->mode = mode;
0346     sspi->speed = speed;
0347     sspi->cs = spi->chip_select;
0348     sspi->bus_width = bus_width;
0349 
0350     return 0;
0351 }
0352 
0353 static int synquacer_spi_transfer_one(struct spi_master *master,
0354                       struct spi_device *spi,
0355                       struct spi_transfer *xfer)
0356 {
0357     struct synquacer_spi *sspi = spi_master_get_devdata(master);
0358     int ret;
0359     int status = 0;
0360     u32 words;
0361     u8 bpw;
0362     u32 val;
0363 
0364     val = readl(sspi->regs + SYNQUACER_HSSPI_REG_DMSTART);
0365     val &= ~SYNQUACER_HSSPI_DMSTOP_STOP;
0366     writel(val, sspi->regs + SYNQUACER_HSSPI_REG_DMSTART);
0367 
0368     val = readl(sspi->regs + SYNQUACER_HSSPI_REG_FIFOCFG);
0369     val |= SYNQUACER_HSSPI_FIFOCFG_RX_FLUSH;
0370     val |= SYNQUACER_HSSPI_FIFOCFG_TX_FLUSH;
0371     writel(val, sspi->regs + SYNQUACER_HSSPI_REG_FIFOCFG);
0372 
0373     /*
0374      * See if we can transfer 4-bytes as 1 word
0375      * to maximize the FIFO buffer efficiency.
0376      */
0377     bpw = xfer->bits_per_word;
0378     if (bpw == 8 && !(xfer->len % 4) && !(spi->mode & SPI_LSB_FIRST))
0379         xfer->bits_per_word = 32;
0380 
0381     ret = synquacer_spi_config(master, spi, xfer);
0382 
0383     /* restore */
0384     xfer->bits_per_word = bpw;
0385 
0386     if (ret)
0387         return ret;
0388 
0389     reinit_completion(&sspi->transfer_done);
0390 
0391     sspi->tx_buf = xfer->tx_buf;
0392     sspi->rx_buf = xfer->rx_buf;
0393 
0394     switch (sspi->bpw) {
0395     case 8:
0396         words = xfer->len;
0397         break;
0398     case 16:
0399         words = xfer->len / 2;
0400         break;
0401     case 24:
0402         /* fallthrough, should use 32-bits access */
0403     case 32:
0404         words = xfer->len / 4;
0405         break;
0406     default:
0407         dev_err(sspi->dev, "unsupported bpw: %d\n", sspi->bpw);
0408         return -EINVAL;
0409     }
0410 
0411     if (xfer->tx_buf)
0412         sspi->tx_words = words;
0413     else
0414         sspi->tx_words = 0;
0415 
0416     if (xfer->rx_buf)
0417         sspi->rx_words = words;
0418     else
0419         sspi->rx_words = 0;
0420 
0421     if (xfer->tx_buf) {
0422         status = write_fifo(sspi);
0423         if (status < 0) {
0424             dev_err(sspi->dev, "failed write_fifo. status: 0x%x\n",
0425                 status);
0426             return status;
0427         }
0428     }
0429 
0430     if (xfer->rx_buf) {
0431         val = readl(sspi->regs + SYNQUACER_HSSPI_REG_FIFOCFG);
0432         val &= ~(SYNQUACER_HSSPI_FIFOCFG_RX_THRESHOLD_MASK <<
0433              SYNQUACER_HSSPI_FIFOCFG_RX_THRESHOLD_SHIFT);
0434         val |= ((sspi->rx_words > SYNQUACER_HSSPI_FIFO_DEPTH ?
0435             SYNQUACER_HSSPI_FIFO_RX_THRESHOLD : sspi->rx_words) <<
0436             SYNQUACER_HSSPI_FIFOCFG_RX_THRESHOLD_SHIFT);
0437         writel(val, sspi->regs + SYNQUACER_HSSPI_REG_FIFOCFG);
0438     }
0439 
0440     writel(~0, sspi->regs + SYNQUACER_HSSPI_REG_TXC);
0441     writel(~0, sspi->regs + SYNQUACER_HSSPI_REG_RXC);
0442 
0443     /* Trigger */
0444     val = readl(sspi->regs + SYNQUACER_HSSPI_REG_DMSTART);
0445     val |= SYNQUACER_HSSPI_DMSTART_START;
0446     writel(val, sspi->regs + SYNQUACER_HSSPI_REG_DMSTART);
0447 
0448     if (xfer->tx_buf) {
0449         val = SYNQUACER_HSSPI_TXE_FIFO_EMPTY;
0450         writel(val, sspi->regs + SYNQUACER_HSSPI_REG_TXE);
0451         status = wait_for_completion_timeout(&sspi->transfer_done,
0452             msecs_to_jiffies(SYNQUACER_HSSPI_TRANSFER_TMOUT_MSEC));
0453         writel(0, sspi->regs + SYNQUACER_HSSPI_REG_TXE);
0454     }
0455 
0456     if (xfer->rx_buf) {
0457         u32 buf[SYNQUACER_HSSPI_FIFO_DEPTH];
0458 
0459         val = SYNQUACER_HSSPI_RXE_FIFO_MORE_THAN_THRESHOLD |
0460               SYNQUACER_HSSPI_RXE_SLAVE_RELEASED;
0461         writel(val, sspi->regs + SYNQUACER_HSSPI_REG_RXE);
0462         status = wait_for_completion_timeout(&sspi->transfer_done,
0463             msecs_to_jiffies(SYNQUACER_HSSPI_TRANSFER_TMOUT_MSEC));
0464         writel(0, sspi->regs + SYNQUACER_HSSPI_REG_RXE);
0465 
0466         /* stop RX and clean RXFIFO */
0467         val = readl(sspi->regs + SYNQUACER_HSSPI_REG_DMSTART);
0468         val |= SYNQUACER_HSSPI_DMSTOP_STOP;
0469         writel(val, sspi->regs + SYNQUACER_HSSPI_REG_DMSTART);
0470         sspi->rx_buf = buf;
0471         sspi->rx_words = SYNQUACER_HSSPI_FIFO_DEPTH;
0472         read_fifo(sspi);
0473     }
0474 
0475     if (status < 0) {
0476         dev_err(sspi->dev, "failed to transfer. status: 0x%x\n",
0477             status);
0478         return status;
0479     }
0480 
0481     return 0;
0482 }
0483 
0484 static void synquacer_spi_set_cs(struct spi_device *spi, bool enable)
0485 {
0486     struct synquacer_spi *sspi = spi_master_get_devdata(spi->master);
0487     u32 val;
0488 
0489     val = readl(sspi->regs + SYNQUACER_HSSPI_REG_DMSTART);
0490     val &= ~(SYNQUACER_HSSPI_DMPSEL_CS_MASK <<
0491          SYNQUACER_HSSPI_DMPSEL_CS_SHIFT);
0492     val |= spi->chip_select << SYNQUACER_HSSPI_DMPSEL_CS_SHIFT;
0493 
0494     if (!enable)
0495         val |= SYNQUACER_HSSPI_DMSTOP_STOP;
0496 
0497     writel(val, sspi->regs + SYNQUACER_HSSPI_REG_DMSTART);
0498 }
0499 
0500 static int synquacer_spi_wait_status_update(struct synquacer_spi *sspi,
0501                         bool enable)
0502 {
0503     u32 val;
0504     unsigned long timeout = jiffies +
0505         msecs_to_jiffies(SYNQUACER_HSSPI_ENABLE_TMOUT_MSEC);
0506 
0507     /* wait MES(Module Enable Status) is updated */
0508     do {
0509         val = readl(sspi->regs + SYNQUACER_HSSPI_REG_MCTRL) &
0510               SYNQUACER_HSSPI_MCTRL_MES;
0511         if (enable && val)
0512             return 0;
0513         if (!enable && !val)
0514             return 0;
0515     } while (time_before(jiffies, timeout));
0516 
0517     dev_err(sspi->dev, "timeout occurs in updating Module Enable Status\n");
0518     return -EBUSY;
0519 }
0520 
0521 static int synquacer_spi_enable(struct spi_master *master)
0522 {
0523     u32 val;
0524     int status;
0525     struct synquacer_spi *sspi = spi_master_get_devdata(master);
0526 
0527     /* Disable module */
0528     writel(0, sspi->regs + SYNQUACER_HSSPI_REG_MCTRL);
0529     status = synquacer_spi_wait_status_update(sspi, false);
0530     if (status < 0)
0531         return status;
0532 
0533     writel(0, sspi->regs + SYNQUACER_HSSPI_REG_TXE);
0534     writel(0, sspi->regs + SYNQUACER_HSSPI_REG_RXE);
0535     writel(~0, sspi->regs + SYNQUACER_HSSPI_REG_TXC);
0536     writel(~0, sspi->regs + SYNQUACER_HSSPI_REG_RXC);
0537     writel(~0, sspi->regs + SYNQUACER_HSSPI_REG_FAULTC);
0538 
0539     val = readl(sspi->regs + SYNQUACER_HSSPI_REG_DMCFG);
0540     val &= ~SYNQUACER_HSSPI_DMCFG_SSDC;
0541     val &= ~SYNQUACER_HSSPI_DMCFG_MSTARTEN;
0542     writel(val, sspi->regs + SYNQUACER_HSSPI_REG_DMCFG);
0543 
0544     val = readl(sspi->regs + SYNQUACER_HSSPI_REG_MCTRL);
0545     if (sspi->clk_src_type == SYNQUACER_HSSPI_CLOCK_SRC_IPCLK)
0546         val |= SYNQUACER_HSSPI_MCTRL_CDSS;
0547     else
0548         val &= ~SYNQUACER_HSSPI_MCTRL_CDSS;
0549 
0550     val &= ~SYNQUACER_HSSPI_MCTRL_COMMAND_SEQUENCE_EN;
0551     val |= SYNQUACER_HSSPI_MCTRL_MEN;
0552     val |= SYNQUACER_HSSPI_MCTRL_SYNCON;
0553 
0554     /* Enable module */
0555     writel(val, sspi->regs + SYNQUACER_HSSPI_REG_MCTRL);
0556     status = synquacer_spi_wait_status_update(sspi, true);
0557     if (status < 0)
0558         return status;
0559 
0560     return 0;
0561 }
0562 
0563 static irqreturn_t sq_spi_rx_handler(int irq, void *priv)
0564 {
0565     uint32_t val;
0566     struct synquacer_spi *sspi = priv;
0567 
0568     val = readl(sspi->regs + SYNQUACER_HSSPI_REG_RXF);
0569     if ((val & SYNQUACER_HSSPI_RXF_SLAVE_RELEASED) ||
0570         (val & SYNQUACER_HSSPI_RXF_FIFO_MORE_THAN_THRESHOLD)) {
0571         read_fifo(sspi);
0572 
0573         if (sspi->rx_words == 0) {
0574             writel(0, sspi->regs + SYNQUACER_HSSPI_REG_RXE);
0575             complete(&sspi->transfer_done);
0576         }
0577         return IRQ_HANDLED;
0578     }
0579 
0580     return IRQ_NONE;
0581 }
0582 
0583 static irqreturn_t sq_spi_tx_handler(int irq, void *priv)
0584 {
0585     uint32_t val;
0586     struct synquacer_spi *sspi = priv;
0587 
0588     val = readl(sspi->regs + SYNQUACER_HSSPI_REG_TXF);
0589     if (val & SYNQUACER_HSSPI_TXF_FIFO_EMPTY) {
0590         if (sspi->tx_words == 0) {
0591             writel(0, sspi->regs + SYNQUACER_HSSPI_REG_TXE);
0592             complete(&sspi->transfer_done);
0593         } else {
0594             write_fifo(sspi);
0595         }
0596         return IRQ_HANDLED;
0597     }
0598 
0599     return IRQ_NONE;
0600 }
0601 
0602 static int synquacer_spi_probe(struct platform_device *pdev)
0603 {
0604     struct device_node *np = pdev->dev.of_node;
0605     struct spi_master *master;
0606     struct synquacer_spi *sspi;
0607     int ret;
0608     int rx_irq, tx_irq;
0609 
0610     master = spi_alloc_master(&pdev->dev, sizeof(*sspi));
0611     if (!master)
0612         return -ENOMEM;
0613 
0614     platform_set_drvdata(pdev, master);
0615 
0616     sspi = spi_master_get_devdata(master);
0617     sspi->dev = &pdev->dev;
0618 
0619     init_completion(&sspi->transfer_done);
0620 
0621     sspi->regs = devm_platform_ioremap_resource(pdev, 0);
0622     if (IS_ERR(sspi->regs)) {
0623         ret = PTR_ERR(sspi->regs);
0624         goto put_spi;
0625     }
0626 
0627     sspi->clk_src_type = SYNQUACER_HSSPI_CLOCK_SRC_IHCLK; /* Default */
0628     device_property_read_u32(&pdev->dev, "socionext,ihclk-rate",
0629                  &master->max_speed_hz); /* for ACPI */
0630 
0631     if (dev_of_node(&pdev->dev)) {
0632         if (device_property_match_string(&pdev->dev,
0633                      "clock-names", "iHCLK") >= 0) {
0634             sspi->clk_src_type = SYNQUACER_HSSPI_CLOCK_SRC_IHCLK;
0635             sspi->clk = devm_clk_get(sspi->dev, "iHCLK");
0636         } else if (device_property_match_string(&pdev->dev,
0637                         "clock-names", "iPCLK") >= 0) {
0638             sspi->clk_src_type = SYNQUACER_HSSPI_CLOCK_SRC_IPCLK;
0639             sspi->clk = devm_clk_get(sspi->dev, "iPCLK");
0640         } else {
0641             dev_err(&pdev->dev, "specified wrong clock source\n");
0642             ret = -EINVAL;
0643             goto put_spi;
0644         }
0645 
0646         if (IS_ERR(sspi->clk)) {
0647             ret = dev_err_probe(&pdev->dev, PTR_ERR(sspi->clk),
0648                         "clock not found\n");
0649             goto put_spi;
0650         }
0651 
0652         ret = clk_prepare_enable(sspi->clk);
0653         if (ret) {
0654             dev_err(&pdev->dev, "failed to enable clock (%d)\n",
0655                 ret);
0656             goto put_spi;
0657         }
0658 
0659         master->max_speed_hz = clk_get_rate(sspi->clk);
0660     }
0661 
0662     if (!master->max_speed_hz) {
0663         dev_err(&pdev->dev, "missing clock source\n");
0664         ret = -EINVAL;
0665         goto disable_clk;
0666     }
0667     master->min_speed_hz = master->max_speed_hz / 254;
0668 
0669     sspi->aces = device_property_read_bool(&pdev->dev,
0670                            "socionext,set-aces");
0671     sspi->rtm = device_property_read_bool(&pdev->dev, "socionext,use-rtm");
0672 
0673     master->num_chipselect = SYNQUACER_HSSPI_NUM_CHIP_SELECT;
0674 
0675     rx_irq = platform_get_irq(pdev, 0);
0676     if (rx_irq <= 0) {
0677         ret = rx_irq;
0678         goto disable_clk;
0679     }
0680     snprintf(sspi->rx_irq_name, SYNQUACER_HSSPI_IRQ_NAME_MAX, "%s-rx",
0681          dev_name(&pdev->dev));
0682     ret = devm_request_irq(&pdev->dev, rx_irq, sq_spi_rx_handler,
0683                 0, sspi->rx_irq_name, sspi);
0684     if (ret) {
0685         dev_err(&pdev->dev, "request rx_irq failed (%d)\n", ret);
0686         goto disable_clk;
0687     }
0688 
0689     tx_irq = platform_get_irq(pdev, 1);
0690     if (tx_irq <= 0) {
0691         ret = tx_irq;
0692         goto disable_clk;
0693     }
0694     snprintf(sspi->tx_irq_name, SYNQUACER_HSSPI_IRQ_NAME_MAX, "%s-tx",
0695          dev_name(&pdev->dev));
0696     ret = devm_request_irq(&pdev->dev, tx_irq, sq_spi_tx_handler,
0697                 0, sspi->tx_irq_name, sspi);
0698     if (ret) {
0699         dev_err(&pdev->dev, "request tx_irq failed (%d)\n", ret);
0700         goto disable_clk;
0701     }
0702 
0703     master->dev.of_node = np;
0704     master->dev.fwnode = pdev->dev.fwnode;
0705     master->auto_runtime_pm = true;
0706     master->bus_num = pdev->id;
0707 
0708     master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_TX_DUAL | SPI_RX_DUAL |
0709                 SPI_TX_QUAD | SPI_RX_QUAD;
0710     master->bits_per_word_mask = SPI_BPW_MASK(32) | SPI_BPW_MASK(24) |
0711                      SPI_BPW_MASK(16) | SPI_BPW_MASK(8);
0712 
0713     master->set_cs = synquacer_spi_set_cs;
0714     master->transfer_one = synquacer_spi_transfer_one;
0715 
0716     ret = synquacer_spi_enable(master);
0717     if (ret)
0718         goto disable_clk;
0719 
0720     pm_runtime_set_active(sspi->dev);
0721     pm_runtime_enable(sspi->dev);
0722 
0723     ret = devm_spi_register_master(sspi->dev, master);
0724     if (ret)
0725         goto disable_pm;
0726 
0727     return 0;
0728 
0729 disable_pm:
0730     pm_runtime_disable(sspi->dev);
0731 disable_clk:
0732     clk_disable_unprepare(sspi->clk);
0733 put_spi:
0734     spi_master_put(master);
0735 
0736     return ret;
0737 }
0738 
0739 static int synquacer_spi_remove(struct platform_device *pdev)
0740 {
0741     struct spi_master *master = platform_get_drvdata(pdev);
0742     struct synquacer_spi *sspi = spi_master_get_devdata(master);
0743 
0744     pm_runtime_disable(sspi->dev);
0745 
0746     clk_disable_unprepare(sspi->clk);
0747 
0748     return 0;
0749 }
0750 
0751 static int __maybe_unused synquacer_spi_suspend(struct device *dev)
0752 {
0753     struct spi_master *master = dev_get_drvdata(dev);
0754     struct synquacer_spi *sspi = spi_master_get_devdata(master);
0755     int ret;
0756 
0757     ret = spi_master_suspend(master);
0758     if (ret)
0759         return ret;
0760 
0761     if (!pm_runtime_suspended(dev))
0762         clk_disable_unprepare(sspi->clk);
0763 
0764     return ret;
0765 }
0766 
0767 static int __maybe_unused synquacer_spi_resume(struct device *dev)
0768 {
0769     struct spi_master *master = dev_get_drvdata(dev);
0770     struct synquacer_spi *sspi = spi_master_get_devdata(master);
0771     int ret;
0772 
0773     if (!pm_runtime_suspended(dev)) {
0774         /* Ensure reconfigure during next xfer */
0775         sspi->speed = 0;
0776 
0777         ret = clk_prepare_enable(sspi->clk);
0778         if (ret < 0) {
0779             dev_err(dev, "failed to enable clk (%d)\n",
0780                 ret);
0781             return ret;
0782         }
0783 
0784         ret = synquacer_spi_enable(master);
0785         if (ret) {
0786             clk_disable_unprepare(sspi->clk);
0787             dev_err(dev, "failed to enable spi (%d)\n", ret);
0788             return ret;
0789         }
0790     }
0791 
0792     ret = spi_master_resume(master);
0793     if (ret < 0)
0794         clk_disable_unprepare(sspi->clk);
0795 
0796     return ret;
0797 }
0798 
0799 static SIMPLE_DEV_PM_OPS(synquacer_spi_pm_ops, synquacer_spi_suspend,
0800              synquacer_spi_resume);
0801 
0802 static const struct of_device_id synquacer_spi_of_match[] = {
0803     {.compatible = "socionext,synquacer-spi"},
0804     {}
0805 };
0806 MODULE_DEVICE_TABLE(of, synquacer_spi_of_match);
0807 
0808 #ifdef CONFIG_ACPI
0809 static const struct acpi_device_id synquacer_hsspi_acpi_ids[] = {
0810     { "SCX0004" },
0811     { /* sentinel */ }
0812 };
0813 MODULE_DEVICE_TABLE(acpi, synquacer_hsspi_acpi_ids);
0814 #endif
0815 
0816 static struct platform_driver synquacer_spi_driver = {
0817     .driver = {
0818         .name = "synquacer-spi",
0819         .pm = &synquacer_spi_pm_ops,
0820         .of_match_table = synquacer_spi_of_match,
0821         .acpi_match_table = ACPI_PTR(synquacer_hsspi_acpi_ids),
0822     },
0823     .probe = synquacer_spi_probe,
0824     .remove = synquacer_spi_remove,
0825 };
0826 module_platform_driver(synquacer_spi_driver);
0827 
0828 MODULE_DESCRIPTION("Socionext Synquacer HS-SPI controller driver");
0829 MODULE_AUTHOR("Masahisa Kojima <masahisa.kojima@linaro.org>");
0830 MODULE_AUTHOR("Jassi Brar <jaswinder.singh@linaro.org>");
0831 MODULE_LICENSE("GPL v2");