From 37f49e37ab4cb5d0bc4c60eb5c6d4dd57db767bb Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Fri, 10 May 2024 07:44:59 +0000
Subject: [PATCH] gmac get mac form eeprom
---
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