From f70575805708cabdedea7498aaa3f710fde4d920 Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Wed, 31 Jan 2024 03:29:01 +0000
Subject: [PATCH] add lvds1024*800

---
 kernel/drivers/soc/rockchip/rockchip_decompress.c |  111 +++++++++++++++++++++++++++++++++++++++++--------------
 1 files changed, 83 insertions(+), 28 deletions(-)

diff --git a/kernel/drivers/soc/rockchip/rockchip_decompress.c b/kernel/drivers/soc/rockchip/rockchip_decompress.c
index 47401f4..275a605 100644
--- a/kernel/drivers/soc/rockchip/rockchip_decompress.c
+++ b/kernel/drivers/soc/rockchip/rockchip_decompress.c
@@ -93,32 +93,67 @@
 
 static struct rk_decom *g_decom;
 
-static DECLARE_WAIT_QUEUE_HEAD(initrd_decom_done);
-static bool initrd_continue;
+static DECLARE_WAIT_QUEUE_HEAD(g_decom_wait);
+static bool g_decom_complete;
+static bool g_decom_noblocking;
+static u64 g_decom_data_len;
 
 void __init wait_initrd_hw_decom_done(void)
 {
-	wait_event(initrd_decom_done, initrd_continue);
+	wait_event(g_decom_wait, g_decom_complete);
 }
+
+int rk_decom_wait_done(u32 timeout, u64 *decom_len)
+{
+	int ret;
+
+	if (!decom_len)
+		return -EINVAL;
+
+	ret = wait_event_timeout(g_decom_wait, g_decom_complete, timeout * HZ);
+	if (!ret) {
+		if (g_decom)
+			clk_bulk_disable_unprepare(g_decom->num_clocks, g_decom->clocks);
+
+		return -ETIMEDOUT;
+	}
+
+	*decom_len = g_decom_data_len;
+
+	return 0;
+}
+EXPORT_SYMBOL(rk_decom_wait_done);
 
 static DECLARE_WAIT_QUEUE_HEAD(decom_init_done);
 
 int rk_decom_start(u32 mode, phys_addr_t src, phys_addr_t dst, u32 dst_max_size)
 {
+	int ret;
 	u32 irq_status;
 	u32 decom_enr;
-
-	pr_info("%s: mode %u src %pa dst %pa max_size %u\n",
-		__func__, mode, &src, &dst, dst_max_size);
+	u32 decom_mode = rk_get_decom_mode(mode);
 
 	wait_event_timeout(decom_init_done, g_decom, HZ);
 	if (!g_decom)
 		return -EINVAL;
 
+	if (g_decom->mem_start)
+		pr_info("%s: mode %u src %pa dst %pa max_size %u\n",
+			__func__, mode, &src, &dst, dst_max_size);
+
+	ret = clk_bulk_prepare_enable(g_decom->num_clocks, g_decom->clocks);
+	if (ret)
+		return ret;
+
+	g_decom_complete   = false;
+	g_decom_data_len   = 0;
+	g_decom_noblocking = rk_get_noblocking_flag(mode);
+
 	decom_enr = readl(g_decom->regs + DECOM_ENR);
 	if (decom_enr & 0x1) {
 		pr_err("decompress busy\n");
-		return -EBUSY;
+		ret = -EBUSY;
+		goto error;
 	}
 
 	if (g_decom->reset) {
@@ -132,7 +167,7 @@
 	if (irq_status)
 		writel(irq_status, g_decom->regs + DECOM_ISR);
 
-	switch (mode) {
+	switch (decom_mode) {
 	case LZ4_MOD:
 		writel(LZ4_CONT_CSUM_CHECK_EN |
 		       LZ4_HEAD_CSUM_CHECK_EN |
@@ -148,8 +183,9 @@
 		       g_decom->regs + DECOM_CTRL);
 		break;
 	default:
-		pr_err("undefined mode : %d\n", mode);
-		return -EINVAL;
+		pr_err("undefined mode : %d\n", decom_mode);
+		ret = -EINVAL;
+		goto error;
 	}
 
 	writel(src, g_decom->regs + DECOM_RADDR);
@@ -161,9 +197,11 @@
 	writel(DECOM_INT_MASK, g_decom->regs + DECOM_IEN);
 	writel(DECOM_ENABLE, g_decom->regs + DECOM_ENR);
 
-	pr_info("%s: started\n", __func__);
-
 	return 0;
+error:
+	clk_bulk_disable_unprepare(g_decom->num_clocks, g_decom->clocks);
+
+	return ret;
 }
 EXPORT_SYMBOL(rk_decom_start);
 
@@ -179,9 +217,15 @@
 	if (irq_status & DECOM_STOP) {
 		decom_status = readl(rk_dec->regs + DECOM_STAT);
 		if (decom_status & DECOM_COMPLETE) {
-			initrd_continue = true;
-			wake_up(&initrd_decom_done);
-			dev_info(rk_dec->dev, "decom completed\n");
+			g_decom_complete = true;
+			g_decom_data_len = readl(rk_dec->regs + DECOM_TSIZEH);
+			g_decom_data_len = (g_decom_data_len << 32) |
+					   readl(rk_dec->regs + DECOM_TSIZEL);
+			wake_up(&g_decom_wait);
+			if (rk_dec->mem_start)
+				dev_info(rk_dec->dev,
+					 "decom completed, decom_data_len = %llu\n",
+					 g_decom_data_len);
 		} else {
 			dev_info(rk_dec->dev,
 				 "decom failed, irq_status = 0x%x, decom_status = 0x%x, try again !\n",
@@ -190,7 +234,18 @@
 			print_hex_dump(KERN_WARNING, "", DUMP_PREFIX_OFFSET,
 				       32, 4, rk_dec->regs, 0x128, false);
 
-			writel(DECOM_ENABLE, rk_dec->regs + DECOM_ENR);
+			if (g_decom_noblocking) {
+				dev_info(rk_dec->dev, "decom failed and exit in noblocking mode.");
+				writel(DECOM_DISABLE, rk_dec->regs + DECOM_ENR);
+				writel(0, g_decom->regs + DECOM_IEN);
+
+				g_decom_complete  = true;
+				g_decom_data_len = 0;
+				g_decom_noblocking = false;
+				wake_up(&g_decom_wait);
+			} else {
+				writel(DECOM_ENABLE, rk_dec->regs + DECOM_ENR);
+			}
 		}
 	}
 
@@ -201,16 +256,20 @@
 {
 	struct rk_decom *rk_dec = priv;
 
-	if (initrd_continue) {
+	if (g_decom_complete) {
 		void *start, *end;
 
-		/*
-		 * Now it is safe to free reserve memory that
-		 * store the origin ramdisk file
-		 */
-		start = phys_to_virt(rk_dec->mem_start);
-		end = start + rk_dec->mem_size;
-		free_reserved_area(start, end, -1, "ramdisk gzip archive");
+		if (rk_dec->mem_start) {
+			/*
+			 * Now it is safe to free reserve memory that
+			 * store the origin ramdisk file
+			 */
+			start = phys_to_virt(rk_dec->mem_start);
+			end = start + rk_dec->mem_size;
+			free_reserved_area(start, end, -1, "ramdisk gzip archive");
+			rk_dec->mem_start = 0;
+		}
+
 		clk_bulk_disable_unprepare(rk_dec->num_clocks, rk_dec->clocks);
 	}
 
@@ -259,10 +318,6 @@
 		dev_err(dev, "failed to get decompress clock\n");
 		return -ENODEV;
 	}
-
-	ret = clk_bulk_prepare_enable(rk_dec->num_clocks, rk_dec->clocks);
-	if (ret)
-		return ret;
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	rk_dec->regs = devm_ioremap_resource(dev, res);

--
Gitblit v1.6.2