hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/drivers/spi/spi-s3c64xx.c
....@@ -29,7 +29,7 @@
2929 #define S3C64XX_SPI_CH_CFG 0x00
3030 #define S3C64XX_SPI_CLK_CFG 0x04
3131 #define S3C64XX_SPI_MODE_CFG 0x08
32
-#define S3C64XX_SPI_SLAVE_SEL 0x0C
32
+#define S3C64XX_SPI_CS_REG 0x0C
3333 #define S3C64XX_SPI_INT_EN 0x10
3434 #define S3C64XX_SPI_STATUS 0x14
3535 #define S3C64XX_SPI_TX_DATA 0x18
....@@ -64,9 +64,9 @@
6464 #define S3C64XX_SPI_MODE_TXDMA_ON (1<<1)
6565 #define S3C64XX_SPI_MODE_4BURST (1<<0)
6666
67
-#define S3C64XX_SPI_SLAVE_AUTO (1<<1)
68
-#define S3C64XX_SPI_SLAVE_SIG_INACT (1<<0)
69
-#define S3C64XX_SPI_SLAVE_NSC_CNT_2 (2<<4)
67
+#define S3C64XX_SPI_CS_NSC_CNT_2 (2<<4)
68
+#define S3C64XX_SPI_CS_AUTO (1<<1)
69
+#define S3C64XX_SPI_CS_SIG_INACT (1<<0)
7070
7171 #define S3C64XX_SPI_INT_TRAILING_EN (1<<6)
7272 #define S3C64XX_SPI_INT_RX_OVERRUN_EN (1<<5)
....@@ -84,6 +84,7 @@
8484 #define S3C64XX_SPI_ST_TX_FIFORDY (1<<0)
8585
8686 #define S3C64XX_SPI_PACKET_CNT_EN (1<<16)
87
+#define S3C64XX_SPI_PACKET_CNT_MASK GENMASK(15, 0)
8788
8889 #define S3C64XX_SPI_PND_TX_UNDERRUN_CLR (1<<4)
8990 #define S3C64XX_SPI_PND_TX_OVERRUN_CLR (1<<3)
....@@ -131,9 +132,11 @@
131132 * @fifo_lvl_mask: Bit-mask for {TX|RX}_FIFO_LVL bits in SPI_STATUS register.
132133 * @rx_lvl_offset: Bit offset of RX_FIFO_LVL bits in SPI_STATUS regiter.
133134 * @tx_st_done: Bit offset of TX_DONE bit in SPI_STATUS regiter.
135
+ * @quirks: Bitmask of known quirks
134136 * @high_speed: True, if the controller supports HIGH_SPEED_EN bit.
135137 * @clk_from_cmu: True, if the controller does not include a clock mux and
136138 * prescaler unit.
139
+ * @clk_ioclk: True if clock is present on this device
137140 *
138141 * The Samsung s3c64xx SPI controller are used on various Samsung SoC's but
139142 * differ in some aspects such as the size of the fifo and spi bus clock
....@@ -155,19 +158,21 @@
155158 * @clk: Pointer to the spi clock.
156159 * @src_clk: Pointer to the clock used to generate SPI signals.
157160 * @ioclk: Pointer to the i/o clock between master and slave
161
+ * @pdev: Pointer to device's platform device data
158162 * @master: Pointer to the SPI Protocol master.
159163 * @cntrlr_info: Platform specific data for the controller this driver manages.
160164 * @lock: Controller specific lock.
161165 * @state: Set of FLAGS to indicate status.
162
- * @rx_dmach: Controller's DMA channel for Rx.
163
- * @tx_dmach: Controller's DMA channel for Tx.
164166 * @sfr_start: BUS address of SPI controller regs.
165167 * @regs: Pointer to ioremap'ed controller registers.
166
- * @irq: interrupt
167168 * @xfer_completion: To indicate completion of xfer task.
168169 * @cur_mode: Stores the active configuration of the controller.
169170 * @cur_bpw: Stores the active bits per word settings.
170
- * @cur_speed: Stores the active xfer clock speed.
171
+ * @cur_speed: Current clock speed
172
+ * @rx_dma: Local receive DMA data (e.g. chan and direction)
173
+ * @tx_dma: Local transmit DMA data (e.g. chan and direction)
174
+ * @port_conf: Local SPI port configuartion data
175
+ * @port_id: Port identification number
171176 */
172177 struct s3c64xx_spi_driver_data {
173178 void __iomem *regs;
....@@ -176,7 +181,7 @@
176181 struct clk *ioclk;
177182 struct platform_device *pdev;
178183 struct spi_master *master;
179
- struct s3c64xx_spi_info *cntrlr_info;
184
+ struct s3c64xx_spi_info *cntrlr_info;
180185 spinlock_t lock;
181186 unsigned long sfr_start;
182187 struct completion xfer_completion;
....@@ -325,18 +330,18 @@
325330
326331 if (enable) {
327332 if (!(sdd->port_conf->quirks & S3C64XX_SPI_QUIRK_CS_AUTO)) {
328
- writel(0, sdd->regs + S3C64XX_SPI_SLAVE_SEL);
333
+ writel(0, sdd->regs + S3C64XX_SPI_CS_REG);
329334 } else {
330
- u32 ssel = readl(sdd->regs + S3C64XX_SPI_SLAVE_SEL);
335
+ u32 ssel = readl(sdd->regs + S3C64XX_SPI_CS_REG);
331336
332
- ssel |= (S3C64XX_SPI_SLAVE_AUTO |
333
- S3C64XX_SPI_SLAVE_NSC_CNT_2);
334
- writel(ssel, sdd->regs + S3C64XX_SPI_SLAVE_SEL);
337
+ ssel |= (S3C64XX_SPI_CS_AUTO |
338
+ S3C64XX_SPI_CS_NSC_CNT_2);
339
+ writel(ssel, sdd->regs + S3C64XX_SPI_CS_REG);
335340 }
336341 } else {
337342 if (!(sdd->port_conf->quirks & S3C64XX_SPI_QUIRK_CS_AUTO))
338
- writel(S3C64XX_SPI_SLAVE_SIG_INACT,
339
- sdd->regs + S3C64XX_SPI_SLAVE_SEL);
343
+ writel(S3C64XX_SPI_CS_SIG_INACT,
344
+ sdd->regs + S3C64XX_SPI_CS_REG);
340345 }
341346 }
342347
....@@ -469,7 +474,8 @@
469474
470475 /* millisecs to xfer 'len' bytes @ 'cur_speed' */
471476 ms = xfer->len * 8 * 1000 / sdd->cur_speed;
472
- ms += 10; /* some tolerance */
477
+ ms += 30; /* some tolerance */
478
+ ms = max(ms, 100); /* minimum timeout */
473479
474480 val = msecs_to_jiffies(ms) + 10;
475481 val = wait_for_completion_timeout(&sdd->xfer_completion, val);
....@@ -622,6 +628,7 @@
622628 ret = clk_set_rate(sdd->src_clk, sdd->cur_speed * 2);
623629 if (ret)
624630 return ret;
631
+ sdd->cur_speed = clk_get_rate(sdd->src_clk) / 2;
625632 } else {
626633 /* Configure Clock */
627634 val = readl(regs + S3C64XX_SPI_CLK_CFG);
....@@ -652,6 +659,13 @@
652659 writel(cs->fb_delay & 0x3, sdd->regs + S3C64XX_SPI_FB_CLK);
653660
654661 return 0;
662
+}
663
+
664
+static size_t s3c64xx_spi_max_transfer_size(struct spi_device *spi)
665
+{
666
+ struct spi_controller *ctlr = spi->controller;
667
+
668
+ return ctlr->can_dma ? S3C64XX_SPI_PACKET_CNT_MASK : SIZE_MAX;
655669 }
656670
657671 static int s3c64xx_spi_transfer_one(struct spi_master *master,
....@@ -724,17 +738,28 @@
724738
725739 if (status) {
726740 dev_err(&spi->dev,
727
- "I/O Error: rx-%d tx-%d res:rx-%c tx-%c len-%d\n",
741
+ "I/O Error: rx-%d tx-%d rx-%c tx-%c len-%d dma-%d res-(%d)\n",
728742 xfer->rx_buf ? 1 : 0, xfer->tx_buf ? 1 : 0,
729743 (sdd->state & RXBUSY) ? 'f' : 'p',
730744 (sdd->state & TXBUSY) ? 'f' : 'p',
731
- xfer->len);
745
+ xfer->len, use_dma ? 1 : 0, status);
732746
733747 if (use_dma) {
734
- if (xfer->tx_buf && (sdd->state & TXBUSY))
748
+ struct dma_tx_state s;
749
+
750
+ if (xfer->tx_buf && (sdd->state & TXBUSY)) {
751
+ dmaengine_pause(sdd->tx_dma.ch);
752
+ dmaengine_tx_status(sdd->tx_dma.ch, sdd->tx_dma.cookie, &s);
735753 dmaengine_terminate_all(sdd->tx_dma.ch);
736
- if (xfer->rx_buf && (sdd->state & RXBUSY))
754
+ dev_err(&spi->dev, "TX residue: %d\n", s.residue);
755
+
756
+ }
757
+ if (xfer->rx_buf && (sdd->state & RXBUSY)) {
758
+ dmaengine_pause(sdd->rx_dma.ch);
759
+ dmaengine_tx_status(sdd->rx_dma.ch, sdd->rx_dma.cookie, &s);
737760 dmaengine_terminate_all(sdd->rx_dma.ch);
761
+ dev_err(&spi->dev, "RX residue: %d\n", s.residue);
762
+ }
738763 }
739764 } else {
740765 s3c64xx_flush_fifo(sdd);
....@@ -964,9 +989,9 @@
964989 sdd->cur_speed = 0;
965990
966991 if (sci->no_cs)
967
- writel(0, sdd->regs + S3C64XX_SPI_SLAVE_SEL);
992
+ writel(0, sdd->regs + S3C64XX_SPI_CS_REG);
968993 else if (!(sdd->port_conf->quirks & S3C64XX_SPI_QUIRK_CS_AUTO))
969
- writel(S3C64XX_SPI_SLAVE_SIG_INACT, sdd->regs + S3C64XX_SPI_SLAVE_SEL);
994
+ writel(S3C64XX_SPI_CS_SIG_INACT, sdd->regs + S3C64XX_SPI_CS_REG);
970995
971996 /* Disable Interrupts - we use Polling if not DMA mode */
972997 writel(0, regs + S3C64XX_SPI_INT_EN);
....@@ -1118,6 +1143,7 @@
11181143 master->prepare_transfer_hardware = s3c64xx_spi_prepare_transfer;
11191144 master->prepare_message = s3c64xx_spi_prepare_message;
11201145 master->transfer_one = s3c64xx_spi_transfer_one;
1146
+ master->max_transfer_size = s3c64xx_spi_max_transfer_size;
11211147 master->num_chipselect = sci->num_cs;
11221148 master->dma_alignment = 8;
11231149 master->bits_per_word_mask = SPI_BPW_MASK(32) | SPI_BPW_MASK(16) |
....@@ -1186,15 +1212,13 @@
11861212
11871213 if (!is_polling(sdd)) {
11881214 /* Acquire DMA channels */
1189
- sdd->rx_dma.ch = dma_request_slave_channel_reason(&pdev->dev,
1190
- "rx");
1215
+ sdd->rx_dma.ch = dma_request_chan(&pdev->dev, "rx");
11911216 if (IS_ERR(sdd->rx_dma.ch)) {
11921217 dev_err(&pdev->dev, "Failed to get RX DMA channel\n");
11931218 ret = PTR_ERR(sdd->rx_dma.ch);
11941219 goto err_disable_io_clk;
11951220 }
1196
- sdd->tx_dma.ch = dma_request_slave_channel_reason(&pdev->dev,
1197
- "tx");
1221
+ sdd->tx_dma.ch = dma_request_chan(&pdev->dev, "tx");
11981222 if (IS_ERR(sdd->tx_dma.ch)) {
11991223 dev_err(&pdev->dev, "Failed to get TX DMA channel\n");
12001224 ret = PTR_ERR(sdd->tx_dma.ch);
....@@ -1363,6 +1387,10 @@
13631387
13641388 s3c64xx_spi_hwinit(sdd);
13651389
1390
+ writel(S3C64XX_SPI_INT_RX_OVERRUN_EN | S3C64XX_SPI_INT_RX_UNDERRUN_EN |
1391
+ S3C64XX_SPI_INT_TX_OVERRUN_EN | S3C64XX_SPI_INT_TX_UNDERRUN_EN,
1392
+ sdd->regs + S3C64XX_SPI_INT_EN);
1393
+
13661394 return 0;
13671395
13681396 err_disable_src_clk:
....@@ -1406,6 +1434,7 @@
14061434 .tx_st_done = 25,
14071435 .high_speed = true,
14081436 .clk_from_cmu = true,
1437
+ .quirks = S3C64XX_SPI_QUIRK_CS_AUTO,
14091438 };
14101439
14111440 static struct s3c64xx_spi_port_config exynos7_spi_port_config = {