450 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Copyright (C) 2003-2015 Broadcom Corporation4 * All Rights Reserved5 */6#include <linux/acpi.h>7#include <linux/clk.h>8#include <linux/kernel.h>9#include <linux/module.h>10#include <linux/platform_device.h>11#include <linux/spi/spi.h>12#include <linux/interrupt.h>13 14/* SPI Configuration Register */15#define XLP_SPI_CONFIG 0x0016#define XLP_SPI_CPHA BIT(0)17#define XLP_SPI_CPOL BIT(1)18#define XLP_SPI_CS_POL BIT(2)19#define XLP_SPI_TXMISO_EN BIT(3)20#define XLP_SPI_TXMOSI_EN BIT(4)21#define XLP_SPI_RXMISO_EN BIT(5)22#define XLP_SPI_CS_LSBFE BIT(10)23#define XLP_SPI_RXCAP_EN BIT(11)24 25/* SPI Frequency Divider Register */26#define XLP_SPI_FDIV 0x0427 28/* SPI Command Register */29#define XLP_SPI_CMD 0x0830#define XLP_SPI_CMD_IDLE_MASK 0x031#define XLP_SPI_CMD_TX_MASK 0x132#define XLP_SPI_CMD_RX_MASK 0x233#define XLP_SPI_CMD_TXRX_MASK 0x334#define XLP_SPI_CMD_CONT BIT(4)35#define XLP_SPI_XFR_BITCNT_SHIFT 1636 37/* SPI Status Register */38#define XLP_SPI_STATUS 0x0c39#define XLP_SPI_XFR_PENDING BIT(0)40#define XLP_SPI_XFR_DONE BIT(1)41#define XLP_SPI_TX_INT BIT(2)42#define XLP_SPI_RX_INT BIT(3)43#define XLP_SPI_TX_UF BIT(4)44#define XLP_SPI_RX_OF BIT(5)45#define XLP_SPI_STAT_MASK 0x3f46 47/* SPI Interrupt Enable Register */48#define XLP_SPI_INTR_EN 0x1049#define XLP_SPI_INTR_DONE BIT(0)50#define XLP_SPI_INTR_TXTH BIT(1)51#define XLP_SPI_INTR_RXTH BIT(2)52#define XLP_SPI_INTR_TXUF BIT(3)53#define XLP_SPI_INTR_RXOF BIT(4)54 55/* SPI FIFO Threshold Register */56#define XLP_SPI_FIFO_THRESH 0x1457 58/* SPI FIFO Word Count Register */59#define XLP_SPI_FIFO_WCNT 0x1860#define XLP_SPI_RXFIFO_WCNT_MASK 0xf61#define XLP_SPI_TXFIFO_WCNT_MASK 0xf062#define XLP_SPI_TXFIFO_WCNT_SHIFT 463 64/* SPI Transmit Data FIFO Register */65#define XLP_SPI_TXDATA_FIFO 0x1c66 67/* SPI Receive Data FIFO Register */68#define XLP_SPI_RXDATA_FIFO 0x2069 70/* SPI System Control Register */71#define XLP_SPI_SYSCTRL 0x10072#define XLP_SPI_SYS_RESET BIT(0)73#define XLP_SPI_SYS_CLKDIS BIT(1)74#define XLP_SPI_SYS_PMEN BIT(8)75 76#define SPI_CS_OFFSET 0x4077#define XLP_SPI_TXRXTH 0x8078#define XLP_SPI_FIFO_SIZE 879#define XLP_SPI_MAX_CS 480#define XLP_SPI_DEFAULT_FREQ 13333333381#define XLP_SPI_FDIV_MIN 482#define XLP_SPI_FDIV_MAX 6553583/*84 * SPI can transfer only 28 bytes properly at a time. So split the85 * transfer into 28 bytes size.86 */87#define XLP_SPI_XFER_SIZE 2888 89struct xlp_spi_priv {90 struct device dev; /* device structure */91 void __iomem *base; /* spi registers base address */92 const u8 *tx_buf; /* tx data buffer */93 u8 *rx_buf; /* rx data buffer */94 int tx_len; /* tx xfer length */95 int rx_len; /* rx xfer length */96 int txerrors; /* TXFIFO underflow count */97 int rxerrors; /* RXFIFO overflow count */98 int cs; /* target device chip select */99 u32 spi_clk; /* spi clock frequency */100 bool cmd_cont; /* cs active */101 struct completion done; /* completion notification */102};103 104static inline u32 xlp_spi_reg_read(struct xlp_spi_priv *priv,105 int cs, int regoff)106{107 return readl(priv->base + regoff + cs * SPI_CS_OFFSET);108}109 110static inline void xlp_spi_reg_write(struct xlp_spi_priv *priv, int cs,111 int regoff, u32 val)112{113 writel(val, priv->base + regoff + cs * SPI_CS_OFFSET);114}115 116static inline void xlp_spi_sysctl_write(struct xlp_spi_priv *priv,117 int regoff, u32 val)118{119 writel(val, priv->base + regoff);120}121 122/*123 * Setup global SPI_SYSCTRL register for all SPI channels.124 */125static void xlp_spi_sysctl_setup(struct xlp_spi_priv *xspi)126{127 int cs;128 129 for (cs = 0; cs < XLP_SPI_MAX_CS; cs++)130 xlp_spi_sysctl_write(xspi, XLP_SPI_SYSCTRL,131 XLP_SPI_SYS_RESET << cs);132 xlp_spi_sysctl_write(xspi, XLP_SPI_SYSCTRL, XLP_SPI_SYS_PMEN);133}134 135static int xlp_spi_setup(struct spi_device *spi)136{137 struct xlp_spi_priv *xspi;138 u32 fdiv, cfg;139 int cs;140 141 xspi = spi_controller_get_devdata(spi->controller);142 cs = spi_get_chipselect(spi, 0);143 /*144 * The value of fdiv must be between 4 and 65535.145 */146 fdiv = DIV_ROUND_UP(xspi->spi_clk, spi->max_speed_hz);147 if (fdiv > XLP_SPI_FDIV_MAX)148 fdiv = XLP_SPI_FDIV_MAX;149 else if (fdiv < XLP_SPI_FDIV_MIN)150 fdiv = XLP_SPI_FDIV_MIN;151 152 xlp_spi_reg_write(xspi, cs, XLP_SPI_FDIV, fdiv);153 xlp_spi_reg_write(xspi, cs, XLP_SPI_FIFO_THRESH, XLP_SPI_TXRXTH);154 cfg = xlp_spi_reg_read(xspi, cs, XLP_SPI_CONFIG);155 if (spi->mode & SPI_CPHA)156 cfg |= XLP_SPI_CPHA;157 else158 cfg &= ~XLP_SPI_CPHA;159 if (spi->mode & SPI_CPOL)160 cfg |= XLP_SPI_CPOL;161 else162 cfg &= ~XLP_SPI_CPOL;163 if (!(spi->mode & SPI_CS_HIGH))164 cfg |= XLP_SPI_CS_POL;165 else166 cfg &= ~XLP_SPI_CS_POL;167 if (spi->mode & SPI_LSB_FIRST)168 cfg |= XLP_SPI_CS_LSBFE;169 else170 cfg &= ~XLP_SPI_CS_LSBFE;171 172 cfg |= XLP_SPI_TXMOSI_EN | XLP_SPI_RXMISO_EN;173 if (fdiv == 4)174 cfg |= XLP_SPI_RXCAP_EN;175 xlp_spi_reg_write(xspi, cs, XLP_SPI_CONFIG, cfg);176 177 return 0;178}179 180static void xlp_spi_read_rxfifo(struct xlp_spi_priv *xspi)181{182 u32 rx_data, rxfifo_cnt;183 int i, j, nbytes;184 185 rxfifo_cnt = xlp_spi_reg_read(xspi, xspi->cs, XLP_SPI_FIFO_WCNT);186 rxfifo_cnt &= XLP_SPI_RXFIFO_WCNT_MASK;187 while (rxfifo_cnt) {188 rx_data = xlp_spi_reg_read(xspi, xspi->cs, XLP_SPI_RXDATA_FIFO);189 j = 0;190 nbytes = min(xspi->rx_len, 4);191 for (i = nbytes - 1; i >= 0; i--, j++)192 xspi->rx_buf[i] = (rx_data >> (j * 8)) & 0xff;193 194 xspi->rx_len -= nbytes;195 xspi->rx_buf += nbytes;196 rxfifo_cnt--;197 }198}199 200static void xlp_spi_fill_txfifo(struct xlp_spi_priv *xspi)201{202 u32 tx_data, txfifo_cnt;203 int i, j, nbytes;204 205 txfifo_cnt = xlp_spi_reg_read(xspi, xspi->cs, XLP_SPI_FIFO_WCNT);206 txfifo_cnt &= XLP_SPI_TXFIFO_WCNT_MASK;207 txfifo_cnt >>= XLP_SPI_TXFIFO_WCNT_SHIFT;208 while (xspi->tx_len && (txfifo_cnt < XLP_SPI_FIFO_SIZE)) {209 j = 0;210 tx_data = 0;211 nbytes = min(xspi->tx_len, 4);212 for (i = nbytes - 1; i >= 0; i--, j++)213 tx_data |= xspi->tx_buf[i] << (j * 8);214 215 xlp_spi_reg_write(xspi, xspi->cs, XLP_SPI_TXDATA_FIFO, tx_data);216 xspi->tx_len -= nbytes;217 xspi->tx_buf += nbytes;218 txfifo_cnt++;219 }220}221 222static irqreturn_t xlp_spi_interrupt(int irq, void *dev_id)223{224 struct xlp_spi_priv *xspi = dev_id;225 u32 stat;226 227 stat = xlp_spi_reg_read(xspi, xspi->cs, XLP_SPI_STATUS) &228 XLP_SPI_STAT_MASK;229 if (!stat)230 return IRQ_NONE;231 232 if (stat & XLP_SPI_TX_INT) {233 if (xspi->tx_len)234 xlp_spi_fill_txfifo(xspi);235 if (stat & XLP_SPI_TX_UF)236 xspi->txerrors++;237 }238 239 if (stat & XLP_SPI_RX_INT) {240 if (xspi->rx_len)241 xlp_spi_read_rxfifo(xspi);242 if (stat & XLP_SPI_RX_OF)243 xspi->rxerrors++;244 }245 246 /* write status back to clear interrupts */247 xlp_spi_reg_write(xspi, xspi->cs, XLP_SPI_STATUS, stat);248 if (stat & XLP_SPI_XFR_DONE)249 complete(&xspi->done);250 251 return IRQ_HANDLED;252}253 254static void xlp_spi_send_cmd(struct xlp_spi_priv *xspi, int xfer_len,255 int cmd_cont)256{257 u32 cmd = 0;258 259 if (xspi->tx_buf)260 cmd |= XLP_SPI_CMD_TX_MASK;261 if (xspi->rx_buf)262 cmd |= XLP_SPI_CMD_RX_MASK;263 if (cmd_cont)264 cmd |= XLP_SPI_CMD_CONT;265 cmd |= ((xfer_len * 8 - 1) << XLP_SPI_XFR_BITCNT_SHIFT);266 xlp_spi_reg_write(xspi, xspi->cs, XLP_SPI_CMD, cmd);267}268 269static int xlp_spi_xfer_block(struct xlp_spi_priv *xs,270 const unsigned char *tx_buf,271 unsigned char *rx_buf, int xfer_len, int cmd_cont)272{273 unsigned long time_left;274 u32 intr_mask = 0;275 276 xs->tx_buf = tx_buf;277 xs->rx_buf = rx_buf;278 xs->tx_len = (xs->tx_buf == NULL) ? 0 : xfer_len;279 xs->rx_len = (xs->rx_buf == NULL) ? 0 : xfer_len;280 xs->txerrors = xs->rxerrors = 0;281 282 /* fill TXDATA_FIFO, then send the CMD */283 if (xs->tx_len)284 xlp_spi_fill_txfifo(xs);285 286 xlp_spi_send_cmd(xs, xfer_len, cmd_cont);287 288 /*289 * We are getting some spurious tx interrupts, so avoid enabling290 * tx interrupts when only rx is in process.291 * Enable all the interrupts in tx case.292 */293 if (xs->tx_len)294 intr_mask |= XLP_SPI_INTR_TXTH | XLP_SPI_INTR_TXUF |295 XLP_SPI_INTR_RXTH | XLP_SPI_INTR_RXOF;296 else297 intr_mask |= XLP_SPI_INTR_RXTH | XLP_SPI_INTR_RXOF;298 299 intr_mask |= XLP_SPI_INTR_DONE;300 xlp_spi_reg_write(xs, xs->cs, XLP_SPI_INTR_EN, intr_mask);301 302 time_left = wait_for_completion_timeout(&xs->done,303 msecs_to_jiffies(1000));304 /* Disable interrupts */305 xlp_spi_reg_write(xs, xs->cs, XLP_SPI_INTR_EN, 0x0);306 if (!time_left) {307 dev_err(&xs->dev, "xfer timedout!\n");308 goto out;309 }310 if (xs->txerrors || xs->rxerrors)311 dev_err(&xs->dev, "Over/Underflow rx %d tx %d xfer %d!\n",312 xs->rxerrors, xs->txerrors, xfer_len);313 314 return xfer_len;315out:316 return -ETIMEDOUT;317}318 319static int xlp_spi_txrx_bufs(struct xlp_spi_priv *xs, struct spi_transfer *t)320{321 int bytesleft, sz;322 unsigned char *rx_buf;323 const unsigned char *tx_buf;324 325 tx_buf = t->tx_buf;326 rx_buf = t->rx_buf;327 bytesleft = t->len;328 while (bytesleft) {329 if (bytesleft > XLP_SPI_XFER_SIZE)330 sz = xlp_spi_xfer_block(xs, tx_buf, rx_buf,331 XLP_SPI_XFER_SIZE, 1);332 else333 sz = xlp_spi_xfer_block(xs, tx_buf, rx_buf,334 bytesleft, xs->cmd_cont);335 if (sz < 0)336 return sz;337 bytesleft -= sz;338 if (tx_buf)339 tx_buf += sz;340 if (rx_buf)341 rx_buf += sz;342 }343 return bytesleft;344}345 346static int xlp_spi_transfer_one(struct spi_controller *host,347 struct spi_device *spi,348 struct spi_transfer *t)349{350 struct xlp_spi_priv *xspi = spi_controller_get_devdata(host);351 int ret = 0;352 353 xspi->cs = spi_get_chipselect(spi, 0);354 xspi->dev = spi->dev;355 356 if (spi_transfer_is_last(host, t))357 xspi->cmd_cont = 0;358 else359 xspi->cmd_cont = 1;360 361 if (xlp_spi_txrx_bufs(xspi, t))362 ret = -EIO;363 364 spi_finalize_current_transfer(host);365 return ret;366}367 368static int xlp_spi_probe(struct platform_device *pdev)369{370 struct spi_controller *host;371 struct xlp_spi_priv *xspi;372 struct clk *clk;373 int irq, err;374 375 xspi = devm_kzalloc(&pdev->dev, sizeof(*xspi), GFP_KERNEL);376 if (!xspi)377 return -ENOMEM;378 379 xspi->base = devm_platform_ioremap_resource(pdev, 0);380 if (IS_ERR(xspi->base))381 return PTR_ERR(xspi->base);382 383 irq = platform_get_irq(pdev, 0);384 if (irq < 0)385 return irq;386 err = devm_request_irq(&pdev->dev, irq, xlp_spi_interrupt, 0,387 pdev->name, xspi);388 if (err) {389 dev_err(&pdev->dev, "unable to request irq %d\n", irq);390 return err;391 }392 393 clk = devm_clk_get(&pdev->dev, NULL);394 if (IS_ERR(clk)) {395 dev_err(&pdev->dev, "could not get spi clock\n");396 return PTR_ERR(clk);397 }398 399 xspi->spi_clk = clk_get_rate(clk);400 401 host = spi_alloc_host(&pdev->dev, 0);402 if (!host) {403 dev_err(&pdev->dev, "could not alloc host\n");404 return -ENOMEM;405 }406 407 host->bus_num = 0;408 host->num_chipselect = XLP_SPI_MAX_CS;409 host->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;410 host->setup = xlp_spi_setup;411 host->transfer_one = xlp_spi_transfer_one;412 host->dev.of_node = pdev->dev.of_node;413 414 init_completion(&xspi->done);415 spi_controller_set_devdata(host, xspi);416 xlp_spi_sysctl_setup(xspi);417 418 /* register spi controller */419 err = devm_spi_register_controller(&pdev->dev, host);420 if (err) {421 dev_err(&pdev->dev, "spi register host failed!\n");422 spi_controller_put(host);423 return err;424 }425 426 return 0;427}428 429#ifdef CONFIG_ACPI430static const struct acpi_device_id xlp_spi_acpi_match[] = {431 { "BRCM900D", 0 },432 { "CAV900D", 0 },433 { },434};435MODULE_DEVICE_TABLE(acpi, xlp_spi_acpi_match);436#endif437 438static struct platform_driver xlp_spi_driver = {439 .probe = xlp_spi_probe,440 .driver = {441 .name = "xlp-spi",442 .acpi_match_table = ACPI_PTR(xlp_spi_acpi_match),443 },444};445module_platform_driver(xlp_spi_driver);446 447MODULE_AUTHOR("Kamlakant Patel <kamlakant.patel@broadcom.com>");448MODULE_DESCRIPTION("Netlogic XLP SPI controller driver");449MODULE_LICENSE("GPL v2");450