rk322x: fix missing HDMI with vendor kernel

multitool utility uses the legacy/vendor 4.4 kernel
and it was failing to turn on HDMI properly.
Assert and deassert all vop and hmdi resets to clean
up the state on uboot exit seems to solve the issue
This commit is contained in:
Paolo Sabatino 2024-05-29 22:34:49 +02:00 committed by Igor
parent e9ecf4b79c
commit fa559a7c1d
2 changed files with 36 additions and 20 deletions

View File

@ -10,18 +10,19 @@ Subject: [PATCH 3/4] rockchip rk3228 HDMI driver
diff --git a/drivers/video/rockchip/rk3228_hdmi.c b/drivers/video/rockchip/rk3228_hdmi.c
new file mode 100644
index 0000000000..b07ac35ce1
index 0000000000..ec67790c71
--- /dev/null
+++ b/drivers/video/rockchip/rk3228_hdmi.c
@@ -0,0 +1,161 @@
@@ -0,0 +1,179 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2023 Edgeble AI Technologies Pvt. Ltd.
+ */
+
+#include <common.h>
+#include <clk.h>
+#include <display.h>
+#include <reset.h>
+#include <linux/delay.h>
+#include <dm.h>
+#include <dw_hdmi.h>
+#include <asm/io.h>
@ -136,9 +137,14 @@ index 0000000000..b07ac35ce1
+ return 0;
+}
+
+/*
+ * Asserting and deasserting the HDMI resets allows the vendor kernel
+ * to turn on HDMI when necessary. Mainline kernel does not need it though
+ */
+static int rk3228_hdmi_remove(struct udevice *dev)
+{
+ struct rk_hdmi_priv *priv = dev_get_priv(dev);
+ struct reset_ctl_bulk resets;
+ int ret;
+
+ debug("%s\n", __func__);
@ -150,6 +156,18 @@ index 0000000000..b07ac35ce1
+ printf("failed to on hdmi phy (ret=%d)\n", ret);
+ }
+
+ ret = reset_get_bulk(dev, &resets);
+ if (ret) {
+ printf("failed to get resets (ret=%d)\n", ret);
+ return ret;
+ }
+
+ reset_assert_bulk(&resets);
+ udelay(20);
+
+ reset_deassert_bulk(&resets);
+ udelay(20);
+
+ return 0;
+
+}

View File

@ -10,15 +10,14 @@ Subject: [PATCH 2/4] rockchip rk3228 VOP driver
diff --git a/drivers/video/rockchip/rk3228_vop.c b/drivers/video/rockchip/rk3228_vop.c
new file mode 100644
index 0000000000..f09097709a
index 0000000000..ec558078a0
--- /dev/null
+++ b/drivers/video/rockchip/rk3228_vop.c
@@ -0,0 +1,109 @@
@@ -0,0 +1,107 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2023 Edgeble AI Technologies Pvt. Ltd.
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <video.h>
@ -57,15 +56,17 @@ index 0000000000..f09097709a
+}
+
+/**
+ * Remove the device deasserting the dclk, thus disabling the VOP.
+ * This is essential to avoid iommu complaining later during kernel boot
+ * During remove phase we assert the resets and deassert them,
+ * so in practice we "turn off" the VOP resetting it and then
+ * "turn on" it. This is especially true for the dlck because
+ * this avoids iommu complaining later during kernel boot
+ * @see https://lore.kernel.org/linux-arm-kernel/20230330131746.1475514-1-jagan@amarulasolutions.com/
+ */
+static int rk3228_vop_remove(struct udevice *dev)
+{
+ struct rk_vop_priv *priv = dev_get_priv(dev);
+ struct rk3288_vop *regs = priv->regs;
+ struct reset_ctl dclk_rst;
+ struct reset_ctl_bulk resets;
+
+ int ret;
+
@ -75,20 +76,17 @@ index 0000000000..f09097709a
+ setbits_le32(&regs->sys_ctrl, V_STANDBY_EN(1));
+ clrsetbits_le32(&regs->sys_ctrl, M_ALL_OUT_EN, 0x0);
+
+ ret = reset_get_by_name(dev, "dclk", &dclk_rst);
+ if (ret)
+ printf("failed to get dclk reset (ret=%d)\n", ret);
+
+ /* assert and deassert reset */
+ ret = reset_assert(&dclk_rst);
+ if (ret)
+ printf("failed to assert dclk reset (ret=%d)\n", ret);
+ ret = reset_get_bulk(dev, &resets);
+ if (ret) {
+ printf("failed to get resets (ret=%d)\n", ret);
+ return ret;
+ }
+
+ reset_assert_bulk(&resets);
+ udelay(20);
+
+ ret = reset_deassert(&dclk_rst);
+ if (ret)
+ printf("failed to deassert dclk reset (ret=%d)\n", ret);
+ reset_deassert_bulk(&resets);
+ udelay(20);
+
+ return 0;
+