From 2f7c68cb55ecb7331f2381deb497c27155f32faf Mon Sep 17 00:00:00 2001 From: hc <hc@nodka.com> Date: Wed, 03 Jan 2024 09:43:39 +0000 Subject: [PATCH] update kernel to 5.10.198 --- kernel/drivers/spi/spidev-rkslv.c | 45 ++++++++++++++++++++++++++++++++++++++------- 1 files changed, 38 insertions(+), 7 deletions(-) diff --git a/kernel/drivers/spi/spidev-rkslv.c b/kernel/drivers/spi/spidev-rkslv.c index 0ff4415..9f8cfcc 100644 --- a/kernel/drivers/spi/spidev-rkslv.c +++ b/kernel/drivers/spi/spidev-rkslv.c @@ -13,6 +13,8 @@ #include <linux/slab.h> #include <linux/spi/spi.h> +#include <soc/rockchip/rockchip-system-status.h> + #define SPI_OBJ_MAX_XFER_SIZE 0x1040 #define SPI_OBJ_APP_RAM_SIZE 0x10000 @@ -21,6 +23,8 @@ #define SPI_OBJ_CTRL_CMD_READ 0x3A #define SPI_OBJ_CTRL_CMD_WRITE 0x4B #define SPI_OBJ_CTRL_CMD_DUPLEX 0x5C + +#define SPI_OBJ_CTRL_DYQ_PERF_THRESHOLD 0x20 struct spi_obj_ctrl { u16 cmd; @@ -38,42 +42,60 @@ struct task_struct *tsk; bool tsk_run; struct miscdevice misc_dev; + + /* + * If the DRAM frequency conversion jitters during the transmission process, + * it will cause the DMA to be unable to transport SPI FIFO data in a timely + * manner, resulting in FIFO overflow/underflow. + * + * However, since the command packet length is smaller than FIFO, this + * problem does not exist. So set performance status dynamically for data packet. + */ + bool dyq_perf; }; static u32 bit_per_word = 8; -static int spidev_slv_write(struct spidev_rkslv_data *spidev, const void *txbuf, size_t n) +static int spidev_slv_write(struct spidev_rkslv_data *spidev, const void *txbuf, size_t len) { - int ret = -1; struct spi_device *spi = spidev->spi; struct spi_transfer t = { .tx_buf = txbuf, - .len = n, + .len = len, .bits_per_word = bit_per_word, }; struct spi_message m; + int ret; spi_message_init(&m); spi_message_add_tail(&t, &m); + if (spidev->dyq_perf && len > SPI_OBJ_CTRL_DYQ_PERF_THRESHOLD) + rockchip_set_system_status(SYS_STATUS_PERFORMANCE); ret = spi_sync(spi, &m); + if (spidev->dyq_perf && len > SPI_OBJ_CTRL_DYQ_PERF_THRESHOLD) + rockchip_clear_system_status(SYS_STATUS_PERFORMANCE); return ret; } -static int spidev_slv_read(struct spidev_rkslv_data *spidev, void *rxbuf, size_t n) +static int spidev_slv_read(struct spidev_rkslv_data *spidev, void *rxbuf, size_t len) { - int ret = -1; struct spi_device *spi = spidev->spi; struct spi_transfer t = { .rx_buf = rxbuf, - .len = n, + .len = len, .bits_per_word = bit_per_word, }; struct spi_message m; + int ret; spi_message_init(&m); spi_message_add_tail(&t, &m); + if (spidev->dyq_perf && len > SPI_OBJ_CTRL_DYQ_PERF_THRESHOLD) + rockchip_set_system_status(SYS_STATUS_PERFORMANCE); ret = spi_sync(spi, &m); + if (spidev->dyq_perf && len > SPI_OBJ_CTRL_DYQ_PERF_THRESHOLD) + rockchip_clear_system_status(SYS_STATUS_PERFORMANCE); return ret; } @@ -88,10 +110,18 @@ .len = len, }; struct spi_message m; + int ret; spi_message_init(&m); spi_message_add_tail(&t, &m); - return spi_sync(spi, &m); + + if (spidev->dyq_perf && len > SPI_OBJ_CTRL_DYQ_PERF_THRESHOLD) + rockchip_set_system_status(SYS_STATUS_PERFORMANCE); + ret = spi_sync(spi, &m); + if (spidev->dyq_perf && len > SPI_OBJ_CTRL_DYQ_PERF_THRESHOLD) + rockchip_clear_system_status(SYS_STATUS_PERFORMANCE); + + return ret; } static ssize_t spidev_rkslv_misc_write(struct file *filp, const char __user *buf, @@ -318,6 +348,7 @@ if (!spidev->tempbuf) return -ENOMEM; + spidev->dyq_perf = true; spidev->spi = spi; spidev->dev = &spi->dev; dev_set_drvdata(&spi->dev, spidev); -- Gitblit v1.6.2