mirror of
https://github.com/armbian/build.git
synced 2025-09-19 12:41:39 +02:00
Fix: dtb dtbo install, wrong select media sensors Disable incorrectly designed patches. They need to be aligned with the kernel code.
979 lines
31 KiB
Diff
979 lines
31 KiB
Diff
From 6a040d7333daad91cbcf44e4e777ff4050ccf30e Mon Sep 17 00:00:00 2001
|
|
From: orangepi-xunlong <258384131@qq.com>
|
|
Date: Mon, 5 Jun 2023 14:16:04 +0800
|
|
Subject: [PATCH] drivers: hack for h616 hdmi video output
|
|
|
|
---
|
|
drivers/clk/sunxi-ng/Kconfig | 4 +
|
|
drivers/clk/sunxi-ng/Makefile | 2 +
|
|
drivers/clk/sunxi-ng/ccu-sun8i-de33.c | 181 +++++++++++++++++++++
|
|
drivers/clk/sunxi-ng/ccu-sun8i-de33.h | 19 +++
|
|
drivers/gpu/drm/sun4i/sun4i_tcon.c | 4 +
|
|
drivers/gpu/drm/sun4i/sun4i_tcon.h | 1 +
|
|
drivers/gpu/drm/sun4i/sun8i_csc.c | 51 +++++-
|
|
drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c | 81 ++++++++++
|
|
drivers/gpu/drm/sun4i/sun8i_mixer.c | 200 +++++++++++++++++++-----
|
|
drivers/gpu/drm/sun4i/sun8i_mixer.h | 22 ++-
|
|
drivers/gpu/drm/sun4i/sun8i_ui_layer.c | 22 ++-
|
|
drivers/gpu/drm/sun4i/sun8i_vi_layer.c | 6 +-
|
|
drivers/gpu/drm/sun4i/sun8i_vi_scaler.c | 4 +-
|
|
13 files changed, 547 insertions(+), 50 deletions(-)
|
|
create mode 100644 drivers/clk/sunxi-ng/ccu-sun8i-de33.c
|
|
create mode 100644 drivers/clk/sunxi-ng/ccu-sun8i-de33.h
|
|
|
|
diff --git a/drivers/clk/sunxi-ng/Kconfig b/drivers/clk/sunxi-ng/Kconfig
|
|
index 461537679..2ca069af4 100644
|
|
--- a/drivers/clk/sunxi-ng/Kconfig
|
|
+++ b/drivers/clk/sunxi-ng/Kconfig
|
|
@@ -103,6 +103,10 @@ config SUN8I_DE2_CCU
|
|
tristate "Support for the Allwinner SoCs DE2 CCU"
|
|
default MACH_SUN8I || (ARM64 && ARCH_SUNXI)
|
|
|
|
+config SUN8I_DE33_CCU
|
|
+ tristate "Support for the Allwinner SoCs DE3.3 CCU"
|
|
+ default MACH_SUN8I || (ARM64 && ARCH_SUNXI)
|
|
+
|
|
config SUN8I_R40_CCU
|
|
tristate "Support for the Allwinner R40 CCU"
|
|
default MACH_SUN8I
|
|
diff --git a/drivers/clk/sunxi-ng/Makefile b/drivers/clk/sunxi-ng/Makefile
|
|
index 6b3ae2b62..cd20050cd 100644
|
|
--- a/drivers/clk/sunxi-ng/Makefile
|
|
+++ b/drivers/clk/sunxi-ng/Makefile
|
|
@@ -44,6 +44,7 @@ obj-$(CONFIG_SUN8I_H3_CCU) += sun8i-h3-ccu.o
|
|
obj-$(CONFIG_SUN8I_R40_CCU) += sun8i-r40-ccu.o
|
|
obj-$(CONFIG_SUN8I_V3S_CCU) += sun8i-v3s-ccu.o
|
|
obj-$(CONFIG_SUN8I_DE2_CCU) += sun8i-de2-ccu.o
|
|
+obj-$(CONFIG_SUN8I_DE33_CCU) += sun8i-de33-ccu.o
|
|
obj-$(CONFIG_SUN8I_R_CCU) += sun8i-r-ccu.o
|
|
obj-$(CONFIG_SUN9I_A80_CCU) += sun9i-a80-ccu.o
|
|
obj-$(CONFIG_SUN9I_A80_CCU) += sun9i-a80-de-ccu.o
|
|
@@ -69,6 +70,7 @@ sun8i-h3-ccu-y += ccu-sun8i-h3.o
|
|
sun8i-r40-ccu-y += ccu-sun8i-r40.o
|
|
sun8i-v3s-ccu-y += ccu-sun8i-v3s.o
|
|
sun8i-de2-ccu-y += ccu-sun8i-de2.o
|
|
+sun8i-de33-ccu-y += ccu-sun8i-de33.o
|
|
sun8i-r-ccu-y += ccu-sun8i-r.o
|
|
sun9i-a80-ccu-y += ccu-sun9i-a80.o
|
|
sun9i-a80-de-ccu-y += ccu-sun9i-a80-de.o
|
|
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-de33.c b/drivers/clk/sunxi-ng/ccu-sun8i-de33.c
|
|
new file mode 100644
|
|
index 000000000..fa5b1cf62
|
|
--- /dev/null
|
|
+++ b/drivers/clk/sunxi-ng/ccu-sun8i-de33.c
|
|
@@ -0,0 +1,181 @@
|
|
+// SPDX-License-Identifier: GPL-2.0-only
|
|
+/*
|
|
+ * Copyright (c) 2017 Icenowy Zheng <icenowy@aosc.io>
|
|
+ */
|
|
+
|
|
+#include <linux/clk.h>
|
|
+#include <linux/clk-provider.h>
|
|
+#include <linux/of_address.h>
|
|
+#include <linux/of_platform.h>
|
|
+#include <linux/platform_device.h>
|
|
+#include <linux/reset.h>
|
|
+
|
|
+#include "ccu_common.h"
|
|
+#include "ccu_div.h"
|
|
+#include "ccu_gate.h"
|
|
+#include "ccu_reset.h"
|
|
+
|
|
+#include "ccu-sun8i-de33.h"
|
|
+
|
|
+static SUNXI_CCU_GATE(bus_mixer0_clk, "bus-mixer0", "bus-de",
|
|
+ 0x04, BIT(0), 0);
|
|
+static SUNXI_CCU_GATE(bus_mixer1_clk, "bus-mixer1", "bus-de",
|
|
+ 0x04, BIT(1), 0);
|
|
+static SUNXI_CCU_GATE(bus_wb_clk, "bus-wb", "bus-de",
|
|
+ 0x04, BIT(2), 0);
|
|
+
|
|
+static SUNXI_CCU_GATE(mixer0_clk, "mixer0", "mixer0-div",
|
|
+ 0x00, BIT(0), CLK_SET_RATE_PARENT);
|
|
+static SUNXI_CCU_GATE(mixer1_clk, "mixer1", "mixer1-div",
|
|
+ 0x00, BIT(1), CLK_SET_RATE_PARENT);
|
|
+static SUNXI_CCU_GATE(wb_clk, "wb", "wb-div",
|
|
+ 0x00, BIT(2), CLK_SET_RATE_PARENT);
|
|
+
|
|
+static SUNXI_CCU_M(mixer0_div_clk, "mixer0-div", "de", 0x0c, 0, 4,
|
|
+ CLK_SET_RATE_PARENT);
|
|
+static SUNXI_CCU_M(mixer1_div_clk, "mixer1-div", "de", 0x0c, 4, 4,
|
|
+ CLK_SET_RATE_PARENT);
|
|
+static SUNXI_CCU_M(wb_div_clk, "wb-div", "de", 0x0c, 8, 4,
|
|
+ CLK_SET_RATE_PARENT);
|
|
+
|
|
+static struct ccu_common *sun50i_h616_de33_clks[] = {
|
|
+ &mixer0_clk.common,
|
|
+ &mixer1_clk.common,
|
|
+ &wb_clk.common,
|
|
+
|
|
+ &bus_mixer0_clk.common,
|
|
+ &bus_mixer1_clk.common,
|
|
+ &bus_wb_clk.common,
|
|
+
|
|
+ &mixer0_div_clk.common,
|
|
+ &mixer1_div_clk.common,
|
|
+ &wb_div_clk.common,
|
|
+};
|
|
+
|
|
+static struct clk_hw_onecell_data sun50i_h616_de33_hw_clks = {
|
|
+ .hws = {
|
|
+ [CLK_MIXER0] = &mixer0_clk.common.hw,
|
|
+ [CLK_MIXER1] = &mixer1_clk.common.hw,
|
|
+ [CLK_WB] = &wb_clk.common.hw,
|
|
+
|
|
+ [CLK_BUS_MIXER0] = &bus_mixer0_clk.common.hw,
|
|
+ [CLK_BUS_MIXER1] = &bus_mixer1_clk.common.hw,
|
|
+ [CLK_BUS_WB] = &bus_wb_clk.common.hw,
|
|
+
|
|
+ [CLK_MIXER0_DIV] = &mixer0_div_clk.common.hw,
|
|
+ [CLK_MIXER1_DIV] = &mixer1_div_clk.common.hw,
|
|
+ [CLK_WB_DIV] = &wb_div_clk.common.hw,
|
|
+ },
|
|
+ .num = CLK_NUMBER,
|
|
+};
|
|
+
|
|
+static struct ccu_reset_map sun50i_h616_de33_resets[] = {
|
|
+ [RST_MIXER0] = { 0x08, BIT(0) },
|
|
+ [RST_MIXER1] = { 0x08, BIT(1) },
|
|
+ [RST_WB] = { 0x08, BIT(2) },
|
|
+};
|
|
+
|
|
+static const struct sunxi_ccu_desc sun50i_h616_de33_clk_desc = {
|
|
+ .ccu_clks = sun50i_h616_de33_clks,
|
|
+ .num_ccu_clks = ARRAY_SIZE(sun50i_h616_de33_clks),
|
|
+
|
|
+ .hw_clks = &sun50i_h616_de33_hw_clks,
|
|
+
|
|
+ .resets = sun50i_h616_de33_resets,
|
|
+ .num_resets = ARRAY_SIZE(sun50i_h616_de33_resets),
|
|
+};
|
|
+
|
|
+static int sunxi_de33_clk_probe(struct platform_device *pdev)
|
|
+{
|
|
+ struct resource *res;
|
|
+ struct clk *bus_clk, *mod_clk;
|
|
+ struct reset_control *rstc;
|
|
+ void __iomem *reg;
|
|
+ const struct sunxi_ccu_desc *ccu_desc;
|
|
+ int ret;
|
|
+
|
|
+ ccu_desc = of_device_get_match_data(&pdev->dev);
|
|
+ if (!ccu_desc)
|
|
+ return -EINVAL;
|
|
+
|
|
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
|
+ reg = devm_ioremap_resource(&pdev->dev, res);
|
|
+ if (IS_ERR(reg))
|
|
+ return PTR_ERR(reg);
|
|
+
|
|
+ bus_clk = devm_clk_get(&pdev->dev, "bus");
|
|
+ if (IS_ERR(bus_clk)) {
|
|
+ ret = PTR_ERR(bus_clk);
|
|
+ if (ret != -EPROBE_DEFER)
|
|
+ dev_err(&pdev->dev, "Couldn't get bus clk: %d\n", ret);
|
|
+ return ret;
|
|
+ }
|
|
+
|
|
+ mod_clk = devm_clk_get(&pdev->dev, "mod");
|
|
+ if (IS_ERR(mod_clk)) {
|
|
+ ret = PTR_ERR(mod_clk);
|
|
+ if (ret != -EPROBE_DEFER)
|
|
+ dev_err(&pdev->dev, "Couldn't get mod clk: %d\n", ret);
|
|
+ return ret;
|
|
+ }
|
|
+
|
|
+ rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL);
|
|
+ if (IS_ERR(rstc)) {
|
|
+ ret = PTR_ERR(rstc);
|
|
+ if (ret != -EPROBE_DEFER)
|
|
+ dev_err(&pdev->dev,
|
|
+ "Couldn't get reset control: %d\n", ret);
|
|
+ return ret;
|
|
+ }
|
|
+
|
|
+ /* The clocks need to be enabled for us to access the registers */
|
|
+ ret = clk_prepare_enable(bus_clk);
|
|
+ if (ret) {
|
|
+ dev_err(&pdev->dev, "Couldn't enable bus clk: %d\n", ret);
|
|
+ return ret;
|
|
+ }
|
|
+
|
|
+ ret = clk_prepare_enable(mod_clk);
|
|
+ if (ret) {
|
|
+ dev_err(&pdev->dev, "Couldn't enable mod clk: %d\n", ret);
|
|
+ goto err_disable_bus_clk;
|
|
+ }
|
|
+
|
|
+ /* The reset control needs to be asserted for the controls to work */
|
|
+ ret = reset_control_deassert(rstc);
|
|
+ if (ret) {
|
|
+ dev_err(&pdev->dev,
|
|
+ "Couldn't deassert reset control: %d\n", ret);
|
|
+ goto err_disable_mod_clk;
|
|
+ }
|
|
+
|
|
+ writel(0, reg + 0x24);
|
|
+ writel(0x0000A980, reg + 0x28);
|
|
+
|
|
+ of_sunxi_ccu_probe(pdev->dev.of_node, reg, ccu_desc);
|
|
+
|
|
+ return 0;
|
|
+
|
|
+err_disable_mod_clk:
|
|
+ clk_disable_unprepare(mod_clk);
|
|
+err_disable_bus_clk:
|
|
+ clk_disable_unprepare(bus_clk);
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+static const struct of_device_id sunxi_de33_clk_ids[] = {
|
|
+ {
|
|
+ .compatible = "allwinner,sun50i-h616-de33-clk",
|
|
+ .data = &sun50i_h616_de33_clk_desc,
|
|
+ },
|
|
+ { }
|
|
+};
|
|
+
|
|
+static struct platform_driver sunxi_de33_clk_driver = {
|
|
+ .probe = sunxi_de33_clk_probe,
|
|
+ .driver = {
|
|
+ .name = "sunxi-de33-clks",
|
|
+ .of_match_table = sunxi_de33_clk_ids,
|
|
+ },
|
|
+};
|
|
+builtin_platform_driver(sunxi_de33_clk_driver);
|
|
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-de33.h b/drivers/clk/sunxi-ng/ccu-sun8i-de33.h
|
|
new file mode 100644
|
|
index 000000000..83cbef5a3
|
|
--- /dev/null
|
|
+++ b/drivers/clk/sunxi-ng/ccu-sun8i-de33.h
|
|
@@ -0,0 +1,19 @@
|
|
+/* SPDX-License-Identifier: GPL-2.0-or-later */
|
|
+/*
|
|
+ * Copyright 2016 Icenowy Zheng <icenowy@aosc.io>
|
|
+ */
|
|
+
|
|
+#ifndef _CCU_SUN8I_DE2_H_
|
|
+#define _CCU_SUN8I_DE2_H_
|
|
+
|
|
+#include <dt-bindings/clock/sun8i-de2.h>
|
|
+#include <dt-bindings/reset/sun8i-de2.h>
|
|
+
|
|
+/* Intermediary clock dividers are not exported */
|
|
+#define CLK_MIXER0_DIV 3
|
|
+#define CLK_MIXER1_DIV 4
|
|
+#define CLK_WB_DIV 5
|
|
+
|
|
+#define CLK_NUMBER (CLK_WB + 1)
|
|
+
|
|
+#endif /* _CCU_SUN8I_DE2_H_ */
|
|
diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/sun4i_tcon.c
|
|
index 972f44e13..3bf7bbbf1 100644
|
|
--- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
|
|
+++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
|
|
@@ -1313,6 +1313,10 @@ static int sun4i_tcon_bind(struct device *dev, struct device *master,
|
|
goto err_free_dotclock;
|
|
}
|
|
|
|
+ regmap_update_bits(tcon->regs, SUN4I_TCON_GCTL_REG,
|
|
+ SUN4I_TCON_GCTL_PAD_SEL,
|
|
+ SUN4I_TCON_GCTL_PAD_SEL);
|
|
+
|
|
if (tcon->quirks->needs_de_be_mux) {
|
|
/*
|
|
* We assume there is no dynamic muxing of backends
|
|
diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.h b/drivers/gpu/drm/sun4i/sun4i_tcon.h
|
|
index 7ba3df9e2..e8687a696 100644
|
|
--- a/drivers/gpu/drm/sun4i/sun4i_tcon.h
|
|
+++ b/drivers/gpu/drm/sun4i/sun4i_tcon.h
|
|
@@ -20,6 +20,7 @@
|
|
#define SUN4I_TCON_GCTL_REG 0x0
|
|
#define SUN4I_TCON_GCTL_TCON_ENABLE BIT(31)
|
|
#define SUN4I_TCON_GCTL_GAMMA_ENABLE BIT(30)
|
|
+#define SUN4I_TCON_GCTL_PAD_SEL BIT (1)
|
|
#define SUN4I_TCON_GCTL_IOMAP_MASK BIT(0)
|
|
#define SUN4I_TCON_GCTL_IOMAP_TCON1 (1 << 0)
|
|
#define SUN4I_TCON_GCTL_IOMAP_TCON0 (0 << 0)
|
|
diff --git a/drivers/gpu/drm/sun4i/sun8i_csc.c b/drivers/gpu/drm/sun4i/sun8i_csc.c
|
|
index 58480d8e4..703c55ba7 100644
|
|
--- a/drivers/gpu/drm/sun4i/sun8i_csc.c
|
|
+++ b/drivers/gpu/drm/sun4i/sun8i_csc.c
|
|
@@ -107,6 +107,14 @@ static const u32 yuv2rgb_de3[2][3][12] = {
|
|
},
|
|
};
|
|
|
|
+static u32 sun8i_csc_base(struct sun8i_mixer *mixer, int layer)
|
|
+{
|
|
+ if (mixer->cfg->is_de33)
|
|
+ return sun8i_channel_base(mixer, layer) - 0x200;
|
|
+ else
|
|
+ return ccsc_base[mixer->cfg->ccsc][layer];
|
|
+}
|
|
+
|
|
static void sun8i_csc_set_coefficients(struct regmap *map, u32 base,
|
|
enum sun8i_csc_mode mode,
|
|
enum drm_color_encoding encoding,
|
|
@@ -178,6 +186,41 @@ static void sun8i_de3_ccsc_set_coefficients(struct regmap *map, int layer,
|
|
}
|
|
}
|
|
|
|
+static void sun8i_de33_ccsc_set_coefficients(struct sun8i_mixer *mixer,
|
|
+ int layer,
|
|
+ enum sun8i_csc_mode mode,
|
|
+ enum drm_color_encoding encoding,
|
|
+ enum drm_color_range range)
|
|
+{
|
|
+ const u32 *table;
|
|
+ u32 base, addr;
|
|
+ int i;
|
|
+
|
|
+ base = sun8i_csc_base(mixer, layer);
|
|
+ table = yuv2rgb_de3[range][encoding];
|
|
+
|
|
+ regmap_write(mixer->engine.regs, base + 4, table[3] >> 16);
|
|
+ regmap_write(mixer->engine.regs, base + 8, table[7] >> 16);
|
|
+ regmap_write(mixer->engine.regs, base + 12, table[11] >> 16);
|
|
+
|
|
+ for (i = 0; i < 12; i++) {
|
|
+ u32 val = table[i];
|
|
+
|
|
+ addr = SUN8I_CSC_COEFF(base, i);
|
|
+ if (mode == SUN8I_CSC_MODE_YVU2RGB) {
|
|
+ if ((i & 3) == 1)
|
|
+ addr = SUN8I_CSC_COEFF(base, i + 1);
|
|
+ else if ((i & 3) == 2)
|
|
+ addr = SUN8I_CSC_COEFF(base, i - 1);
|
|
+ }
|
|
+
|
|
+ if (i == 3 || i == 7 || i == 11)
|
|
+ val &= 0xffff;
|
|
+
|
|
+ regmap_write(mixer->engine.regs, addr, val);
|
|
+ }
|
|
+}
|
|
+
|
|
static void sun8i_csc_enable(struct regmap *map, u32 base, bool enable)
|
|
{
|
|
u32 val;
|
|
@@ -218,6 +261,12 @@ void sun8i_csc_set_ccsc_coefficients(struct sun8i_mixer *mixer, int layer,
|
|
return;
|
|
}
|
|
|
|
+ if (mixer->cfg->is_de33) {
|
|
+ sun8i_de33_ccsc_set_coefficients(mixer, layer, mode,
|
|
+ encoding, range);
|
|
+ return;
|
|
+ }
|
|
+
|
|
base = ccsc_base[mixer->cfg->ccsc][layer];
|
|
|
|
sun8i_csc_set_coefficients(mixer->engine.regs, base,
|
|
@@ -233,7 +282,7 @@ void sun8i_csc_enable_ccsc(struct sun8i_mixer *mixer, int layer, bool enable)
|
|
return;
|
|
}
|
|
|
|
- base = ccsc_base[mixer->cfg->ccsc][layer];
|
|
+ base = sun8i_csc_base(mixer, layer);
|
|
|
|
sun8i_csc_enable(mixer->engine.regs, base, enable);
|
|
}
|
|
diff --git a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
|
|
index ca53b5e9f..856b5ab5b 100644
|
|
--- a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
|
|
+++ b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
|
|
@@ -123,6 +123,76 @@ static const struct dw_hdmi_phy_config sun50i_h6_phy_config[] = {
|
|
{ ~0UL, 0x0000, 0x0000, 0x0000}
|
|
};
|
|
|
|
+static const struct dw_hdmi_mpll_config sun50i_h616_mpll_cfg[] = {
|
|
+ {
|
|
+ 27000000,
|
|
+ {
|
|
+ {0x00b3, 0x0003},
|
|
+ {0x2153, 0x0003},
|
|
+ {0x40f3, 0x0003},
|
|
+ },
|
|
+ },
|
|
+ {
|
|
+ 74250000,
|
|
+ {
|
|
+ {0x0072, 0x0003},
|
|
+ {0x2145, 0x0003},
|
|
+ {0x4061, 0x0003},
|
|
+ },
|
|
+ },
|
|
+ {
|
|
+ 148500000,
|
|
+ {
|
|
+ {0x0051, 0x0003},
|
|
+ {0x214c, 0x0003},
|
|
+ {0x4064, 0x0003},
|
|
+ },
|
|
+ },
|
|
+ {
|
|
+ 297000000,
|
|
+ {
|
|
+ {0x0040, 0x0003},
|
|
+ {0x3b4c, 0x0003},
|
|
+ {0x5a64, 0x0003},
|
|
+ },
|
|
+ },
|
|
+ {
|
|
+ 594000000,
|
|
+ {
|
|
+ {0x1a40, 0x0003},
|
|
+ {0x3b4c, 0x0003},
|
|
+ {0x5a64, 0x0003},
|
|
+ },
|
|
+ },
|
|
+ {
|
|
+ ~0UL,
|
|
+ {
|
|
+ {0x0000, 0x0000},
|
|
+ {0x0000, 0x0000},
|
|
+ {0x0000, 0x0000},
|
|
+ },
|
|
+ }};
|
|
+
|
|
+static const struct dw_hdmi_curr_ctrl sun50i_h616_cur_ctr[] = {
|
|
+ /* pixelclk bpp8 bpp10 bpp12 */
|
|
+ { 27000000, { 0x0012, 0x0000, 0x0000 }, },
|
|
+ { 74250000, { 0x0013, 0x0013, 0x0013 }, },
|
|
+ { 148500000, { 0x0019, 0x0019, 0x0019 }, },
|
|
+ { 297000000, { 0x0019, 0x001b, 0x0019 }, },
|
|
+ { 594000000, { 0x0010, 0x0010, 0x0010 }, },
|
|
+ { ~0UL, { 0x0000, 0x0000, 0x0000 }, }
|
|
+};
|
|
+
|
|
+static const struct dw_hdmi_phy_config sun50i_h616_phy_config[] = {
|
|
+ /*pixelclk symbol term vlev*/
|
|
+ {27000000, 0x8009, 0x0007, 0x02b0},
|
|
+ {74250000, 0x8019, 0x0004, 0x0290},
|
|
+ {148500000, 0x8019, 0x0004, 0x0290},
|
|
+ {297000000, 0x8039, 0x0004, 0x022b},
|
|
+ {594000000, 0x8029, 0x0000, 0x008a},
|
|
+ {~0UL, 0x0000, 0x0000, 0x0000}
|
|
+};
|
|
+
|
|
static void sun8i_hdmi_phy_set_polarity(struct sun8i_hdmi_phy *phy,
|
|
const struct drm_display_mode *mode)
|
|
{
|
|
@@ -625,6 +695,13 @@ static const struct sun8i_hdmi_phy_variant sun50i_h6_hdmi_phy = {
|
|
.phy_init = &sun50i_hdmi_phy_init_h6,
|
|
};
|
|
|
|
+static const struct sun8i_hdmi_phy_variant sun50i_h616_hdmi_phy = {
|
|
+ .cur_ctr = sun50i_h616_cur_ctr,
|
|
+ .mpll_cfg = sun50i_h616_mpll_cfg,
|
|
+ .phy_cfg = sun50i_h616_phy_config,
|
|
+ .phy_init = &sun50i_hdmi_phy_init_h6,
|
|
+};
|
|
+
|
|
static const struct of_device_id sun8i_hdmi_phy_of_table[] = {
|
|
{
|
|
.compatible = "allwinner,sun8i-a83t-hdmi-phy",
|
|
@@ -646,6 +723,10 @@ static const struct of_device_id sun8i_hdmi_phy_of_table[] = {
|
|
.compatible = "allwinner,sun50i-h6-hdmi-phy",
|
|
.data = &sun50i_h6_hdmi_phy,
|
|
},
|
|
+ {
|
|
+ .compatible = "allwinner,sun50i-h616-hdmi-phy",
|
|
+ .data = &sun50i_h616_hdmi_phy,
|
|
+ },
|
|
{ /* sentinel */ }
|
|
};
|
|
|
|
diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/sun4i/sun8i_mixer.c
|
|
index 9aae44e33..cf620cca2 100644
|
|
--- a/drivers/gpu/drm/sun4i/sun8i_mixer.c
|
|
+++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c
|
|
@@ -278,6 +278,9 @@ static void sun8i_mixer_commit(struct sunxi_engine *engine,
|
|
struct drm_plane_state *plane_state;
|
|
struct drm_plane *plane;
|
|
u32 route = 0, pipe_en = 0;
|
|
+ struct regmap *bld_regs;
|
|
+
|
|
+ bld_regs = sun8i_blender_regmap(mixer);
|
|
|
|
if (mixer->hw_preconfigured && engine->id == 0) {
|
|
struct sun4i_tcon* tcon;
|
|
@@ -339,7 +342,7 @@ static void sun8i_mixer_commit(struct sunxi_engine *engine,
|
|
pipe_en |= SUN8I_MIXER_BLEND_PIPE_CTL_EN(zpos);
|
|
}
|
|
|
|
- regmap_update_bits(mixer->engine.regs,
|
|
+ regmap_update_bits(bld_regs,
|
|
SUN8I_MIXER_BLEND_ROUTE(bld_base),
|
|
SUN8I_MIXER_BLEND_ROUTE_PIPE_MSK(0) |
|
|
SUN8I_MIXER_BLEND_ROUTE_PIPE_MSK(1) |
|
|
@@ -347,7 +350,7 @@ static void sun8i_mixer_commit(struct sunxi_engine *engine,
|
|
SUN8I_MIXER_BLEND_ROUTE_PIPE_MSK(3),
|
|
route);
|
|
|
|
- regmap_update_bits(mixer->engine.regs,
|
|
+ regmap_update_bits(bld_regs,
|
|
SUN8I_MIXER_BLEND_PIPE_CTL(bld_base),
|
|
SUN8I_MIXER_BLEND_PIPE_CTL_EN(0) |
|
|
SUN8I_MIXER_BLEND_PIPE_CTL_EN(1) |
|
|
@@ -355,8 +358,12 @@ static void sun8i_mixer_commit(struct sunxi_engine *engine,
|
|
SUN8I_MIXER_BLEND_PIPE_CTL_EN(3),
|
|
pipe_en);
|
|
|
|
- regmap_write(engine->regs, SUN8I_MIXER_GLOBAL_DBUFF,
|
|
- SUN8I_MIXER_GLOBAL_DBUFF_ENABLE);
|
|
+ if (mixer->cfg->is_de33)
|
|
+ regmap_write(mixer->top_regs, SUN50I_MIXER_GLOBAL_DBUFF,
|
|
+ SUN8I_MIXER_GLOBAL_DBUFF_ENABLE);
|
|
+ else
|
|
+ regmap_write(engine->regs, SUN8I_MIXER_GLOBAL_DBUFF,
|
|
+ SUN8I_MIXER_GLOBAL_DBUFF_ENABLE);
|
|
}
|
|
|
|
static struct drm_plane **sun8i_layers_init(struct drm_device *drm,
|
|
@@ -405,25 +412,31 @@ static void sun8i_mixer_mode_set(struct sunxi_engine *engine,
|
|
const struct drm_display_mode *mode)
|
|
{
|
|
struct sun8i_mixer *mixer = engine_to_sun8i_mixer(engine);
|
|
+ struct regmap *bld_regs;
|
|
u32 bld_base, size, val;
|
|
bool interlaced;
|
|
|
|
bld_base = sun8i_blender_base(mixer);
|
|
+ bld_regs = sun8i_blender_regmap(mixer);
|
|
interlaced = !!(mode->flags & DRM_MODE_FLAG_INTERLACE);
|
|
size = SUN8I_MIXER_SIZE(mode->hdisplay, mode->vdisplay);
|
|
|
|
DRM_DEBUG_DRIVER("Updating global size W: %u H: %u\n",
|
|
mode->hdisplay, mode->vdisplay);
|
|
|
|
- regmap_write(engine->regs, SUN8I_MIXER_GLOBAL_SIZE, size);
|
|
- regmap_write(engine->regs, SUN8I_MIXER_BLEND_OUTSIZE(bld_base), size);
|
|
+ if (mixer->cfg->is_de33)
|
|
+ regmap_write(mixer->top_regs, SUN50I_MIXER_GLOBAL_SIZE, size);
|
|
+ else
|
|
+ regmap_write(engine->regs, SUN8I_MIXER_GLOBAL_SIZE, size);
|
|
+
|
|
+ regmap_write(bld_regs, SUN8I_MIXER_BLEND_OUTSIZE(bld_base), size);
|
|
|
|
if (interlaced)
|
|
val = SUN8I_MIXER_BLEND_OUTCTL_INTERLACED;
|
|
else
|
|
val = 0;
|
|
|
|
- regmap_update_bits(engine->regs, SUN8I_MIXER_BLEND_OUTCTL(bld_base),
|
|
+ regmap_update_bits(bld_regs, SUN8I_MIXER_BLEND_OUTCTL(bld_base),
|
|
SUN8I_MIXER_BLEND_OUTCTL_INTERLACED, val);
|
|
|
|
DRM_DEBUG_DRIVER("Switching display mixer interlaced mode %s\n",
|
|
@@ -443,6 +456,20 @@ static const struct regmap_config sun8i_mixer_regmap_config = {
|
|
.max_register = 0xffffc, /* guessed */
|
|
};
|
|
|
|
+static const struct regmap_config sun8i_top_regmap_config = {
|
|
+ .reg_bits = 32,
|
|
+ .val_bits = 32,
|
|
+ .reg_stride = 4,
|
|
+ .max_register = 0x3c,
|
|
+};
|
|
+
|
|
+static const struct regmap_config sun8i_disp_regmap_config = {
|
|
+ .reg_bits = 32,
|
|
+ .val_bits = 32,
|
|
+ .reg_stride = 4,
|
|
+ .max_register = 0x20000,
|
|
+};
|
|
+
|
|
static int sun8i_mixer_of_get_id(struct device_node *node)
|
|
{
|
|
struct device_node *ep, *remote;
|
|
@@ -463,6 +490,84 @@ static int sun8i_mixer_of_get_id(struct device_node *node)
|
|
return of_ep.id;
|
|
}
|
|
|
|
+static void sun8i_mixer_de2_init(struct sun8i_mixer *mixer)
|
|
+{
|
|
+ unsigned int base;
|
|
+ int plane_cnt, i;
|
|
+
|
|
+ base = sun8i_blender_base(mixer);
|
|
+
|
|
+ if (!mixer->hw_preconfigured) {
|
|
+ /* Enable the mixer */
|
|
+ regmap_write(mixer->engine.regs, SUN8I_MIXER_GLOBAL_CTL,
|
|
+ SUN8I_MIXER_GLOBAL_CTL_RT_EN);
|
|
+ } /* hw_preconfigured */
|
|
+
|
|
+ /* Set background color to black */
|
|
+ regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_BKCOLOR(base),
|
|
+ SUN8I_MIXER_BLEND_COLOR_BLACK);
|
|
+
|
|
+ /*
|
|
+ * Set fill color of bottom plane to black. Generally not needed
|
|
+ * except when VI plane is at bottom (zpos = 0) and enabled.
|
|
+ */
|
|
+ regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_PIPE_CTL(base),
|
|
+ SUN8I_MIXER_BLEND_PIPE_CTL_FC_EN(0));
|
|
+ regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_ATTR_FCOLOR(base, 0),
|
|
+ SUN8I_MIXER_BLEND_COLOR_BLACK);
|
|
+
|
|
+ plane_cnt = mixer->cfg->vi_num + mixer->cfg->ui_num;
|
|
+ for (i = 0; i < plane_cnt; i++)
|
|
+ regmap_write(mixer->engine.regs,
|
|
+ SUN8I_MIXER_BLEND_MODE(base, i),
|
|
+ SUN8I_MIXER_BLEND_MODE_DEF);
|
|
+
|
|
+ if (!mixer->hw_preconfigured) {
|
|
+ regmap_update_bits(mixer->engine.regs, SUN8I_MIXER_BLEND_PIPE_CTL(base),
|
|
+ SUN8I_MIXER_BLEND_PIPE_CTL_EN_MSK, 0);
|
|
+ } /* hw_preconfigured */
|
|
+}
|
|
+
|
|
+static void sun8i_mixer_de33_init(struct sun8i_mixer *mixer)
|
|
+{
|
|
+ unsigned int base;
|
|
+ int plane_cnt, i;
|
|
+
|
|
+ base = sun8i_blender_base(mixer);
|
|
+
|
|
+ if (!mixer->hw_preconfigured) {
|
|
+ /* Enable the mixer */
|
|
+ regmap_write(mixer->top_regs, SUN50I_MIXER_GLOBAL_CTL,
|
|
+ SUN8I_MIXER_GLOBAL_CTL_RT_EN);
|
|
+ } /* hw_preconfigured */
|
|
+
|
|
+ regmap_write(mixer->top_regs, SUN50I_MIXER_GLOBAL_CLK, 1);
|
|
+
|
|
+ /* Set background color to black */
|
|
+ regmap_write(mixer->disp_regs, SUN8I_MIXER_BLEND_BKCOLOR(base),
|
|
+ SUN8I_MIXER_BLEND_COLOR_BLACK);
|
|
+
|
|
+ /*
|
|
+ * Set fill color of bottom plane to black. Generally not needed
|
|
+ * except when VI plane is at bottom (zpos = 0) and enabled.
|
|
+ */
|
|
+ regmap_write(mixer->disp_regs, SUN8I_MIXER_BLEND_PIPE_CTL(base),
|
|
+ SUN8I_MIXER_BLEND_PIPE_CTL_FC_EN(0));
|
|
+ regmap_write(mixer->disp_regs, SUN8I_MIXER_BLEND_ATTR_FCOLOR(base, 0),
|
|
+ SUN8I_MIXER_BLEND_COLOR_BLACK);
|
|
+
|
|
+ plane_cnt = mixer->cfg->vi_num + mixer->cfg->ui_num;
|
|
+ for (i = 0; i < plane_cnt; i++)
|
|
+ regmap_write(mixer->disp_regs,
|
|
+ SUN8I_MIXER_BLEND_MODE(base, i),
|
|
+ SUN8I_MIXER_BLEND_MODE_DEF);
|
|
+
|
|
+ if (!mixer->hw_preconfigured) {
|
|
+ regmap_update_bits(mixer->disp_regs, SUN8I_MIXER_BLEND_PIPE_CTL(base),
|
|
+ SUN8I_MIXER_BLEND_PIPE_CTL_EN_MSK, 0);
|
|
+ } /* hw_preconfigured */
|
|
+}
|
|
+
|
|
static int sun8i_mixer_bind(struct device *dev, struct device *master,
|
|
void *data)
|
|
{
|
|
@@ -539,6 +644,30 @@ static int sun8i_mixer_bind(struct device *dev, struct device *master,
|
|
return PTR_ERR(mixer->engine.regs);
|
|
}
|
|
|
|
+ if (mixer->cfg->is_de33) {
|
|
+ regs = devm_platform_ioremap_resource(pdev, 1);
|
|
+ if (IS_ERR(regs))
|
|
+ return PTR_ERR(regs);
|
|
+
|
|
+ mixer->top_regs = devm_regmap_init_mmio(dev, regs,
|
|
+ &sun8i_top_regmap_config);
|
|
+ if (IS_ERR(mixer->top_regs)) {
|
|
+ dev_err(dev, "Couldn't create the top regmap\n");
|
|
+ return PTR_ERR(mixer->top_regs);
|
|
+ }
|
|
+
|
|
+ regs = devm_platform_ioremap_resource(pdev, 2);
|
|
+ if (IS_ERR(regs))
|
|
+ return PTR_ERR(regs);
|
|
+
|
|
+ mixer->disp_regs = devm_regmap_init_mmio(dev, regs,
|
|
+ &sun8i_disp_regmap_config);
|
|
+ if (IS_ERR(mixer->disp_regs)) {
|
|
+ dev_err(dev, "Couldn't create the disp regmap\n");
|
|
+ return PTR_ERR(mixer->disp_regs);
|
|
+ }
|
|
+ }
|
|
+
|
|
mixer->reset = devm_reset_control_get(dev, NULL);
|
|
if (IS_ERR(mixer->reset)) {
|
|
dev_err(dev, "Couldn't get our reset line\n");
|
|
@@ -581,11 +710,11 @@ static int sun8i_mixer_bind(struct device *dev, struct device *master,
|
|
|
|
list_add_tail(&mixer->engine.list, &drv->engine_list);
|
|
|
|
- base = sun8i_blender_base(mixer);
|
|
-
|
|
- if (!mixer->hw_preconfigured) {
|
|
/* Reset registers and disable unused sub-engines */
|
|
- if (mixer->cfg->is_de3) {
|
|
+ if (mixer->cfg->is_de33) {
|
|
+ sun8i_mixer_de33_init(mixer);
|
|
+ } else if (mixer->cfg->is_de3) {
|
|
+ if (!mixer->hw_preconfigured) {
|
|
for (i = 0; i < DE3_MIXER_UNIT_SIZE; i += 4)
|
|
regmap_write(mixer->engine.regs, i, 0);
|
|
|
|
@@ -599,7 +728,10 @@ static int sun8i_mixer_bind(struct device *dev, struct device *master,
|
|
regmap_write(mixer->engine.regs, SUN50I_MIXER_FMT_EN, 0);
|
|
regmap_write(mixer->engine.regs, SUN50I_MIXER_CDC0_EN, 0);
|
|
regmap_write(mixer->engine.regs, SUN50I_MIXER_CDC1_EN, 0);
|
|
+ } /* hw_preconfigured */
|
|
+ sun8i_mixer_de2_init(mixer);
|
|
} else {
|
|
+ if (!mixer->hw_preconfigured) {
|
|
for (i = 0; i < DE2_MIXER_UNIT_SIZE; i += 4)
|
|
regmap_write(mixer->engine.regs, i, 0);
|
|
|
|
@@ -610,35 +742,8 @@ static int sun8i_mixer_bind(struct device *dev, struct device *master,
|
|
regmap_write(mixer->engine.regs, SUN8I_MIXER_ASE_EN, 0);
|
|
regmap_write(mixer->engine.regs, SUN8I_MIXER_FCC_EN, 0);
|
|
regmap_write(mixer->engine.regs, SUN8I_MIXER_DCSC_EN, 0);
|
|
- }
|
|
-
|
|
- /* Enable the mixer */
|
|
- regmap_write(mixer->engine.regs, SUN8I_MIXER_GLOBAL_CTL,
|
|
- SUN8I_MIXER_GLOBAL_CTL_RT_EN);
|
|
- } /* hw_preconfigured */
|
|
-
|
|
- /* Set background color to black */
|
|
- regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_BKCOLOR(base),
|
|
- SUN8I_MIXER_BLEND_COLOR_BLACK);
|
|
-
|
|
- /*
|
|
- * Set fill color of bottom plane to black. Generally not needed
|
|
- * except when VI plane is at bottom (zpos = 0) and enabled.
|
|
- */
|
|
- regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_PIPE_CTL(base),
|
|
- SUN8I_MIXER_BLEND_PIPE_CTL_FC_EN(0));
|
|
- regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_ATTR_FCOLOR(base, 0),
|
|
- SUN8I_MIXER_BLEND_COLOR_BLACK);
|
|
-
|
|
- plane_cnt = mixer->cfg->vi_num + mixer->cfg->ui_num;
|
|
- for (i = 0; i < plane_cnt; i++)
|
|
- regmap_write(mixer->engine.regs,
|
|
- SUN8I_MIXER_BLEND_MODE(base, i),
|
|
- SUN8I_MIXER_BLEND_MODE_DEF);
|
|
-
|
|
- if (!mixer->hw_preconfigured) {
|
|
- regmap_update_bits(mixer->engine.regs, SUN8I_MIXER_BLEND_PIPE_CTL(base),
|
|
- SUN8I_MIXER_BLEND_PIPE_CTL_EN_MSK, 0);
|
|
+ } /* hw_preconfigured */
|
|
+ sun8i_mixer_de2_init(mixer);
|
|
}
|
|
|
|
return 0;
|
|
@@ -794,6 +899,17 @@ static const struct sun8i_mixer_cfg sun50i_h6_mixer0_cfg = {
|
|
.vi_num = 1,
|
|
};
|
|
|
|
+static const struct sun8i_mixer_cfg sun50i_h616_mixer0_cfg = {
|
|
+ .ccsc = 0,
|
|
+ .is_de33 = true,
|
|
+ .mod_rate = 600000000,
|
|
+ .scaler_mask = 0xf,
|
|
+ .scanline_yuv = 4096,
|
|
+ .ui_num = 3,
|
|
+ .vi_num = 1,
|
|
+ .map = {0, 6, 7, 8},
|
|
+};
|
|
+
|
|
static const struct of_device_id sun8i_mixer_of_table[] = {
|
|
{
|
|
.compatible = "allwinner,sun8i-a83t-de2-mixer-0",
|
|
@@ -843,6 +959,10 @@ static const struct of_device_id sun8i_mixer_of_table[] = {
|
|
.compatible = "allwinner,sun50i-h6-de3-mixer-0",
|
|
.data = &sun50i_h6_mixer0_cfg,
|
|
},
|
|
+ {
|
|
+ .compatible = "allwinner,sun50i-h616-de33-mixer-0",
|
|
+ .data = &sun50i_h616_mixer0_cfg,
|
|
+ },
|
|
{ }
|
|
};
|
|
MODULE_DEVICE_TABLE(of, sun8i_mixer_of_table);
|
|
diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.h b/drivers/gpu/drm/sun4i/sun8i_mixer.h
|
|
index 68e2741b0..e41066b08 100644
|
|
--- a/drivers/gpu/drm/sun4i/sun8i_mixer.h
|
|
+++ b/drivers/gpu/drm/sun4i/sun8i_mixer.h
|
|
@@ -21,6 +21,12 @@
|
|
#define SUN8I_MIXER_GLOBAL_DBUFF 0x8
|
|
#define SUN8I_MIXER_GLOBAL_SIZE 0xc
|
|
|
|
+#define SUN50I_MIXER_GLOBAL_CTL 0x0
|
|
+#define SUN50I_MIXER_GLOBAL_STATUS 0x4
|
|
+#define SUN50I_MIXER_GLOBAL_SIZE 0x8
|
|
+#define SUN50I_MIXER_GLOBAL_CLK 0xc
|
|
+#define SUN50I_MIXER_GLOBAL_DBUFF 0x10
|
|
+
|
|
#define SUN8I_MIXER_GLOBAL_CTL_RT_EN BIT(0)
|
|
|
|
#define SUN8I_MIXER_GLOBAL_DBUFF_ENABLE BIT(0)
|
|
@@ -163,6 +169,7 @@ enum {
|
|
* @mod_rate: module clock rate that needs to be set in order to have
|
|
* a functional block.
|
|
* @is_de3: true, if this is next gen display engine 3.0, false otherwise.
|
|
+ * @is_de33: true, if this is next gen display engine 3.3, false otherwise.
|
|
* @scaline_yuv: size of a scanline for VI scaler for YUV formats.
|
|
*/
|
|
struct sun8i_mixer_cfg {
|
|
@@ -172,7 +179,9 @@ struct sun8i_mixer_cfg {
|
|
int ccsc;
|
|
unsigned long mod_rate;
|
|
unsigned int is_de3 : 1;
|
|
+ unsigned int is_de33 : 1;
|
|
unsigned int scanline_yuv;
|
|
+ unsigned int map[6];
|
|
};
|
|
|
|
struct sun8i_mixer {
|
|
@@ -187,6 +196,8 @@ struct sun8i_mixer {
|
|
|
|
struct sun4i_drv *drv;
|
|
bool hw_preconfigured;
|
|
+ struct regmap *top_regs;
|
|
+ struct regmap *disp_regs;
|
|
};
|
|
|
|
enum {
|
|
@@ -220,10 +231,19 @@ sun8i_blender_base(struct sun8i_mixer *mixer)
|
|
return mixer->cfg->is_de3 ? DE3_BLD_BASE : DE2_BLD_BASE;
|
|
}
|
|
|
|
+static inline struct regmap *
|
|
+sun8i_blender_regmap(struct sun8i_mixer *mixer)
|
|
+{
|
|
+ return mixer->cfg->is_de33 ?
|
|
+ mixer->disp_regs : mixer->engine.regs;
|
|
+}
|
|
+
|
|
static inline u32
|
|
sun8i_channel_base(struct sun8i_mixer *mixer, int channel)
|
|
{
|
|
- if (mixer->cfg->is_de3)
|
|
+ if (mixer->cfg->is_de33)
|
|
+ return mixer->cfg->map[channel] * 0x20000 + DE2_CH_SIZE;
|
|
+ else if (mixer->cfg->is_de3)
|
|
return DE3_CH_BASE + channel * DE3_CH_SIZE;
|
|
else
|
|
return DE2_CH_BASE + channel * DE2_CH_SIZE;
|
|
diff --git a/drivers/gpu/drm/sun4i/sun8i_ui_layer.c b/drivers/gpu/drm/sun4i/sun8i_ui_layer.c
|
|
index b90e5edef..92ab1ac97 100644
|
|
--- a/drivers/gpu/drm/sun4i/sun8i_ui_layer.c
|
|
+++ b/drivers/gpu/drm/sun4i/sun8i_ui_layer.c
|
|
@@ -23,6 +23,7 @@
|
|
#include "sun8i_mixer.h"
|
|
#include "sun8i_ui_layer.h"
|
|
#include "sun8i_ui_scaler.h"
|
|
+#include "sun8i_vi_scaler.h"
|
|
|
|
static void sun8i_ui_layer_update_alpha(struct sun8i_mixer *mixer, int channel,
|
|
int overlay, struct drm_plane *plane)
|
|
@@ -50,6 +51,7 @@ static int sun8i_ui_layer_update_coord(struct sun8i_mixer *mixer, int channel,
|
|
unsigned int zpos)
|
|
{
|
|
struct drm_plane_state *state = plane->state;
|
|
+ struct regmap *bld_regs;
|
|
u32 src_w, src_h, dst_w, dst_h;
|
|
u32 bld_base, ch_base;
|
|
u32 outsize, insize;
|
|
@@ -59,6 +61,7 @@ static int sun8i_ui_layer_update_coord(struct sun8i_mixer *mixer, int channel,
|
|
channel, overlay);
|
|
|
|
bld_base = sun8i_blender_base(mixer);
|
|
+ bld_regs = sun8i_blender_regmap(mixer);
|
|
ch_base = sun8i_channel_base(mixer, channel);
|
|
|
|
src_w = drm_rect_width(&state->src) >> 16;
|
|
@@ -91,9 +94,18 @@ static int sun8i_ui_layer_update_coord(struct sun8i_mixer *mixer, int channel,
|
|
hscale = state->src_w / state->crtc_w;
|
|
vscale = state->src_h / state->crtc_h;
|
|
|
|
- sun8i_ui_scaler_setup(mixer, channel, src_w, src_h, dst_w,
|
|
- dst_h, hscale, vscale, hphase, vphase);
|
|
- sun8i_ui_scaler_enable(mixer, channel, true);
|
|
+ if (mixer->cfg->is_de33) {
|
|
+ sun8i_ui_scaler_setup(mixer, channel, src_w, src_h,
|
|
+ dst_w, dst_h, hscale, vscale,
|
|
+ hphase, vphase);
|
|
+ sun8i_ui_scaler_enable(mixer, channel, true);
|
|
+ } else {
|
|
+ sun8i_vi_scaler_setup(mixer, channel, src_w, src_h,
|
|
+ dst_w, dst_h, hscale, vscale,
|
|
+ hphase, vphase,
|
|
+ state->fb->format);
|
|
+ sun8i_vi_scaler_enable(mixer, channel, true);
|
|
+ }
|
|
} else {
|
|
DRM_DEBUG_DRIVER("HW scaling is not needed\n");
|
|
sun8i_ui_scaler_enable(mixer, channel, false);
|
|
@@ -103,10 +115,10 @@ static int sun8i_ui_layer_update_coord(struct sun8i_mixer *mixer, int channel,
|
|
DRM_DEBUG_DRIVER("Layer destination coordinates X: %d Y: %d\n",
|
|
state->dst.x1, state->dst.y1);
|
|
DRM_DEBUG_DRIVER("Layer destination size W: %d H: %d\n", dst_w, dst_h);
|
|
- regmap_write(mixer->engine.regs,
|
|
+ regmap_write(bld_regs,
|
|
SUN8I_MIXER_BLEND_ATTR_COORD(bld_base, zpos),
|
|
SUN8I_MIXER_COORD(state->dst.x1, state->dst.y1));
|
|
- regmap_write(mixer->engine.regs,
|
|
+ regmap_write(bld_regs,
|
|
SUN8I_MIXER_BLEND_ATTR_INSIZE(bld_base, zpos),
|
|
outsize);
|
|
|
|
diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c
|
|
index 9c09d9c08..dca22df8c 100644
|
|
--- a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c
|
|
+++ b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c
|
|
@@ -54,6 +54,7 @@ static int sun8i_vi_layer_update_coord(struct sun8i_mixer *mixer, int channel,
|
|
{
|
|
struct drm_plane_state *state = plane->state;
|
|
const struct drm_format_info *format = state->fb->format;
|
|
+ struct regmap *bld_regs;
|
|
u32 src_w, src_h, dst_w, dst_h;
|
|
u32 bld_base, ch_base;
|
|
u32 outsize, insize;
|
|
@@ -66,6 +67,7 @@ static int sun8i_vi_layer_update_coord(struct sun8i_mixer *mixer, int channel,
|
|
channel, overlay);
|
|
|
|
bld_base = sun8i_blender_base(mixer);
|
|
+ bld_regs = sun8i_blender_regmap(mixer);
|
|
ch_base = sun8i_channel_base(mixer, channel);
|
|
|
|
src_w = drm_rect_width(&state->src) >> 16;
|
|
@@ -183,10 +185,10 @@ static int sun8i_vi_layer_update_coord(struct sun8i_mixer *mixer, int channel,
|
|
DRM_DEBUG_DRIVER("Layer destination coordinates X: %d Y: %d\n",
|
|
state->dst.x1, state->dst.y1);
|
|
DRM_DEBUG_DRIVER("Layer destination size W: %d H: %d\n", dst_w, dst_h);
|
|
- regmap_write(mixer->engine.regs,
|
|
+ regmap_write(bld_regs,
|
|
SUN8I_MIXER_BLEND_ATTR_COORD(bld_base, zpos),
|
|
SUN8I_MIXER_COORD(state->dst.x1, state->dst.y1));
|
|
- regmap_write(mixer->engine.regs,
|
|
+ regmap_write(bld_regs,
|
|
SUN8I_MIXER_BLEND_ATTR_INSIZE(bld_base, zpos),
|
|
outsize);
|
|
|
|
diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c b/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c
|
|
index 7ba75011a..3f7afa8d3 100644
|
|
--- a/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c
|
|
+++ b/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c
|
|
@@ -835,7 +835,9 @@ static const u32 bicubic4coefftab32[480] = {
|
|
|
|
static u32 sun8i_vi_scaler_base(struct sun8i_mixer *mixer, int channel)
|
|
{
|
|
- if (mixer->cfg->is_de3)
|
|
+ if (mixer->cfg->is_de33)
|
|
+ return sun8i_channel_base(mixer, channel) + 0x3000;
|
|
+ else if (mixer->cfg->is_de3)
|
|
return DE3_VI_SCALER_UNIT_BASE +
|
|
DE3_VI_SCALER_UNIT_SIZE * channel;
|
|
else
|
|
--
|
|
2.35.3
|
|
|