hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/drivers/spi/spidev-rkslv.c
....@@ -13,6 +13,8 @@
1313 #include <linux/slab.h>
1414 #include <linux/spi/spi.h>
1515
16
+#include <soc/rockchip/rockchip-system-status.h>
17
+
1618 #define SPI_OBJ_MAX_XFER_SIZE 0x1040
1719 #define SPI_OBJ_APP_RAM_SIZE 0x10000
1820
....@@ -21,6 +23,8 @@
2123 #define SPI_OBJ_CTRL_CMD_READ 0x3A
2224 #define SPI_OBJ_CTRL_CMD_WRITE 0x4B
2325 #define SPI_OBJ_CTRL_CMD_DUPLEX 0x5C
26
+
27
+#define SPI_OBJ_CTRL_DYQ_PERF_THRESHOLD 0x20
2428
2529 struct spi_obj_ctrl {
2630 u16 cmd;
....@@ -38,42 +42,60 @@
3842 struct task_struct *tsk;
3943 bool tsk_run;
4044 struct miscdevice misc_dev;
45
+
46
+ /*
47
+ * If the DRAM frequency conversion jitters during the transmission process,
48
+ * it will cause the DMA to be unable to transport SPI FIFO data in a timely
49
+ * manner, resulting in FIFO overflow/underflow.
50
+ *
51
+ * However, since the command packet length is smaller than FIFO, this
52
+ * problem does not exist. So set performance status dynamically for data packet.
53
+ */
54
+ bool dyq_perf;
4155 };
4256
4357 static u32 bit_per_word = 8;
4458
45
-static int spidev_slv_write(struct spidev_rkslv_data *spidev, const void *txbuf, size_t n)
59
+static int spidev_slv_write(struct spidev_rkslv_data *spidev, const void *txbuf, size_t len)
4660 {
47
- int ret = -1;
4861 struct spi_device *spi = spidev->spi;
4962 struct spi_transfer t = {
5063 .tx_buf = txbuf,
51
- .len = n,
64
+ .len = len,
5265 .bits_per_word = bit_per_word,
5366 };
5467 struct spi_message m;
68
+ int ret;
5569
5670 spi_message_init(&m);
5771 spi_message_add_tail(&t, &m);
72
+ if (spidev->dyq_perf && len > SPI_OBJ_CTRL_DYQ_PERF_THRESHOLD)
73
+ rockchip_set_system_status(SYS_STATUS_PERFORMANCE);
5874 ret = spi_sync(spi, &m);
75
+ if (spidev->dyq_perf && len > SPI_OBJ_CTRL_DYQ_PERF_THRESHOLD)
76
+ rockchip_clear_system_status(SYS_STATUS_PERFORMANCE);
5977
6078 return ret;
6179 }
6280
63
-static int spidev_slv_read(struct spidev_rkslv_data *spidev, void *rxbuf, size_t n)
81
+static int spidev_slv_read(struct spidev_rkslv_data *spidev, void *rxbuf, size_t len)
6482 {
65
- int ret = -1;
6683 struct spi_device *spi = spidev->spi;
6784 struct spi_transfer t = {
6885 .rx_buf = rxbuf,
69
- .len = n,
86
+ .len = len,
7087 .bits_per_word = bit_per_word,
7188 };
7289 struct spi_message m;
90
+ int ret;
7391
7492 spi_message_init(&m);
7593 spi_message_add_tail(&t, &m);
94
+ if (spidev->dyq_perf && len > SPI_OBJ_CTRL_DYQ_PERF_THRESHOLD)
95
+ rockchip_set_system_status(SYS_STATUS_PERFORMANCE);
7696 ret = spi_sync(spi, &m);
97
+ if (spidev->dyq_perf && len > SPI_OBJ_CTRL_DYQ_PERF_THRESHOLD)
98
+ rockchip_clear_system_status(SYS_STATUS_PERFORMANCE);
7799
78100 return ret;
79101 }
....@@ -88,10 +110,18 @@
88110 .len = len,
89111 };
90112 struct spi_message m;
113
+ int ret;
91114
92115 spi_message_init(&m);
93116 spi_message_add_tail(&t, &m);
94
- return spi_sync(spi, &m);
117
+
118
+ if (spidev->dyq_perf && len > SPI_OBJ_CTRL_DYQ_PERF_THRESHOLD)
119
+ rockchip_set_system_status(SYS_STATUS_PERFORMANCE);
120
+ ret = spi_sync(spi, &m);
121
+ if (spidev->dyq_perf && len > SPI_OBJ_CTRL_DYQ_PERF_THRESHOLD)
122
+ rockchip_clear_system_status(SYS_STATUS_PERFORMANCE);
123
+
124
+ return ret;
95125 }
96126
97127 static ssize_t spidev_rkslv_misc_write(struct file *filp, const char __user *buf,
....@@ -318,6 +348,7 @@
318348 if (!spidev->tempbuf)
319349 return -ENOMEM;
320350
351
+ spidev->dyq_perf = true;
321352 spidev->spi = spi;
322353 spidev->dev = &spi->dev;
323354 dev_set_drvdata(&spi->dev, spidev);