root/drivers/spi/spi-uniphier.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. bytes_per_word
  2. uniphier_spi_irq_enable
  3. uniphier_spi_irq_disable
  4. uniphier_spi_set_mode
  5. uniphier_spi_set_transfer_size
  6. uniphier_spi_set_baudrate
  7. uniphier_spi_setup_transfer
  8. uniphier_spi_send
  9. uniphier_spi_recv
  10. uniphier_spi_set_fifo_threshold
  11. uniphier_spi_fill_tx_fifo
  12. uniphier_spi_set_cs
  13. uniphier_spi_transfer_one_irq
  14. uniphier_spi_transfer_one_poll
  15. uniphier_spi_transfer_one
  16. uniphier_spi_prepare_transfer_hardware
  17. uniphier_spi_unprepare_transfer_hardware
  18. uniphier_spi_handler
  19. uniphier_spi_probe
  20. uniphier_spi_remove

   1 // SPDX-License-Identifier: GPL-2.0
   2 // spi-uniphier.c - Socionext UniPhier SPI controller driver
   3 // Copyright 2012      Panasonic Corporation
   4 // Copyright 2016-2018 Socionext Inc.
   5 
   6 #include <linux/kernel.h>
   7 #include <linux/bitfield.h>
   8 #include <linux/bitops.h>
   9 #include <linux/clk.h>
  10 #include <linux/delay.h>
  11 #include <linux/interrupt.h>
  12 #include <linux/io.h>
  13 #include <linux/module.h>
  14 #include <linux/platform_device.h>
  15 #include <linux/spi/spi.h>
  16 
  17 #include <asm/unaligned.h>
  18 
  19 #define SSI_TIMEOUT_MS          2000
  20 #define SSI_POLL_TIMEOUT_US     200
  21 #define SSI_MAX_CLK_DIVIDER     254
  22 #define SSI_MIN_CLK_DIVIDER     4
  23 
  24 struct uniphier_spi_priv {
  25         void __iomem *base;
  26         struct clk *clk;
  27         struct spi_master *master;
  28         struct completion xfer_done;
  29 
  30         int error;
  31         unsigned int tx_bytes;
  32         unsigned int rx_bytes;
  33         const u8 *tx_buf;
  34         u8 *rx_buf;
  35 
  36         bool is_save_param;
  37         u8 bits_per_word;
  38         u16 mode;
  39         u32 speed_hz;
  40 };
  41 
  42 #define SSI_CTL                 0x00
  43 #define   SSI_CTL_EN            BIT(0)
  44 
  45 #define SSI_CKS                 0x04
  46 #define   SSI_CKS_CKRAT_MASK    GENMASK(7, 0)
  47 #define   SSI_CKS_CKPHS         BIT(14)
  48 #define   SSI_CKS_CKINIT        BIT(13)
  49 #define   SSI_CKS_CKDLY         BIT(12)
  50 
  51 #define SSI_TXWDS               0x08
  52 #define   SSI_TXWDS_WDLEN_MASK  GENMASK(13, 8)
  53 #define   SSI_TXWDS_TDTF_MASK   GENMASK(7, 6)
  54 #define   SSI_TXWDS_DTLEN_MASK  GENMASK(5, 0)
  55 
  56 #define SSI_RXWDS               0x0c
  57 #define   SSI_RXWDS_DTLEN_MASK  GENMASK(5, 0)
  58 
  59 #define SSI_FPS                 0x10
  60 #define   SSI_FPS_FSPOL         BIT(15)
  61 #define   SSI_FPS_FSTRT         BIT(14)
  62 
  63 #define SSI_SR                  0x14
  64 #define   SSI_SR_RNE            BIT(0)
  65 
  66 #define SSI_IE                  0x18
  67 #define   SSI_IE_RCIE           BIT(3)
  68 #define   SSI_IE_RORIE          BIT(0)
  69 
  70 #define SSI_IS                  0x1c
  71 #define   SSI_IS_RXRS           BIT(9)
  72 #define   SSI_IS_RCID           BIT(3)
  73 #define   SSI_IS_RORID          BIT(0)
  74 
  75 #define SSI_IC                  0x1c
  76 #define   SSI_IC_TCIC           BIT(4)
  77 #define   SSI_IC_RCIC           BIT(3)
  78 #define   SSI_IC_RORIC          BIT(0)
  79 
  80 #define SSI_FC                  0x20
  81 #define   SSI_FC_TXFFL          BIT(12)
  82 #define   SSI_FC_TXFTH_MASK     GENMASK(11, 8)
  83 #define   SSI_FC_RXFFL          BIT(4)
  84 #define   SSI_FC_RXFTH_MASK     GENMASK(3, 0)
  85 
  86 #define SSI_TXDR                0x24
  87 #define SSI_RXDR                0x24
  88 
  89 #define SSI_FIFO_DEPTH          8U
  90 
  91 static inline unsigned int bytes_per_word(unsigned int bits)
  92 {
  93         return bits <= 8 ? 1 : (bits <= 16 ? 2 : 4);
  94 }
  95 
  96 static inline void uniphier_spi_irq_enable(struct spi_device *spi, u32 mask)
  97 {
  98         struct uniphier_spi_priv *priv = spi_master_get_devdata(spi->master);
  99         u32 val;
 100 
 101         val = readl(priv->base + SSI_IE);
 102         val |= mask;
 103         writel(val, priv->base + SSI_IE);
 104 }
 105 
 106 static inline void uniphier_spi_irq_disable(struct spi_device *spi, u32 mask)
 107 {
 108         struct uniphier_spi_priv *priv = spi_master_get_devdata(spi->master);
 109         u32 val;
 110 
 111         val = readl(priv->base + SSI_IE);
 112         val &= ~mask;
 113         writel(val, priv->base + SSI_IE);
 114 }
 115 
 116 static void uniphier_spi_set_mode(struct spi_device *spi)
 117 {
 118         struct uniphier_spi_priv *priv = spi_master_get_devdata(spi->master);
 119         u32 val1, val2;
 120 
 121         /*
 122          * clock setting
 123          * CKPHS    capture timing. 0:rising edge, 1:falling edge
 124          * CKINIT   clock initial level. 0:low, 1:high
 125          * CKDLY    clock delay. 0:no delay, 1:delay depending on FSTRT
 126          *          (FSTRT=0: 1 clock, FSTRT=1: 0.5 clock)
 127          *
 128          * frame setting
 129          * FSPOL    frame signal porarity. 0: low, 1: high
 130          * FSTRT    start frame timing
 131          *          0: rising edge of clock, 1: falling edge of clock
 132          */
 133         switch (spi->mode & (SPI_CPOL | SPI_CPHA)) {
 134         case SPI_MODE_0:
 135                 /* CKPHS=1, CKINIT=0, CKDLY=1, FSTRT=0 */
 136                 val1 = SSI_CKS_CKPHS | SSI_CKS_CKDLY;
 137                 val2 = 0;
 138                 break;
 139         case SPI_MODE_1:
 140                 /* CKPHS=0, CKINIT=0, CKDLY=0, FSTRT=1 */
 141                 val1 = 0;
 142                 val2 = SSI_FPS_FSTRT;
 143                 break;
 144         case SPI_MODE_2:
 145                 /* CKPHS=0, CKINIT=1, CKDLY=1, FSTRT=1 */
 146                 val1 = SSI_CKS_CKINIT | SSI_CKS_CKDLY;
 147                 val2 = SSI_FPS_FSTRT;
 148                 break;
 149         case SPI_MODE_3:
 150                 /* CKPHS=1, CKINIT=1, CKDLY=0, FSTRT=0 */
 151                 val1 = SSI_CKS_CKPHS | SSI_CKS_CKINIT;
 152                 val2 = 0;
 153                 break;
 154         }
 155 
 156         if (!(spi->mode & SPI_CS_HIGH))
 157                 val2 |= SSI_FPS_FSPOL;
 158 
 159         writel(val1, priv->base + SSI_CKS);
 160         writel(val2, priv->base + SSI_FPS);
 161 
 162         val1 = 0;
 163         if (spi->mode & SPI_LSB_FIRST)
 164                 val1 |= FIELD_PREP(SSI_TXWDS_TDTF_MASK, 1);
 165         writel(val1, priv->base + SSI_TXWDS);
 166         writel(val1, priv->base + SSI_RXWDS);
 167 }
 168 
 169 static void uniphier_spi_set_transfer_size(struct spi_device *spi, int size)
 170 {
 171         struct uniphier_spi_priv *priv = spi_master_get_devdata(spi->master);
 172         u32 val;
 173 
 174         val = readl(priv->base + SSI_TXWDS);
 175         val &= ~(SSI_TXWDS_WDLEN_MASK | SSI_TXWDS_DTLEN_MASK);
 176         val |= FIELD_PREP(SSI_TXWDS_WDLEN_MASK, size);
 177         val |= FIELD_PREP(SSI_TXWDS_DTLEN_MASK, size);
 178         writel(val, priv->base + SSI_TXWDS);
 179 
 180         val = readl(priv->base + SSI_RXWDS);
 181         val &= ~SSI_RXWDS_DTLEN_MASK;
 182         val |= FIELD_PREP(SSI_RXWDS_DTLEN_MASK, size);
 183         writel(val, priv->base + SSI_RXWDS);
 184 }
 185 
 186 static void uniphier_spi_set_baudrate(struct spi_device *spi,
 187                                       unsigned int speed)
 188 {
 189         struct uniphier_spi_priv *priv = spi_master_get_devdata(spi->master);
 190         u32 val, ckdiv;
 191 
 192         /*
 193          * the supported rates are even numbers from 4 to 254. (4,6,8...254)
 194          * round up as we look for equal or less speed
 195          */
 196         ckdiv = DIV_ROUND_UP(clk_get_rate(priv->clk), speed);
 197         ckdiv = round_up(ckdiv, 2);
 198 
 199         val = readl(priv->base + SSI_CKS);
 200         val &= ~SSI_CKS_CKRAT_MASK;
 201         val |= ckdiv & SSI_CKS_CKRAT_MASK;
 202         writel(val, priv->base + SSI_CKS);
 203 }
 204 
 205 static void uniphier_spi_setup_transfer(struct spi_device *spi,
 206                                        struct spi_transfer *t)
 207 {
 208         struct uniphier_spi_priv *priv = spi_master_get_devdata(spi->master);
 209         u32 val;
 210 
 211         priv->error = 0;
 212         priv->tx_buf = t->tx_buf;
 213         priv->rx_buf = t->rx_buf;
 214         priv->tx_bytes = priv->rx_bytes = t->len;
 215 
 216         if (!priv->is_save_param || priv->mode != spi->mode) {
 217                 uniphier_spi_set_mode(spi);
 218                 priv->mode = spi->mode;
 219                 priv->is_save_param = false;
 220         }
 221 
 222         if (!priv->is_save_param || priv->bits_per_word != t->bits_per_word) {
 223                 uniphier_spi_set_transfer_size(spi, t->bits_per_word);
 224                 priv->bits_per_word = t->bits_per_word;
 225         }
 226 
 227         if (!priv->is_save_param || priv->speed_hz != t->speed_hz) {
 228                 uniphier_spi_set_baudrate(spi, t->speed_hz);
 229                 priv->speed_hz = t->speed_hz;
 230         }
 231 
 232         priv->is_save_param = true;
 233 
 234         /* reset FIFOs */
 235         val = SSI_FC_TXFFL | SSI_FC_RXFFL;
 236         writel(val, priv->base + SSI_FC);
 237 }
 238 
 239 static void uniphier_spi_send(struct uniphier_spi_priv *priv)
 240 {
 241         int wsize;
 242         u32 val = 0;
 243 
 244         wsize = min(bytes_per_word(priv->bits_per_word), priv->tx_bytes);
 245         priv->tx_bytes -= wsize;
 246 
 247         if (priv->tx_buf) {
 248                 switch (wsize) {
 249                 case 1:
 250                         val = *priv->tx_buf;
 251                         break;
 252                 case 2:
 253                         val = get_unaligned_le16(priv->tx_buf);
 254                         break;
 255                 case 4:
 256                         val = get_unaligned_le32(priv->tx_buf);
 257                         break;
 258                 }
 259 
 260                 priv->tx_buf += wsize;
 261         }
 262 
 263         writel(val, priv->base + SSI_TXDR);
 264 }
 265 
 266 static void uniphier_spi_recv(struct uniphier_spi_priv *priv)
 267 {
 268         int rsize;
 269         u32 val;
 270 
 271         rsize = min(bytes_per_word(priv->bits_per_word), priv->rx_bytes);
 272         priv->rx_bytes -= rsize;
 273 
 274         val = readl(priv->base + SSI_RXDR);
 275 
 276         if (priv->rx_buf) {
 277                 switch (rsize) {
 278                 case 1:
 279                         *priv->rx_buf = val;
 280                         break;
 281                 case 2:
 282                         put_unaligned_le16(val, priv->rx_buf);
 283                         break;
 284                 case 4:
 285                         put_unaligned_le32(val, priv->rx_buf);
 286                         break;
 287                 }
 288 
 289                 priv->rx_buf += rsize;
 290         }
 291 }
 292 
 293 static void uniphier_spi_set_fifo_threshold(struct uniphier_spi_priv *priv,
 294                                             unsigned int threshold)
 295 {
 296         u32 val;
 297 
 298         val = readl(priv->base + SSI_FC);
 299         val &= ~(SSI_FC_TXFTH_MASK | SSI_FC_RXFTH_MASK);
 300         val |= FIELD_PREP(SSI_FC_TXFTH_MASK, SSI_FIFO_DEPTH - threshold);
 301         val |= FIELD_PREP(SSI_FC_RXFTH_MASK, threshold);
 302         writel(val, priv->base + SSI_FC);
 303 }
 304 
 305 static void uniphier_spi_fill_tx_fifo(struct uniphier_spi_priv *priv)
 306 {
 307         unsigned int fifo_threshold, fill_words;
 308         unsigned int bpw = bytes_per_word(priv->bits_per_word);
 309 
 310         fifo_threshold = DIV_ROUND_UP(priv->rx_bytes, bpw);
 311         fifo_threshold = min(fifo_threshold, SSI_FIFO_DEPTH);
 312 
 313         uniphier_spi_set_fifo_threshold(priv, fifo_threshold);
 314 
 315         fill_words = fifo_threshold -
 316                 DIV_ROUND_UP(priv->rx_bytes - priv->tx_bytes, bpw);
 317 
 318         while (fill_words--)
 319                 uniphier_spi_send(priv);
 320 }
 321 
 322 static void uniphier_spi_set_cs(struct spi_device *spi, bool enable)
 323 {
 324         struct uniphier_spi_priv *priv = spi_master_get_devdata(spi->master);
 325         u32 val;
 326 
 327         val = readl(priv->base + SSI_FPS);
 328 
 329         if (enable)
 330                 val |= SSI_FPS_FSPOL;
 331         else
 332                 val &= ~SSI_FPS_FSPOL;
 333 
 334         writel(val, priv->base + SSI_FPS);
 335 }
 336 
 337 static int uniphier_spi_transfer_one_irq(struct spi_master *master,
 338                                          struct spi_device *spi,
 339                                          struct spi_transfer *t)
 340 {
 341         struct uniphier_spi_priv *priv = spi_master_get_devdata(master);
 342         struct device *dev = master->dev.parent;
 343         unsigned long time_left;
 344 
 345         reinit_completion(&priv->xfer_done);
 346 
 347         uniphier_spi_fill_tx_fifo(priv);
 348 
 349         uniphier_spi_irq_enable(spi, SSI_IE_RCIE | SSI_IE_RORIE);
 350 
 351         time_left = wait_for_completion_timeout(&priv->xfer_done,
 352                                         msecs_to_jiffies(SSI_TIMEOUT_MS));
 353 
 354         uniphier_spi_irq_disable(spi, SSI_IE_RCIE | SSI_IE_RORIE);
 355 
 356         if (!time_left) {
 357                 dev_err(dev, "transfer timeout.\n");
 358                 return -ETIMEDOUT;
 359         }
 360 
 361         return priv->error;
 362 }
 363 
 364 static int uniphier_spi_transfer_one_poll(struct spi_master *master,
 365                                           struct spi_device *spi,
 366                                           struct spi_transfer *t)
 367 {
 368         struct uniphier_spi_priv *priv = spi_master_get_devdata(master);
 369         int loop = SSI_POLL_TIMEOUT_US * 10;
 370 
 371         while (priv->tx_bytes) {
 372                 uniphier_spi_fill_tx_fifo(priv);
 373 
 374                 while ((priv->rx_bytes - priv->tx_bytes) > 0) {
 375                         while (!(readl(priv->base + SSI_SR) & SSI_SR_RNE)
 376                                                                 && loop--)
 377                                 ndelay(100);
 378 
 379                         if (loop == -1)
 380                                 goto irq_transfer;
 381 
 382                         uniphier_spi_recv(priv);
 383                 }
 384         }
 385 
 386         return 0;
 387 
 388 irq_transfer:
 389         return uniphier_spi_transfer_one_irq(master, spi, t);
 390 }
 391 
 392 static int uniphier_spi_transfer_one(struct spi_master *master,
 393                                      struct spi_device *spi,
 394                                      struct spi_transfer *t)
 395 {
 396         struct uniphier_spi_priv *priv = spi_master_get_devdata(master);
 397         unsigned long threshold;
 398 
 399         /* Terminate and return success for 0 byte length transfer */
 400         if (!t->len)
 401                 return 0;
 402 
 403         uniphier_spi_setup_transfer(spi, t);
 404 
 405         /*
 406          * If the transfer operation will take longer than
 407          * SSI_POLL_TIMEOUT_US, it should use irq.
 408          */
 409         threshold = DIV_ROUND_UP(SSI_POLL_TIMEOUT_US * priv->speed_hz,
 410                                         USEC_PER_SEC * BITS_PER_BYTE);
 411         if (t->len > threshold)
 412                 return uniphier_spi_transfer_one_irq(master, spi, t);
 413         else
 414                 return uniphier_spi_transfer_one_poll(master, spi, t);
 415 }
 416 
 417 static int uniphier_spi_prepare_transfer_hardware(struct spi_master *master)
 418 {
 419         struct uniphier_spi_priv *priv = spi_master_get_devdata(master);
 420 
 421         writel(SSI_CTL_EN, priv->base + SSI_CTL);
 422 
 423         return 0;
 424 }
 425 
 426 static int uniphier_spi_unprepare_transfer_hardware(struct spi_master *master)
 427 {
 428         struct uniphier_spi_priv *priv = spi_master_get_devdata(master);
 429 
 430         writel(0, priv->base + SSI_CTL);
 431 
 432         return 0;
 433 }
 434 
 435 static irqreturn_t uniphier_spi_handler(int irq, void *dev_id)
 436 {
 437         struct uniphier_spi_priv *priv = dev_id;
 438         u32 val, stat;
 439 
 440         stat = readl(priv->base + SSI_IS);
 441         val = SSI_IC_TCIC | SSI_IC_RCIC | SSI_IC_RORIC;
 442         writel(val, priv->base + SSI_IC);
 443 
 444         /* rx fifo overrun */
 445         if (stat & SSI_IS_RORID) {
 446                 priv->error = -EIO;
 447                 goto done;
 448         }
 449 
 450         /* rx complete */
 451         if ((stat & SSI_IS_RCID) && (stat & SSI_IS_RXRS)) {
 452                 while ((readl(priv->base + SSI_SR) & SSI_SR_RNE) &&
 453                                 (priv->rx_bytes - priv->tx_bytes) > 0)
 454                         uniphier_spi_recv(priv);
 455 
 456                 if ((readl(priv->base + SSI_SR) & SSI_SR_RNE) ||
 457                                 (priv->rx_bytes != priv->tx_bytes)) {
 458                         priv->error = -EIO;
 459                         goto done;
 460                 } else if (priv->rx_bytes == 0)
 461                         goto done;
 462 
 463                 /* next tx transfer */
 464                 uniphier_spi_fill_tx_fifo(priv);
 465 
 466                 return IRQ_HANDLED;
 467         }
 468 
 469         return IRQ_NONE;
 470 
 471 done:
 472         complete(&priv->xfer_done);
 473         return IRQ_HANDLED;
 474 }
 475 
 476 static int uniphier_spi_probe(struct platform_device *pdev)
 477 {
 478         struct uniphier_spi_priv *priv;
 479         struct spi_master *master;
 480         unsigned long clk_rate;
 481         int irq;
 482         int ret;
 483 
 484         master = spi_alloc_master(&pdev->dev, sizeof(*priv));
 485         if (!master)
 486                 return -ENOMEM;
 487 
 488         platform_set_drvdata(pdev, master);
 489 
 490         priv = spi_master_get_devdata(master);
 491         priv->master = master;
 492         priv->is_save_param = false;
 493 
 494         priv->base = devm_platform_ioremap_resource(pdev, 0);
 495         if (IS_ERR(priv->base)) {
 496                 ret = PTR_ERR(priv->base);
 497                 goto out_master_put;
 498         }
 499 
 500         priv->clk = devm_clk_get(&pdev->dev, NULL);
 501         if (IS_ERR(priv->clk)) {
 502                 dev_err(&pdev->dev, "failed to get clock\n");
 503                 ret = PTR_ERR(priv->clk);
 504                 goto out_master_put;
 505         }
 506 
 507         ret = clk_prepare_enable(priv->clk);
 508         if (ret)
 509                 goto out_master_put;
 510 
 511         irq = platform_get_irq(pdev, 0);
 512         if (irq < 0) {
 513                 ret = irq;
 514                 goto out_disable_clk;
 515         }
 516 
 517         ret = devm_request_irq(&pdev->dev, irq, uniphier_spi_handler,
 518                                0, "uniphier-spi", priv);
 519         if (ret) {
 520                 dev_err(&pdev->dev, "failed to request IRQ\n");
 521                 goto out_disable_clk;
 522         }
 523 
 524         init_completion(&priv->xfer_done);
 525 
 526         clk_rate = clk_get_rate(priv->clk);
 527 
 528         master->max_speed_hz = DIV_ROUND_UP(clk_rate, SSI_MIN_CLK_DIVIDER);
 529         master->min_speed_hz = DIV_ROUND_UP(clk_rate, SSI_MAX_CLK_DIVIDER);
 530         master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LSB_FIRST;
 531         master->dev.of_node = pdev->dev.of_node;
 532         master->bus_num = pdev->id;
 533         master->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 32);
 534 
 535         master->set_cs = uniphier_spi_set_cs;
 536         master->transfer_one = uniphier_spi_transfer_one;
 537         master->prepare_transfer_hardware
 538                                 = uniphier_spi_prepare_transfer_hardware;
 539         master->unprepare_transfer_hardware
 540                                 = uniphier_spi_unprepare_transfer_hardware;
 541         master->num_chipselect = 1;
 542 
 543         ret = devm_spi_register_master(&pdev->dev, master);
 544         if (ret)
 545                 goto out_disable_clk;
 546 
 547         return 0;
 548 
 549 out_disable_clk:
 550         clk_disable_unprepare(priv->clk);
 551 
 552 out_master_put:
 553         spi_master_put(master);
 554         return ret;
 555 }
 556 
 557 static int uniphier_spi_remove(struct platform_device *pdev)
 558 {
 559         struct uniphier_spi_priv *priv = platform_get_drvdata(pdev);
 560 
 561         clk_disable_unprepare(priv->clk);
 562 
 563         return 0;
 564 }
 565 
 566 static const struct of_device_id uniphier_spi_match[] = {
 567         { .compatible = "socionext,uniphier-scssi" },
 568         { /* sentinel */ }
 569 };
 570 MODULE_DEVICE_TABLE(of, uniphier_spi_match);
 571 
 572 static struct platform_driver uniphier_spi_driver = {
 573         .probe = uniphier_spi_probe,
 574         .remove = uniphier_spi_remove,
 575         .driver = {
 576                 .name = "uniphier-spi",
 577                 .of_match_table = uniphier_spi_match,
 578         },
 579 };
 580 module_platform_driver(uniphier_spi_driver);
 581 
 582 MODULE_AUTHOR("Kunihiko Hayashi <hayashi.kunihiko@socionext.com>");
 583 MODULE_AUTHOR("Keiji Hayashibara <hayashibara.keiji@socionext.com>");
 584 MODULE_DESCRIPTION("Socionext UniPhier SPI controller driver");
 585 MODULE_LICENSE("GPL v2");

/* [<][>][^][v][top][bottom][index][help] */