summaryrefslogtreecommitdiffstats
path: root/target/linux/bcm27xx/patches-6.1/950-0943-drm-vc4-hvs-Create-hw_init-function.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/bcm27xx/patches-6.1/950-0943-drm-vc4-hvs-Create-hw_init-function.patch')
-rw-r--r--target/linux/bcm27xx/patches-6.1/950-0943-drm-vc4-hvs-Create-hw_init-function.patch188
1 files changed, 188 insertions, 0 deletions
diff --git a/target/linux/bcm27xx/patches-6.1/950-0943-drm-vc4-hvs-Create-hw_init-function.patch b/target/linux/bcm27xx/patches-6.1/950-0943-drm-vc4-hvs-Create-hw_init-function.patch
new file mode 100644
index 0000000000..5b748b5e94
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.1/950-0943-drm-vc4-hvs-Create-hw_init-function.patch
@@ -0,0 +1,188 @@
+From f3c84bb53107cef0009347d071c1a188ce24b8a3 Mon Sep 17 00:00:00 2001
+From: Maxime Ripard <maxime@cerno.tech>
+Date: Fri, 17 Feb 2023 14:36:28 +0100
+Subject: [PATCH] drm/vc4: hvs: Create hw_init function
+
+Since the BCM2712 will feature a significantly different HVS, let's move
+the hardware initialisation part of our bind function into a separate
+function.
+
+That way, it will be easier to extend in the future.
+
+Signed-off-by: Maxime Ripard <maxime@cerno.tech>
+---
+ drivers/gpu/drm/vc4/vc4_hvs.c | 155 ++++++++++++++++++----------------
+ 1 file changed, 83 insertions(+), 72 deletions(-)
+
+--- a/drivers/gpu/drm/vc4/vc4_hvs.c
++++ b/drivers/gpu/drm/vc4/vc4_hvs.c
+@@ -1291,79 +1291,10 @@ struct vc4_hvs *__vc4_hvs_alloc(struct v
+ return hvs;
+ }
+
+-static int vc4_hvs_bind(struct device *dev, struct device *master, void *data)
++static int vc4_hvs_hw_init(struct vc4_hvs *hvs)
+ {
+- struct platform_device *pdev = to_platform_device(dev);
+- struct drm_device *drm = dev_get_drvdata(master);
+- struct vc4_dev *vc4 = to_vc4_dev(drm);
+- struct vc4_hvs *hvs = NULL;
+- int ret;
+- u32 dispctrl;
+- u32 reg, top;
+-
+- hvs = __vc4_hvs_alloc(vc4, NULL);
+- if (IS_ERR(hvs))
+- return PTR_ERR(hvs);
+-
+- hvs->regs = vc4_ioremap_regs(pdev, 0);
+- if (IS_ERR(hvs->regs))
+- return PTR_ERR(hvs->regs);
+-
+- hvs->regset.base = hvs->regs;
+- hvs->regset.regs = hvs_regs;
+- hvs->regset.nregs = ARRAY_SIZE(hvs_regs);
+-
+- if (vc4->gen == VC4_GEN_5) {
+- struct rpi_firmware *firmware;
+- struct device_node *node;
+- unsigned int max_rate;
+-
+- node = rpi_firmware_find_node();
+- if (!node)
+- return -EINVAL;
+-
+- firmware = rpi_firmware_get(node);
+- of_node_put(node);
+- if (!firmware)
+- return -EPROBE_DEFER;
+-
+- hvs->core_clk = devm_clk_get(&pdev->dev, NULL);
+- if (IS_ERR(hvs->core_clk)) {
+- dev_err(&pdev->dev, "Couldn't get core clock\n");
+- return PTR_ERR(hvs->core_clk);
+- }
+-
+- max_rate = rpi_firmware_clk_get_max_rate(firmware,
+- RPI_FIRMWARE_CORE_CLK_ID);
+- rpi_firmware_put(firmware);
+- if (max_rate >= 550000000)
+- hvs->vc5_hdmi_enable_hdmi_20 = true;
+-
+- if (max_rate >= 600000000)
+- hvs->vc5_hdmi_enable_4096by2160 = true;
+-
+- hvs->max_core_rate = max_rate;
+-
+- ret = clk_prepare_enable(hvs->core_clk);
+- if (ret) {
+- dev_err(&pdev->dev, "Couldn't enable the core clock\n");
+- return ret;
+- }
+- }
+-
+- if (vc4->gen == VC4_GEN_4)
+- hvs->dlist = hvs->regs + SCALER_DLIST_START;
+- else
+- hvs->dlist = hvs->regs + SCALER5_DLIST_START;
+-
+- /* Upload filter kernels. We only have the one for now, so we
+- * keep it around for the lifetime of the driver.
+- */
+- ret = vc4_hvs_upload_linear_kernel(hvs,
+- &hvs->mitchell_netravali_filter,
+- mitchell_netravali_1_3_1_3_kernel);
+- if (ret)
+- return ret;
++ struct vc4_dev *vc4 = hvs->vc4;
++ u32 dispctrl, reg;
+
+ reg = HVS_READ(SCALER_DISPECTRL);
+ reg &= ~SCALER_DISPECTRL_DSP2_MUX_MASK;
+@@ -1445,6 +1376,86 @@ static int vc4_hvs_bind(struct device *d
+
+ HVS_WRITE(SCALER_DISPCTRL, dispctrl);
+
++ return 0;
++}
++
++static int vc4_hvs_bind(struct device *dev, struct device *master, void *data)
++{
++ struct platform_device *pdev = to_platform_device(dev);
++ struct drm_device *drm = dev_get_drvdata(master);
++ struct vc4_dev *vc4 = to_vc4_dev(drm);
++ struct vc4_hvs *hvs = NULL;
++ int ret;
++ u32 reg, top;
++
++ hvs = __vc4_hvs_alloc(vc4, NULL);
++ if (IS_ERR(hvs))
++ return PTR_ERR(hvs);
++
++ hvs->regs = vc4_ioremap_regs(pdev, 0);
++ if (IS_ERR(hvs->regs))
++ return PTR_ERR(hvs->regs);
++
++ hvs->regset.base = hvs->regs;
++ hvs->regset.regs = hvs_regs;
++ hvs->regset.nregs = ARRAY_SIZE(hvs_regs);
++
++ if (vc4->gen == VC4_GEN_5) {
++ struct rpi_firmware *firmware;
++ struct device_node *node;
++ unsigned int max_rate;
++
++ node = rpi_firmware_find_node();
++ if (!node)
++ return -EINVAL;
++
++ firmware = rpi_firmware_get(node);
++ of_node_put(node);
++ if (!firmware)
++ return -EPROBE_DEFER;
++
++ hvs->core_clk = devm_clk_get(&pdev->dev, NULL);
++ if (IS_ERR(hvs->core_clk)) {
++ dev_err(&pdev->dev, "Couldn't get core clock\n");
++ return PTR_ERR(hvs->core_clk);
++ }
++
++ max_rate = rpi_firmware_clk_get_max_rate(firmware,
++ RPI_FIRMWARE_CORE_CLK_ID);
++ rpi_firmware_put(firmware);
++ if (max_rate >= 550000000)
++ hvs->vc5_hdmi_enable_hdmi_20 = true;
++
++ if (max_rate >= 600000000)
++ hvs->vc5_hdmi_enable_4096by2160 = true;
++
++ hvs->max_core_rate = max_rate;
++
++ ret = clk_prepare_enable(hvs->core_clk);
++ if (ret) {
++ dev_err(&pdev->dev, "Couldn't enable the core clock\n");
++ return ret;
++ }
++ }
++
++ if (vc4->gen == VC4_GEN_4)
++ hvs->dlist = hvs->regs + SCALER_DLIST_START;
++ else
++ hvs->dlist = hvs->regs + SCALER5_DLIST_START;
++
++ /* Upload filter kernels. We only have the one for now, so we
++ * keep it around for the lifetime of the driver.
++ */
++ ret = vc4_hvs_upload_linear_kernel(hvs,
++ &hvs->mitchell_netravali_filter,
++ mitchell_netravali_1_3_1_3_kernel);
++ if (ret)
++ return ret;
++
++ ret = vc4_hvs_hw_init(hvs);
++ if (ret)
++ return ret;
++
+ /* Recompute Composite Output Buffer (COB) allocations for the displays
+ */
+ if (vc4->gen == VC4_GEN_4) {