.. | .. |
---|
13 | 13 | #include <linux/slab.h> |
---|
14 | 14 | #include <linux/spi/spi.h> |
---|
15 | 15 | |
---|
| 16 | +#include <soc/rockchip/rockchip-system-status.h> |
---|
| 17 | + |
---|
16 | 18 | #define SPI_OBJ_MAX_XFER_SIZE 0x1040 |
---|
17 | 19 | #define SPI_OBJ_APP_RAM_SIZE 0x10000 |
---|
18 | 20 | |
---|
.. | .. |
---|
21 | 23 | #define SPI_OBJ_CTRL_CMD_READ 0x3A |
---|
22 | 24 | #define SPI_OBJ_CTRL_CMD_WRITE 0x4B |
---|
23 | 25 | #define SPI_OBJ_CTRL_CMD_DUPLEX 0x5C |
---|
| 26 | + |
---|
| 27 | +#define SPI_OBJ_CTRL_DYQ_PERF_THRESHOLD 0x20 |
---|
24 | 28 | |
---|
25 | 29 | struct spi_obj_ctrl { |
---|
26 | 30 | u16 cmd; |
---|
.. | .. |
---|
38 | 42 | struct task_struct *tsk; |
---|
39 | 43 | bool tsk_run; |
---|
40 | 44 | 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; |
---|
41 | 55 | }; |
---|
42 | 56 | |
---|
43 | 57 | static u32 bit_per_word = 8; |
---|
44 | 58 | |
---|
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) |
---|
46 | 60 | { |
---|
47 | | - int ret = -1; |
---|
48 | 61 | struct spi_device *spi = spidev->spi; |
---|
49 | 62 | struct spi_transfer t = { |
---|
50 | 63 | .tx_buf = txbuf, |
---|
51 | | - .len = n, |
---|
| 64 | + .len = len, |
---|
52 | 65 | .bits_per_word = bit_per_word, |
---|
53 | 66 | }; |
---|
54 | 67 | struct spi_message m; |
---|
| 68 | + int ret; |
---|
55 | 69 | |
---|
56 | 70 | spi_message_init(&m); |
---|
57 | 71 | 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); |
---|
58 | 74 | 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); |
---|
59 | 77 | |
---|
60 | 78 | return ret; |
---|
61 | 79 | } |
---|
62 | 80 | |
---|
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) |
---|
64 | 82 | { |
---|
65 | | - int ret = -1; |
---|
66 | 83 | struct spi_device *spi = spidev->spi; |
---|
67 | 84 | struct spi_transfer t = { |
---|
68 | 85 | .rx_buf = rxbuf, |
---|
69 | | - .len = n, |
---|
| 86 | + .len = len, |
---|
70 | 87 | .bits_per_word = bit_per_word, |
---|
71 | 88 | }; |
---|
72 | 89 | struct spi_message m; |
---|
| 90 | + int ret; |
---|
73 | 91 | |
---|
74 | 92 | spi_message_init(&m); |
---|
75 | 93 | 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); |
---|
76 | 96 | 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); |
---|
77 | 99 | |
---|
78 | 100 | return ret; |
---|
79 | 101 | } |
---|
.. | .. |
---|
88 | 110 | .len = len, |
---|
89 | 111 | }; |
---|
90 | 112 | struct spi_message m; |
---|
| 113 | + int ret; |
---|
91 | 114 | |
---|
92 | 115 | spi_message_init(&m); |
---|
93 | 116 | 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; |
---|
95 | 125 | } |
---|
96 | 126 | |
---|
97 | 127 | static ssize_t spidev_rkslv_misc_write(struct file *filp, const char __user *buf, |
---|
.. | .. |
---|
318 | 348 | if (!spidev->tempbuf) |
---|
319 | 349 | return -ENOMEM; |
---|
320 | 350 | |
---|
| 351 | + spidev->dyq_perf = true; |
---|
321 | 352 | spidev->spi = spi; |
---|
322 | 353 | spidev->dev = &spi->dev; |
---|
323 | 354 | dev_set_drvdata(&spi->dev, spidev); |
---|