* [U-Boot] [PATCH 0/8] arm: meson: add Video support for G12A and SEI510 board
@ 2019-08-30 12:09 Neil Armstrong
2019-08-30 12:09 ` [U-Boot] [PATCH 1/8] power: domain: meson-gx-pwrc: add G12A support Neil Armstrong
` (8 more replies)
0 siblings, 9 replies; 19+ messages in thread
From: Neil Armstrong @ 2019-08-30 12:09 UTC (permalink / raw)
To: u-boot
This patchset adds Amlogic G12A support for HDMI & Composite video output like
the Amlogic GXBB/GXL/GXM, by syncing from the latest Linux VPU DRM driver.
It also adds VPU/VAPB/HDMI Clock & VPU Power Domain support.
Finally it adds the necessary config to show a logo from a fastboot flashed
partition on the SEI510 board.
U200 and Odroid-N2 config support will be added later.
Neil Armstrong (8):
power: domain: meson-gx-pwrc: add G12A support
clk: meson: g12a: add support for VPU/HDMI clocks
video: meson: remove power domain get
video: meson: sync with linux drm-misc tree
video: meson: add compatible for Amlogic G12A
arm: meson: board-g12a: Setup VPU in fdt
ARM: dts: meson-g12a: add U-Boot specific DT for graphics
configs: sei510: enable Video Display support
arch/arm/dts/meson-g12a-sei510-u-boot.dtsi | 7 +
arch/arm/dts/meson-g12a-u-boot.dtsi | 29 +
arch/arm/dts/meson-g12a-u200-u-boot.dtsi | 7 +
arch/arm/dts/meson-g12b-odroid-n2-u-boot.dtsi | 7 +
arch/arm/mach-meson/board-g12a.c | 5 +
configs/sei510_defconfig | 11 +
drivers/clk/meson/g12a.c | 620 +++++++++++++++++-
drivers/power/domain/meson-gx-pwrc-vpu.c | 155 ++++-
drivers/video/meson/meson_dw_hdmi.c | 61 +-
drivers/video/meson/meson_plane.c | 47 +-
drivers/video/meson/meson_registers.h | 373 ++++++++++-
drivers/video/meson/meson_vclk.c | 233 +++++--
drivers/video/meson/meson_venc.c | 169 ++++-
drivers/video/meson/meson_vpu.c | 11 +-
drivers/video/meson/meson_vpu.h | 2 +
drivers/video/meson/meson_vpu_init.c | 205 ++++--
include/configs/sei510.h | 12 +
17 files changed, 1757 insertions(+), 197 deletions(-)
create mode 100644 arch/arm/dts/meson-g12a-sei510-u-boot.dtsi
create mode 100644 arch/arm/dts/meson-g12a-u-boot.dtsi
create mode 100644 arch/arm/dts/meson-g12a-u200-u-boot.dtsi
create mode 100644 arch/arm/dts/meson-g12b-odroid-n2-u-boot.dtsi
--
2.22.0
^ permalink raw reply [flat|nested] 19+ messages in thread* [U-Boot] [PATCH 1/8] power: domain: meson-gx-pwrc: add G12A support 2019-08-30 12:09 [U-Boot] [PATCH 0/8] arm: meson: add Video support for G12A and SEI510 board Neil Armstrong @ 2019-08-30 12:09 ` Neil Armstrong 2019-10-10 18:15 ` Anatolij Gustschin 2019-08-30 12:09 ` [U-Boot] [PATCH 2/8] clk: meson: g12a: add support for VPU/HDMI clocks Neil Armstrong ` (7 subsequent siblings) 8 siblings, 1 reply; 19+ messages in thread From: Neil Armstrong @ 2019-08-30 12:09 UTC (permalink / raw) To: u-boot Add Amlogic G12A support for the gx-pwrc driver, aligned on the Linux v5.2 driver. Signed-off-by: Neil Armstrong <narmstrong@baylibre.com> --- drivers/power/domain/meson-gx-pwrc-vpu.c | 155 +++++++++++++++++++++-- 1 file changed, 145 insertions(+), 10 deletions(-) diff --git a/drivers/power/domain/meson-gx-pwrc-vpu.c b/drivers/power/domain/meson-gx-pwrc-vpu.c index d631d3e6ff..f44e33bacb 100644 --- a/drivers/power/domain/meson-gx-pwrc-vpu.c +++ b/drivers/power/domain/meson-gx-pwrc-vpu.c @@ -14,6 +14,11 @@ #include <reset.h> #include <clk.h> +enum { + VPU_PWRC_COMPATIBLE_GX = 0, + VPU_PWRC_COMPATIBLE_G12A = 1, +}; + /* AO Offsets */ #define AO_RTI_GEN_PWR_SLEEP0 (0x3a << 2) @@ -26,6 +31,7 @@ #define HHI_MEM_PD_REG0 (0x40 << 2) #define HHI_VPU_MEM_PD_REG0 (0x41 << 2) #define HHI_VPU_MEM_PD_REG1 (0x42 << 2) +#define HHI_VPU_MEM_PD_REG2 (0x4d << 2) struct meson_gx_pwrc_vpu_priv { struct regmap *regmap_ao; @@ -34,12 +40,12 @@ struct meson_gx_pwrc_vpu_priv { struct clk_bulk clks; }; -static int meson_gx_pwrc_vpu_request(struct power_domain *power_domain) +static int meson_pwrc_vpu_request(struct power_domain *power_domain) { return 0; } -static int meson_gx_pwrc_vpu_free(struct power_domain *power_domain) +static int meson_pwrc_vpu_free(struct power_domain *power_domain) { return 0; } @@ -91,6 +97,73 @@ static int meson_gx_pwrc_vpu_on(struct power_domain *power_domain) return 0; } +static int meson_g12a_pwrc_vpu_on(struct power_domain *power_domain) +{ + struct meson_gx_pwrc_vpu_priv *priv = dev_get_priv(power_domain->dev); + int i, ret; + + regmap_update_bits(priv->regmap_ao, AO_RTI_GEN_PWR_SLEEP0, + GEN_PWR_VPU_HDMI, 0); + udelay(20); + + /* Power Up Memories */ + for (i = 0; i < 32; i += 2) { + regmap_update_bits(priv->regmap_hhi, HHI_VPU_MEM_PD_REG0, + 0x3 << i, 0); + udelay(5); + } + + for (i = 0; i < 32; i += 2) { + regmap_update_bits(priv->regmap_hhi, HHI_VPU_MEM_PD_REG1, + 0x3 << i, 0); + udelay(5); + } + + for (i = 0; i < 32; i += 2) { + regmap_update_bits(priv->regmap_hhi, HHI_VPU_MEM_PD_REG2, + 0x3 << i, 0); + udelay(5); + } + + for (i = 8; i < 16; i++) { + regmap_update_bits(priv->regmap_hhi, HHI_MEM_PD_REG0, + BIT(i), 0); + udelay(5); + } + udelay(20); + + ret = reset_assert_bulk(&priv->resets); + if (ret) + return ret; + + regmap_update_bits(priv->regmap_ao, AO_RTI_GEN_PWR_SLEEP0, + GEN_PWR_VPU_HDMI_ISO, 0); + + ret = reset_deassert_bulk(&priv->resets); + if (ret) + return ret; + + ret = clk_enable_bulk(&priv->clks); + if (ret) + return ret; + + return 0; +} + +static int meson_pwrc_vpu_on(struct power_domain *power_domain) +{ + unsigned int compat = dev_get_driver_data(power_domain->dev); + + switch (compat) { + case VPU_PWRC_COMPATIBLE_GX: + return meson_gx_pwrc_vpu_on(power_domain); + case VPU_PWRC_COMPATIBLE_G12A: + return meson_g12a_pwrc_vpu_on(power_domain); + } + + return -EINVAL; +} + static int meson_gx_pwrc_vpu_off(struct power_domain *power_domain) { struct meson_gx_pwrc_vpu_priv *priv = dev_get_priv(power_domain->dev); @@ -127,8 +200,63 @@ static int meson_gx_pwrc_vpu_off(struct power_domain *power_domain) return 0; } -static int meson_gx_pwrc_vpu_of_xlate(struct power_domain *power_domain, - struct ofnode_phandle_args *args) +static int meson_g12a_pwrc_vpu_off(struct power_domain *power_domain) +{ + struct meson_gx_pwrc_vpu_priv *priv = dev_get_priv(power_domain->dev); + int i; + + regmap_update_bits(priv->regmap_ao, AO_RTI_GEN_PWR_SLEEP0, + GEN_PWR_VPU_HDMI_ISO, GEN_PWR_VPU_HDMI_ISO); + udelay(20); + + /* Power Down Memories */ + for (i = 0; i < 32; i += 2) { + regmap_update_bits(priv->regmap_hhi, HHI_VPU_MEM_PD_REG0, + 0x3 << i, 0x3 << i); + udelay(5); + } + for (i = 0; i < 32; i += 2) { + regmap_update_bits(priv->regmap_hhi, HHI_VPU_MEM_PD_REG1, + 0x3 << i, 0x3 << i); + udelay(5); + } + for (i = 0; i < 32; i += 2) { + regmap_update_bits(priv->regmap_hhi, HHI_VPU_MEM_PD_REG2, + 0x3 << i, 0x3 << i); + udelay(5); + } + for (i = 8; i < 16; i++) { + regmap_update_bits(priv->regmap_hhi, HHI_MEM_PD_REG0, + BIT(i), BIT(i)); + udelay(5); + } + udelay(20); + + regmap_update_bits(priv->regmap_ao, AO_RTI_GEN_PWR_SLEEP0, + GEN_PWR_VPU_HDMI, GEN_PWR_VPU_HDMI); + mdelay(20); + + clk_disable_bulk(&priv->clks); + + return 0; +} + +static int meson_pwrc_vpu_off(struct power_domain *power_domain) +{ + unsigned int compat = dev_get_driver_data(power_domain->dev); + + switch (compat) { + case VPU_PWRC_COMPATIBLE_GX: + return meson_gx_pwrc_vpu_off(power_domain); + case VPU_PWRC_COMPATIBLE_G12A: + return meson_g12a_pwrc_vpu_off(power_domain); + } + + return -EINVAL; +} + +static int meson_pwrc_vpu_of_xlate(struct power_domain *power_domain, + struct ofnode_phandle_args *args) { /* #power-domain-cells is 0 */ @@ -141,15 +269,22 @@ static int meson_gx_pwrc_vpu_of_xlate(struct power_domain *power_domain, } struct power_domain_ops meson_gx_pwrc_vpu_ops = { - .free = meson_gx_pwrc_vpu_free, - .off = meson_gx_pwrc_vpu_off, - .on = meson_gx_pwrc_vpu_on, - .request = meson_gx_pwrc_vpu_request, - .of_xlate = meson_gx_pwrc_vpu_of_xlate, + .free = meson_pwrc_vpu_free, + .off = meson_pwrc_vpu_off, + .on = meson_pwrc_vpu_on, + .request = meson_pwrc_vpu_request, + .of_xlate = meson_pwrc_vpu_of_xlate, }; static const struct udevice_id meson_gx_pwrc_vpu_ids[] = { - { .compatible = "amlogic,meson-gx-pwrc-vpu" }, + { + .compatible = "amlogic,meson-gx-pwrc-vpu", + .data = VPU_PWRC_COMPATIBLE_GX, + }, + { + .compatible = "amlogic,meson-g12a-pwrc-vpu", + .data = VPU_PWRC_COMPATIBLE_G12A, + }, { } }; -- 2.22.0 ^ permalink raw reply related [flat|nested] 19+ messages in thread
* [U-Boot] [PATCH 1/8] power: domain: meson-gx-pwrc: add G12A support 2019-08-30 12:09 ` [U-Boot] [PATCH 1/8] power: domain: meson-gx-pwrc: add G12A support Neil Armstrong @ 2019-10-10 18:15 ` Anatolij Gustschin 0 siblings, 0 replies; 19+ messages in thread From: Anatolij Gustschin @ 2019-10-10 18:15 UTC (permalink / raw) To: u-boot On Fri, 30 Aug 2019 14:09:21 +0200 Neil Armstrong narmstrong at baylibre.com wrote: > Add Amlogic G12A support for the gx-pwrc driver, aligned on the > Linux v5.2 driver. > > Signed-off-by: Neil Armstrong <narmstrong@baylibre.com> Reviewed-by: Anatolij Gustschin <agust@denx.de> -- Anatolij ^ permalink raw reply [flat|nested] 19+ messages in thread
* [U-Boot] [PATCH 2/8] clk: meson: g12a: add support for VPU/HDMI clocks 2019-08-30 12:09 [U-Boot] [PATCH 0/8] arm: meson: add Video support for G12A and SEI510 board Neil Armstrong 2019-08-30 12:09 ` [U-Boot] [PATCH 1/8] power: domain: meson-gx-pwrc: add G12A support Neil Armstrong @ 2019-08-30 12:09 ` Neil Armstrong 2019-10-10 18:15 ` Anatolij Gustschin 2019-08-30 12:09 ` [U-Boot] [PATCH 3/8] video: meson: remove power domain get Neil Armstrong ` (6 subsequent siblings) 8 siblings, 1 reply; 19+ messages in thread From: Neil Armstrong @ 2019-08-30 12:09 UTC (permalink / raw) To: u-boot Add necessary clock support to set up clock for the VPU and HDMI support. Signed-off-by: Neil Armstrong <narmstrong@baylibre.com> --- drivers/clk/meson/g12a.c | 620 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 603 insertions(+), 17 deletions(-) diff --git a/drivers/clk/meson/g12a.c b/drivers/clk/meson/g12a.c index 43dac1aa37..c03738b6ca 100644 --- a/drivers/clk/meson/g12a.c +++ b/drivers/clk/meson/g12a.c @@ -14,16 +14,93 @@ #include <syscon.h> #include <div64.h> #include <dt-bindings/clock/g12a-clkc.h> +#include <linux/kernel.h> #include "clk_meson.h" +/* This driver support only basic clock tree operations : + * - Can calculate clock frequency on a limited tree + * - Can Read muxes and basic dividers (0-based only) + * - Can enable/disable gates with limited propagation + * - Can reparent without propagation, only on muxes + * - Can set rates without reparenting + * This driver is adapted to what is actually supported by U-Boot + */ + +/* Only the clocks ids we don't want to expose, such as the internal muxes + * and dividers of composite clocks, will remain defined here. + */ +#define CLKID_MPEG_SEL 8 +#define CLKID_MPEG_DIV 9 +#define CLKID_SD_EMMC_A_CLK0_SEL 63 +#define CLKID_SD_EMMC_A_CLK0_DIV 64 +#define CLKID_SD_EMMC_B_CLK0_SEL 65 +#define CLKID_SD_EMMC_B_CLK0_DIV 66 +#define CLKID_SD_EMMC_C_CLK0_SEL 67 +#define CLKID_SD_EMMC_C_CLK0_DIV 68 +#define CLKID_MPLL0_DIV 69 +#define CLKID_MPLL1_DIV 70 +#define CLKID_MPLL2_DIV 71 +#define CLKID_MPLL3_DIV 72 +#define CLKID_MPLL_PREDIV 73 +#define CLKID_FCLK_DIV2_DIV 75 +#define CLKID_FCLK_DIV3_DIV 76 +#define CLKID_FCLK_DIV4_DIV 77 +#define CLKID_FCLK_DIV5_DIV 78 +#define CLKID_FCLK_DIV7_DIV 79 +#define CLKID_FCLK_DIV2P5_DIV 100 +#define CLKID_FIXED_PLL_DCO 101 +#define CLKID_SYS_PLL_DCO 102 +#define CLKID_GP0_PLL_DCO 103 +#define CLKID_HIFI_PLL_DCO 104 +#define CLKID_VPU_0_DIV 111 +#define CLKID_VPU_1_DIV 114 +#define CLKID_VAPB_0_DIV 118 +#define CLKID_VAPB_1_DIV 121 +#define CLKID_HDMI_PLL_DCO 125 +#define CLKID_HDMI_PLL_OD 126 +#define CLKID_HDMI_PLL_OD2 127 +#define CLKID_VID_PLL_SEL 130 +#define CLKID_VID_PLL_DIV 131 +#define CLKID_VCLK_SEL 132 +#define CLKID_VCLK2_SEL 133 +#define CLKID_VCLK_INPUT 134 +#define CLKID_VCLK2_INPUT 135 +#define CLKID_VCLK_DIV 136 +#define CLKID_VCLK2_DIV 137 +#define CLKID_VCLK_DIV2_EN 140 +#define CLKID_VCLK_DIV4_EN 141 +#define CLKID_VCLK_DIV6_EN 142 +#define CLKID_VCLK_DIV12_EN 143 +#define CLKID_VCLK2_DIV2_EN 144 +#define CLKID_VCLK2_DIV4_EN 145 +#define CLKID_VCLK2_DIV6_EN 146 +#define CLKID_VCLK2_DIV12_EN 147 +#define CLKID_CTS_ENCI_SEL 158 +#define CLKID_CTS_ENCP_SEL 159 +#define CLKID_CTS_VDAC_SEL 160 +#define CLKID_HDMI_TX_SEL 161 +#define CLKID_HDMI_SEL 166 +#define CLKID_HDMI_DIV 167 +#define CLKID_MALI_0_DIV 170 +#define CLKID_MALI_1_DIV 173 + +#define CLKID_XTAL 0x10000000 + #define XTAL_RATE 24000000 struct meson_clk { struct regmap *map; }; +static ulong meson_div_get_rate(struct clk *clk, unsigned long id); +static ulong meson_div_set_rate(struct clk *clk, unsigned long id, ulong rate, + ulong current_rate); +static ulong meson_mux_set_parent(struct clk *clk, unsigned long id, + unsigned long parent_id); +static ulong meson_mux_get_rate(struct clk *clk, unsigned long id); static ulong meson_clk_set_rate_by_id(struct clk *clk, unsigned long id, ulong rate, ulong current_rate); +static ulong meson_mux_get_parent(struct clk *clk, unsigned long id); static ulong meson_clk_get_rate_by_id(struct clk *clk, unsigned long id); #define NUM_CLKS 178 @@ -39,40 +116,447 @@ static struct meson_gate gates[NUM_CLKS] = { MESON_GATE(CLKID_ETH, HHI_GCLK_MPEG1, 3), MESON_GATE(CLKID_UART1, HHI_GCLK_MPEG1, 16), MESON_GATE(CLKID_USB, HHI_GCLK_MPEG1, 25), + MESON_GATE(CLKID_HTX_PCLK, HHI_GCLK_MPEG2, 4), MESON_GATE(CLKID_USB1_DDR_BRIDGE, HHI_GCLK_MPEG2, 8), + MESON_GATE(CLKID_VPU_INTR, HHI_GCLK_MPEG2, 25), /* Peripheral Gates */ + MESON_GATE(CLKID_FCLK_DIV2, HHI_FIX_PLL_CNTL1, 24), + MESON_GATE(CLKID_FCLK_DIV3, HHI_FIX_PLL_CNTL1, 20), + MESON_GATE(CLKID_FCLK_DIV4, HHI_FIX_PLL_CNTL1, 21), + MESON_GATE(CLKID_FCLK_DIV5, HHI_FIX_PLL_CNTL1, 22), + MESON_GATE(CLKID_FCLK_DIV7, HHI_FIX_PLL_CNTL1, 23), MESON_GATE(CLKID_SD_EMMC_B_CLK0, HHI_SD_EMMC_CLK_CNTL, 23), MESON_GATE(CLKID_SD_EMMC_C_CLK0, HHI_NAND_CLK_CNTL, 7), + MESON_GATE(CLKID_VPU_0, HHI_VPU_CLK_CNTL, 8), + MESON_GATE(CLKID_VPU_1, HHI_VPU_CLK_CNTL, 24), + MESON_GATE(CLKID_VAPB_0, HHI_VAPBCLK_CNTL, 8), + MESON_GATE(CLKID_VAPB_1, HHI_VAPBCLK_CNTL, 24), + MESON_GATE(CLKID_VAPB, HHI_VAPBCLK_CNTL, 30), + MESON_GATE(CLKID_HDMI, HHI_HDMI_CLK_CNTL, 8), }; -static int meson_set_gate(struct clk *clk, bool on) +static int meson_set_gate_by_id(struct clk *clk, unsigned long id, bool on) { struct meson_clk *priv = dev_get_priv(clk->dev); struct meson_gate *gate; - if (clk->id >= ARRAY_SIZE(gates)) + debug("%s: %sabling %ld\n", __func__, on ? "en" : "dis", id); + + /* Propagate through muxes */ + switch (id) { + case CLKID_VPU: + return meson_set_gate_by_id(clk, + meson_mux_get_parent(clk, CLKID_VPU), on); + case CLKID_VAPB_SEL: + return meson_set_gate_by_id(clk, + meson_mux_get_parent(clk, CLKID_VAPB_SEL), on); + } + + if (id >= ARRAY_SIZE(gates)) return -ENOENT; - gate = &gates[clk->id]; + gate = &gates[id]; if (gate->reg == 0) return 0; + debug("%s: really %sabling %ld\n", __func__, on ? "en" : "dis", id); + regmap_update_bits(priv->map, gate->reg, BIT(gate->bit), on ? BIT(gate->bit) : 0); + /* Propagate to next gate(s) */ + switch (id) { + case CLKID_VAPB: + return meson_set_gate_by_id(clk, CLKID_VAPB_SEL, on); + case CLKID_VAPB_0: + return meson_set_gate_by_id(clk, + meson_mux_get_parent(clk, CLKID_VAPB_0_SEL), on); + case CLKID_VAPB_1: + return meson_set_gate_by_id(clk, + meson_mux_get_parent(clk, CLKID_VAPB_0_SEL), on); + case CLKID_VPU_0: + return meson_set_gate_by_id(clk, + meson_mux_get_parent(clk, CLKID_VPU_0_SEL), on); + case CLKID_VPU_1: + return meson_set_gate_by_id(clk, + meson_mux_get_parent(clk, CLKID_VPU_1_SEL), on); + } + return 0; } static int meson_clk_enable(struct clk *clk) { - return meson_set_gate(clk, true); + return meson_set_gate_by_id(clk, clk->id, true); } static int meson_clk_disable(struct clk *clk) { - return meson_set_gate(clk, false); + return meson_set_gate_by_id(clk, clk->id, false); +} + +static struct parm meson_vpu_0_div_parm = { + HHI_VPU_CLK_CNTL, 0, 7, +}; + +int meson_vpu_0_div_parent = CLKID_VPU_0_SEL; + +static struct parm meson_vpu_1_div_parm = { + HHI_VPU_CLK_CNTL, 16, 7, +}; + +int meson_vpu_1_div_parent = CLKID_VPU_1_SEL; + +static struct parm meson_vapb_0_div_parm = { + HHI_VAPBCLK_CNTL, 0, 7, +}; + +int meson_vapb_0_div_parent = CLKID_VAPB_0_SEL; + +static struct parm meson_vapb_1_div_parm = { + HHI_VAPBCLK_CNTL, 16, 7, +}; + +int meson_vapb_1_div_parent = CLKID_VAPB_1_SEL; + +static struct parm meson_hdmi_div_parm = { + HHI_HDMI_CLK_CNTL, 0, 7, +}; + +int meson_hdmi_div_parent = CLKID_HDMI_SEL; + +static ulong meson_div_get_rate(struct clk *clk, unsigned long id) +{ + struct meson_clk *priv = dev_get_priv(clk->dev); + unsigned int rate, parent_rate; + struct parm *parm; + int parent; + uint reg; + + switch (id) { + case CLKID_VPU_0_DIV: + parm = &meson_vpu_0_div_parm; + parent = meson_vpu_0_div_parent; + break; + case CLKID_VPU_1_DIV: + parm = &meson_vpu_1_div_parm; + parent = meson_vpu_1_div_parent; + break; + case CLKID_VAPB_0_DIV: + parm = &meson_vapb_0_div_parm; + parent = meson_vapb_0_div_parent; + break; + case CLKID_VAPB_1_DIV: + parm = &meson_vapb_1_div_parm; + parent = meson_vapb_1_div_parent; + break; + case CLKID_HDMI_DIV: + parm = &meson_hdmi_div_parm; + parent = meson_hdmi_div_parent; + break; + default: + return -ENOENT; + } + + regmap_read(priv->map, parm->reg_off, ®); + reg = PARM_GET(parm->width, parm->shift, reg); + + debug("%s: div of %ld is %d\n", __func__, id, reg + 1); + + parent_rate = meson_clk_get_rate_by_id(clk, parent); + if (IS_ERR_VALUE(parent_rate)) + return parent_rate; + + debug("%s: parent rate of %ld is %d\n", __func__, id, parent_rate); + + rate = parent_rate / (reg + 1); + + debug("%s: rate of %ld is %d\n", __func__, id, rate); + + return rate; +} + +static ulong meson_div_set_rate(struct clk *clk, unsigned long id, ulong rate, + ulong current_rate) +{ + struct meson_clk *priv = dev_get_priv(clk->dev); + unsigned int new_div = -EINVAL; + unsigned long parent_rate; + struct parm *parm; + int parent; + int ret; + + if (current_rate == rate) + return 0; + + debug("%s: setting rate of %ld from %ld to %ld\n", + __func__, id, current_rate, rate); + + switch (id) { + case CLKID_VPU_0_DIV: + parm = &meson_vpu_0_div_parm; + parent = meson_vpu_0_div_parent; + break; + case CLKID_VPU_1_DIV: + parm = &meson_vpu_1_div_parm; + parent = meson_vpu_1_div_parent; + break; + case CLKID_VAPB_0_DIV: + parm = &meson_vapb_0_div_parm; + parent = meson_vapb_0_div_parent; + break; + case CLKID_VAPB_1_DIV: + parm = &meson_vapb_1_div_parm; + parent = meson_vapb_1_div_parent; + break; + case CLKID_HDMI_DIV: + parm = &meson_hdmi_div_parm; + parent = meson_hdmi_div_parent; + break; + default: + return -ENOENT; + } + + parent_rate = meson_clk_get_rate_by_id(clk, parent); + if (IS_ERR_VALUE(parent_rate)) + return parent_rate; + + debug("%s: parent rate of %ld is %ld\n", __func__, id, parent_rate); + + /* If can't divide, set parent instead */ + if (!parent_rate || rate > parent_rate) + return meson_clk_set_rate_by_id(clk, parent, rate, + current_rate); + + new_div = DIV_ROUND_CLOSEST(parent_rate, rate); + + debug("%s: new div of %ld is %d\n", __func__, id, new_div); + + /* If overflow, try to set parent rate and retry */ + if (!new_div || new_div > (1 << parm->width)) { + ret = meson_clk_set_rate_by_id(clk, parent, rate, current_rate); + if (IS_ERR_VALUE(ret)) + return ret; + + parent_rate = meson_clk_get_rate_by_id(clk, parent); + if (IS_ERR_VALUE(parent_rate)) + return parent_rate; + + new_div = DIV_ROUND_CLOSEST(parent_rate, rate); + + debug("%s: new new div of %ld is %d\n", __func__, id, new_div); + + if (!new_div || new_div > (1 << parm->width)) + return -EINVAL; + } + + debug("%s: setting div of %ld to %d\n", __func__, id, new_div); + + regmap_update_bits(priv->map, parm->reg_off, + SETPMASK(parm->width, parm->shift), + (new_div - 1) << parm->shift); + + debug("%s: new rate of %ld is %ld\n", + __func__, id, meson_div_get_rate(clk, id)); + + return 0; +} + +static struct parm meson_vpu_mux_parm = { + HHI_VPU_CLK_CNTL, 31, 1, +}; + +int meson_vpu_mux_parents[] = { + CLKID_VPU_0, + CLKID_VPU_1, +}; + +static struct parm meson_vpu_0_mux_parm = { + HHI_VPU_CLK_CNTL, 9, 3, +}; + +static struct parm meson_vpu_1_mux_parm = { + HHI_VPU_CLK_CNTL, 25, 3, +}; + +static int meson_vpu_0_1_mux_parents[] = { + CLKID_FCLK_DIV3, + CLKID_FCLK_DIV4, + CLKID_FCLK_DIV5, + CLKID_FCLK_DIV7, + -ENOENT, + -ENOENT, + -ENOENT, + -ENOENT, +}; + +static struct parm meson_vapb_sel_mux_parm = { + HHI_VAPBCLK_CNTL, 31, 1, +}; + +int meson_vapb_sel_mux_parents[] = { + CLKID_VAPB_0, + CLKID_VAPB_1, +}; + +static struct parm meson_vapb_0_mux_parm = { + HHI_VAPBCLK_CNTL, 9, 2, +}; + +static struct parm meson_vapb_1_mux_parm = { + HHI_VAPBCLK_CNTL, 25, 2, +}; + +static int meson_vapb_0_1_mux_parents[] = { + CLKID_FCLK_DIV4, + CLKID_FCLK_DIV3, + CLKID_FCLK_DIV5, + CLKID_FCLK_DIV7, +}; + +static struct parm meson_hdmi_mux_parm = { + HHI_HDMI_CLK_CNTL, 9, 2, +}; + +static int meson_hdmi_mux_parents[] = { + CLKID_XTAL, + CLKID_FCLK_DIV4, + CLKID_FCLK_DIV3, + CLKID_FCLK_DIV5, +}; + +static ulong meson_mux_get_parent(struct clk *clk, unsigned long id) +{ + struct meson_clk *priv = dev_get_priv(clk->dev); + struct parm *parm; + int *parents; + uint reg; + + switch (id) { + case CLKID_VPU: + parm = &meson_vpu_mux_parm; + parents = meson_vpu_mux_parents; + break; + case CLKID_VPU_0_SEL: + parm = &meson_vpu_0_mux_parm; + parents = meson_vpu_0_1_mux_parents; + break; + case CLKID_VPU_1_SEL: + parm = &meson_vpu_1_mux_parm; + parents = meson_vpu_0_1_mux_parents; + break; + case CLKID_VAPB_SEL: + parm = &meson_vapb_sel_mux_parm; + parents = meson_vapb_sel_mux_parents; + break; + case CLKID_VAPB_0_SEL: + parm = &meson_vapb_0_mux_parm; + parents = meson_vapb_0_1_mux_parents; + break; + case CLKID_VAPB_1_SEL: + parm = &meson_vapb_1_mux_parm; + parents = meson_vapb_0_1_mux_parents; + break; + case CLKID_HDMI_SEL: + parm = &meson_hdmi_mux_parm; + parents = meson_hdmi_mux_parents; + break; + default: + return -ENOENT; + } + + regmap_read(priv->map, parm->reg_off, ®); + reg = PARM_GET(parm->width, parm->shift, reg); + + debug("%s: parent of %ld is %d (%d)\n", + __func__, id, parents[reg], reg); + + return parents[reg]; +} + +static ulong meson_mux_set_parent(struct clk *clk, unsigned long id, + unsigned long parent_id) +{ + unsigned long cur_parent = meson_mux_get_parent(clk, id); + struct meson_clk *priv = dev_get_priv(clk->dev); + unsigned int new_index = -EINVAL; + struct parm *parm; + int *parents; + int i; + + if (IS_ERR_VALUE(cur_parent)) + return cur_parent; + + debug("%s: setting parent of %ld from %ld to %ld\n", + __func__, id, cur_parent, parent_id); + + if (cur_parent == parent_id) + return 0; + + switch (id) { + case CLKID_VPU: + parm = &meson_vpu_mux_parm; + parents = meson_vpu_mux_parents; + break; + case CLKID_VPU_0_SEL: + parm = &meson_vpu_0_mux_parm; + parents = meson_vpu_0_1_mux_parents; + break; + case CLKID_VPU_1_SEL: + parm = &meson_vpu_1_mux_parm; + parents = meson_vpu_0_1_mux_parents; + break; + case CLKID_VAPB_SEL: + parm = &meson_vapb_sel_mux_parm; + parents = meson_vapb_sel_mux_parents; + break; + case CLKID_VAPB_0_SEL: + parm = &meson_vapb_0_mux_parm; + parents = meson_vapb_0_1_mux_parents; + break; + case CLKID_VAPB_1_SEL: + parm = &meson_vapb_1_mux_parm; + parents = meson_vapb_0_1_mux_parents; + break; + case CLKID_HDMI_SEL: + parm = &meson_hdmi_mux_parm; + parents = meson_hdmi_mux_parents; + break; + default: + /* Not a mux */ + return -ENOENT; + } + + for (i = 0 ; i < (1 << parm->width) ; ++i) { + if (parents[i] == parent_id) + new_index = i; + } + + if (IS_ERR_VALUE(new_index)) + return new_index; + + debug("%s: new index of %ld is %d\n", __func__, id, new_index); + + regmap_update_bits(priv->map, parm->reg_off, + SETPMASK(parm->width, parm->shift), + new_index << parm->shift); + + debug("%s: new parent of %ld is %ld\n", + __func__, id, meson_mux_get_parent(clk, id)); + + return 0; +} + +static ulong meson_mux_get_rate(struct clk *clk, unsigned long id) +{ + int parent = meson_mux_get_parent(clk, id); + + if (IS_ERR_VALUE(parent)) + return parent; + + return meson_clk_get_rate_by_id(clk, parent); } static unsigned long meson_clk81_get_rate(struct clk *clk) @@ -81,7 +565,7 @@ static unsigned long meson_clk81_get_rate(struct clk *clk) unsigned long parent_rate; uint reg; int parents[] = { - -1, + CLKID_XTAL, -1, CLKID_FCLK_DIV7, CLKID_MPLL1, @@ -96,9 +580,6 @@ static unsigned long meson_clk81_get_rate(struct clk *clk) reg = (reg >> 12) & 7; switch (reg) { - case 0: - parent_rate = XTAL_RATE; - break; case 1: return -ENOENT; default: @@ -183,24 +664,26 @@ static ulong meson_mpll_get_rate(struct clk *clk, unsigned long id) return mpll_rate_from_params(parent_rate, sdm, n2); } -static struct parm meson_fixed_pll_parm[3] = { - {HHI_FIX_PLL_CNTL0, 0, 8}, /* pm */ +static struct parm meson_fixed_pll_parm[4] = { + {HHI_FIX_PLL_CNTL0, 0, 9}, /* pm */ {HHI_FIX_PLL_CNTL0, 10, 5}, /* pn */ {HHI_FIX_PLL_CNTL0, 16, 2}, /* pod */ + {HHI_FIX_PLL_CNTL1, 0, 17}, /* pfrac */ }; static struct parm meson_sys_pll_parm[3] = { - {HHI_SYS_PLL_CNTL0, 0, 8}, /* pm */ + {HHI_SYS_PLL_CNTL0, 0, 9}, /* pm */ {HHI_SYS_PLL_CNTL0, 10, 5}, /* pn */ - {HHI_SYS_PLL_CNTL0, 16, 2}, /* pod */ + {HHI_SYS_PLL_CNTL0, 16, 3}, /* pod */ }; static ulong meson_pll_get_rate(struct clk *clk, unsigned long id) { struct meson_clk *priv = dev_get_priv(clk->dev); - struct parm *pm, *pn, *pod; + struct parm *pm, *pn, *pod, *pfrac = NULL; unsigned long parent_rate_mhz = XTAL_RATE / 1000000; - u16 n, m, od; + u16 n, m, od, frac; + ulong rate; uint reg; /* @@ -213,6 +696,7 @@ static ulong meson_pll_get_rate(struct clk *clk, unsigned long id) pm = &meson_fixed_pll_parm[0]; pn = &meson_fixed_pll_parm[1]; pod = &meson_fixed_pll_parm[2]; + pfrac = &meson_fixed_pll_parm[3]; break; case CLKID_SYS_PLL: pm = &meson_sys_pll_parm[0]; @@ -232,7 +716,24 @@ static ulong meson_pll_get_rate(struct clk *clk, unsigned long id) regmap_read(priv->map, pod->reg_off, ®); od = PARM_GET(pod->width, pod->shift, reg); - return ((parent_rate_mhz * m / n) >> od) * 1000000; + rate = parent_rate_mhz * m; + + if (pfrac) { + ulong frac_rate; + + regmap_read(priv->map, pfrac->reg_off, ®); + frac = PARM_GET(pfrac->width - 1, pfrac->shift, reg); + + frac_rate = DIV_ROUND_UP_ULL((u64)parent_rate_mhz * frac, + 1 << (pfrac->width - 2)); + + if (frac & BIT(pfrac->width - 1)) + rate -= frac_rate; + else + rate += frac_rate; + } + + return (DIV_ROUND_UP_ULL(rate, n) >> od) * 1000000; } static struct parm meson_pcie_pll_parm[3] = { @@ -270,6 +771,9 @@ static ulong meson_clk_get_rate_by_id(struct clk *clk, unsigned long id) ulong rate; switch (id) { + case CLKID_XTAL: + rate = XTAL_RATE; + break; case CLKID_FIXED_PLL: case CLKID_SYS_PLL: rate = meson_pll_get_rate(clk, id); @@ -299,6 +803,39 @@ static ulong meson_clk_get_rate_by_id(struct clk *clk, unsigned long id) break; case CLKID_PCIE_PLL: rate = meson_pcie_pll_get_rate(clk); + case CLKID_VPU_0: + rate = meson_div_get_rate(clk, CLKID_VPU_0_DIV); + break; + case CLKID_VPU_1: + rate = meson_div_get_rate(clk, CLKID_VPU_1_DIV); + break; + case CLKID_VAPB: + rate = meson_mux_get_rate(clk, CLKID_VAPB_SEL); + break; + case CLKID_VAPB_0: + rate = meson_div_get_rate(clk, CLKID_VAPB_0_DIV); + break; + case CLKID_VAPB_1: + rate = meson_div_get_rate(clk, CLKID_VAPB_1_DIV); + break; + case CLKID_HDMI: + rate = meson_div_get_rate(clk, CLKID_HDMI_DIV); + break; + case CLKID_VPU_0_DIV: + case CLKID_VPU_1_DIV: + case CLKID_VAPB_0_DIV: + case CLKID_VAPB_1_DIV: + case CLKID_HDMI_DIV: + rate = meson_div_get_rate(clk, id); + break; + case CLKID_VPU: + case CLKID_VPU_0_SEL: + case CLKID_VPU_1_SEL: + case CLKID_VAPB_SEL: + case CLKID_VAPB_0_SEL: + case CLKID_VAPB_1_SEL: + case CLKID_HDMI_SEL: + rate = meson_mux_get_rate(clk, id); break; default: if (gates[id].reg != 0) { @@ -343,6 +880,11 @@ static ulong meson_pcie_pll_set_rate(struct clk *clk, ulong rate) return 100000000; } +static int meson_clk_set_parent(struct clk *clk, struct clk *parent) +{ + return meson_mux_set_parent(clk, clk->id, parent->id); +} + static ulong meson_clk_set_rate_by_id(struct clk *clk, unsigned long id, ulong rate, ulong current_rate) { @@ -351,9 +893,53 @@ static ulong meson_clk_set_rate_by_id(struct clk *clk, unsigned long id, switch (id) { /* Fixed clocks */ + case CLKID_FIXED_PLL: + case CLKID_SYS_PLL: + case CLKID_FCLK_DIV2: + case CLKID_FCLK_DIV3: + case CLKID_FCLK_DIV4: + case CLKID_FCLK_DIV5: + case CLKID_FCLK_DIV7: + case CLKID_MPLL0: + case CLKID_MPLL1: + case CLKID_MPLL2: + case CLKID_CLK81: + if (current_rate != rate) + return -EINVAL; case CLKID_PCIE_PLL: return meson_pcie_pll_set_rate(clk, rate); + return 0; + case CLKID_VPU: + return meson_clk_set_rate_by_id(clk, + meson_mux_get_parent(clk, CLKID_VPU), rate, + current_rate); + case CLKID_VAPB: + case CLKID_VAPB_SEL: + return meson_clk_set_rate_by_id(clk, + meson_mux_get_parent(clk, CLKID_VAPB_SEL), + rate, current_rate); + case CLKID_VPU_0: + return meson_div_set_rate(clk, CLKID_VPU_0_DIV, rate, + current_rate); + case CLKID_VPU_1: + return meson_div_set_rate(clk, CLKID_VPU_1_DIV, rate, + current_rate); + case CLKID_VAPB_0: + return meson_div_set_rate(clk, CLKID_VAPB_0_DIV, rate, + current_rate); + case CLKID_VAPB_1: + return meson_div_set_rate(clk, CLKID_VAPB_1_DIV, rate, + current_rate); + case CLKID_VPU_0_DIV: + case CLKID_VPU_1_DIV: + case CLKID_VAPB_0_DIV: + case CLKID_VAPB_1_DIV: + case CLKID_HDMI_DIV: + return meson_div_set_rate(clk, id, rate, current_rate); + case CLKID_HDMI: + return meson_clk_set_rate_by_id(clk, CLKID_HDMI_DIV, + rate, current_rate); default: return -ENOENT; } @@ -361,7 +947,6 @@ static ulong meson_clk_set_rate_by_id(struct clk *clk, unsigned long id, return -EINVAL; } - static ulong meson_clk_set_rate(struct clk *clk, ulong rate) { ulong current_rate = meson_clk_get_rate_by_id(clk, clk->id); @@ -400,6 +985,7 @@ static struct clk_ops meson_clk_ops = { .disable = meson_clk_disable, .enable = meson_clk_enable, .get_rate = meson_clk_get_rate, + .set_parent = meson_clk_set_parent, .set_rate = meson_clk_set_rate, }; -- 2.22.0 ^ permalink raw reply related [flat|nested] 19+ messages in thread
* [U-Boot] [PATCH 2/8] clk: meson: g12a: add support for VPU/HDMI clocks 2019-08-30 12:09 ` [U-Boot] [PATCH 2/8] clk: meson: g12a: add support for VPU/HDMI clocks Neil Armstrong @ 2019-10-10 18:15 ` Anatolij Gustschin 0 siblings, 0 replies; 19+ messages in thread From: Anatolij Gustschin @ 2019-10-10 18:15 UTC (permalink / raw) To: u-boot On Fri, 30 Aug 2019 14:09:22 +0200 Neil Armstrong narmstrong at baylibre.com wrote: > Add necessary clock support to set up clock for the VPU and > HDMI support. > > Signed-off-by: Neil Armstrong <narmstrong@baylibre.com> Reviewed-by: Anatolij Gustschin <agust@denx.de> -- Anatolij ^ permalink raw reply [flat|nested] 19+ messages in thread
* [U-Boot] [PATCH 3/8] video: meson: remove power domain get 2019-08-30 12:09 [U-Boot] [PATCH 0/8] arm: meson: add Video support for G12A and SEI510 board Neil Armstrong 2019-08-30 12:09 ` [U-Boot] [PATCH 1/8] power: domain: meson-gx-pwrc: add G12A support Neil Armstrong 2019-08-30 12:09 ` [U-Boot] [PATCH 2/8] clk: meson: g12a: add support for VPU/HDMI clocks Neil Armstrong @ 2019-08-30 12:09 ` Neil Armstrong 2019-10-10 18:15 ` Anatolij Gustschin 2019-08-30 12:09 ` [U-Boot] [PATCH 4/8] video: meson: sync with linux drm-misc tree Neil Armstrong ` (5 subsequent siblings) 8 siblings, 1 reply; 19+ messages in thread From: Neil Armstrong @ 2019-08-30 12:09 UTC (permalink / raw) To: u-boot Remove getting and enabling the node power domain since it's now handled by the dm core directly. Signed-off-by: Neil Armstrong <narmstrong@baylibre.com> --- drivers/video/meson/meson_vpu.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/drivers/video/meson/meson_vpu.c b/drivers/video/meson/meson_vpu.c index 279401d597..34d35749eb 100644 --- a/drivers/video/meson/meson_vpu.c +++ b/drivers/video/meson/meson_vpu.c @@ -7,7 +7,6 @@ */ #include "meson_vpu.h" -#include <power-domain.h> #include <efi_loader.h> #include <dm/device-internal.h> #include <dm/uclass-internal.h> @@ -93,7 +92,6 @@ static const struct udevice_id meson_vpu_ids[] = { static int meson_vpu_probe(struct udevice *dev) { struct meson_vpu_priv *priv = dev_get_priv(dev); - struct power_domain pd; struct udevice *disp; int ret; @@ -115,14 +113,6 @@ static int meson_vpu_probe(struct udevice *dev) if (!priv->dmc_base) return -EINVAL; - ret = power_domain_get(dev, &pd); - if (ret) - return ret; - - ret = power_domain_on(&pd); - if (ret) - return ret; - meson_vpu_init(dev); /* probe the display */ -- 2.22.0 ^ permalink raw reply related [flat|nested] 19+ messages in thread
* [U-Boot] [PATCH 3/8] video: meson: remove power domain get 2019-08-30 12:09 ` [U-Boot] [PATCH 3/8] video: meson: remove power domain get Neil Armstrong @ 2019-10-10 18:15 ` Anatolij Gustschin 0 siblings, 0 replies; 19+ messages in thread From: Anatolij Gustschin @ 2019-10-10 18:15 UTC (permalink / raw) To: u-boot On Fri, 30 Aug 2019 14:09:23 +0200 Neil Armstrong narmstrong at baylibre.com wrote: > Remove getting and enabling the node power domain since it's now handled > by the dm core directly. > > Signed-off-by: Neil Armstrong <narmstrong@baylibre.com> Reviewed-by: Anatolij Gustschin <agust@denx.de> -- Anatolij ^ permalink raw reply [flat|nested] 19+ messages in thread
* [U-Boot] [PATCH 4/8] video: meson: sync with linux drm-misc tree 2019-08-30 12:09 [U-Boot] [PATCH 0/8] arm: meson: add Video support for G12A and SEI510 board Neil Armstrong ` (2 preceding siblings ...) 2019-08-30 12:09 ` [U-Boot] [PATCH 3/8] video: meson: remove power domain get Neil Armstrong @ 2019-08-30 12:09 ` Neil Armstrong 2019-10-09 15:12 ` Neil Armstrong 2019-10-10 20:48 ` Anatolij Gustschin 2019-08-30 12:09 ` [U-Boot] [PATCH 5/8] video: meson: add compatible for Amlogic G12A Neil Armstrong ` (4 subsequent siblings) 8 siblings, 2 replies; 19+ messages in thread From: Neil Armstrong @ 2019-08-30 12:09 UTC (permalink / raw) To: u-boot Synchronize the Amlogic Meson Video driver back with the latest DRM misc tree, adding G12A platform support, from the latest commit: 528a25d040bc ("drm: meson: use match data to detect vpu compatibility") The sync includes the following changes from Linux adapted to U-Boot: - Add support for VIC alternate timings - Switch PLL to 5.94GHz base for 297Mhz pixel clock - Add registers for G12A SoC - Add G12A Support for VPP setup - Add G12A Support for VIU setup - Add G12A support for OSD1 Plane - Add G12A support for plane handling in CRTC driver - Add G12A support for CVBS Encoder - Add G12A Video Clock setup - Add G12A support for the DW-HDMI Glue - fix G12A HDMI PLL settings for 4K60 1000/1001 variations - fix primary plane disabling - fix G12A primary plane disabling - mask value when writing bits relaxed - crtc: drv: vpp: viu: venc: use proper macros instead of magic constants - global clean-up - add macro used to enable HDMI PLL - venc: set the correct macrovision max amplitude value Signed-off-by: Neil Armstrong <narmstrong@baylibre.com> --- drivers/video/meson/meson_dw_hdmi.c | 61 ++++- drivers/video/meson/meson_plane.c | 47 +++- drivers/video/meson/meson_registers.h | 373 +++++++++++++++++++++++++- drivers/video/meson/meson_vclk.c | 233 ++++++++++++---- drivers/video/meson/meson_venc.c | 169 +++++++++--- drivers/video/meson/meson_vpu.h | 1 + drivers/video/meson/meson_vpu_init.c | 205 +++++++++++--- 7 files changed, 929 insertions(+), 160 deletions(-) diff --git a/drivers/video/meson/meson_dw_hdmi.c b/drivers/video/meson/meson_dw_hdmi.c index 9831d978fc..ae2e6288f3 100644 --- a/drivers/video/meson/meson_dw_hdmi.c +++ b/drivers/video/meson/meson_dw_hdmi.c @@ -24,6 +24,7 @@ #define HDMITX_TOP_ADDR_REG 0x0 #define HDMITX_TOP_DATA_REG 0x4 #define HDMITX_TOP_CTRL_REG 0x8 +#define HDMITX_TOP_G12A_OFFSET 0x8000 /* Controller Communication Channel */ #define HDMITX_DWC_ADDR_REG 0x10 @@ -37,6 +38,8 @@ #define HHI_HDMI_PHY_CNTL1 0x3a4 /* 0xe9 */ #define HHI_HDMI_PHY_CNTL2 0x3a8 /* 0xea */ #define HHI_HDMI_PHY_CNTL3 0x3ac /* 0xeb */ +#define HHI_HDMI_PHY_CNTL4 0x3b0 /* 0xec */ +#define HHI_HDMI_PHY_CNTL5 0x3b4 /* 0xed */ struct meson_dw_hdmi { struct udevice *dev; @@ -48,6 +51,7 @@ enum hdmi_compatible { HDMI_COMPATIBLE_GXBB = 0, HDMI_COMPATIBLE_GXL = 1, HDMI_COMPATIBLE_GXM = 2, + HDMI_COMPATIBLE_G12A = 3, }; static inline bool meson_hdmi_is_compatible(struct meson_dw_hdmi *priv, @@ -60,8 +64,14 @@ static inline bool meson_hdmi_is_compatible(struct meson_dw_hdmi *priv, static unsigned int dw_hdmi_top_read(struct dw_hdmi *hdmi, unsigned int addr) { + struct meson_dw_hdmi *priv = container_of(hdmi, struct meson_dw_hdmi, + hdmi); unsigned int data; + if (meson_hdmi_is_compatible(priv, HDMI_COMPATIBLE_G12A)) + return readl(hdmi->ioaddr + + HDMITX_TOP_G12A_OFFSET + (addr << 2)); + /* ADDR must be written twice */ writel(addr & 0xffff, hdmi->ioaddr + HDMITX_TOP_ADDR_REG); writel(addr & 0xffff, hdmi->ioaddr + HDMITX_TOP_ADDR_REG); @@ -76,6 +86,15 @@ static unsigned int dw_hdmi_top_read(struct dw_hdmi *hdmi, unsigned int addr) static inline void dw_hdmi_top_write(struct dw_hdmi *hdmi, unsigned int addr, unsigned int data) { + struct meson_dw_hdmi *priv = container_of(hdmi, struct meson_dw_hdmi, + hdmi); + + if (meson_hdmi_is_compatible(priv, HDMI_COMPATIBLE_G12A)) { + writel(data, hdmi->ioaddr + + HDMITX_TOP_G12A_OFFSET + (addr << 2)); + return; + } + /* ADDR must be written twice */ writel(addr & 0xffff, hdmi->ioaddr + HDMITX_TOP_ADDR_REG); writel(addr & 0xffff, hdmi->ioaddr + HDMITX_TOP_ADDR_REG); @@ -237,7 +256,7 @@ static void meson_dw_hdmi_phy_setup_mode(struct meson_dw_hdmi *priv, hhi_write(HHI_HDMI_PHY_CNTL0, 0x33604142); hhi_write(HHI_HDMI_PHY_CNTL3, 0x0016315b); } - } else { + } else if (meson_hdmi_is_compatible(priv, HDMI_COMPATIBLE_GXBB)) { if (pixel_clock >= 371250) { /* 5.94Gbps, 3.7125Gbps */ hhi_write(HHI_HDMI_PHY_CNTL0, 0x33353245); @@ -251,6 +270,23 @@ static void meson_dw_hdmi_phy_setup_mode(struct meson_dw_hdmi *priv, hhi_write(HHI_HDMI_PHY_CNTL0, 0x33632122); hhi_write(HHI_HDMI_PHY_CNTL3, 0x2000115b); } + } else if (meson_hdmi_is_compatible(priv, HDMI_COMPATIBLE_G12A)) { + if (pixel_clock >= 371250) { + /* 5.94Gbps, 3.7125Gbps */ + hhi_write(HHI_HDMI_PHY_CNTL0, 0x37eb65c4); + hhi_write(HHI_HDMI_PHY_CNTL3, 0x2ab0ff3b); + hhi_write(HHI_HDMI_PHY_CNTL5, 0x0000080b); + } else if (pixel_clock >= 297000) { + /* 2.97Gbps */ + hhi_write(HHI_HDMI_PHY_CNTL0, 0x33eb6262); + hhi_write(HHI_HDMI_PHY_CNTL3, 0x2ab0ff3b); + hhi_write(HHI_HDMI_PHY_CNTL5, 0x00000003); + } else { + /* 1.485Gbps, and below */ + hhi_write(HHI_HDMI_PHY_CNTL0, 0x33eb4242); + hhi_write(HHI_HDMI_PHY_CNTL3, 0x2ab0ff3b); + hhi_write(HHI_HDMI_PHY_CNTL5, 0x00000003); + } } } @@ -292,7 +328,8 @@ static int meson_dw_hdmi_phy_init(struct dw_hdmi *hdmi, uint pixel_clock) /* BIT_INVERT */ if (meson_hdmi_is_compatible(priv, HDMI_COMPATIBLE_GXL) || - meson_hdmi_is_compatible(priv, HDMI_COMPATIBLE_GXM)) + meson_hdmi_is_compatible(priv, HDMI_COMPATIBLE_GXM) || + meson_hdmi_is_compatible(priv, HDMI_COMPATIBLE_G12A)) dw_hdmi_hhi_update_bits(priv, HHI_HDMI_PHY_CNTL1, BIT(17), 0); else dw_hdmi_hhi_update_bits(priv, HHI_HDMI_PHY_CNTL1, @@ -356,8 +393,12 @@ static int meson_dw_hdmi_probe(struct udevice *dev) priv->hdmi.hdmi_data.enc_out_bus_format = MEDIA_BUS_FMT_RGB888_1X24; priv->hdmi.hdmi_data.enc_in_bus_format = MEDIA_BUS_FMT_YUV8_1X24; priv->hdmi.phy_set = meson_dw_hdmi_phy_init; - priv->hdmi.write_reg = dw_hdmi_dwc_write; - priv->hdmi.read_reg = dw_hdmi_dwc_read; + if (meson_hdmi_is_compatible(priv, HDMI_COMPATIBLE_G12A)) + priv->hdmi.reg_io_width = 1; + else { + priv->hdmi.write_reg = dw_hdmi_dwc_write; + priv->hdmi.read_reg = dw_hdmi_dwc_read; + } priv->hdmi.i2c_clk_high = 0x67; priv->hdmi.i2c_clk_low = 0x78; @@ -409,9 +450,13 @@ static int meson_dw_hdmi_probe(struct udevice *dev) if (ret) return ret; - /* Enable APB3 fail on error */ - writel_bits(BIT(15), BIT(15), priv->hdmi.ioaddr + HDMITX_TOP_CTRL_REG); - writel_bits(BIT(15), BIT(15), priv->hdmi.ioaddr + HDMITX_DWC_CTRL_REG); + if (!meson_hdmi_is_compatible(priv, HDMI_COMPATIBLE_G12A)) { + /* Enable APB3 fail on error */ + writel_bits(BIT(15), BIT(15), + priv->hdmi.ioaddr + HDMITX_TOP_CTRL_REG); + writel_bits(BIT(15), BIT(15), + priv->hdmi.ioaddr + HDMITX_DWC_CTRL_REG); + } /* Bring out of reset */ dw_hdmi_top_write(&priv->hdmi, HDMITX_TOP_SW_RESET, 0); @@ -448,6 +493,8 @@ static const struct udevice_id meson_dw_hdmi_ids[] = { .data = HDMI_COMPATIBLE_GXL }, { .compatible = "amlogic,meson-gxm-dw-hdmi", .data = HDMI_COMPATIBLE_GXM }, + { .compatible = "amlogic,meson-g12a-dw-hdmi", + .data = HDMI_COMPATIBLE_G12A }, { } }; diff --git a/drivers/video/meson/meson_plane.c b/drivers/video/meson/meson_plane.c index 63a4bf2d8d..2bc9327e1e 100644 --- a/drivers/video/meson/meson_plane.c +++ b/drivers/video/meson/meson_plane.c @@ -108,12 +108,33 @@ void meson_vpu_setup_plane(struct udevice *dev, bool is_interlaced) dest_y1 = src_y1 = 0; dest_y2 = src_y2 = uc_priv->ysize; - /* Enable VPP Postblend */ - writel(uc_priv->xsize, - priv->io_base + _REG(VPP_POSTBLEND_H_SIZE)); + if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) { + /* VD1 Preblend vertical start/end */ + writel(FIELD_PREP(GENMASK(11, 0), 2303), + priv->io_base + _REG(VPP_PREBLEND_VD1_V_START_END)); + + /* Setup Blender */ + writel(uc_priv->xsize | + uc_priv->ysize << 16, + priv->io_base + _REG(VPP_POSTBLEND_H_SIZE)); + + writel(0 << 16 | + (uc_priv->xsize - 1), + priv->io_base + _REG(VPP_OSD1_BLD_H_SCOPE)); + writel(0 << 16 | + (uc_priv->ysize - 1), + priv->io_base + _REG(VPP_OSD1_BLD_V_SCOPE)); + writel(uc_priv->xsize << 16 | + uc_priv->ysize, + priv->io_base + _REG(VPP_OUT_H_V_SIZE)); + } else { + /* Enable VPP Postblend */ + writel(uc_priv->xsize, + priv->io_base + _REG(VPP_POSTBLEND_H_SIZE)); - writel_bits(VPP_POSTBLEND_ENABLE, VPP_POSTBLEND_ENABLE, - priv->io_base + _REG(VPP_MISC)); + writel_bits(VPP_POSTBLEND_ENABLE, VPP_POSTBLEND_ENABLE, + priv->io_base + _REG(VPP_MISC)); + } /* uc_plat->base is the framebuffer */ @@ -172,6 +193,18 @@ void meson_vpu_setup_plane(struct udevice *dev, bool is_interlaced) MESON_CANVAS_BLKMODE_LINEAR); /* Enable OSD1 */ - writel_bits(VPP_OSD1_POSTBLEND, VPP_OSD1_POSTBLEND, - priv->io_base + _REG(VPP_MISC)); + if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) { + writel(((dest_x2 - 1) << 16) | dest_x1, + priv->io_base + _REG(VIU_OSD_BLEND_DIN0_SCOPE_H)); + writel(((dest_y2 - 1) << 16) | dest_y1, + priv->io_base + _REG(VIU_OSD_BLEND_DIN0_SCOPE_V)); + writel(uc_priv->xsize << 16 | uc_priv->ysize, + priv->io_base + _REG(VIU_OSD_BLEND_BLEND0_SIZE)); + writel(uc_priv->xsize << 16 | uc_priv->ysize, + priv->io_base + _REG(VIU_OSD_BLEND_BLEND1_SIZE)); + writel_bits(3 << 8, 3 << 8, + priv->io_base + _REG(OSD1_BLEND_SRC_CTRL)); + } else + writel_bits(VPP_OSD1_POSTBLEND, VPP_OSD1_POSTBLEND, + priv->io_base + _REG(VPP_MISC)); } diff --git a/drivers/video/meson/meson_registers.h b/drivers/video/meson/meson_registers.h index 01fe7d2431..39e8ec8639 100644 --- a/drivers/video/meson/meson_registers.h +++ b/drivers/video/meson/meson_registers.h @@ -136,11 +136,19 @@ #define VIU_ADDR_START 0x1a00 #define VIU_ADDR_END 0x1aff #define VIU_SW_RESET 0x1a01 +#define VIU_SW_RESET_OSD1 BIT(0) #define VIU_MISC_CTRL0 0x1a06 +#define VIU_CTRL0_VD1_AFBC_MASK 0x170000 #define VIU_MISC_CTRL1 0x1a07 #define D2D3_INTF_LENGTH 0x1a08 #define D2D3_INTF_CTRL0 0x1a09 #define VIU_OSD1_CTRL_STAT 0x1a10 +#define VIU_OSD1_OSD_BLK_ENABLE BIT(0) +#define VIU_OSD1_POSTBLD_SRC_VD1 (1 << 8) +#define VIU_OSD1_POSTBLD_SRC_VD2 (2 << 8) +#define VIU_OSD1_POSTBLD_SRC_OSD1 (3 << 8) +#define VIU_OSD1_POSTBLD_SRC_OSD2 (4 << 8) +#define VIU_OSD1_OSD_ENABLE BIT(21) #define VIU_OSD1_CTRL_STAT2 0x1a2d #define VIU_OSD1_COLOR_ADDR 0x1a11 #define VIU_OSD1_COLOR 0x1a12 @@ -206,6 +214,35 @@ #define VIU_OSD2_FIFO_CTRL_STAT 0x1a4b #define VIU_OSD2_TEST_RDDATA 0x1a4c #define VIU_OSD2_PROT_CTRL 0x1a4e +#define VIU_OSD2_MALI_UNPACK_CTRL 0x1abd +#define VIU_OSD2_DIMM_CTRL 0x1acf + +#define VIU_OSD3_CTRL_STAT 0x3d80 +#define VIU_OSD3_CTRL_STAT2 0x3d81 +#define VIU_OSD3_COLOR_ADDR 0x3d82 +#define VIU_OSD3_COLOR 0x3d83 +#define VIU_OSD3_TCOLOR_AG0 0x3d84 +#define VIU_OSD3_TCOLOR_AG1 0x3d85 +#define VIU_OSD3_TCOLOR_AG2 0x3d86 +#define VIU_OSD3_TCOLOR_AG3 0x3d87 +#define VIU_OSD3_BLK0_CFG_W0 0x3d88 +#define VIU_OSD3_BLK0_CFG_W1 0x3d8c +#define VIU_OSD3_BLK0_CFG_W2 0x3d90 +#define VIU_OSD3_BLK0_CFG_W3 0x3d94 +#define VIU_OSD3_BLK0_CFG_W4 0x3d98 +#define VIU_OSD3_BLK1_CFG_W4 0x3d99 +#define VIU_OSD3_BLK2_CFG_W4 0x3d9a +#define VIU_OSD3_FIFO_CTRL_STAT 0x3d9c +#define VIU_OSD3_TEST_RDDATA 0x3d9d +#define VIU_OSD3_PROT_CTRL 0x3d9e +#define VIU_OSD3_MALI_UNPACK_CTRL 0x3d9f +#define VIU_OSD3_DIMM_CTRL 0x3da0 + +#define VIU_OSD_DDR_PRIORITY_URGENT BIT(0) +#define VIU_OSD_HOLD_FIFO_LINES(lines) ((lines & 0x1f) << 5) +#define VIU_OSD_FIFO_DEPTH_VAL(val) ((val & 0x7f) << 12) +#define VIU_OSD_WORDS_PER_BURST(words) (((words & 0x4) >> 1) << 22) +#define VIU_OSD_FIFO_LIMITS(size) ((size & 0xf) << 24) #define VD1_IF0_GEN_REG 0x1a50 #define VD1_IF0_CANVAS0 0x1a51 @@ -277,6 +314,27 @@ #define VIU_OSD1_MATRIX_COEF31_32 0x1a9e #define VIU_OSD1_MATRIX_COEF40_41 0x1a9f #define VD1_IF0_GEN_REG3 0x1aa7 + +#define VIU_OSD_BLENDO_H_START_END 0x1aa9 +#define VIU_OSD_BLENDO_V_START_END 0x1aaa +#define VIU_OSD_BLEND_GEN_CTRL0 0x1aab +#define VIU_OSD_BLEND_GEN_CTRL1 0x1aac +#define VIU_OSD_BLEND_DUMMY_DATA 0x1aad +#define VIU_OSD_BLEND_CURRENT_XY 0x1aae + +#define VIU_OSD2_MATRIX_CTRL 0x1ab0 +#define VIU_OSD2_MATRIX_COEF00_01 0x1ab1 +#define VIU_OSD2_MATRIX_COEF02_10 0x1ab2 +#define VIU_OSD2_MATRIX_COEF11_12 0x1ab3 +#define VIU_OSD2_MATRIX_COEF20_21 0x1ab4 +#define VIU_OSD2_MATRIX_COEF22 0x1ab5 +#define VIU_OSD2_MATRIX_OFFSET0_1 0x1ab6 +#define VIU_OSD2_MATRIX_OFFSET2 0x1ab7 +#define VIU_OSD2_MATRIX_PRE_OFFSET0_1 0x1ab8 +#define VIU_OSD2_MATRIX_PRE_OFFSET2 0x1ab9 +#define VIU_OSD2_MATRIX_PROBE_COLOR 0x1aba +#define VIU_OSD2_MATRIX_HL_COLOR 0x1abb +#define VIU_OSD2_MATRIX_PROBE_POS 0x1abc #define VIU_OSD1_EOTF_CTL 0x1ad4 #define VIU_OSD1_EOTF_COEF00_01 0x1ad5 #define VIU_OSD1_EOTF_COEF02_10 0x1ad6 @@ -295,6 +353,7 @@ #define VPP_LINE_IN_LENGTH 0x1d01 #define VPP_PIC_IN_HEIGHT 0x1d02 #define VPP_SCALE_COEF_IDX 0x1d03 +#define VPP_SCALE_HORIZONTAL_COEF BIT(8) #define VPP_SCALE_COEF 0x1d04 #define VPP_VSC_REGION12_STARTP 0x1d05 #define VPP_VSC_REGION34_STARTP 0x1d06 @@ -316,6 +375,12 @@ #define VPP_HSC_REGION4_PHASE_SLOPE 0x1d17 #define VPP_HSC_PHASE_CTRL 0x1d18 #define VPP_SC_MISC 0x1d19 +#define VPP_SC_VD_EN_ENABLE BIT(15) +#define VPP_SC_TOP_EN_ENABLE BIT(16) +#define VPP_SC_HSC_EN_ENABLE BIT(17) +#define VPP_SC_VSC_EN_ENABLE BIT(18) +#define VPP_VSC_BANK_LENGTH(length) (length & 0x7) +#define VPP_HSC_BANK_LENGTH(length) ((length & 0x7) << 8) #define VPP_PREBLEND_VD1_H_START_END 0x1d1a #define VPP_PREBLEND_VD1_V_START_END 0x1d1b #define VPP_POSTBLEND_VD1_H_START_END 0x1d1c @@ -325,24 +390,28 @@ #define VPP_PREBLEND_H_SIZE 0x1d20 #define VPP_POSTBLEND_H_SIZE 0x1d21 #define VPP_HOLD_LINES 0x1d22 +#define VPP_POSTBLEND_HOLD_LINES(lines) (lines & 0xf) +#define VPP_PREBLEND_HOLD_LINES(lines) ((lines & 0xf) << 8) #define VPP_BLEND_ONECOLOR_CTRL 0x1d23 #define VPP_PREBLEND_CURRENT_XY 0x1d24 #define VPP_POSTBLEND_CURRENT_XY 0x1d25 #define VPP_MISC 0x1d26 -#define VPP_PREBLEND_ENABLE BIT(6) -#define VPP_POSTBLEND_ENABLE BIT(7) -#define VPP_OSD2_ALPHA_PREMULT BIT(8) -#define VPP_OSD1_ALPHA_PREMULT BIT(9) -#define VPP_VD1_POSTBLEND BIT(10) -#define VPP_VD2_POSTBLEND BIT(11) -#define VPP_OSD1_POSTBLEND BIT(12) -#define VPP_OSD2_POSTBLEND BIT(13) -#define VPP_VD1_PREBLEND BIT(14) -#define VPP_VD2_PREBLEND BIT(15) -#define VPP_OSD1_PREBLEND BIT(16) -#define VPP_OSD2_PREBLEND BIT(17) -#define VPP_COLOR_MNG_ENABLE BIT(28) +#define VPP_PREBLEND_ENABLE BIT(6) +#define VPP_POSTBLEND_ENABLE BIT(7) +#define VPP_OSD2_ALPHA_PREMULT BIT(8) +#define VPP_OSD1_ALPHA_PREMULT BIT(9) +#define VPP_VD1_POSTBLEND BIT(10) +#define VPP_VD2_POSTBLEND BIT(11) +#define VPP_OSD1_POSTBLEND BIT(12) +#define VPP_OSD2_POSTBLEND BIT(13) +#define VPP_VD1_PREBLEND BIT(14) +#define VPP_VD2_PREBLEND BIT(15) +#define VPP_OSD1_PREBLEND BIT(16) +#define VPP_OSD2_PREBLEND BIT(17) +#define VPP_COLOR_MNG_ENABLE BIT(28) #define VPP_OFIFO_SIZE 0x1d27 +#define VPP_OFIFO_SIZE_MASK GENMASK(13, 0) +#define VPP_OFIFO_SIZE_DEFAULT (0xfff << 20 | 0x1000) #define VPP_FIFO_STATUS 0x1d28 #define VPP_SMOKE_CTRL 0x1d29 #define VPP_SMOKE1_VAL 0x1d2a @@ -358,6 +427,8 @@ #define VPP_HSC_PHASE_CTRL1 0x1d34 #define VPP_HSC_INI_PAT_CTRL 0x1d35 #define VPP_VADJ_CTRL 0x1d40 +#define VPP_MINUS_BLACK_LVL_VADJ1_ENABLE BIT(1) + #define VPP_VADJ1_Y 0x1d41 #define VPP_VADJ1_MA_MB 0x1d42 #define VPP_VADJ1_MC_MD 0x1d43 @@ -417,6 +488,7 @@ #define VPP_PEAKING_VGAIN 0x1d92 #define VPP_PEAKING_NLP_1 0x1d93 #define VPP_DOLBY_CTRL 0x1d93 +#define VPP_PPS_DUMMY_DATA_MODE (1 << 17) #define VPP_PEAKING_NLP_2 0x1d94 #define VPP_PEAKING_NLP_3 0x1d95 #define VPP_PEAKING_NLP_4 0x1d96 @@ -471,6 +543,83 @@ #define VPP_OSD_SCALE_COEF 0x1dcd #define VPP_INT_LINE_NUM 0x1dce +#define VPP_WRAP_OSD1_MATRIX_COEF00_01 0x3d60 +#define VPP_WRAP_OSD1_MATRIX_COEF02_10 0x3d61 +#define VPP_WRAP_OSD1_MATRIX_COEF11_12 0x3d62 +#define VPP_WRAP_OSD1_MATRIX_COEF20_21 0x3d63 +#define VPP_WRAP_OSD1_MATRIX_COEF22 0x3d64 +#define VPP_WRAP_OSD1_MATRIX_COEF13_14 0x3d65 +#define VPP_WRAP_OSD1_MATRIX_COEF23_24 0x3d66 +#define VPP_WRAP_OSD1_MATRIX_COEF15_25 0x3d67 +#define VPP_WRAP_OSD1_MATRIX_CLIP 0x3d68 +#define VPP_WRAP_OSD1_MATRIX_OFFSET0_1 0x3d69 +#define VPP_WRAP_OSD1_MATRIX_OFFSET2 0x3d6a +#define VPP_WRAP_OSD1_MATRIX_PRE_OFFSET0_1 0x3d6b +#define VPP_WRAP_OSD1_MATRIX_PRE_OFFSET2 0x3d6c +#define VPP_WRAP_OSD1_MATRIX_EN_CTRL 0x3d6d + +#define VPP_WRAP_OSD2_MATRIX_COEF00_01 0x3d70 +#define VPP_WRAP_OSD2_MATRIX_COEF02_10 0x3d71 +#define VPP_WRAP_OSD2_MATRIX_COEF11_12 0x3d72 +#define VPP_WRAP_OSD2_MATRIX_COEF20_21 0x3d73 +#define VPP_WRAP_OSD2_MATRIX_COEF22 0x3d74 +#define VPP_WRAP_OSD2_MATRIX_COEF13_14 0x3d75 +#define VPP_WRAP_OSD2_MATRIX_COEF23_24 0x3d76 +#define VPP_WRAP_OSD2_MATRIX_COEF15_25 0x3d77 +#define VPP_WRAP_OSD2_MATRIX_CLIP 0x3d78 +#define VPP_WRAP_OSD2_MATRIX_OFFSET0_1 0x3d79 +#define VPP_WRAP_OSD2_MATRIX_OFFSET2 0x3d7a +#define VPP_WRAP_OSD2_MATRIX_PRE_OFFSET0_1 0x3d7b +#define VPP_WRAP_OSD2_MATRIX_PRE_OFFSET2 0x3d7c +#define VPP_WRAP_OSD2_MATRIX_EN_CTRL 0x3d7d + +#define VPP_WRAP_OSD3_MATRIX_COEF00_01 0x3db0 +#define VPP_WRAP_OSD3_MATRIX_COEF02_10 0x3db1 +#define VPP_WRAP_OSD3_MATRIX_COEF11_12 0x3db2 +#define VPP_WRAP_OSD3_MATRIX_COEF20_21 0x3db3 +#define VPP_WRAP_OSD3_MATRIX_COEF22 0x3db4 +#define VPP_WRAP_OSD3_MATRIX_COEF13_14 0x3db5 +#define VPP_WRAP_OSD3_MATRIX_COEF23_24 0x3db6 +#define VPP_WRAP_OSD3_MATRIX_COEF15_25 0x3db7 +#define VPP_WRAP_OSD3_MATRIX_CLIP 0x3db8 +#define VPP_WRAP_OSD3_MATRIX_OFFSET0_1 0x3db9 +#define VPP_WRAP_OSD3_MATRIX_OFFSET2 0x3dba +#define VPP_WRAP_OSD3_MATRIX_PRE_OFFSET0_1 0x3dbb +#define VPP_WRAP_OSD3_MATRIX_PRE_OFFSET2 0x3dbc +#define VPP_WRAP_OSD3_MATRIX_EN_CTRL 0x3dbd + +/* osd2 scaler */ +#define OSD2_VSC_PHASE_STEP 0x3d00 +#define OSD2_VSC_INI_PHASE 0x3d01 +#define OSD2_VSC_CTRL0 0x3d02 +#define OSD2_HSC_PHASE_STEP 0x3d03 +#define OSD2_HSC_INI_PHASE 0x3d04 +#define OSD2_HSC_CTRL0 0x3d05 +#define OSD2_HSC_INI_PAT_CTRL 0x3d06 +#define OSD2_SC_DUMMY_DATA 0x3d07 +#define OSD2_SC_CTRL0 0x3d08 +#define OSD2_SCI_WH_M1 0x3d09 +#define OSD2_SCO_H_START_END 0x3d0a +#define OSD2_SCO_V_START_END 0x3d0b +#define OSD2_SCALE_COEF_IDX 0x3d18 +#define OSD2_SCALE_COEF 0x3d19 + +/* osd34 scaler */ +#define OSD34_SCALE_COEF_IDX 0x3d1e +#define OSD34_SCALE_COEF 0x3d1f +#define OSD34_VSC_PHASE_STEP 0x3d20 +#define OSD34_VSC_INI_PHASE 0x3d21 +#define OSD34_VSC_CTRL0 0x3d22 +#define OSD34_HSC_PHASE_STEP 0x3d23 +#define OSD34_HSC_INI_PHASE 0x3d24 +#define OSD34_HSC_CTRL0 0x3d25 +#define OSD34_HSC_INI_PAT_CTRL 0x3d26 +#define OSD34_SC_DUMMY_DATA 0x3d27 +#define OSD34_SC_CTRL0 0x3d28 +#define OSD34_SCI_WH_M1 0x3d29 +#define OSD34_SCO_H_START_END 0x3d2a +#define OSD34_SCO_V_START_END 0x3d2b + /* viu2 */ #define VIU2_ADDR_START 0x1e00 #define VIU2_ADDR_END 0x1eff @@ -584,6 +733,25 @@ #define VENC_UPSAMPLE_CTRL0 0x1b64 #define VENC_UPSAMPLE_CTRL1 0x1b65 #define VENC_UPSAMPLE_CTRL2 0x1b66 +#define VENC_UPSAMPLE_CTRL_F0_2_CLK_RATIO BIT(0) +#define VENC_UPSAMPLE_CTRL_F1_EN BIT(5) +#define VENC_UPSAMPLE_CTRL_F1_UPSAMPLE_EN BIT(6) +#define VENC_UPSAMPLE_CTRL_INTERLACE_HIGH_LUMA (0x0 << 12) +#define VENC_UPSAMPLE_CTRL_CVBS (0x1 << 12) +#define VENC_UPSAMPLE_CTRL_S_VIDEO_LUMA (0x2 << 12) +#define VENC_UPSAMPLE_CTRL_S_VIDEO_CHROMA (0x3 << 12) +#define VENC_UPSAMPLE_CTRL_INTERLACE_PB (0x4 << 12) +#define VENC_UPSAMPLE_CTRL_INTERLACE_PR (0x5 << 12) +#define VENC_UPSAMPLE_CTRL_INTERLACE_R (0x6 << 12) +#define VENC_UPSAMPLE_CTRL_INTERLACE_G (0x7 << 12) +#define VENC_UPSAMPLE_CTRL_INTERLACE_B (0x8 << 12) +#define VENC_UPSAMPLE_CTRL_PROGRESSIVE_Y (0x9 << 12) +#define VENC_UPSAMPLE_CTRL_PROGRESSIVE_PB (0xa << 12) +#define VENC_UPSAMPLE_CTRL_PROGRESSIVE_PR (0xb << 12) +#define VENC_UPSAMPLE_CTRL_PROGRESSIVE_R (0xc << 12) +#define VENC_UPSAMPLE_CTRL_PROGRESSIVE_G (0xd << 12) +#define VENC_UPSAMPLE_CTRL_PROGRESSIVE_B (0xe << 12) +#define VENC_UPSAMPLE_CTRL_VDAC_TEST_VALUE (0xf << 12) #define TCON_INVERT_CTL 0x1b67 #define VENC_VIDEO_PROG_MODE 0x1b68 #define VENC_ENCI_LINE 0x1b69 @@ -592,6 +760,7 @@ #define VENC_ENCP_PIXEL 0x1b6c #define VENC_STATA 0x1b6d #define VENC_INTCTRL 0x1b6e +#define VENC_INTCTRL_ENCI_LNRST_INT_EN BIT(1) #define VENC_INTFLAG 0x1b6f #define VENC_VIDEO_TST_EN 0x1b70 #define VENC_VIDEO_TST_MDSEL 0x1b71 @@ -602,6 +771,7 @@ #define VENC_VIDEO_TST_CLRBAR_WIDTH 0x1b76 #define VENC_VIDEO_TST_VDCNT_STSET 0x1b77 #define VENC_VDAC_DACSEL0 0x1b78 +#define VENC_VDAC_SEL_ATV_DMD BIT(5) #define VENC_VDAC_DACSEL1 0x1b79 #define VENC_VDAC_DACSEL2 0x1b7a #define VENC_VDAC_DACSEL3 0x1b7b @@ -622,6 +792,7 @@ #define VENC_VDAC_DAC5_GAINCTRL 0x1bfa #define VENC_VDAC_DAC5_OFFSET 0x1bfb #define VENC_VDAC_FIFO_CTRL 0x1bfc +#define VENC_VDAC_FIFO_EN_ENCI_ENABLE BIT(13) #define ENCL_TCON_INVERT_CTL 0x1bfd #define ENCP_VIDEO_EN 0x1b80 #define ENCP_VIDEO_SYNC_MODE 0x1b81 @@ -637,6 +808,7 @@ #define ENCP_VIDEO_SYNC_OFFST 0x1b8b #define ENCP_VIDEO_MACV_OFFST 0x1b8c #define ENCP_VIDEO_MODE 0x1b8d +#define ENCP_VIDEO_MODE_DE_V_HIGH BIT(14) #define ENCP_VIDEO_MODE_ADV 0x1b8e #define ENCP_DBG_PX_RST 0x1b90 #define ENCP_DBG_LN_RST 0x1b91 @@ -715,6 +887,11 @@ #define C656_FS_LNED 0x1be7 #define ENCI_VIDEO_MODE 0x1b00 #define ENCI_VIDEO_MODE_ADV 0x1b01 +#define ENCI_VIDEO_MODE_ADV_DMXMD(val) (val & 0x3) +#define ENCI_VIDEO_MODE_ADV_VBICTL_LINE_17_22 BIT(2) +#define ENCI_VIDEO_MODE_ADV_YBW_MEDIUM (0 << 4) +#define ENCI_VIDEO_MODE_ADV_YBW_LOW (0x1 << 4) +#define ENCI_VIDEO_MODE_ADV_YBW_HIGH (0x2 << 4) #define ENCI_VIDEO_FSC_ADJ 0x1b02 #define ENCI_VIDEO_BRIGHT 0x1b03 #define ENCI_VIDEO_CONT 0x1b04 @@ -785,13 +962,17 @@ #define ENCI_DBG_MAXPX 0x1b4c #define ENCI_DBG_MAXLN 0x1b4d #define ENCI_MACV_MAX_AMP 0x1b50 +#define ENCI_MACV_MAX_AMP_ENABLE_CHANGE BIT(15) +#define ENCI_MACV_MAX_AMP_VAL(val) (val & 0x83ff) #define ENCI_MACV_PULSE_LO 0x1b51 #define ENCI_MACV_PULSE_HI 0x1b52 #define ENCI_MACV_BKP_MAX 0x1b53 #define ENCI_CFILT_CTRL 0x1b54 +#define ENCI_CFILT_CMPT_SEL_HIGH BIT(1) #define ENCI_CFILT7 0x1b55 #define ENCI_YC_DELAY 0x1b56 #define ENCI_VIDEO_EN 0x1b57 +#define ENCI_VIDEO_EN_ENABLE BIT(0) #define ENCI_DVI_HSO_BEGIN 0x1c00 #define ENCI_DVI_HSO_END 0x1c01 #define ENCI_DVI_VSO_BLINE_EVN 0x1c02 @@ -803,6 +984,10 @@ #define ENCI_DVI_VSO_END_EVN 0x1c08 #define ENCI_DVI_VSO_END_ODD 0x1c09 #define ENCI_CFILT_CTRL2 0x1c0a +#define ENCI_CFILT_CMPT_CR_DLY(delay) (delay & 0xf) +#define ENCI_CFILT_CMPT_CB_DLY(delay) ((delay & 0xf) << 4) +#define ENCI_CFILT_CVBS_CR_DLY(delay) ((delay & 0xf) << 8) +#define ENCI_CFILT_CVBS_CB_DLY(delay) ((delay & 0xf) << 12) #define ENCI_DACSEL_0 0x1c0b #define ENCI_DACSEL_1 0x1c0c #define ENCP_DACSEL_0 0x1c0d @@ -817,6 +1002,8 @@ #define ENCI_TST_CLRBAR_WIDTH 0x1c16 #define ENCI_TST_VDCNT_STSET 0x1c17 #define ENCI_VFIFO2VD_CTL 0x1c18 +#define ENCI_VFIFO2VD_CTL_ENABLE BIT(0) +#define ENCI_VFIFO2VD_CTL_VD_SEL(val) ((val & 0xff) << 8) #define ENCI_VFIFO2VD_PIXEL_START 0x1c19 #define ENCI_VFIFO2VD_PIXEL_END 0x1c1a #define ENCI_VFIFO2VD_LINE_TOP_START 0x1c1b @@ -879,6 +1066,7 @@ #define VENC_VDAC_DAC5_FILT_CTRL0 0x1c56 #define VENC_VDAC_DAC5_FILT_CTRL1 0x1c57 #define VENC_VDAC_DAC0_FILT_CTRL0 0x1c58 +#define VENC_VDAC_DAC0_FILT_CTRL0_EN BIT(0) #define VENC_VDAC_DAC0_FILT_CTRL1 0x1c59 #define VENC_VDAC_DAC1_FILT_CTRL0 0x1c5a #define VENC_VDAC_DAC1_FILT_CTRL1 0x1c5b @@ -1284,6 +1472,18 @@ #define VIU2_SEL_VENC_ENCP (2 << 2) #define VIU2_SEL_VENC_ENCT (3 << 2) #define VPU_HDMI_SETTING 0x271b +#define VPU_HDMI_ENCI_DATA_TO_HDMI BIT(0) +#define VPU_HDMI_ENCP_DATA_TO_HDMI BIT(1) +#define VPU_HDMI_INV_HSYNC BIT(2) +#define VPU_HDMI_INV_VSYNC BIT(3) +#define VPU_HDMI_OUTPUT_CRYCB (0 << 5) +#define VPU_HDMI_OUTPUT_YCBCR (1 << 5) +#define VPU_HDMI_OUTPUT_YCRCB (2 << 5) +#define VPU_HDMI_OUTPUT_CBCRY (3 << 5) +#define VPU_HDMI_OUTPUT_CBYCR (4 << 5) +#define VPU_HDMI_OUTPUT_CRCBY (5 << 5) +#define VPU_HDMI_WR_RATE(rate) (((rate & 0x1f) - 1) << 8) +#define VPU_HDMI_RD_RATE(rate) (((rate & 0x1f) - 1) << 12) #define ENCI_INFO_READ 0x271c #define ENCP_INFO_READ 0x271d #define ENCT_INFO_READ 0x271e @@ -1360,6 +1560,7 @@ #define VPU_RDARB_MODE_L1C2 0x2799 #define VPU_RDARB_MODE_L2C1 0x279d #define VPU_WRARB_MODE_L2C1 0x27a2 +#define VPU_RDARB_SLAVE_TO_MASTER_PORT(dc, port) (port << (16 + dc)) /* osd super scale */ #define OSDSR_HV_SIZEIN 0x3130 @@ -1390,4 +1591,150 @@ #define OSDSR_YBIC_VCOEF0 0x3149 #define OSDSR_CBIC_VCOEF0 0x314a +/* osd afbcd on gxtvbb */ +#define OSD1_AFBCD_ENABLE 0x31a0 +#define OSD1_AFBCD_MODE 0x31a1 +#define OSD1_AFBCD_SIZE_IN 0x31a2 +#define OSD1_AFBCD_HDR_PTR 0x31a3 +#define OSD1_AFBCD_FRAME_PTR 0x31a4 +#define OSD1_AFBCD_CHROMA_PTR 0x31a5 +#define OSD1_AFBCD_CONV_CTRL 0x31a6 +#define OSD1_AFBCD_STATUS 0x31a8 +#define OSD1_AFBCD_PIXEL_HSCOPE 0x31a9 +#define OSD1_AFBCD_PIXEL_VSCOPE 0x31aa + +/* add for gxm and 962e dv core2 */ +#define DOLBY_CORE2A_SWAP_CTRL1 0x3434 +#define DOLBY_CORE2A_SWAP_CTRL2 0x3435 + +/* osd afbc on g12a */ +#define VPU_MAFBC_BLOCK_ID 0x3a00 +#define VPU_MAFBC_IRQ_RAW_STATUS 0x3a01 +#define VPU_MAFBC_IRQ_CLEAR 0x3a02 +#define VPU_MAFBC_IRQ_MASK 0x3a03 +#define VPU_MAFBC_IRQ_STATUS 0x3a04 +#define VPU_MAFBC_COMMAND 0x3a05 +#define VPU_MAFBC_STATUS 0x3a06 +#define VPU_MAFBC_SURFACE_CFG 0x3a07 +#define VPU_MAFBC_HEADER_BUF_ADDR_LOW_S0 0x3a10 +#define VPU_MAFBC_HEADER_BUF_ADDR_HIGH_S0 0x3a11 +#define VPU_MAFBC_FORMAT_SPECIFIER_S0 0x3a12 +#define VPU_MAFBC_BUFFER_WIDTH_S0 0x3a13 +#define VPU_MAFBC_BUFFER_HEIGHT_S0 0x3a14 +#define VPU_MAFBC_BOUNDING_BOX_X_START_S0 0x3a15 +#define VPU_MAFBC_BOUNDING_BOX_X_END_S0 0x3a16 +#define VPU_MAFBC_BOUNDING_BOX_Y_START_S0 0x3a17 +#define VPU_MAFBC_BOUNDING_BOX_Y_END_S0 0x3a18 +#define VPU_MAFBC_OUTPUT_BUF_ADDR_LOW_S0 0x3a19 +#define VPU_MAFBC_OUTPUT_BUF_ADDR_HIGH_S0 0x3a1a +#define VPU_MAFBC_OUTPUT_BUF_STRIDE_S0 0x3a1b +#define VPU_MAFBC_PREFETCH_CFG_S0 0x3a1c + +#define VPU_MAFBC_HEADER_BUF_ADDR_LOW_S1 0x3a30 +#define VPU_MAFBC_HEADER_BUF_ADDR_HIGH_S1 0x3a31 +#define VPU_MAFBC_FORMAT_SPECIFIER_S1 0x3a32 +#define VPU_MAFBC_BUFFER_WIDTH_S1 0x3a33 +#define VPU_MAFBC_BUFFER_HEIGHT_S1 0x3a34 +#define VPU_MAFBC_BOUNDING_BOX_X_START_S1 0x3a35 +#define VPU_MAFBC_BOUNDING_BOX_X_END_S1 0x3a36 +#define VPU_MAFBC_BOUNDING_BOX_Y_START_S1 0x3a37 +#define VPU_MAFBC_BOUNDING_BOX_Y_END_S1 0x3a38 +#define VPU_MAFBC_OUTPUT_BUF_ADDR_LOW_S1 0x3a39 +#define VPU_MAFBC_OUTPUT_BUF_ADDR_HIGH_S1 0x3a3a +#define VPU_MAFBC_OUTPUT_BUF_STRIDE_S1 0x3a3b +#define VPU_MAFBC_PREFETCH_CFG_S1 0x3a3c + +#define VPU_MAFBC_HEADER_BUF_ADDR_LOW_S2 0x3a50 +#define VPU_MAFBC_HEADER_BUF_ADDR_HIGH_S2 0x3a51 +#define VPU_MAFBC_FORMAT_SPECIFIER_S2 0x3a52 +#define VPU_MAFBC_BUFFER_WIDTH_S2 0x3a53 +#define VPU_MAFBC_BUFFER_HEIGHT_S2 0x3a54 +#define VPU_MAFBC_BOUNDING_BOX_X_START_S2 0x3a55 +#define VPU_MAFBC_BOUNDING_BOX_X_END_S2 0x3a56 +#define VPU_MAFBC_BOUNDING_BOX_Y_START_S2 0x3a57 +#define VPU_MAFBC_BOUNDING_BOX_Y_END_S2 0x3a58 +#define VPU_MAFBC_OUTPUT_BUF_ADDR_LOW_S2 0x3a59 +#define VPU_MAFBC_OUTPUT_BUF_ADDR_HIGH_S2 0x3a5a +#define VPU_MAFBC_OUTPUT_BUF_STRIDE_S2 0x3a5b +#define VPU_MAFBC_PREFETCH_CFG_S2 0x3a5c + +#define VPU_MAFBC_HEADER_BUF_ADDR_LOW_S3 0x3a70 +#define VPU_MAFBC_HEADER_BUF_ADDR_HIGH_S3 0x3a71 +#define VPU_MAFBC_FORMAT_SPECIFIER_S3 0x3a72 +#define VPU_MAFBC_BUFFER_WIDTH_S3 0x3a73 +#define VPU_MAFBC_BUFFER_HEIGHT_S3 0x3a74 +#define VPU_MAFBC_BOUNDING_BOX_X_START_S3 0x3a75 +#define VPU_MAFBC_BOUNDING_BOX_X_END_S3 0x3a76 +#define VPU_MAFBC_BOUNDING_BOX_Y_START_S3 0x3a77 +#define VPU_MAFBC_BOUNDING_BOX_Y_END_S3 0x3a78 +#define VPU_MAFBC_OUTPUT_BUF_ADDR_LOW_S3 0x3a79 +#define VPU_MAFBC_OUTPUT_BUF_ADDR_HIGH_S3 0x3a7a +#define VPU_MAFBC_OUTPUT_BUF_STRIDE_S3 0x3a7b +#define VPU_MAFBC_PREFETCH_CFG_S3 0x3a7c + +#define DOLBY_PATH_CTRL 0x1a0c +#define DOLBY_BYPASS_EN(val) (val & 0xf) +#define OSD_PATH_MISC_CTRL 0x1a0e +#define MALI_AFBCD_TOP_CTRL 0x1a0f + +#define VIU_OSD_BLEND_CTRL 0x39b0 +#define VIU_OSD_BLEND_REORDER(dest, src) ((src) << (dest * 4)) +#define VIU_OSD_BLEND_DIN_EN(bits) ((bits & 0xf) << 20) +#define VIU_OSD_BLEND1_DIN3_BYPASS_TO_DOUT1 BIT(24) +#define VIU_OSD_BLEND1_DOUT_BYPASS_TO_BLEND2 BIT(25) +#define VIU_OSD_BLEND_DIN0_BYPASS_TO_DOUT0 BIT(26) +#define VIU_OSD_BLEND_BLEN2_PREMULT_EN(input) ((input & 0x3) << 27) +#define VIU_OSD_BLEND_HOLD_LINES(lines) ((u32)(lines & 0x7) << 29) +#define VIU_OSD_BLEND_CTRL1 0x39c0 +#define VIU_OSD_BLEND_DIN0_SCOPE_H 0x39b1 +#define VIU_OSD_BLEND_DIN0_SCOPE_V 0x39b2 +#define VIU_OSD_BLEND_DIN1_SCOPE_H 0x39b3 +#define VIU_OSD_BLEND_DIN1_SCOPE_V 0x39b4 +#define VIU_OSD_BLEND_DIN2_SCOPE_H 0x39b5 +#define VIU_OSD_BLEND_DIN2_SCOPE_V 0x39b6 +#define VIU_OSD_BLEND_DIN3_SCOPE_H 0x39b7 +#define VIU_OSD_BLEND_DIN3_SCOPE_V 0x39b8 +#define VIU_OSD_BLEND_DUMMY_DATA0 0x39b9 +#define VIU_OSD_BLEND_DUMMY_ALPHA 0x39ba +#define VIU_OSD_BLEND_BLEND0_SIZE 0x39bb +#define VIU_OSD_BLEND_BLEND1_SIZE 0x39bc +#define VIU_OSD_BLEND_RO_CURRENT_XY 0x39bf + +#define VPP_OUT_H_V_SIZE 0x1da5 + +#define VPP_VD2_HDR_IN_SIZE 0x1df0 +#define VPP_OSD1_IN_SIZE 0x1df1 +#define VPP_GCLK_CTRL2 0x1df2 +#define VD2_PPS_DUMMY_DATA 0x1df4 +#define VPP_OSD1_BLD_H_SCOPE 0x1df5 +#define VPP_OSD1_BLD_V_SCOPE 0x1df6 +#define VPP_OSD2_BLD_H_SCOPE 0x1df7 +#define VPP_OSD2_BLD_V_SCOPE 0x1df8 +#define VPP_WRBAK_CTRL 0x1df9 +#define VPP_SLEEP_CTRL 0x1dfa +#define VD1_BLEND_SRC_CTRL 0x1dfb +#define VD2_BLEND_SRC_CTRL 0x1dfc +#define VD_BLEND_PREBLD_SRC_VD1 (1 << 0) +#define VD_BLEND_PREBLD_SRC_VD2 (2 << 0) +#define VD_BLEND_PREBLD_SRC_OSD1 (3 << 0) +#define VD_BLEND_PREBLD_SRC_OSD2 (4 << 0) +#define VD_BLEND_PREBLD_PREMULT_EN BIT(4) +#define VD_BLEND_POSTBLD_SRC_VD1 (1 << 8) +#define VD_BLEND_POSTBLD_SRC_VD2 (2 << 8) +#define VD_BLEND_POSTBLD_SRC_OSD1 (3 << 8) +#define VD_BLEND_POSTBLD_SRC_OSD2 (4 << 8) +#define VD_BLEND_POSTBLD_PREMULT_EN BIT(16) +#define OSD1_BLEND_SRC_CTRL 0x1dfd +#define OSD2_BLEND_SRC_CTRL 0x1dfe +#define OSD_BLEND_POSTBLD_SRC_VD1 (1 << 8) +#define OSD_BLEND_POSTBLD_SRC_VD2 (2 << 8) +#define OSD_BLEND_POSTBLD_SRC_OSD1 (3 << 8) +#define OSD_BLEND_POSTBLD_SRC_OSD2 (4 << 8) +#define OSD_BLEND_PATH_SEL_ENABLE BIT(20) + +#define VPP_POST_BLEND_BLEND_DUMMY_DATA 0x3968 +#define VPP_POST_BLEND_DUMMY_ALPHA 0x3969 +#define VPP_RDARB_MODE 0x3978 +#define VPP_RDARB_REQEN_SLV 0x3979 + #endif /* __MESON_REGISTERS_H */ diff --git a/drivers/video/meson/meson_vclk.c b/drivers/video/meson/meson_vclk.c index 693e0ebe39..0f628e920b 100644 --- a/drivers/video/meson/meson_vclk.c +++ b/drivers/video/meson/meson_vclk.c @@ -68,14 +68,20 @@ enum { #define CTS_HDMI_SYS_EN BIT(8) #define HHI_HDMI_PLL_CNTL 0x320 /* 0xc8 offset in data sheet */ +#define HHI_HDMI_PLL_CNTL_EN BIT(30) #define HHI_HDMI_PLL_CNTL2 0x324 /* 0xc9 offset in data sheet */ #define HHI_HDMI_PLL_CNTL3 0x328 /* 0xca offset in data sheet */ #define HHI_HDMI_PLL_CNTL4 0x32C /* 0xcb offset in data sheet */ #define HHI_HDMI_PLL_CNTL5 0x330 /* 0xcc offset in data sheet */ #define HHI_HDMI_PLL_CNTL6 0x334 /* 0xcd offset in data sheet */ +#define HHI_HDMI_PLL_CNTL7 0x338 /* 0xce offset in data sheet */ #define HDMI_PLL_RESET BIT(28) +#define HDMI_PLL_RESET_G12A BIT(29) #define HDMI_PLL_LOCK BIT(31) +#define HDMI_PLL_LOCK_G12A (3 << 30) + +#define FREQ_1000_1001(_freq) DIV_ROUND_CLOSEST(_freq * 1000, 1001) /* VID PLL Dividers */ enum { @@ -206,8 +212,6 @@ static void meson_venci_cvbs_clock_config(struct meson_vpu_priv *priv) { unsigned int val; - debug("%s:%d\n", __func__, __LINE__); - /* Setup PLL to output 1.485GHz */ if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB)) { hhi_write(HHI_HDMI_PLL_CNTL, 0x5800023d); @@ -217,6 +221,10 @@ static void meson_venci_cvbs_clock_config(struct meson_vpu_priv *priv) hhi_write(HHI_HDMI_PLL_CNTL5, 0x71486980); hhi_write(HHI_HDMI_PLL_CNTL6, 0x00000e55); hhi_write(HHI_HDMI_PLL_CNTL, 0x4800023d); + + /* Poll for lock bit */ + readl_poll_timeout(priv->hhi_base + HHI_HDMI_PLL_CNTL, val, + (val & HDMI_PLL_LOCK), 10); } else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM) || meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXL)) { hhi_write(HHI_HDMI_PLL_CNTL, 0x4000027b); @@ -231,13 +239,26 @@ static void meson_venci_cvbs_clock_config(struct meson_vpu_priv *priv) HDMI_PLL_RESET, HDMI_PLL_RESET); hhi_update_bits(HHI_HDMI_PLL_CNTL, HDMI_PLL_RESET, 0); - } - debug("%s:%d\n", __func__, __LINE__); + /* Poll for lock bit */ + readl_poll_timeout(priv->hhi_base + HHI_HDMI_PLL_CNTL, val, + (val & HDMI_PLL_LOCK), 10); + } else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) { + hhi_write(HHI_HDMI_PLL_CNTL, 0x1a0504f7); + hhi_write(HHI_HDMI_PLL_CNTL2, 0x00010000); + hhi_write(HHI_HDMI_PLL_CNTL3, 0x00000000); + hhi_write(HHI_HDMI_PLL_CNTL4, 0x6a28dc00); + hhi_write(HHI_HDMI_PLL_CNTL5, 0x65771290); + hhi_write(HHI_HDMI_PLL_CNTL6, 0x39272000); + hhi_write(HHI_HDMI_PLL_CNTL7, 0x56540000); + hhi_write(HHI_HDMI_PLL_CNTL, 0x3a0504f7); + hhi_write(HHI_HDMI_PLL_CNTL, 0x1a0504f7); - /* Poll for lock bit */ - readl_poll_timeout(priv->hhi_base + HHI_HDMI_PLL_CNTL, val, - (val & HDMI_PLL_LOCK), 10); + /* Poll for lock bit */ + readl_poll_timeout(priv->hhi_base + HHI_HDMI_PLL_CNTL, val, + ((val & HDMI_PLL_LOCK_G12A) == HDMI_PLL_LOCK_G12A), + 10); + } /* Disable VCLK2 */ hhi_update_bits(HHI_VIID_CLK_CNTL, VCLK2_EN, 0); @@ -250,8 +271,13 @@ static void meson_venci_cvbs_clock_config(struct meson_vpu_priv *priv) VCLK2_DIV_MASK, (55 - 1)); /* select vid_pll for vclk2 */ - hhi_update_bits(HHI_VIID_CLK_CNTL, - VCLK2_SEL_MASK, (4 << VCLK2_SEL_SHIFT)); + if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) + hhi_update_bits(HHI_VIID_CLK_CNTL, + VCLK2_SEL_MASK, (0 << VCLK2_SEL_SHIFT)); + else + hhi_update_bits(HHI_VIID_CLK_CNTL, + VCLK2_SEL_MASK, (4 << VCLK2_SEL_SHIFT)); + /* enable vclk2 gate */ hhi_update_bits(HHI_VIID_CLK_CNTL, VCLK2_EN, VCLK2_EN); @@ -282,14 +308,12 @@ static void meson_venci_cvbs_clock_config(struct meson_vpu_priv *priv) /* enable vdac_clk */ hhi_update_bits(HHI_VID_CLK_CNTL2, CTS_VDAC_EN, CTS_VDAC_EN); - - debug("%s:%d\n", __func__, __LINE__); } enum { /* PLL O1 O2 O3 VP DV EN TX */ /* 4320 /4 /4 /1 /5 /1 => /2 /2 */ - MESON_VCLK_HDMI_ENCI_54000 = 1, + MESON_VCLK_HDMI_ENCI_54000 = 0, /* 4320 /4 /4 /1 /5 /1 => /1 /2 */ MESON_VCLK_HDMI_DDR_54000, /* 2970 /4 /1 /1 /5 /1 => /1 /2 */ @@ -305,6 +329,7 @@ enum { }; struct meson_vclk_params { + unsigned int pixel_freq; unsigned int pll_base_freq; unsigned int pll_od1; unsigned int pll_od2; @@ -313,6 +338,7 @@ struct meson_vclk_params { unsigned int vclk_div; } params[] = { [MESON_VCLK_HDMI_ENCI_54000] = { + .pixel_freq = 54000, .pll_base_freq = 4320000, .pll_od1 = 4, .pll_od2 = 4, @@ -321,6 +347,7 @@ struct meson_vclk_params { .vclk_div = 1, }, [MESON_VCLK_HDMI_DDR_54000] = { + .pixel_freq = 54000, .pll_base_freq = 4320000, .pll_od1 = 4, .pll_od2 = 4, @@ -329,6 +356,7 @@ struct meson_vclk_params { .vclk_div = 1, }, [MESON_VCLK_HDMI_DDR_148500] = { + .pixel_freq = 148500, .pll_base_freq = 2970000, .pll_od1 = 4, .pll_od2 = 1, @@ -337,6 +365,7 @@ struct meson_vclk_params { .vclk_div = 1, }, [MESON_VCLK_HDMI_74250] = { + .pixel_freq = 74250, .pll_base_freq = 2970000, .pll_od1 = 2, .pll_od2 = 2, @@ -345,6 +374,7 @@ struct meson_vclk_params { .vclk_div = 1, }, [MESON_VCLK_HDMI_148500] = { + .pixel_freq = 148500, .pll_base_freq = 2970000, .pll_od1 = 1, .pll_od2 = 2, @@ -353,14 +383,16 @@ struct meson_vclk_params { .vclk_div = 1, }, [MESON_VCLK_HDMI_297000] = { - .pll_base_freq = 2970000, - .pll_od1 = 1, + .pixel_freq = 297000, + .pll_base_freq = 5940000, + .pll_od1 = 2, .pll_od2 = 1, .pll_od3 = 1, .vid_pll_div = VID_PLL_DIV_5, .vclk_div = 2, }, [MESON_VCLK_HDMI_594000] = { + .pixel_freq = 594000, .pll_base_freq = 5940000, .pll_od1 = 1, .pll_od2 = 1, @@ -368,6 +400,7 @@ struct meson_vclk_params { .vid_pll_div = VID_PLL_DIV_5, .vclk_div = 1, }, + { /* sentinel */ }, }; static inline unsigned int pll_od_to_reg(unsigned int od) @@ -431,6 +464,50 @@ void meson_hdmi_pll_set_params(struct meson_vpu_priv *priv, unsigned int m, /* Poll for lock bit */ readl_poll_timeout(priv->hhi_base + HHI_HDMI_PLL_CNTL, val, (val & HDMI_PLL_LOCK), 10); + } else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) { + hhi_write(HHI_HDMI_PLL_CNTL, 0x0b3a0400 | m); + + /* Enable and reset */ + hhi_update_bits(HHI_HDMI_PLL_CNTL, 0x3 << 28, 0x3 << 28); + + hhi_write(HHI_HDMI_PLL_CNTL2, frac); + hhi_write(HHI_HDMI_PLL_CNTL3, 0x00000000); + + /* G12A HDMI PLL Needs specific parameters for 5.4GHz */ + if (m >= 0xf7) { + if (frac < 0x10000) { + hhi_write(HHI_HDMI_PLL_CNTL4, 0x6a685c00); + hhi_write(HHI_HDMI_PLL_CNTL5, 0x11551293); + } else { + hhi_write(HHI_HDMI_PLL_CNTL4, 0xea68dc00); + hhi_write(HHI_HDMI_PLL_CNTL5, 0x65771290); + } + hhi_write(HHI_HDMI_PLL_CNTL6, 0x39272000); + hhi_write(HHI_HDMI_PLL_CNTL7, 0x55540000); + } else { + hhi_write(HHI_HDMI_PLL_CNTL4, 0x0a691c00); + hhi_write(HHI_HDMI_PLL_CNTL5, 0x33771290); + hhi_write(HHI_HDMI_PLL_CNTL6, 0x39270000); + hhi_write(HHI_HDMI_PLL_CNTL7, 0x50540000); + } + + do { + /* Reset PLL */ + hhi_update_bits(HHI_HDMI_PLL_CNTL, + HDMI_PLL_RESET_G12A, + HDMI_PLL_RESET_G12A); + + /* UN-Reset PLL */ + hhi_update_bits(HHI_HDMI_PLL_CNTL, + HDMI_PLL_RESET_G12A, 0); + + /* Poll for lock bits */ + if (!readl_poll_timeout( + priv->hhi_base + HHI_HDMI_PLL_CNTL, val, + ((val & HDMI_PLL_LOCK_G12A) + == HDMI_PLL_LOCK_G12A), 100)) + break; + } while (1); } if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB)) @@ -440,6 +517,9 @@ void meson_hdmi_pll_set_params(struct meson_vpu_priv *priv, unsigned int m, meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXL)) hhi_update_bits(HHI_HDMI_PLL_CNTL3, 3 << 21, pll_od_to_reg(od1) << 21); + else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) + hhi_update_bits(HHI_HDMI_PLL_CNTL, + 3 << 16, pll_od_to_reg(od1) << 16); if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB)) hhi_update_bits(HHI_HDMI_PLL_CNTL2, @@ -448,6 +528,9 @@ void meson_hdmi_pll_set_params(struct meson_vpu_priv *priv, unsigned int m, meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXL)) hhi_update_bits(HHI_HDMI_PLL_CNTL3, 3 << 23, pll_od_to_reg(od2) << 23); + else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) + hhi_update_bits(HHI_HDMI_PLL_CNTL, + 3 << 18, pll_od_to_reg(od2) << 18); if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB)) hhi_update_bits(HHI_HDMI_PLL_CNTL2, @@ -456,6 +539,9 @@ void meson_hdmi_pll_set_params(struct meson_vpu_priv *priv, unsigned int m, meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXL)) hhi_update_bits(HHI_HDMI_PLL_CNTL3, 3 << 19, pll_od_to_reg(od3) << 19); + else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) + hhi_update_bits(HHI_HDMI_PLL_CNTL, + 3 << 20, pll_od_to_reg(od3) << 20); } #define XTAL_FREQ 24000 @@ -472,6 +558,7 @@ static unsigned int meson_hdmi_pll_get_m(struct meson_vpu_priv *priv, #define HDMI_FRAC_MAX_GXBB 4096 #define HDMI_FRAC_MAX_GXL 1024 +#define HDMI_FRAC_MAX_G12A 131072 static unsigned int meson_hdmi_pll_get_frac(struct meson_vpu_priv *priv, unsigned int m, @@ -488,6 +575,9 @@ static unsigned int meson_hdmi_pll_get_frac(struct meson_vpu_priv *priv, parent_freq *= 2; } + if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) + frac_max = HDMI_FRAC_MAX_G12A; + /* We can have a perfect match !*/ if (pll_freq / m == parent_freq && pll_freq % m == 0) @@ -519,6 +609,12 @@ static bool meson_hdmi_pll_validate_params(struct meson_vpu_priv *priv, return false; if (frac >= HDMI_FRAC_MAX_GXL) return false; + } else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) { + /* Empiric supported min/max dividers */ + if (m < 106 || m > 247) + return false; + if (frac >= HDMI_FRAC_MAX_G12A) + return false; } return true; @@ -595,8 +691,10 @@ meson_vclk_set(struct meson_vpu_priv *priv, unsigned int pll_base_freq, unsigned int od1, unsigned int od2, unsigned int od3, unsigned int vid_pll_div, unsigned int vclk_div, unsigned int hdmi_tx_div, unsigned int venc_div, - bool hdmi_use_enci) + bool hdmi_use_enci, bool vic_alternate_clock) { + unsigned int m = 0, frac = 0; + /* Set HDMI-TX sys clock */ hhi_update_bits(HHI_HDMI_CLK_CNTL, CTS_HDMI_SYS_SEL_MASK, 0); @@ -611,34 +709,55 @@ meson_vclk_set(struct meson_vpu_priv *priv, unsigned int pll_base_freq, } else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB)) { switch (pll_base_freq) { case 2970000: - meson_hdmi_pll_set_params(priv, 0x3d, 0xe00, - od1, od2, od3); + m = 0x3d; + frac = vic_alternate_clock ? 0xd02 : 0xe00; break; case 4320000: - meson_hdmi_pll_set_params(priv, 0x5a, 0, - od1, od2, od3); + m = vic_alternate_clock ? 0x59 : 0x5a; + frac = vic_alternate_clock ? 0xe8f : 0; break; case 5940000: - meson_hdmi_pll_set_params(priv, 0x7b, 0xc00, - od1, od2, od3); + m = 0x7b; + frac = vic_alternate_clock ? 0xa05 : 0xc00; break; } + + meson_hdmi_pll_set_params(priv, m, frac, od1, od2, od3); } else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM) || meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXL)) { switch (pll_base_freq) { case 2970000: - meson_hdmi_pll_set_params(priv, 0x7b, 0x300, - od1, od2, od3); + m = 0x7b; + frac = vic_alternate_clock ? 0x281 : 0x300; + break; + case 4320000: + m = vic_alternate_clock ? 0xb3 : 0xb4; + frac = vic_alternate_clock ? 0x347 : 0; + break; + case 5940000: + m = 0xf7; + frac = vic_alternate_clock ? 0x102 : 0x200; + break; + } + + meson_hdmi_pll_set_params(priv, m, frac, od1, od2, od3); + } else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) { + switch (pll_base_freq) { + case 2970000: + m = 0x7b; + frac = vic_alternate_clock ? 0x140b4 : 0x18000; break; case 4320000: - meson_hdmi_pll_set_params(priv, 0xb4, 0, - od1, od2, od3); + m = vic_alternate_clock ? 0xb3 : 0xb4; + frac = vic_alternate_clock ? 0x1a3ee : 0; break; case 5940000: - meson_hdmi_pll_set_params(priv, 0xf7, 0x200, - od1, od2, od3); + m = 0xf7; + frac = vic_alternate_clock ? 0x8148 : 0x10000; break; } + + meson_hdmi_pll_set_params(priv, m, frac, od1, od2, od3); } /* Setup vid_pll divider */ @@ -803,6 +922,7 @@ static void meson_vclk_setup(struct meson_vpu_priv *priv, unsigned int target, unsigned int vclk_freq, unsigned int venc_freq, unsigned int dac_freq, bool hdmi_use_enci) { + bool vic_alternate_clock = false; unsigned int freq; unsigned int hdmi_tx_div; unsigned int venc_div; @@ -820,8 +940,7 @@ static void meson_vclk_setup(struct meson_vpu_priv *priv, unsigned int target, * - encp encoder */ meson_vclk_set(priv, vclk_freq * 10, 0, 0, 0, - VID_PLL_DIV_5, 2, 1, 1, false); - + VID_PLL_DIV_5, 2, 1, 1, false, false); return; } @@ -841,31 +960,35 @@ static void meson_vclk_setup(struct meson_vpu_priv *priv, unsigned int target, return; } - switch (vclk_freq) { - case 54000: - if (hdmi_use_enci) - freq = MESON_VCLK_HDMI_ENCI_54000; - else - freq = MESON_VCLK_HDMI_DDR_54000; - break; - case 74250: - freq = MESON_VCLK_HDMI_74250; - break; - case 148500: - if (dac_freq != 148500) - freq = MESON_VCLK_HDMI_DDR_148500; - else - freq = MESON_VCLK_HDMI_148500; - break; - case 297000: - freq = MESON_VCLK_HDMI_297000; - break; - case 594000: - freq = MESON_VCLK_HDMI_594000; - break; - default: - printf("Fatal Error, invalid HDMI vclk freq %d\n", - vclk_freq); + for (freq = 0 ; params[freq].pixel_freq ; ++freq) { + if (vclk_freq == params[freq].pixel_freq || + vclk_freq == FREQ_1000_1001(params[freq].pixel_freq)) { + if (vclk_freq != params[freq].pixel_freq) + vic_alternate_clock = true; + else + vic_alternate_clock = false; + + if (freq == MESON_VCLK_HDMI_ENCI_54000 && + !hdmi_use_enci) + continue; + + if (freq == MESON_VCLK_HDMI_DDR_54000 && + hdmi_use_enci) + continue; + + if (freq == MESON_VCLK_HDMI_DDR_148500 && + dac_freq == vclk_freq) + continue; + + if (freq == MESON_VCLK_HDMI_148500 && + dac_freq != vclk_freq) + continue; + break; + } + } + + if (!params[freq].pixel_freq) { + pr_err("Fatal Error, invalid HDMI vclk freq %d\n", vclk_freq); return; } @@ -873,7 +996,7 @@ static void meson_vclk_setup(struct meson_vpu_priv *priv, unsigned int target, params[freq].pll_od1, params[freq].pll_od2, params[freq].pll_od3, params[freq].vid_pll_div, params[freq].vclk_div, hdmi_tx_div, venc_div, - hdmi_use_enci); + hdmi_use_enci, vic_alternate_clock); } void meson_vpu_setup_vclk(struct udevice *dev, diff --git a/drivers/video/meson/meson_venc.c b/drivers/video/meson/meson_venc.c index d137dde8e2..5da4b3f096 100644 --- a/drivers/video/meson/meson_venc.c +++ b/drivers/video/meson/meson_venc.c @@ -23,7 +23,9 @@ enum meson_venc_source { }; #define HHI_VDAC_CNTL0 0x2F4 /* 0xbd offset in data sheet */ +#define HHI_VDAC_CNTL0_G12A 0x2EC /* 0xbb offset in data sheet */ #define HHI_VDAC_CNTL1 0x2F8 /* 0xbe offset in data sheet */ +#define HHI_VDAC_CNTL1_G12A 0x2F0 /* 0xbc offset in data sheet */ struct meson_cvbs_enci_mode { unsigned int mode_tag; @@ -175,7 +177,7 @@ union meson_hdmi_venc_mode meson_hdmi_enci_mode_480i = { .hso_end = 129, .vso_even = 3, .vso_odd = 260, - .macv_max_amp = 0x810b, + .macv_max_amp = 0xb, .video_prog_mode = 0xf0, .video_mode = 0x8, .sch_adjust = 0x20, @@ -195,7 +197,7 @@ union meson_hdmi_venc_mode meson_hdmi_enci_mode_576i = { .hso_end = 129, .vso_even = 3, .vso_odd = 260, - .macv_max_amp = 8107, + .macv_max_amp = 0x7, .video_prog_mode = 0xff, .video_mode = 0x13, .sch_adjust = 0x28, @@ -774,12 +776,13 @@ static void meson_venc_hdmi_mode_set(struct meson_vpu_priv *priv, unsigned int eof_lines; unsigned int sof_lines; unsigned int vsync_lines; + u32 reg; /* Use VENCI for 480i and 576i and double HDMI pixels */ if (mode->flags & DISPLAY_FLAGS_DOUBLECLK) { - venc_hdmi_latency = 1; hdmi_repeat = true; use_enci = true; + venc_hdmi_latency = 1; } meson_venc_hdmi_get_dmt_vmode(mode, &vmode_dmt); @@ -850,8 +853,11 @@ static void meson_venc_hdmi_mode_set(struct meson_vpu_priv *priv, unsigned int lines_f1; /* CVBS Filter settings */ - writel(0x12, priv->io_base + _REG(ENCI_CFILT_CTRL)); - writel(0x12, priv->io_base + _REG(ENCI_CFILT_CTRL2)); + writel(ENCI_CFILT_CMPT_SEL_HIGH | 0x10, + priv->io_base + _REG(ENCI_CFILT_CTRL)); + writel(ENCI_CFILT_CMPT_CR_DLY(2) | + ENCI_CFILT_CMPT_CB_DLY(1), + priv->io_base + _REG(ENCI_CFILT_CTRL2)); /* Digital Video Select : Interlace, clk27 clk, external */ writel(0, priv->io_base + _REG(VENC_DVI_SETTING)); @@ -873,7 +879,8 @@ static void meson_venc_hdmi_mode_set(struct meson_vpu_priv *priv, priv->io_base + _REG(ENCI_SYNC_VSO_ODDLN)); /* Macrovision max amplitude change */ - writel(vmode->enci.macv_max_amp, + writel(ENCI_MACV_MAX_AMP_ENABLE_CHANGE | + ENCI_MACV_MAX_AMP_VAL(vmode->enci.macv_max_amp), priv->io_base + _REG(ENCI_MACV_MAX_AMP)); /* Video mode */ @@ -882,7 +889,8 @@ static void meson_venc_hdmi_mode_set(struct meson_vpu_priv *priv, writel(vmode->enci.video_mode, priv->io_base + _REG(ENCI_VIDEO_MODE)); - /* Advanced Video Mode : + /* + * Advanced Video Mode : * Demux shifting 0x2 * Blank line end at line17/22 * High bandwidth Luma Filter @@ -890,7 +898,10 @@ static void meson_venc_hdmi_mode_set(struct meson_vpu_priv *priv, * Bypass luma low pass filter * No macrovision on CSYNC */ - writel(0x26, priv->io_base + _REG(ENCI_VIDEO_MODE_ADV)); + writel(ENCI_VIDEO_MODE_ADV_DMXMD(2) | + ENCI_VIDEO_MODE_ADV_VBICTL_LINE_17_22 | + ENCI_VIDEO_MODE_ADV_YBW_HIGH, + priv->io_base + _REG(ENCI_VIDEO_MODE_ADV)); writel(vmode->enci.sch_adjust, priv->io_base + _REG(ENCI_VIDEO_SCH)); @@ -905,8 +916,17 @@ static void meson_venc_hdmi_mode_set(struct meson_vpu_priv *priv, /* UNreset Interlaced TV Encoder */ writel(0, priv->io_base + _REG(ENCI_DBG_PX_RST)); - /* Enable Vfifo2vd, Y_Cb_Y_Cr select */ - writel(0x4e01, priv->io_base + _REG(ENCI_VFIFO2VD_CTL)); + /* + * Enable Vfifo2vd and set Y_Cb_Y_Cr: + * Corresponding value: + * Y => 00 or 10 + * Cb => 01 + * Cr => 11 + * Ex: 0x4e => 01001110 would mean Cb/Y/Cr/Y + */ + writel(ENCI_VFIFO2VD_CTL_ENABLE | + ENCI_VFIFO2VD_CTL_VD_SEL(0x4e), + priv->io_base + _REG(ENCI_VFIFO2VD_CTL)); /* Timings */ writel(vmode->enci.pixel_start, @@ -928,7 +948,8 @@ static void meson_venc_hdmi_mode_set(struct meson_vpu_priv *priv, meson_vpp_setup_mux(priv, MESON_VIU_VPP_MUX_ENCI); /* Interlace video enable */ - writel(1, priv->io_base + _REG(ENCI_VIDEO_EN)); + writel(ENCI_VIDEO_EN_ENABLE, + priv->io_base + _REG(ENCI_VIDEO_EN)); lines_f0 = mode->vback_porch.typ + mode->vactive.typ + mode->vback_porch.typ + mode->vsync_len.typ; @@ -1177,7 +1198,8 @@ static void meson_venc_hdmi_mode_set(struct meson_vpu_priv *priv, writel(1, priv->io_base + _REG(ENCP_VIDEO_EN)); /* Set DE signal's polarity is active high */ - writel_bits(BIT(14), BIT(14), + writel_bits(ENCP_VIDEO_MODE_DE_V_HIGH, + ENCP_VIDEO_MODE_DE_V_HIGH, priv->io_base + _REG(ENCP_VIDEO_MODE)); /* Program DE timing */ @@ -1302,21 +1324,52 @@ static void meson_venc_hdmi_mode_set(struct meson_vpu_priv *priv, meson_vpp_setup_mux(priv, MESON_VIU_VPP_MUX_ENCP); } - writel((use_enci ? 1 : 2) | - (mode->flags & DISPLAY_FLAGS_HSYNC_HIGH ? 1 << 2 : 0) | - (mode->flags & DISPLAY_FLAGS_VSYNC_HIGH ? 1 << 3 : 0) | - 4 << 5 | - (venc_repeat ? 1 << 8 : 0) | - (hdmi_repeat ? 1 << 12 : 0), - priv->io_base + _REG(VPU_HDMI_SETTING)); + /* Set VPU HDMI setting */ + /* Select ENCP or ENCI data to HDMI */ + if (use_enci) + reg = VPU_HDMI_ENCI_DATA_TO_HDMI; + else + reg = VPU_HDMI_ENCP_DATA_TO_HDMI; + + /* Invert polarity of HSYNC from VENC */ + if (mode->flags & DISPLAY_FLAGS_HSYNC_HIGH) + reg |= VPU_HDMI_INV_HSYNC; + + /* Invert polarity of VSYNC from VENC */ + if (mode->flags & DISPLAY_FLAGS_VSYNC_HIGH) + reg |= VPU_HDMI_INV_VSYNC; + + /* Output data format: CbYCr */ + reg |= VPU_HDMI_OUTPUT_CBYCR; + + /* + * Write rate to the async FIFO between VENC and HDMI. + * One write every 2 wr_clk. + */ + if (venc_repeat) + reg |= VPU_HDMI_WR_RATE(2); + + /* + * Read rate to the async FIFO between VENC and HDMI. + * One read every 2 wr_clk. + */ + if (hdmi_repeat) + reg |= VPU_HDMI_RD_RATE(2); + + writel(reg, priv->io_base + _REG(VPU_HDMI_SETTING)); } static void meson_venci_cvbs_mode_set(struct meson_vpu_priv *priv, struct meson_cvbs_enci_mode *mode) { + u32 reg; + /* CVBS Filter settings */ - writel(0x12, priv->io_base + _REG(ENCI_CFILT_CTRL)); - writel(0x12, priv->io_base + _REG(ENCI_CFILT_CTRL2)); + writel(ENCI_CFILT_CMPT_SEL_HIGH | 0x10, + priv->io_base + _REG(ENCI_CFILT_CTRL)); + writel(ENCI_CFILT_CMPT_CR_DLY(2) | + ENCI_CFILT_CMPT_CB_DLY(1), + priv->io_base + _REG(ENCI_CFILT_CTRL2)); /* Digital Video Select : Interlace, clk27 clk, external */ writel(0, priv->io_base + _REG(VENC_DVI_SETTING)); @@ -1338,7 +1391,8 @@ static void meson_venci_cvbs_mode_set(struct meson_vpu_priv *priv, priv->io_base + _REG(ENCI_SYNC_VSO_ODDLN)); /* Macrovision max amplitude change */ - writel(0x8100 + mode->macv_max_amp, + writel(ENCI_MACV_MAX_AMP_ENABLE_CHANGE | + ENCI_MACV_MAX_AMP_VAL(mode->macv_max_amp), priv->io_base + _REG(ENCI_MACV_MAX_AMP)); /* Video mode */ @@ -1347,7 +1401,8 @@ static void meson_venci_cvbs_mode_set(struct meson_vpu_priv *priv, writel(mode->video_mode, priv->io_base + _REG(ENCI_VIDEO_MODE)); - /* Advanced Video Mode : + /* + * Advanced Video Mode : * Demux shifting 0x2 * Blank line end at line17/22 * High bandwidth Luma Filter @@ -1355,7 +1410,10 @@ static void meson_venci_cvbs_mode_set(struct meson_vpu_priv *priv, * Bypass luma low pass filter * No macrovision on CSYNC */ - writel(0x26, priv->io_base + _REG(ENCI_VIDEO_MODE_ADV)); + writel(ENCI_VIDEO_MODE_ADV_DMXMD(2) | + ENCI_VIDEO_MODE_ADV_VBICTL_LINE_17_22 | + ENCI_VIDEO_MODE_ADV_YBW_HIGH, + priv->io_base + _REG(ENCI_VIDEO_MODE_ADV)); writel(mode->sch_adjust, priv->io_base + _REG(ENCI_VIDEO_SCH)); @@ -1387,16 +1445,50 @@ static void meson_venci_cvbs_mode_set(struct meson_vpu_priv *priv, /* UNreset Interlaced TV Encoder */ writel(0, priv->io_base + _REG(ENCI_DBG_PX_RST)); - /* Enable Vfifo2vd, Y_Cb_Y_Cr select */ - writel(0x4e01, priv->io_base + _REG(ENCI_VFIFO2VD_CTL)); + /* + * Enable Vfifo2vd and set Y_Cb_Y_Cr: + * Corresponding value: + * Y => 00 or 10 + * Cb => 01 + * Cr => 11 + * Ex: 0x4e => 01001110 would mean Cb/Y/Cr/Y + */ + writel(ENCI_VFIFO2VD_CTL_ENABLE | + ENCI_VFIFO2VD_CTL_VD_SEL(0x4e), + priv->io_base + _REG(ENCI_VFIFO2VD_CTL)); /* Power UP Dacs */ writel(0, priv->io_base + _REG(VENC_VDAC_SETTING)); /* Video Upsampling */ - writel(0x0061, priv->io_base + _REG(VENC_UPSAMPLE_CTRL0)); - writel(0x4061, priv->io_base + _REG(VENC_UPSAMPLE_CTRL1)); - writel(0x5061, priv->io_base + _REG(VENC_UPSAMPLE_CTRL2)); + /* + * CTRL0, CTRL1 and CTRL2: + * Filter0: input data sample every 2 cloks + * Filter1: filtering and upsample enable + */ + reg = VENC_UPSAMPLE_CTRL_F0_2_CLK_RATIO | VENC_UPSAMPLE_CTRL_F1_EN | + VENC_UPSAMPLE_CTRL_F1_UPSAMPLE_EN; + + /* + * Upsample CTRL0: + * Interlace High Bandwidth Luma + */ + writel(VENC_UPSAMPLE_CTRL_INTERLACE_HIGH_LUMA | reg, + priv->io_base + _REG(VENC_UPSAMPLE_CTRL0)); + + /* + * Upsample CTRL1: + * Interlace Pb + */ + writel(VENC_UPSAMPLE_CTRL_INTERLACE_PB | reg, + priv->io_base + _REG(VENC_UPSAMPLE_CTRL1)); + + /* + * Upsample CTRL2: + * Interlace R + */ + writel(VENC_UPSAMPLE_CTRL_INTERLACE_PR | reg, + priv->io_base + _REG(VENC_UPSAMPLE_CTRL2)); /* Select Interlace Y DACs */ writel(0, priv->io_base + _REG(VENC_VDAC_DACSEL0)); @@ -1410,14 +1502,16 @@ static void meson_venci_cvbs_mode_set(struct meson_vpu_priv *priv, meson_vpp_setup_mux(priv, MESON_VIU_VPP_MUX_ENCI); /* Enable ENCI FIFO */ - writel(0x2000, priv->io_base + _REG(VENC_VDAC_FIFO_CTRL)); + writel(VENC_VDAC_FIFO_EN_ENCI_ENABLE, + priv->io_base + _REG(VENC_VDAC_FIFO_CTRL)); /* Select ENCI DACs 0, 1, 4, and 5 */ writel(0x11, priv->io_base + _REG(ENCI_DACSEL_0)); writel(0x11, priv->io_base + _REG(ENCI_DACSEL_1)); /* Interlace video enable */ - writel(1, priv->io_base + _REG(ENCI_VIDEO_EN)); + writel(ENCI_VIDEO_EN_ENABLE, + priv->io_base + _REG(ENCI_VIDEO_EN)); /* Configure Video Saturation / Contrast / Brightness / Hue */ writel(mode->video_saturation, @@ -1430,7 +1524,8 @@ static void meson_venci_cvbs_mode_set(struct meson_vpu_priv *priv, priv->io_base + _REG(ENCI_VIDEO_HUE)); /* Enable DAC0 Filter */ - writel(0x1, priv->io_base + _REG(VENC_VDAC_DAC0_FILT_CTRL0)); + writel(VENC_VDAC_DAC0_FILT_CTRL0_EN, + priv->io_base + _REG(VENC_VDAC_DAC0_FILT_CTRL0)); writel(0xfc48, priv->io_base + _REG(VENC_VDAC_DAC0_FILT_CTRL1)); /* 0 in Macrovision register 0 */ @@ -1441,15 +1536,21 @@ static void meson_venci_cvbs_mode_set(struct meson_vpu_priv *priv, priv->io_base + _REG(ENCI_SYNC_ADJ)); /* enable VDAC */ - writel_bits(BIT(5), 0, priv->io_base + _REG(VENC_VDAC_DACSEL0)); + writel_bits(VENC_VDAC_SEL_ATV_DMD, 0, + priv->io_base + _REG(VENC_VDAC_DACSEL0)); if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB)) hhi_write(HHI_VDAC_CNTL0, 1); else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXL) || meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM)) hhi_write(HHI_VDAC_CNTL0, 0xf0001); + else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) + hhi_write(HHI_VDAC_CNTL0_G12A, 0x906001); - hhi_write(HHI_VDAC_CNTL1, 0); + if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) + hhi_write(HHI_VDAC_CNTL1_G12A, 0); + else + hhi_write(HHI_VDAC_CNTL1, 0); } void meson_vpu_setup_venc(struct udevice *dev, diff --git a/drivers/video/meson/meson_vpu.h b/drivers/video/meson/meson_vpu.h index ef5f10eae3..3412dac052 100644 --- a/drivers/video/meson/meson_vpu.h +++ b/drivers/video/meson/meson_vpu.h @@ -14,6 +14,7 @@ #include <video.h> #include <display.h> #include <linux/io.h> +#include <linux/bitfield.h> #include "meson_registers.h" enum { diff --git a/drivers/video/meson/meson_vpu_init.c b/drivers/video/meson/meson_vpu_init.c index 92228b5ceb..12f8c4194a 100644 --- a/drivers/video/meson/meson_vpu_init.c +++ b/drivers/video/meson/meson_vpu_init.c @@ -12,7 +12,9 @@ /* HHI Registers */ #define HHI_VDAC_CNTL0 0x2F4 /* 0xbd offset in data sheet */ +#define HHI_VDAC_CNTL0_G12A 0x2EC /* 0xbd offset in data sheet */ #define HHI_VDAC_CNTL1 0x2F8 /* 0xbe offset in data sheet */ +#define HHI_VDAC_CNTL1_G12A 0x2F0 /* 0xbe offset in data sheet */ #define HHI_HDMI_PHY_CNTL0 0x3a0 /* 0xe8 offset in data sheet */ /* OSDx_CTRL_STAT2 */ @@ -42,7 +44,7 @@ static void meson_vpp_write_scaling_filter_coefs(struct meson_vpu_priv *priv, { int i; - writel(is_horizontal ? BIT(8) : 0, + writel(is_horizontal ? VPP_SCALE_HORIZONTAL_COEF : 0, priv->io_base + _REG(VPP_OSD_SCALE_COEF_IDX)); for (i = 0; i < 33; i++) writel(coefs[i], @@ -67,7 +69,7 @@ static void meson_vpp_write_vd_scaling_filter_coefs(struct meson_vpu_priv *priv, { int i; - writel(is_horizontal ? BIT(8) : 0, + writel(is_horizontal ? VPP_SCALE_HORIZONTAL_COEF : 0, priv->io_base + _REG(VPP_SCALE_COEF_IDX)); for (i = 0; i < 33; i++) writel(coefs[i], @@ -112,6 +114,34 @@ static int eotf_bypass_coeff[EOTF_COEFF_SIZE] = { EOTF_COEFF_RIGHTSHIFT /* right shift */ }; +static void meson_viu_set_g12a_osd1_matrix(struct meson_vpu_priv *priv, + int *m, bool csc_on) +{ + /* VPP WRAP OSD1 matrix */ + writel(((m[0] & 0xfff) << 16) | (m[1] & 0xfff), + priv->io_base + _REG(VPP_WRAP_OSD1_MATRIX_PRE_OFFSET0_1)); + writel(m[2] & 0xfff, + priv->io_base + _REG(VPP_WRAP_OSD1_MATRIX_PRE_OFFSET2)); + writel(((m[3] & 0x1fff) << 16) | (m[4] & 0x1fff), + priv->io_base + _REG(VPP_WRAP_OSD1_MATRIX_COEF00_01)); + writel(((m[5] & 0x1fff) << 16) | (m[6] & 0x1fff), + priv->io_base + _REG(VPP_WRAP_OSD1_MATRIX_COEF02_10)); + writel(((m[7] & 0x1fff) << 16) | (m[8] & 0x1fff), + priv->io_base + _REG(VPP_WRAP_OSD1_MATRIX_COEF11_12)); + writel(((m[9] & 0x1fff) << 16) | (m[10] & 0x1fff), + priv->io_base + _REG(VPP_WRAP_OSD1_MATRIX_COEF20_21)); + writel((m[11] & 0x1fff) << 16, + priv->io_base + _REG(VPP_WRAP_OSD1_MATRIX_COEF22)); + + writel(((m[18] & 0xfff) << 16) | (m[19] & 0xfff), + priv->io_base + _REG(VPP_WRAP_OSD1_MATRIX_OFFSET0_1)); + writel(m[20] & 0xfff, + priv->io_base + _REG(VPP_WRAP_OSD1_MATRIX_OFFSET2)); + + writel_bits(BIT(0), csc_on ? BIT(0) : 0, + priv->io_base + _REG(VPP_WRAP_OSD1_MATRIX_EN_CTRL)); +} + static void meson_viu_set_osd_matrix(struct meson_vpu_priv *priv, enum viu_matrix_sel_e m_select, int *m, bool csc_on) @@ -322,20 +352,47 @@ static void meson_viu_load_matrix(struct meson_vpu_priv *priv) true); } +static inline uint32_t meson_viu_osd_burst_length_reg(uint32_t length) +{ + u32 val = (((length & 0x80) % 24) / 12); + + return (((val & 0x3) << 10) | (((val & 0x4) >> 2) << 31)); +} + void meson_vpu_init(struct udevice *dev) { struct meson_vpu_priv *priv = dev_get_priv(dev); u32 reg; - /* vpu initialization */ - writel(0x210000, priv->io_base + _REG(VPU_RDARB_MODE_L1C1)); - writel(0x10000, priv->io_base + _REG(VPU_RDARB_MODE_L1C2)); - writel(0x900000, priv->io_base + _REG(VPU_RDARB_MODE_L2C1)); - writel(0x20000, priv->io_base + _REG(VPU_WRARB_MODE_L2C1)); + /* + * Slave dc0 and dc5 connected to master port 1. + * By default other slaves are connected to master port 0. + */ + reg = VPU_RDARB_SLAVE_TO_MASTER_PORT(0, 1) | + VPU_RDARB_SLAVE_TO_MASTER_PORT(5, 1); + writel(reg, priv->io_base + _REG(VPU_RDARB_MODE_L1C1)); + + /* Slave dc0 connected to master port 1 */ + reg = VPU_RDARB_SLAVE_TO_MASTER_PORT(0, 1); + writel(reg, priv->io_base + _REG(VPU_RDARB_MODE_L1C2)); + + /* Slave dc4 and dc7 connected to master port 1 */ + reg = VPU_RDARB_SLAVE_TO_MASTER_PORT(4, 1) | + VPU_RDARB_SLAVE_TO_MASTER_PORT(7, 1); + writel(reg, priv->io_base + _REG(VPU_RDARB_MODE_L2C1)); + + /* Slave dc1 connected to master port 1 */ + reg = VPU_RDARB_SLAVE_TO_MASTER_PORT(1, 1); + writel(reg, priv->io_base + _REG(VPU_WRARB_MODE_L2C1)); /* Disable CVBS VDAC */ - hhi_write(HHI_VDAC_CNTL0, 0); - hhi_write(HHI_VDAC_CNTL1, 8); + if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) { + hhi_write(HHI_VDAC_CNTL0_G12A, 0); + hhi_write(HHI_VDAC_CNTL1_G12A, 8); + } else { + hhi_write(HHI_VDAC_CNTL0, 0); + hhi_write(HHI_VDAC_CNTL1, 8); + } /* Power Down Dacs */ writel(0xff, priv->io_base + _REG(VENC_VDAC_SETTING)); @@ -344,7 +401,9 @@ void meson_vpu_init(struct udevice *dev) hhi_write(HHI_HDMI_PHY_CNTL0, 0); /* Disable HDMI */ - writel_bits(0x3, 0, priv->io_base + _REG(VPU_HDMI_SETTING)); + writel_bits(VPU_HDMI_ENCI_DATA_TO_HDMI | + VPU_HDMI_ENCP_DATA_TO_HDMI, 0, + priv->io_base + _REG(VPU_HDMI_SETTING)); /* Disable all encoders */ writel(0, priv->io_base + _REG(ENCI_VIDEO_EN)); @@ -360,43 +419,58 @@ void meson_vpu_init(struct udevice *dev) } else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM)) { writel_bits(0xff << 16, 0xff << 16, priv->io_base + _REG(VIU_MISC_CTRL1)); - writel(0x20000, priv->io_base + _REG(VPP_DOLBY_CTRL)); + writel(VPP_PPS_DUMMY_DATA_MODE, + priv->io_base + _REG(VPP_DOLBY_CTRL)); writel(0x1020080, priv->io_base + _REG(VPP_DUMMY_DATA1)); - } + } else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) + writel(0xf, priv->io_base + _REG(DOLBY_PATH_CTRL)); /* Initialize vpu fifo control registers */ - writel(readl(priv->io_base + _REG(VPP_OFIFO_SIZE)) | - 0x77f, priv->io_base + _REG(VPP_OFIFO_SIZE)); - writel(0x08080808, priv->io_base + _REG(VPP_HOLD_LINES)); - - /* Turn off preblend */ - writel_bits(VPP_PREBLEND_ENABLE, 0, - priv->io_base + _REG(VPP_MISC)); - - /* Turn off POSTBLEND */ - writel_bits(VPP_POSTBLEND_ENABLE, 0, - priv->io_base + _REG(VPP_MISC)); - - /* Force all planes off */ - writel_bits(VPP_OSD1_POSTBLEND | VPP_OSD2_POSTBLEND | - VPP_VD1_POSTBLEND | VPP_VD2_POSTBLEND | - VPP_VD1_PREBLEND | VPP_VD2_PREBLEND, 0, - priv->io_base + _REG(VPP_MISC)); - - /* Setup default VD settings */ - writel(4096, - priv->io_base + _REG(VPP_PREBLEND_VD1_H_START_END)); - writel(4096, - priv->io_base + _REG(VPP_BLEND_VD2_H_START_END)); + if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) + writel(VPP_OFIFO_SIZE_DEFAULT, + priv->io_base + _REG(VPP_OFIFO_SIZE)); + else + writel_bits(VPP_OFIFO_SIZE_MASK, 0x77f, + priv->io_base + _REG(VPP_OFIFO_SIZE)); + writel(VPP_POSTBLEND_HOLD_LINES(4) | VPP_PREBLEND_HOLD_LINES(4), + priv->io_base + _REG(VPP_HOLD_LINES)); + + if (!meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) { + /* Turn off preblend */ + writel_bits(VPP_PREBLEND_ENABLE, 0, + priv->io_base + _REG(VPP_MISC)); + + /* Turn off POSTBLEND */ + writel_bits(VPP_POSTBLEND_ENABLE, 0, + priv->io_base + _REG(VPP_MISC)); + + /* Force all planes off */ + writel_bits(VPP_OSD1_POSTBLEND | VPP_OSD2_POSTBLEND | + VPP_VD1_POSTBLEND | VPP_VD2_POSTBLEND | + VPP_VD1_PREBLEND | VPP_VD2_PREBLEND, 0, + priv->io_base + _REG(VPP_MISC)); + + /* Setup default VD settings */ + writel(4096, + priv->io_base + _REG(VPP_PREBLEND_VD1_H_START_END)); + writel(4096, + priv->io_base + _REG(VPP_BLEND_VD2_H_START_END)); + } /* Disable Scalers */ writel(0, priv->io_base + _REG(VPP_OSD_SC_CTRL0)); writel(0, priv->io_base + _REG(VPP_OSD_VSC_CTRL0)); writel(0, priv->io_base + _REG(VPP_OSD_HSC_CTRL0)); - writel(4 | (4 << 8) | BIT(15), + + writel(VPP_VSC_BANK_LENGTH(4) | VPP_HSC_BANK_LENGTH(4) | + VPP_SC_VD_EN_ENABLE, priv->io_base + _REG(VPP_SC_MISC)); + /* Enable minus black level for vadj1 */ + writel(VPP_MINUS_BLACK_LVL_VADJ1_ENABLE, + priv->io_base + _REG(VPP_VADJ_CTRL)); + /* Write in the proper filter coefficients. */ meson_vpp_write_scaling_filter_coefs(priv, vpp_filter_coefs_4point_bspline, false); @@ -410,23 +484,31 @@ void meson_vpu_init(struct udevice *dev) true); /* Disable OSDs */ - writel_bits(BIT(0) | BIT(21), 0, + writel_bits(VIU_OSD1_OSD_BLK_ENABLE | VIU_OSD1_OSD_ENABLE, 0, priv->io_base + _REG(VIU_OSD1_CTRL_STAT)); - writel_bits(BIT(0) | BIT(21), 0, + writel_bits(VIU_OSD1_OSD_BLK_ENABLE | VIU_OSD1_OSD_ENABLE, 0, priv->io_base + _REG(VIU_OSD2_CTRL_STAT)); /* On GXL/GXM, Use the 10bit HDR conversion matrix */ if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM) || meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXL)) meson_viu_load_matrix(priv); + else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) + meson_viu_set_g12a_osd1_matrix(priv, RGB709_to_YUV709l_coeff, + true); /* Initialize OSD1 fifo control register */ - reg = BIT(0) | /* Urgent DDR request priority */ - (4 << 5) | /* hold_fifo_lines */ - (3 << 10) | /* burst length 64 */ - (32 << 12) | /* fifo_depth_val: 32*8=256 */ - (2 << 22) | /* 4 words in 1 burst */ - (2 << 24); + reg = VIU_OSD_DDR_PRIORITY_URGENT | + VIU_OSD_HOLD_FIFO_LINES(4) | + VIU_OSD_FIFO_DEPTH_VAL(32) | /* fifo_depth_val: 32*8=256 */ + VIU_OSD_WORDS_PER_BURST(4) | /* 4 words in 1 burst */ + VIU_OSD_FIFO_LIMITS(2); /* fifo_lim: 2*16=32 */ + + if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) + reg |= meson_viu_osd_burst_length_reg(32); + else + reg |= meson_viu_osd_burst_length_reg(64); + writel(reg, priv->io_base + _REG(VIU_OSD1_FIFO_CTRL_STAT)); writel(reg, priv->io_base + _REG(VIU_OSD2_FIFO_CTRL_STAT)); @@ -437,4 +519,39 @@ void meson_vpu_init(struct udevice *dev) writel_bits(0xff << OSD_REPLACE_SHIFT, 0xff << OSD_REPLACE_SHIFT, priv->io_base + _REG(VIU_OSD2_CTRL_STAT2)); + + /* Disable VD1 AFBC */ + /* di_mif0_en=0 mif0_to_vpp_en=0 di_mad_en=0 and afbc vd1 set=0*/ + writel_bits(VIU_CTRL0_VD1_AFBC_MASK, 0, + priv->io_base + _REG(VIU_MISC_CTRL0)); + writel(0, priv->io_base + _REG(AFBC_ENABLE)); + + writel(0x00FF00C0, + priv->io_base + _REG(VD1_IF0_LUMA_FIFO_SIZE)); + writel(0x00FF00C0, + priv->io_base + _REG(VD2_IF0_LUMA_FIFO_SIZE)); + + if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) { + writel(VIU_OSD_BLEND_REORDER(0, 1) | + VIU_OSD_BLEND_REORDER(1, 0) | + VIU_OSD_BLEND_REORDER(2, 0) | + VIU_OSD_BLEND_REORDER(3, 0) | + VIU_OSD_BLEND_DIN_EN(1) | + VIU_OSD_BLEND1_DIN3_BYPASS_TO_DOUT1 | + VIU_OSD_BLEND1_DOUT_BYPASS_TO_BLEND2 | + VIU_OSD_BLEND_DIN0_BYPASS_TO_DOUT0 | + VIU_OSD_BLEND_BLEN2_PREMULT_EN(1) | + VIU_OSD_BLEND_HOLD_LINES(4), + priv->io_base + _REG(VIU_OSD_BLEND_CTRL)); + writel(OSD_BLEND_PATH_SEL_ENABLE, + priv->io_base + _REG(OSD1_BLEND_SRC_CTRL)); + writel(OSD_BLEND_PATH_SEL_ENABLE, + priv->io_base + _REG(OSD2_BLEND_SRC_CTRL)); + writel(0, priv->io_base + _REG(VD1_BLEND_SRC_CTRL)); + writel(0, priv->io_base + _REG(VD2_BLEND_SRC_CTRL)); + writel(0, priv->io_base + _REG(VIU_OSD_BLEND_DUMMY_DATA0)); + writel(0, priv->io_base + _REG(VIU_OSD_BLEND_DUMMY_ALPHA)); + writel_bits(DOLBY_BYPASS_EN(0xc), DOLBY_BYPASS_EN(0xc), + priv->io_base + _REG(DOLBY_PATH_CTRL)); + } } -- 2.22.0 ^ permalink raw reply related [flat|nested] 19+ messages in thread
* [U-Boot] [PATCH 4/8] video: meson: sync with linux drm-misc tree 2019-08-30 12:09 ` [U-Boot] [PATCH 4/8] video: meson: sync with linux drm-misc tree Neil Armstrong @ 2019-10-09 15:12 ` Neil Armstrong 2019-10-10 20:48 ` Anatolij Gustschin 1 sibling, 0 replies; 19+ messages in thread From: Neil Armstrong @ 2019-10-09 15:12 UTC (permalink / raw) To: u-boot Hi Anatolij, Gentle ping, did you have time to review this patchset ? Thanks, Neil On 30/08/2019 14:09, Neil Armstrong wrote: > Synchronize the Amlogic Meson Video driver back with the latest > DRM misc tree, adding G12A platform support, from the latest commit: > 528a25d040bc ("drm: meson: use match data to detect vpu compatibility") > > The sync includes the following changes from Linux adapted to U-Boot: > - Add support for VIC alternate timings > - Switch PLL to 5.94GHz base for 297Mhz pixel clock > - Add registers for G12A SoC > - Add G12A Support for VPP setup > - Add G12A Support for VIU setup > - Add G12A support for OSD1 Plane > - Add G12A support for plane handling in CRTC driver > - Add G12A support for CVBS Encoder > - Add G12A Video Clock setup > - Add G12A support for the DW-HDMI Glue > - fix G12A HDMI PLL settings for 4K60 1000/1001 variations > - fix primary plane disabling > - fix G12A primary plane disabling > - mask value when writing bits relaxed > - crtc: drv: vpp: viu: venc: use proper macros instead of magic constants > - global clean-up > - add macro used to enable HDMI PLL > - venc: set the correct macrovision max amplitude value > > Signed-off-by: Neil Armstrong <narmstrong@baylibre.com> > --- > drivers/video/meson/meson_dw_hdmi.c | 61 ++++- > drivers/video/meson/meson_plane.c | 47 +++- > drivers/video/meson/meson_registers.h | 373 +++++++++++++++++++++++++- > drivers/video/meson/meson_vclk.c | 233 ++++++++++++---- > drivers/video/meson/meson_venc.c | 169 +++++++++--- > drivers/video/meson/meson_vpu.h | 1 + > drivers/video/meson/meson_vpu_init.c | 205 +++++++++++--- > 7 files changed, 929 insertions(+), 160 deletions(-) > > diff --git a/drivers/video/meson/meson_dw_hdmi.c b/drivers/video/meson/meson_dw_hdmi.c > index 9831d978fc..ae2e6288f3 100644 > --- a/drivers/video/meson/meson_dw_hdmi.c > +++ b/drivers/video/meson/meson_dw_hdmi.c > @@ -24,6 +24,7 @@ > #define HDMITX_TOP_ADDR_REG 0x0 > #define HDMITX_TOP_DATA_REG 0x4 > #define HDMITX_TOP_CTRL_REG 0x8 > +#define HDMITX_TOP_G12A_OFFSET 0x8000 > > /* Controller Communication Channel */ > #define HDMITX_DWC_ADDR_REG 0x10 > @@ -37,6 +38,8 @@ > #define HHI_HDMI_PHY_CNTL1 0x3a4 /* 0xe9 */ > #define HHI_HDMI_PHY_CNTL2 0x3a8 /* 0xea */ > #define HHI_HDMI_PHY_CNTL3 0x3ac /* 0xeb */ > +#define HHI_HDMI_PHY_CNTL4 0x3b0 /* 0xec */ > +#define HHI_HDMI_PHY_CNTL5 0x3b4 /* 0xed */ > > struct meson_dw_hdmi { > struct udevice *dev; > @@ -48,6 +51,7 @@ enum hdmi_compatible { > HDMI_COMPATIBLE_GXBB = 0, > HDMI_COMPATIBLE_GXL = 1, > HDMI_COMPATIBLE_GXM = 2, > + HDMI_COMPATIBLE_G12A = 3, > }; > > static inline bool meson_hdmi_is_compatible(struct meson_dw_hdmi *priv, > @@ -60,8 +64,14 @@ static inline bool meson_hdmi_is_compatible(struct meson_dw_hdmi *priv, > > static unsigned int dw_hdmi_top_read(struct dw_hdmi *hdmi, unsigned int addr) > { > + struct meson_dw_hdmi *priv = container_of(hdmi, struct meson_dw_hdmi, > + hdmi); > unsigned int data; > > + if (meson_hdmi_is_compatible(priv, HDMI_COMPATIBLE_G12A)) > + return readl(hdmi->ioaddr + > + HDMITX_TOP_G12A_OFFSET + (addr << 2)); > + > /* ADDR must be written twice */ > writel(addr & 0xffff, hdmi->ioaddr + HDMITX_TOP_ADDR_REG); > writel(addr & 0xffff, hdmi->ioaddr + HDMITX_TOP_ADDR_REG); > @@ -76,6 +86,15 @@ static unsigned int dw_hdmi_top_read(struct dw_hdmi *hdmi, unsigned int addr) > static inline void dw_hdmi_top_write(struct dw_hdmi *hdmi, > unsigned int addr, unsigned int data) > { > + struct meson_dw_hdmi *priv = container_of(hdmi, struct meson_dw_hdmi, > + hdmi); > + > + if (meson_hdmi_is_compatible(priv, HDMI_COMPATIBLE_G12A)) { > + writel(data, hdmi->ioaddr + > + HDMITX_TOP_G12A_OFFSET + (addr << 2)); > + return; > + } > + > /* ADDR must be written twice */ > writel(addr & 0xffff, hdmi->ioaddr + HDMITX_TOP_ADDR_REG); > writel(addr & 0xffff, hdmi->ioaddr + HDMITX_TOP_ADDR_REG); > @@ -237,7 +256,7 @@ static void meson_dw_hdmi_phy_setup_mode(struct meson_dw_hdmi *priv, > hhi_write(HHI_HDMI_PHY_CNTL0, 0x33604142); > hhi_write(HHI_HDMI_PHY_CNTL3, 0x0016315b); > } > - } else { > + } else if (meson_hdmi_is_compatible(priv, HDMI_COMPATIBLE_GXBB)) { > if (pixel_clock >= 371250) { > /* 5.94Gbps, 3.7125Gbps */ > hhi_write(HHI_HDMI_PHY_CNTL0, 0x33353245); > @@ -251,6 +270,23 @@ static void meson_dw_hdmi_phy_setup_mode(struct meson_dw_hdmi *priv, > hhi_write(HHI_HDMI_PHY_CNTL0, 0x33632122); > hhi_write(HHI_HDMI_PHY_CNTL3, 0x2000115b); > } > + } else if (meson_hdmi_is_compatible(priv, HDMI_COMPATIBLE_G12A)) { > + if (pixel_clock >= 371250) { > + /* 5.94Gbps, 3.7125Gbps */ > + hhi_write(HHI_HDMI_PHY_CNTL0, 0x37eb65c4); > + hhi_write(HHI_HDMI_PHY_CNTL3, 0x2ab0ff3b); > + hhi_write(HHI_HDMI_PHY_CNTL5, 0x0000080b); > + } else if (pixel_clock >= 297000) { > + /* 2.97Gbps */ > + hhi_write(HHI_HDMI_PHY_CNTL0, 0x33eb6262); > + hhi_write(HHI_HDMI_PHY_CNTL3, 0x2ab0ff3b); > + hhi_write(HHI_HDMI_PHY_CNTL5, 0x00000003); > + } else { > + /* 1.485Gbps, and below */ > + hhi_write(HHI_HDMI_PHY_CNTL0, 0x33eb4242); > + hhi_write(HHI_HDMI_PHY_CNTL3, 0x2ab0ff3b); > + hhi_write(HHI_HDMI_PHY_CNTL5, 0x00000003); > + } > } > } > > @@ -292,7 +328,8 @@ static int meson_dw_hdmi_phy_init(struct dw_hdmi *hdmi, uint pixel_clock) > > /* BIT_INVERT */ > if (meson_hdmi_is_compatible(priv, HDMI_COMPATIBLE_GXL) || > - meson_hdmi_is_compatible(priv, HDMI_COMPATIBLE_GXM)) > + meson_hdmi_is_compatible(priv, HDMI_COMPATIBLE_GXM) || > + meson_hdmi_is_compatible(priv, HDMI_COMPATIBLE_G12A)) > dw_hdmi_hhi_update_bits(priv, HHI_HDMI_PHY_CNTL1, BIT(17), 0); > else > dw_hdmi_hhi_update_bits(priv, HHI_HDMI_PHY_CNTL1, > @@ -356,8 +393,12 @@ static int meson_dw_hdmi_probe(struct udevice *dev) > priv->hdmi.hdmi_data.enc_out_bus_format = MEDIA_BUS_FMT_RGB888_1X24; > priv->hdmi.hdmi_data.enc_in_bus_format = MEDIA_BUS_FMT_YUV8_1X24; > priv->hdmi.phy_set = meson_dw_hdmi_phy_init; > - priv->hdmi.write_reg = dw_hdmi_dwc_write; > - priv->hdmi.read_reg = dw_hdmi_dwc_read; > + if (meson_hdmi_is_compatible(priv, HDMI_COMPATIBLE_G12A)) > + priv->hdmi.reg_io_width = 1; > + else { > + priv->hdmi.write_reg = dw_hdmi_dwc_write; > + priv->hdmi.read_reg = dw_hdmi_dwc_read; > + } > priv->hdmi.i2c_clk_high = 0x67; > priv->hdmi.i2c_clk_low = 0x78; > > @@ -409,9 +450,13 @@ static int meson_dw_hdmi_probe(struct udevice *dev) > if (ret) > return ret; > > - /* Enable APB3 fail on error */ > - writel_bits(BIT(15), BIT(15), priv->hdmi.ioaddr + HDMITX_TOP_CTRL_REG); > - writel_bits(BIT(15), BIT(15), priv->hdmi.ioaddr + HDMITX_DWC_CTRL_REG); > + if (!meson_hdmi_is_compatible(priv, HDMI_COMPATIBLE_G12A)) { > + /* Enable APB3 fail on error */ > + writel_bits(BIT(15), BIT(15), > + priv->hdmi.ioaddr + HDMITX_TOP_CTRL_REG); > + writel_bits(BIT(15), BIT(15), > + priv->hdmi.ioaddr + HDMITX_DWC_CTRL_REG); > + } > > /* Bring out of reset */ > dw_hdmi_top_write(&priv->hdmi, HDMITX_TOP_SW_RESET, 0); > @@ -448,6 +493,8 @@ static const struct udevice_id meson_dw_hdmi_ids[] = { > .data = HDMI_COMPATIBLE_GXL }, > { .compatible = "amlogic,meson-gxm-dw-hdmi", > .data = HDMI_COMPATIBLE_GXM }, > + { .compatible = "amlogic,meson-g12a-dw-hdmi", > + .data = HDMI_COMPATIBLE_G12A }, > { } > }; > > diff --git a/drivers/video/meson/meson_plane.c b/drivers/video/meson/meson_plane.c > index 63a4bf2d8d..2bc9327e1e 100644 > --- a/drivers/video/meson/meson_plane.c > +++ b/drivers/video/meson/meson_plane.c > @@ -108,12 +108,33 @@ void meson_vpu_setup_plane(struct udevice *dev, bool is_interlaced) > dest_y1 = src_y1 = 0; > dest_y2 = src_y2 = uc_priv->ysize; > > - /* Enable VPP Postblend */ > - writel(uc_priv->xsize, > - priv->io_base + _REG(VPP_POSTBLEND_H_SIZE)); > + if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) { > + /* VD1 Preblend vertical start/end */ > + writel(FIELD_PREP(GENMASK(11, 0), 2303), > + priv->io_base + _REG(VPP_PREBLEND_VD1_V_START_END)); > + > + /* Setup Blender */ > + writel(uc_priv->xsize | > + uc_priv->ysize << 16, > + priv->io_base + _REG(VPP_POSTBLEND_H_SIZE)); > + > + writel(0 << 16 | > + (uc_priv->xsize - 1), > + priv->io_base + _REG(VPP_OSD1_BLD_H_SCOPE)); > + writel(0 << 16 | > + (uc_priv->ysize - 1), > + priv->io_base + _REG(VPP_OSD1_BLD_V_SCOPE)); > + writel(uc_priv->xsize << 16 | > + uc_priv->ysize, > + priv->io_base + _REG(VPP_OUT_H_V_SIZE)); > + } else { > + /* Enable VPP Postblend */ > + writel(uc_priv->xsize, > + priv->io_base + _REG(VPP_POSTBLEND_H_SIZE)); > > - writel_bits(VPP_POSTBLEND_ENABLE, VPP_POSTBLEND_ENABLE, > - priv->io_base + _REG(VPP_MISC)); > + writel_bits(VPP_POSTBLEND_ENABLE, VPP_POSTBLEND_ENABLE, > + priv->io_base + _REG(VPP_MISC)); > + } > > /* uc_plat->base is the framebuffer */ > > @@ -172,6 +193,18 @@ void meson_vpu_setup_plane(struct udevice *dev, bool is_interlaced) > MESON_CANVAS_BLKMODE_LINEAR); > > /* Enable OSD1 */ > - writel_bits(VPP_OSD1_POSTBLEND, VPP_OSD1_POSTBLEND, > - priv->io_base + _REG(VPP_MISC)); > + if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) { > + writel(((dest_x2 - 1) << 16) | dest_x1, > + priv->io_base + _REG(VIU_OSD_BLEND_DIN0_SCOPE_H)); > + writel(((dest_y2 - 1) << 16) | dest_y1, > + priv->io_base + _REG(VIU_OSD_BLEND_DIN0_SCOPE_V)); > + writel(uc_priv->xsize << 16 | uc_priv->ysize, > + priv->io_base + _REG(VIU_OSD_BLEND_BLEND0_SIZE)); > + writel(uc_priv->xsize << 16 | uc_priv->ysize, > + priv->io_base + _REG(VIU_OSD_BLEND_BLEND1_SIZE)); > + writel_bits(3 << 8, 3 << 8, > + priv->io_base + _REG(OSD1_BLEND_SRC_CTRL)); > + } else > + writel_bits(VPP_OSD1_POSTBLEND, VPP_OSD1_POSTBLEND, > + priv->io_base + _REG(VPP_MISC)); > } > diff --git a/drivers/video/meson/meson_registers.h b/drivers/video/meson/meson_registers.h > index 01fe7d2431..39e8ec8639 100644 > --- a/drivers/video/meson/meson_registers.h > +++ b/drivers/video/meson/meson_registers.h > @@ -136,11 +136,19 @@ > #define VIU_ADDR_START 0x1a00 > #define VIU_ADDR_END 0x1aff > #define VIU_SW_RESET 0x1a01 > +#define VIU_SW_RESET_OSD1 BIT(0) > #define VIU_MISC_CTRL0 0x1a06 > +#define VIU_CTRL0_VD1_AFBC_MASK 0x170000 > #define VIU_MISC_CTRL1 0x1a07 > #define D2D3_INTF_LENGTH 0x1a08 > #define D2D3_INTF_CTRL0 0x1a09 > #define VIU_OSD1_CTRL_STAT 0x1a10 > +#define VIU_OSD1_OSD_BLK_ENABLE BIT(0) > +#define VIU_OSD1_POSTBLD_SRC_VD1 (1 << 8) > +#define VIU_OSD1_POSTBLD_SRC_VD2 (2 << 8) > +#define VIU_OSD1_POSTBLD_SRC_OSD1 (3 << 8) > +#define VIU_OSD1_POSTBLD_SRC_OSD2 (4 << 8) > +#define VIU_OSD1_OSD_ENABLE BIT(21) > #define VIU_OSD1_CTRL_STAT2 0x1a2d > #define VIU_OSD1_COLOR_ADDR 0x1a11 > #define VIU_OSD1_COLOR 0x1a12 > @@ -206,6 +214,35 @@ > #define VIU_OSD2_FIFO_CTRL_STAT 0x1a4b > #define VIU_OSD2_TEST_RDDATA 0x1a4c > #define VIU_OSD2_PROT_CTRL 0x1a4e > +#define VIU_OSD2_MALI_UNPACK_CTRL 0x1abd > +#define VIU_OSD2_DIMM_CTRL 0x1acf > + > +#define VIU_OSD3_CTRL_STAT 0x3d80 > +#define VIU_OSD3_CTRL_STAT2 0x3d81 > +#define VIU_OSD3_COLOR_ADDR 0x3d82 > +#define VIU_OSD3_COLOR 0x3d83 > +#define VIU_OSD3_TCOLOR_AG0 0x3d84 > +#define VIU_OSD3_TCOLOR_AG1 0x3d85 > +#define VIU_OSD3_TCOLOR_AG2 0x3d86 > +#define VIU_OSD3_TCOLOR_AG3 0x3d87 > +#define VIU_OSD3_BLK0_CFG_W0 0x3d88 > +#define VIU_OSD3_BLK0_CFG_W1 0x3d8c > +#define VIU_OSD3_BLK0_CFG_W2 0x3d90 > +#define VIU_OSD3_BLK0_CFG_W3 0x3d94 > +#define VIU_OSD3_BLK0_CFG_W4 0x3d98 > +#define VIU_OSD3_BLK1_CFG_W4 0x3d99 > +#define VIU_OSD3_BLK2_CFG_W4 0x3d9a > +#define VIU_OSD3_FIFO_CTRL_STAT 0x3d9c > +#define VIU_OSD3_TEST_RDDATA 0x3d9d > +#define VIU_OSD3_PROT_CTRL 0x3d9e > +#define VIU_OSD3_MALI_UNPACK_CTRL 0x3d9f > +#define VIU_OSD3_DIMM_CTRL 0x3da0 > + > +#define VIU_OSD_DDR_PRIORITY_URGENT BIT(0) > +#define VIU_OSD_HOLD_FIFO_LINES(lines) ((lines & 0x1f) << 5) > +#define VIU_OSD_FIFO_DEPTH_VAL(val) ((val & 0x7f) << 12) > +#define VIU_OSD_WORDS_PER_BURST(words) (((words & 0x4) >> 1) << 22) > +#define VIU_OSD_FIFO_LIMITS(size) ((size & 0xf) << 24) > > #define VD1_IF0_GEN_REG 0x1a50 > #define VD1_IF0_CANVAS0 0x1a51 > @@ -277,6 +314,27 @@ > #define VIU_OSD1_MATRIX_COEF31_32 0x1a9e > #define VIU_OSD1_MATRIX_COEF40_41 0x1a9f > #define VD1_IF0_GEN_REG3 0x1aa7 > + > +#define VIU_OSD_BLENDO_H_START_END 0x1aa9 > +#define VIU_OSD_BLENDO_V_START_END 0x1aaa > +#define VIU_OSD_BLEND_GEN_CTRL0 0x1aab > +#define VIU_OSD_BLEND_GEN_CTRL1 0x1aac > +#define VIU_OSD_BLEND_DUMMY_DATA 0x1aad > +#define VIU_OSD_BLEND_CURRENT_XY 0x1aae > + > +#define VIU_OSD2_MATRIX_CTRL 0x1ab0 > +#define VIU_OSD2_MATRIX_COEF00_01 0x1ab1 > +#define VIU_OSD2_MATRIX_COEF02_10 0x1ab2 > +#define VIU_OSD2_MATRIX_COEF11_12 0x1ab3 > +#define VIU_OSD2_MATRIX_COEF20_21 0x1ab4 > +#define VIU_OSD2_MATRIX_COEF22 0x1ab5 > +#define VIU_OSD2_MATRIX_OFFSET0_1 0x1ab6 > +#define VIU_OSD2_MATRIX_OFFSET2 0x1ab7 > +#define VIU_OSD2_MATRIX_PRE_OFFSET0_1 0x1ab8 > +#define VIU_OSD2_MATRIX_PRE_OFFSET2 0x1ab9 > +#define VIU_OSD2_MATRIX_PROBE_COLOR 0x1aba > +#define VIU_OSD2_MATRIX_HL_COLOR 0x1abb > +#define VIU_OSD2_MATRIX_PROBE_POS 0x1abc > #define VIU_OSD1_EOTF_CTL 0x1ad4 > #define VIU_OSD1_EOTF_COEF00_01 0x1ad5 > #define VIU_OSD1_EOTF_COEF02_10 0x1ad6 > @@ -295,6 +353,7 @@ > #define VPP_LINE_IN_LENGTH 0x1d01 > #define VPP_PIC_IN_HEIGHT 0x1d02 > #define VPP_SCALE_COEF_IDX 0x1d03 > +#define VPP_SCALE_HORIZONTAL_COEF BIT(8) > #define VPP_SCALE_COEF 0x1d04 > #define VPP_VSC_REGION12_STARTP 0x1d05 > #define VPP_VSC_REGION34_STARTP 0x1d06 > @@ -316,6 +375,12 @@ > #define VPP_HSC_REGION4_PHASE_SLOPE 0x1d17 > #define VPP_HSC_PHASE_CTRL 0x1d18 > #define VPP_SC_MISC 0x1d19 > +#define VPP_SC_VD_EN_ENABLE BIT(15) > +#define VPP_SC_TOP_EN_ENABLE BIT(16) > +#define VPP_SC_HSC_EN_ENABLE BIT(17) > +#define VPP_SC_VSC_EN_ENABLE BIT(18) > +#define VPP_VSC_BANK_LENGTH(length) (length & 0x7) > +#define VPP_HSC_BANK_LENGTH(length) ((length & 0x7) << 8) > #define VPP_PREBLEND_VD1_H_START_END 0x1d1a > #define VPP_PREBLEND_VD1_V_START_END 0x1d1b > #define VPP_POSTBLEND_VD1_H_START_END 0x1d1c > @@ -325,24 +390,28 @@ > #define VPP_PREBLEND_H_SIZE 0x1d20 > #define VPP_POSTBLEND_H_SIZE 0x1d21 > #define VPP_HOLD_LINES 0x1d22 > +#define VPP_POSTBLEND_HOLD_LINES(lines) (lines & 0xf) > +#define VPP_PREBLEND_HOLD_LINES(lines) ((lines & 0xf) << 8) > #define VPP_BLEND_ONECOLOR_CTRL 0x1d23 > #define VPP_PREBLEND_CURRENT_XY 0x1d24 > #define VPP_POSTBLEND_CURRENT_XY 0x1d25 > #define VPP_MISC 0x1d26 > -#define VPP_PREBLEND_ENABLE BIT(6) > -#define VPP_POSTBLEND_ENABLE BIT(7) > -#define VPP_OSD2_ALPHA_PREMULT BIT(8) > -#define VPP_OSD1_ALPHA_PREMULT BIT(9) > -#define VPP_VD1_POSTBLEND BIT(10) > -#define VPP_VD2_POSTBLEND BIT(11) > -#define VPP_OSD1_POSTBLEND BIT(12) > -#define VPP_OSD2_POSTBLEND BIT(13) > -#define VPP_VD1_PREBLEND BIT(14) > -#define VPP_VD2_PREBLEND BIT(15) > -#define VPP_OSD1_PREBLEND BIT(16) > -#define VPP_OSD2_PREBLEND BIT(17) > -#define VPP_COLOR_MNG_ENABLE BIT(28) > +#define VPP_PREBLEND_ENABLE BIT(6) > +#define VPP_POSTBLEND_ENABLE BIT(7) > +#define VPP_OSD2_ALPHA_PREMULT BIT(8) > +#define VPP_OSD1_ALPHA_PREMULT BIT(9) > +#define VPP_VD1_POSTBLEND BIT(10) > +#define VPP_VD2_POSTBLEND BIT(11) > +#define VPP_OSD1_POSTBLEND BIT(12) > +#define VPP_OSD2_POSTBLEND BIT(13) > +#define VPP_VD1_PREBLEND BIT(14) > +#define VPP_VD2_PREBLEND BIT(15) > +#define VPP_OSD1_PREBLEND BIT(16) > +#define VPP_OSD2_PREBLEND BIT(17) > +#define VPP_COLOR_MNG_ENABLE BIT(28) > #define VPP_OFIFO_SIZE 0x1d27 > +#define VPP_OFIFO_SIZE_MASK GENMASK(13, 0) > +#define VPP_OFIFO_SIZE_DEFAULT (0xfff << 20 | 0x1000) > #define VPP_FIFO_STATUS 0x1d28 > #define VPP_SMOKE_CTRL 0x1d29 > #define VPP_SMOKE1_VAL 0x1d2a > @@ -358,6 +427,8 @@ > #define VPP_HSC_PHASE_CTRL1 0x1d34 > #define VPP_HSC_INI_PAT_CTRL 0x1d35 > #define VPP_VADJ_CTRL 0x1d40 > +#define VPP_MINUS_BLACK_LVL_VADJ1_ENABLE BIT(1) > + > #define VPP_VADJ1_Y 0x1d41 > #define VPP_VADJ1_MA_MB 0x1d42 > #define VPP_VADJ1_MC_MD 0x1d43 > @@ -417,6 +488,7 @@ > #define VPP_PEAKING_VGAIN 0x1d92 > #define VPP_PEAKING_NLP_1 0x1d93 > #define VPP_DOLBY_CTRL 0x1d93 > +#define VPP_PPS_DUMMY_DATA_MODE (1 << 17) > #define VPP_PEAKING_NLP_2 0x1d94 > #define VPP_PEAKING_NLP_3 0x1d95 > #define VPP_PEAKING_NLP_4 0x1d96 > @@ -471,6 +543,83 @@ > #define VPP_OSD_SCALE_COEF 0x1dcd > #define VPP_INT_LINE_NUM 0x1dce > > +#define VPP_WRAP_OSD1_MATRIX_COEF00_01 0x3d60 > +#define VPP_WRAP_OSD1_MATRIX_COEF02_10 0x3d61 > +#define VPP_WRAP_OSD1_MATRIX_COEF11_12 0x3d62 > +#define VPP_WRAP_OSD1_MATRIX_COEF20_21 0x3d63 > +#define VPP_WRAP_OSD1_MATRIX_COEF22 0x3d64 > +#define VPP_WRAP_OSD1_MATRIX_COEF13_14 0x3d65 > +#define VPP_WRAP_OSD1_MATRIX_COEF23_24 0x3d66 > +#define VPP_WRAP_OSD1_MATRIX_COEF15_25 0x3d67 > +#define VPP_WRAP_OSD1_MATRIX_CLIP 0x3d68 > +#define VPP_WRAP_OSD1_MATRIX_OFFSET0_1 0x3d69 > +#define VPP_WRAP_OSD1_MATRIX_OFFSET2 0x3d6a > +#define VPP_WRAP_OSD1_MATRIX_PRE_OFFSET0_1 0x3d6b > +#define VPP_WRAP_OSD1_MATRIX_PRE_OFFSET2 0x3d6c > +#define VPP_WRAP_OSD1_MATRIX_EN_CTRL 0x3d6d > + > +#define VPP_WRAP_OSD2_MATRIX_COEF00_01 0x3d70 > +#define VPP_WRAP_OSD2_MATRIX_COEF02_10 0x3d71 > +#define VPP_WRAP_OSD2_MATRIX_COEF11_12 0x3d72 > +#define VPP_WRAP_OSD2_MATRIX_COEF20_21 0x3d73 > +#define VPP_WRAP_OSD2_MATRIX_COEF22 0x3d74 > +#define VPP_WRAP_OSD2_MATRIX_COEF13_14 0x3d75 > +#define VPP_WRAP_OSD2_MATRIX_COEF23_24 0x3d76 > +#define VPP_WRAP_OSD2_MATRIX_COEF15_25 0x3d77 > +#define VPP_WRAP_OSD2_MATRIX_CLIP 0x3d78 > +#define VPP_WRAP_OSD2_MATRIX_OFFSET0_1 0x3d79 > +#define VPP_WRAP_OSD2_MATRIX_OFFSET2 0x3d7a > +#define VPP_WRAP_OSD2_MATRIX_PRE_OFFSET0_1 0x3d7b > +#define VPP_WRAP_OSD2_MATRIX_PRE_OFFSET2 0x3d7c > +#define VPP_WRAP_OSD2_MATRIX_EN_CTRL 0x3d7d > + > +#define VPP_WRAP_OSD3_MATRIX_COEF00_01 0x3db0 > +#define VPP_WRAP_OSD3_MATRIX_COEF02_10 0x3db1 > +#define VPP_WRAP_OSD3_MATRIX_COEF11_12 0x3db2 > +#define VPP_WRAP_OSD3_MATRIX_COEF20_21 0x3db3 > +#define VPP_WRAP_OSD3_MATRIX_COEF22 0x3db4 > +#define VPP_WRAP_OSD3_MATRIX_COEF13_14 0x3db5 > +#define VPP_WRAP_OSD3_MATRIX_COEF23_24 0x3db6 > +#define VPP_WRAP_OSD3_MATRIX_COEF15_25 0x3db7 > +#define VPP_WRAP_OSD3_MATRIX_CLIP 0x3db8 > +#define VPP_WRAP_OSD3_MATRIX_OFFSET0_1 0x3db9 > +#define VPP_WRAP_OSD3_MATRIX_OFFSET2 0x3dba > +#define VPP_WRAP_OSD3_MATRIX_PRE_OFFSET0_1 0x3dbb > +#define VPP_WRAP_OSD3_MATRIX_PRE_OFFSET2 0x3dbc > +#define VPP_WRAP_OSD3_MATRIX_EN_CTRL 0x3dbd > + > +/* osd2 scaler */ > +#define OSD2_VSC_PHASE_STEP 0x3d00 > +#define OSD2_VSC_INI_PHASE 0x3d01 > +#define OSD2_VSC_CTRL0 0x3d02 > +#define OSD2_HSC_PHASE_STEP 0x3d03 > +#define OSD2_HSC_INI_PHASE 0x3d04 > +#define OSD2_HSC_CTRL0 0x3d05 > +#define OSD2_HSC_INI_PAT_CTRL 0x3d06 > +#define OSD2_SC_DUMMY_DATA 0x3d07 > +#define OSD2_SC_CTRL0 0x3d08 > +#define OSD2_SCI_WH_M1 0x3d09 > +#define OSD2_SCO_H_START_END 0x3d0a > +#define OSD2_SCO_V_START_END 0x3d0b > +#define OSD2_SCALE_COEF_IDX 0x3d18 > +#define OSD2_SCALE_COEF 0x3d19 > + > +/* osd34 scaler */ > +#define OSD34_SCALE_COEF_IDX 0x3d1e > +#define OSD34_SCALE_COEF 0x3d1f > +#define OSD34_VSC_PHASE_STEP 0x3d20 > +#define OSD34_VSC_INI_PHASE 0x3d21 > +#define OSD34_VSC_CTRL0 0x3d22 > +#define OSD34_HSC_PHASE_STEP 0x3d23 > +#define OSD34_HSC_INI_PHASE 0x3d24 > +#define OSD34_HSC_CTRL0 0x3d25 > +#define OSD34_HSC_INI_PAT_CTRL 0x3d26 > +#define OSD34_SC_DUMMY_DATA 0x3d27 > +#define OSD34_SC_CTRL0 0x3d28 > +#define OSD34_SCI_WH_M1 0x3d29 > +#define OSD34_SCO_H_START_END 0x3d2a > +#define OSD34_SCO_V_START_END 0x3d2b > + > /* viu2 */ > #define VIU2_ADDR_START 0x1e00 > #define VIU2_ADDR_END 0x1eff > @@ -584,6 +733,25 @@ > #define VENC_UPSAMPLE_CTRL0 0x1b64 > #define VENC_UPSAMPLE_CTRL1 0x1b65 > #define VENC_UPSAMPLE_CTRL2 0x1b66 > +#define VENC_UPSAMPLE_CTRL_F0_2_CLK_RATIO BIT(0) > +#define VENC_UPSAMPLE_CTRL_F1_EN BIT(5) > +#define VENC_UPSAMPLE_CTRL_F1_UPSAMPLE_EN BIT(6) > +#define VENC_UPSAMPLE_CTRL_INTERLACE_HIGH_LUMA (0x0 << 12) > +#define VENC_UPSAMPLE_CTRL_CVBS (0x1 << 12) > +#define VENC_UPSAMPLE_CTRL_S_VIDEO_LUMA (0x2 << 12) > +#define VENC_UPSAMPLE_CTRL_S_VIDEO_CHROMA (0x3 << 12) > +#define VENC_UPSAMPLE_CTRL_INTERLACE_PB (0x4 << 12) > +#define VENC_UPSAMPLE_CTRL_INTERLACE_PR (0x5 << 12) > +#define VENC_UPSAMPLE_CTRL_INTERLACE_R (0x6 << 12) > +#define VENC_UPSAMPLE_CTRL_INTERLACE_G (0x7 << 12) > +#define VENC_UPSAMPLE_CTRL_INTERLACE_B (0x8 << 12) > +#define VENC_UPSAMPLE_CTRL_PROGRESSIVE_Y (0x9 << 12) > +#define VENC_UPSAMPLE_CTRL_PROGRESSIVE_PB (0xa << 12) > +#define VENC_UPSAMPLE_CTRL_PROGRESSIVE_PR (0xb << 12) > +#define VENC_UPSAMPLE_CTRL_PROGRESSIVE_R (0xc << 12) > +#define VENC_UPSAMPLE_CTRL_PROGRESSIVE_G (0xd << 12) > +#define VENC_UPSAMPLE_CTRL_PROGRESSIVE_B (0xe << 12) > +#define VENC_UPSAMPLE_CTRL_VDAC_TEST_VALUE (0xf << 12) > #define TCON_INVERT_CTL 0x1b67 > #define VENC_VIDEO_PROG_MODE 0x1b68 > #define VENC_ENCI_LINE 0x1b69 > @@ -592,6 +760,7 @@ > #define VENC_ENCP_PIXEL 0x1b6c > #define VENC_STATA 0x1b6d > #define VENC_INTCTRL 0x1b6e > +#define VENC_INTCTRL_ENCI_LNRST_INT_EN BIT(1) > #define VENC_INTFLAG 0x1b6f > #define VENC_VIDEO_TST_EN 0x1b70 > #define VENC_VIDEO_TST_MDSEL 0x1b71 > @@ -602,6 +771,7 @@ > #define VENC_VIDEO_TST_CLRBAR_WIDTH 0x1b76 > #define VENC_VIDEO_TST_VDCNT_STSET 0x1b77 > #define VENC_VDAC_DACSEL0 0x1b78 > +#define VENC_VDAC_SEL_ATV_DMD BIT(5) > #define VENC_VDAC_DACSEL1 0x1b79 > #define VENC_VDAC_DACSEL2 0x1b7a > #define VENC_VDAC_DACSEL3 0x1b7b > @@ -622,6 +792,7 @@ > #define VENC_VDAC_DAC5_GAINCTRL 0x1bfa > #define VENC_VDAC_DAC5_OFFSET 0x1bfb > #define VENC_VDAC_FIFO_CTRL 0x1bfc > +#define VENC_VDAC_FIFO_EN_ENCI_ENABLE BIT(13) > #define ENCL_TCON_INVERT_CTL 0x1bfd > #define ENCP_VIDEO_EN 0x1b80 > #define ENCP_VIDEO_SYNC_MODE 0x1b81 > @@ -637,6 +808,7 @@ > #define ENCP_VIDEO_SYNC_OFFST 0x1b8b > #define ENCP_VIDEO_MACV_OFFST 0x1b8c > #define ENCP_VIDEO_MODE 0x1b8d > +#define ENCP_VIDEO_MODE_DE_V_HIGH BIT(14) > #define ENCP_VIDEO_MODE_ADV 0x1b8e > #define ENCP_DBG_PX_RST 0x1b90 > #define ENCP_DBG_LN_RST 0x1b91 > @@ -715,6 +887,11 @@ > #define C656_FS_LNED 0x1be7 > #define ENCI_VIDEO_MODE 0x1b00 > #define ENCI_VIDEO_MODE_ADV 0x1b01 > +#define ENCI_VIDEO_MODE_ADV_DMXMD(val) (val & 0x3) > +#define ENCI_VIDEO_MODE_ADV_VBICTL_LINE_17_22 BIT(2) > +#define ENCI_VIDEO_MODE_ADV_YBW_MEDIUM (0 << 4) > +#define ENCI_VIDEO_MODE_ADV_YBW_LOW (0x1 << 4) > +#define ENCI_VIDEO_MODE_ADV_YBW_HIGH (0x2 << 4) > #define ENCI_VIDEO_FSC_ADJ 0x1b02 > #define ENCI_VIDEO_BRIGHT 0x1b03 > #define ENCI_VIDEO_CONT 0x1b04 > @@ -785,13 +962,17 @@ > #define ENCI_DBG_MAXPX 0x1b4c > #define ENCI_DBG_MAXLN 0x1b4d > #define ENCI_MACV_MAX_AMP 0x1b50 > +#define ENCI_MACV_MAX_AMP_ENABLE_CHANGE BIT(15) > +#define ENCI_MACV_MAX_AMP_VAL(val) (val & 0x83ff) > #define ENCI_MACV_PULSE_LO 0x1b51 > #define ENCI_MACV_PULSE_HI 0x1b52 > #define ENCI_MACV_BKP_MAX 0x1b53 > #define ENCI_CFILT_CTRL 0x1b54 > +#define ENCI_CFILT_CMPT_SEL_HIGH BIT(1) > #define ENCI_CFILT7 0x1b55 > #define ENCI_YC_DELAY 0x1b56 > #define ENCI_VIDEO_EN 0x1b57 > +#define ENCI_VIDEO_EN_ENABLE BIT(0) > #define ENCI_DVI_HSO_BEGIN 0x1c00 > #define ENCI_DVI_HSO_END 0x1c01 > #define ENCI_DVI_VSO_BLINE_EVN 0x1c02 > @@ -803,6 +984,10 @@ > #define ENCI_DVI_VSO_END_EVN 0x1c08 > #define ENCI_DVI_VSO_END_ODD 0x1c09 > #define ENCI_CFILT_CTRL2 0x1c0a > +#define ENCI_CFILT_CMPT_CR_DLY(delay) (delay & 0xf) > +#define ENCI_CFILT_CMPT_CB_DLY(delay) ((delay & 0xf) << 4) > +#define ENCI_CFILT_CVBS_CR_DLY(delay) ((delay & 0xf) << 8) > +#define ENCI_CFILT_CVBS_CB_DLY(delay) ((delay & 0xf) << 12) > #define ENCI_DACSEL_0 0x1c0b > #define ENCI_DACSEL_1 0x1c0c > #define ENCP_DACSEL_0 0x1c0d > @@ -817,6 +1002,8 @@ > #define ENCI_TST_CLRBAR_WIDTH 0x1c16 > #define ENCI_TST_VDCNT_STSET 0x1c17 > #define ENCI_VFIFO2VD_CTL 0x1c18 > +#define ENCI_VFIFO2VD_CTL_ENABLE BIT(0) > +#define ENCI_VFIFO2VD_CTL_VD_SEL(val) ((val & 0xff) << 8) > #define ENCI_VFIFO2VD_PIXEL_START 0x1c19 > #define ENCI_VFIFO2VD_PIXEL_END 0x1c1a > #define ENCI_VFIFO2VD_LINE_TOP_START 0x1c1b > @@ -879,6 +1066,7 @@ > #define VENC_VDAC_DAC5_FILT_CTRL0 0x1c56 > #define VENC_VDAC_DAC5_FILT_CTRL1 0x1c57 > #define VENC_VDAC_DAC0_FILT_CTRL0 0x1c58 > +#define VENC_VDAC_DAC0_FILT_CTRL0_EN BIT(0) > #define VENC_VDAC_DAC0_FILT_CTRL1 0x1c59 > #define VENC_VDAC_DAC1_FILT_CTRL0 0x1c5a > #define VENC_VDAC_DAC1_FILT_CTRL1 0x1c5b > @@ -1284,6 +1472,18 @@ > #define VIU2_SEL_VENC_ENCP (2 << 2) > #define VIU2_SEL_VENC_ENCT (3 << 2) > #define VPU_HDMI_SETTING 0x271b > +#define VPU_HDMI_ENCI_DATA_TO_HDMI BIT(0) > +#define VPU_HDMI_ENCP_DATA_TO_HDMI BIT(1) > +#define VPU_HDMI_INV_HSYNC BIT(2) > +#define VPU_HDMI_INV_VSYNC BIT(3) > +#define VPU_HDMI_OUTPUT_CRYCB (0 << 5) > +#define VPU_HDMI_OUTPUT_YCBCR (1 << 5) > +#define VPU_HDMI_OUTPUT_YCRCB (2 << 5) > +#define VPU_HDMI_OUTPUT_CBCRY (3 << 5) > +#define VPU_HDMI_OUTPUT_CBYCR (4 << 5) > +#define VPU_HDMI_OUTPUT_CRCBY (5 << 5) > +#define VPU_HDMI_WR_RATE(rate) (((rate & 0x1f) - 1) << 8) > +#define VPU_HDMI_RD_RATE(rate) (((rate & 0x1f) - 1) << 12) > #define ENCI_INFO_READ 0x271c > #define ENCP_INFO_READ 0x271d > #define ENCT_INFO_READ 0x271e > @@ -1360,6 +1560,7 @@ > #define VPU_RDARB_MODE_L1C2 0x2799 > #define VPU_RDARB_MODE_L2C1 0x279d > #define VPU_WRARB_MODE_L2C1 0x27a2 > +#define VPU_RDARB_SLAVE_TO_MASTER_PORT(dc, port) (port << (16 + dc)) > > /* osd super scale */ > #define OSDSR_HV_SIZEIN 0x3130 > @@ -1390,4 +1591,150 @@ > #define OSDSR_YBIC_VCOEF0 0x3149 > #define OSDSR_CBIC_VCOEF0 0x314a > > +/* osd afbcd on gxtvbb */ > +#define OSD1_AFBCD_ENABLE 0x31a0 > +#define OSD1_AFBCD_MODE 0x31a1 > +#define OSD1_AFBCD_SIZE_IN 0x31a2 > +#define OSD1_AFBCD_HDR_PTR 0x31a3 > +#define OSD1_AFBCD_FRAME_PTR 0x31a4 > +#define OSD1_AFBCD_CHROMA_PTR 0x31a5 > +#define OSD1_AFBCD_CONV_CTRL 0x31a6 > +#define OSD1_AFBCD_STATUS 0x31a8 > +#define OSD1_AFBCD_PIXEL_HSCOPE 0x31a9 > +#define OSD1_AFBCD_PIXEL_VSCOPE 0x31aa > + > +/* add for gxm and 962e dv core2 */ > +#define DOLBY_CORE2A_SWAP_CTRL1 0x3434 > +#define DOLBY_CORE2A_SWAP_CTRL2 0x3435 > + > +/* osd afbc on g12a */ > +#define VPU_MAFBC_BLOCK_ID 0x3a00 > +#define VPU_MAFBC_IRQ_RAW_STATUS 0x3a01 > +#define VPU_MAFBC_IRQ_CLEAR 0x3a02 > +#define VPU_MAFBC_IRQ_MASK 0x3a03 > +#define VPU_MAFBC_IRQ_STATUS 0x3a04 > +#define VPU_MAFBC_COMMAND 0x3a05 > +#define VPU_MAFBC_STATUS 0x3a06 > +#define VPU_MAFBC_SURFACE_CFG 0x3a07 > +#define VPU_MAFBC_HEADER_BUF_ADDR_LOW_S0 0x3a10 > +#define VPU_MAFBC_HEADER_BUF_ADDR_HIGH_S0 0x3a11 > +#define VPU_MAFBC_FORMAT_SPECIFIER_S0 0x3a12 > +#define VPU_MAFBC_BUFFER_WIDTH_S0 0x3a13 > +#define VPU_MAFBC_BUFFER_HEIGHT_S0 0x3a14 > +#define VPU_MAFBC_BOUNDING_BOX_X_START_S0 0x3a15 > +#define VPU_MAFBC_BOUNDING_BOX_X_END_S0 0x3a16 > +#define VPU_MAFBC_BOUNDING_BOX_Y_START_S0 0x3a17 > +#define VPU_MAFBC_BOUNDING_BOX_Y_END_S0 0x3a18 > +#define VPU_MAFBC_OUTPUT_BUF_ADDR_LOW_S0 0x3a19 > +#define VPU_MAFBC_OUTPUT_BUF_ADDR_HIGH_S0 0x3a1a > +#define VPU_MAFBC_OUTPUT_BUF_STRIDE_S0 0x3a1b > +#define VPU_MAFBC_PREFETCH_CFG_S0 0x3a1c > + > +#define VPU_MAFBC_HEADER_BUF_ADDR_LOW_S1 0x3a30 > +#define VPU_MAFBC_HEADER_BUF_ADDR_HIGH_S1 0x3a31 > +#define VPU_MAFBC_FORMAT_SPECIFIER_S1 0x3a32 > +#define VPU_MAFBC_BUFFER_WIDTH_S1 0x3a33 > +#define VPU_MAFBC_BUFFER_HEIGHT_S1 0x3a34 > +#define VPU_MAFBC_BOUNDING_BOX_X_START_S1 0x3a35 > +#define VPU_MAFBC_BOUNDING_BOX_X_END_S1 0x3a36 > +#define VPU_MAFBC_BOUNDING_BOX_Y_START_S1 0x3a37 > +#define VPU_MAFBC_BOUNDING_BOX_Y_END_S1 0x3a38 > +#define VPU_MAFBC_OUTPUT_BUF_ADDR_LOW_S1 0x3a39 > +#define VPU_MAFBC_OUTPUT_BUF_ADDR_HIGH_S1 0x3a3a > +#define VPU_MAFBC_OUTPUT_BUF_STRIDE_S1 0x3a3b > +#define VPU_MAFBC_PREFETCH_CFG_S1 0x3a3c > + > +#define VPU_MAFBC_HEADER_BUF_ADDR_LOW_S2 0x3a50 > +#define VPU_MAFBC_HEADER_BUF_ADDR_HIGH_S2 0x3a51 > +#define VPU_MAFBC_FORMAT_SPECIFIER_S2 0x3a52 > +#define VPU_MAFBC_BUFFER_WIDTH_S2 0x3a53 > +#define VPU_MAFBC_BUFFER_HEIGHT_S2 0x3a54 > +#define VPU_MAFBC_BOUNDING_BOX_X_START_S2 0x3a55 > +#define VPU_MAFBC_BOUNDING_BOX_X_END_S2 0x3a56 > +#define VPU_MAFBC_BOUNDING_BOX_Y_START_S2 0x3a57 > +#define VPU_MAFBC_BOUNDING_BOX_Y_END_S2 0x3a58 > +#define VPU_MAFBC_OUTPUT_BUF_ADDR_LOW_S2 0x3a59 > +#define VPU_MAFBC_OUTPUT_BUF_ADDR_HIGH_S2 0x3a5a > +#define VPU_MAFBC_OUTPUT_BUF_STRIDE_S2 0x3a5b > +#define VPU_MAFBC_PREFETCH_CFG_S2 0x3a5c > + > +#define VPU_MAFBC_HEADER_BUF_ADDR_LOW_S3 0x3a70 > +#define VPU_MAFBC_HEADER_BUF_ADDR_HIGH_S3 0x3a71 > +#define VPU_MAFBC_FORMAT_SPECIFIER_S3 0x3a72 > +#define VPU_MAFBC_BUFFER_WIDTH_S3 0x3a73 > +#define VPU_MAFBC_BUFFER_HEIGHT_S3 0x3a74 > +#define VPU_MAFBC_BOUNDING_BOX_X_START_S3 0x3a75 > +#define VPU_MAFBC_BOUNDING_BOX_X_END_S3 0x3a76 > +#define VPU_MAFBC_BOUNDING_BOX_Y_START_S3 0x3a77 > +#define VPU_MAFBC_BOUNDING_BOX_Y_END_S3 0x3a78 > +#define VPU_MAFBC_OUTPUT_BUF_ADDR_LOW_S3 0x3a79 > +#define VPU_MAFBC_OUTPUT_BUF_ADDR_HIGH_S3 0x3a7a > +#define VPU_MAFBC_OUTPUT_BUF_STRIDE_S3 0x3a7b > +#define VPU_MAFBC_PREFETCH_CFG_S3 0x3a7c > + > +#define DOLBY_PATH_CTRL 0x1a0c > +#define DOLBY_BYPASS_EN(val) (val & 0xf) > +#define OSD_PATH_MISC_CTRL 0x1a0e > +#define MALI_AFBCD_TOP_CTRL 0x1a0f > + > +#define VIU_OSD_BLEND_CTRL 0x39b0 > +#define VIU_OSD_BLEND_REORDER(dest, src) ((src) << (dest * 4)) > +#define VIU_OSD_BLEND_DIN_EN(bits) ((bits & 0xf) << 20) > +#define VIU_OSD_BLEND1_DIN3_BYPASS_TO_DOUT1 BIT(24) > +#define VIU_OSD_BLEND1_DOUT_BYPASS_TO_BLEND2 BIT(25) > +#define VIU_OSD_BLEND_DIN0_BYPASS_TO_DOUT0 BIT(26) > +#define VIU_OSD_BLEND_BLEN2_PREMULT_EN(input) ((input & 0x3) << 27) > +#define VIU_OSD_BLEND_HOLD_LINES(lines) ((u32)(lines & 0x7) << 29) > +#define VIU_OSD_BLEND_CTRL1 0x39c0 > +#define VIU_OSD_BLEND_DIN0_SCOPE_H 0x39b1 > +#define VIU_OSD_BLEND_DIN0_SCOPE_V 0x39b2 > +#define VIU_OSD_BLEND_DIN1_SCOPE_H 0x39b3 > +#define VIU_OSD_BLEND_DIN1_SCOPE_V 0x39b4 > +#define VIU_OSD_BLEND_DIN2_SCOPE_H 0x39b5 > +#define VIU_OSD_BLEND_DIN2_SCOPE_V 0x39b6 > +#define VIU_OSD_BLEND_DIN3_SCOPE_H 0x39b7 > +#define VIU_OSD_BLEND_DIN3_SCOPE_V 0x39b8 > +#define VIU_OSD_BLEND_DUMMY_DATA0 0x39b9 > +#define VIU_OSD_BLEND_DUMMY_ALPHA 0x39ba > +#define VIU_OSD_BLEND_BLEND0_SIZE 0x39bb > +#define VIU_OSD_BLEND_BLEND1_SIZE 0x39bc > +#define VIU_OSD_BLEND_RO_CURRENT_XY 0x39bf > + > +#define VPP_OUT_H_V_SIZE 0x1da5 > + > +#define VPP_VD2_HDR_IN_SIZE 0x1df0 > +#define VPP_OSD1_IN_SIZE 0x1df1 > +#define VPP_GCLK_CTRL2 0x1df2 > +#define VD2_PPS_DUMMY_DATA 0x1df4 > +#define VPP_OSD1_BLD_H_SCOPE 0x1df5 > +#define VPP_OSD1_BLD_V_SCOPE 0x1df6 > +#define VPP_OSD2_BLD_H_SCOPE 0x1df7 > +#define VPP_OSD2_BLD_V_SCOPE 0x1df8 > +#define VPP_WRBAK_CTRL 0x1df9 > +#define VPP_SLEEP_CTRL 0x1dfa > +#define VD1_BLEND_SRC_CTRL 0x1dfb > +#define VD2_BLEND_SRC_CTRL 0x1dfc > +#define VD_BLEND_PREBLD_SRC_VD1 (1 << 0) > +#define VD_BLEND_PREBLD_SRC_VD2 (2 << 0) > +#define VD_BLEND_PREBLD_SRC_OSD1 (3 << 0) > +#define VD_BLEND_PREBLD_SRC_OSD2 (4 << 0) > +#define VD_BLEND_PREBLD_PREMULT_EN BIT(4) > +#define VD_BLEND_POSTBLD_SRC_VD1 (1 << 8) > +#define VD_BLEND_POSTBLD_SRC_VD2 (2 << 8) > +#define VD_BLEND_POSTBLD_SRC_OSD1 (3 << 8) > +#define VD_BLEND_POSTBLD_SRC_OSD2 (4 << 8) > +#define VD_BLEND_POSTBLD_PREMULT_EN BIT(16) > +#define OSD1_BLEND_SRC_CTRL 0x1dfd > +#define OSD2_BLEND_SRC_CTRL 0x1dfe > +#define OSD_BLEND_POSTBLD_SRC_VD1 (1 << 8) > +#define OSD_BLEND_POSTBLD_SRC_VD2 (2 << 8) > +#define OSD_BLEND_POSTBLD_SRC_OSD1 (3 << 8) > +#define OSD_BLEND_POSTBLD_SRC_OSD2 (4 << 8) > +#define OSD_BLEND_PATH_SEL_ENABLE BIT(20) > + > +#define VPP_POST_BLEND_BLEND_DUMMY_DATA 0x3968 > +#define VPP_POST_BLEND_DUMMY_ALPHA 0x3969 > +#define VPP_RDARB_MODE 0x3978 > +#define VPP_RDARB_REQEN_SLV 0x3979 > + > #endif /* __MESON_REGISTERS_H */ > diff --git a/drivers/video/meson/meson_vclk.c b/drivers/video/meson/meson_vclk.c > index 693e0ebe39..0f628e920b 100644 > --- a/drivers/video/meson/meson_vclk.c > +++ b/drivers/video/meson/meson_vclk.c > @@ -68,14 +68,20 @@ enum { > #define CTS_HDMI_SYS_EN BIT(8) > > #define HHI_HDMI_PLL_CNTL 0x320 /* 0xc8 offset in data sheet */ > +#define HHI_HDMI_PLL_CNTL_EN BIT(30) > #define HHI_HDMI_PLL_CNTL2 0x324 /* 0xc9 offset in data sheet */ > #define HHI_HDMI_PLL_CNTL3 0x328 /* 0xca offset in data sheet */ > #define HHI_HDMI_PLL_CNTL4 0x32C /* 0xcb offset in data sheet */ > #define HHI_HDMI_PLL_CNTL5 0x330 /* 0xcc offset in data sheet */ > #define HHI_HDMI_PLL_CNTL6 0x334 /* 0xcd offset in data sheet */ > +#define HHI_HDMI_PLL_CNTL7 0x338 /* 0xce offset in data sheet */ > > #define HDMI_PLL_RESET BIT(28) > +#define HDMI_PLL_RESET_G12A BIT(29) > #define HDMI_PLL_LOCK BIT(31) > +#define HDMI_PLL_LOCK_G12A (3 << 30) > + > +#define FREQ_1000_1001(_freq) DIV_ROUND_CLOSEST(_freq * 1000, 1001) > > /* VID PLL Dividers */ > enum { > @@ -206,8 +212,6 @@ static void meson_venci_cvbs_clock_config(struct meson_vpu_priv *priv) > { > unsigned int val; > > - debug("%s:%d\n", __func__, __LINE__); > - > /* Setup PLL to output 1.485GHz */ > if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB)) { > hhi_write(HHI_HDMI_PLL_CNTL, 0x5800023d); > @@ -217,6 +221,10 @@ static void meson_venci_cvbs_clock_config(struct meson_vpu_priv *priv) > hhi_write(HHI_HDMI_PLL_CNTL5, 0x71486980); > hhi_write(HHI_HDMI_PLL_CNTL6, 0x00000e55); > hhi_write(HHI_HDMI_PLL_CNTL, 0x4800023d); > + > + /* Poll for lock bit */ > + readl_poll_timeout(priv->hhi_base + HHI_HDMI_PLL_CNTL, val, > + (val & HDMI_PLL_LOCK), 10); > } else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM) || > meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXL)) { > hhi_write(HHI_HDMI_PLL_CNTL, 0x4000027b); > @@ -231,13 +239,26 @@ static void meson_venci_cvbs_clock_config(struct meson_vpu_priv *priv) > HDMI_PLL_RESET, HDMI_PLL_RESET); > hhi_update_bits(HHI_HDMI_PLL_CNTL, > HDMI_PLL_RESET, 0); > - } > > - debug("%s:%d\n", __func__, __LINE__); > + /* Poll for lock bit */ > + readl_poll_timeout(priv->hhi_base + HHI_HDMI_PLL_CNTL, val, > + (val & HDMI_PLL_LOCK), 10); > + } else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) { > + hhi_write(HHI_HDMI_PLL_CNTL, 0x1a0504f7); > + hhi_write(HHI_HDMI_PLL_CNTL2, 0x00010000); > + hhi_write(HHI_HDMI_PLL_CNTL3, 0x00000000); > + hhi_write(HHI_HDMI_PLL_CNTL4, 0x6a28dc00); > + hhi_write(HHI_HDMI_PLL_CNTL5, 0x65771290); > + hhi_write(HHI_HDMI_PLL_CNTL6, 0x39272000); > + hhi_write(HHI_HDMI_PLL_CNTL7, 0x56540000); > + hhi_write(HHI_HDMI_PLL_CNTL, 0x3a0504f7); > + hhi_write(HHI_HDMI_PLL_CNTL, 0x1a0504f7); > > - /* Poll for lock bit */ > - readl_poll_timeout(priv->hhi_base + HHI_HDMI_PLL_CNTL, val, > - (val & HDMI_PLL_LOCK), 10); > + /* Poll for lock bit */ > + readl_poll_timeout(priv->hhi_base + HHI_HDMI_PLL_CNTL, val, > + ((val & HDMI_PLL_LOCK_G12A) == HDMI_PLL_LOCK_G12A), > + 10); > + } > > /* Disable VCLK2 */ > hhi_update_bits(HHI_VIID_CLK_CNTL, VCLK2_EN, 0); > @@ -250,8 +271,13 @@ static void meson_venci_cvbs_clock_config(struct meson_vpu_priv *priv) > VCLK2_DIV_MASK, (55 - 1)); > > /* select vid_pll for vclk2 */ > - hhi_update_bits(HHI_VIID_CLK_CNTL, > - VCLK2_SEL_MASK, (4 << VCLK2_SEL_SHIFT)); > + if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) > + hhi_update_bits(HHI_VIID_CLK_CNTL, > + VCLK2_SEL_MASK, (0 << VCLK2_SEL_SHIFT)); > + else > + hhi_update_bits(HHI_VIID_CLK_CNTL, > + VCLK2_SEL_MASK, (4 << VCLK2_SEL_SHIFT)); > + > /* enable vclk2 gate */ > hhi_update_bits(HHI_VIID_CLK_CNTL, VCLK2_EN, VCLK2_EN); > > @@ -282,14 +308,12 @@ static void meson_venci_cvbs_clock_config(struct meson_vpu_priv *priv) > /* enable vdac_clk */ > hhi_update_bits(HHI_VID_CLK_CNTL2, > CTS_VDAC_EN, CTS_VDAC_EN); > - > - debug("%s:%d\n", __func__, __LINE__); > } > > enum { > /* PLL O1 O2 O3 VP DV EN TX */ > /* 4320 /4 /4 /1 /5 /1 => /2 /2 */ > - MESON_VCLK_HDMI_ENCI_54000 = 1, > + MESON_VCLK_HDMI_ENCI_54000 = 0, > /* 4320 /4 /4 /1 /5 /1 => /1 /2 */ > MESON_VCLK_HDMI_DDR_54000, > /* 2970 /4 /1 /1 /5 /1 => /1 /2 */ > @@ -305,6 +329,7 @@ enum { > }; > > struct meson_vclk_params { > + unsigned int pixel_freq; > unsigned int pll_base_freq; > unsigned int pll_od1; > unsigned int pll_od2; > @@ -313,6 +338,7 @@ struct meson_vclk_params { > unsigned int vclk_div; > } params[] = { > [MESON_VCLK_HDMI_ENCI_54000] = { > + .pixel_freq = 54000, > .pll_base_freq = 4320000, > .pll_od1 = 4, > .pll_od2 = 4, > @@ -321,6 +347,7 @@ struct meson_vclk_params { > .vclk_div = 1, > }, > [MESON_VCLK_HDMI_DDR_54000] = { > + .pixel_freq = 54000, > .pll_base_freq = 4320000, > .pll_od1 = 4, > .pll_od2 = 4, > @@ -329,6 +356,7 @@ struct meson_vclk_params { > .vclk_div = 1, > }, > [MESON_VCLK_HDMI_DDR_148500] = { > + .pixel_freq = 148500, > .pll_base_freq = 2970000, > .pll_od1 = 4, > .pll_od2 = 1, > @@ -337,6 +365,7 @@ struct meson_vclk_params { > .vclk_div = 1, > }, > [MESON_VCLK_HDMI_74250] = { > + .pixel_freq = 74250, > .pll_base_freq = 2970000, > .pll_od1 = 2, > .pll_od2 = 2, > @@ -345,6 +374,7 @@ struct meson_vclk_params { > .vclk_div = 1, > }, > [MESON_VCLK_HDMI_148500] = { > + .pixel_freq = 148500, > .pll_base_freq = 2970000, > .pll_od1 = 1, > .pll_od2 = 2, > @@ -353,14 +383,16 @@ struct meson_vclk_params { > .vclk_div = 1, > }, > [MESON_VCLK_HDMI_297000] = { > - .pll_base_freq = 2970000, > - .pll_od1 = 1, > + .pixel_freq = 297000, > + .pll_base_freq = 5940000, > + .pll_od1 = 2, > .pll_od2 = 1, > .pll_od3 = 1, > .vid_pll_div = VID_PLL_DIV_5, > .vclk_div = 2, > }, > [MESON_VCLK_HDMI_594000] = { > + .pixel_freq = 594000, > .pll_base_freq = 5940000, > .pll_od1 = 1, > .pll_od2 = 1, > @@ -368,6 +400,7 @@ struct meson_vclk_params { > .vid_pll_div = VID_PLL_DIV_5, > .vclk_div = 1, > }, > + { /* sentinel */ }, > }; > > static inline unsigned int pll_od_to_reg(unsigned int od) > @@ -431,6 +464,50 @@ void meson_hdmi_pll_set_params(struct meson_vpu_priv *priv, unsigned int m, > /* Poll for lock bit */ > readl_poll_timeout(priv->hhi_base + HHI_HDMI_PLL_CNTL, val, > (val & HDMI_PLL_LOCK), 10); > + } else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) { > + hhi_write(HHI_HDMI_PLL_CNTL, 0x0b3a0400 | m); > + > + /* Enable and reset */ > + hhi_update_bits(HHI_HDMI_PLL_CNTL, 0x3 << 28, 0x3 << 28); > + > + hhi_write(HHI_HDMI_PLL_CNTL2, frac); > + hhi_write(HHI_HDMI_PLL_CNTL3, 0x00000000); > + > + /* G12A HDMI PLL Needs specific parameters for 5.4GHz */ > + if (m >= 0xf7) { > + if (frac < 0x10000) { > + hhi_write(HHI_HDMI_PLL_CNTL4, 0x6a685c00); > + hhi_write(HHI_HDMI_PLL_CNTL5, 0x11551293); > + } else { > + hhi_write(HHI_HDMI_PLL_CNTL4, 0xea68dc00); > + hhi_write(HHI_HDMI_PLL_CNTL5, 0x65771290); > + } > + hhi_write(HHI_HDMI_PLL_CNTL6, 0x39272000); > + hhi_write(HHI_HDMI_PLL_CNTL7, 0x55540000); > + } else { > + hhi_write(HHI_HDMI_PLL_CNTL4, 0x0a691c00); > + hhi_write(HHI_HDMI_PLL_CNTL5, 0x33771290); > + hhi_write(HHI_HDMI_PLL_CNTL6, 0x39270000); > + hhi_write(HHI_HDMI_PLL_CNTL7, 0x50540000); > + } > + > + do { > + /* Reset PLL */ > + hhi_update_bits(HHI_HDMI_PLL_CNTL, > + HDMI_PLL_RESET_G12A, > + HDMI_PLL_RESET_G12A); > + > + /* UN-Reset PLL */ > + hhi_update_bits(HHI_HDMI_PLL_CNTL, > + HDMI_PLL_RESET_G12A, 0); > + > + /* Poll for lock bits */ > + if (!readl_poll_timeout( > + priv->hhi_base + HHI_HDMI_PLL_CNTL, val, > + ((val & HDMI_PLL_LOCK_G12A) > + == HDMI_PLL_LOCK_G12A), 100)) > + break; > + } while (1); > } > > if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB)) > @@ -440,6 +517,9 @@ void meson_hdmi_pll_set_params(struct meson_vpu_priv *priv, unsigned int m, > meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXL)) > hhi_update_bits(HHI_HDMI_PLL_CNTL3, > 3 << 21, pll_od_to_reg(od1) << 21); > + else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) > + hhi_update_bits(HHI_HDMI_PLL_CNTL, > + 3 << 16, pll_od_to_reg(od1) << 16); > > if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB)) > hhi_update_bits(HHI_HDMI_PLL_CNTL2, > @@ -448,6 +528,9 @@ void meson_hdmi_pll_set_params(struct meson_vpu_priv *priv, unsigned int m, > meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXL)) > hhi_update_bits(HHI_HDMI_PLL_CNTL3, > 3 << 23, pll_od_to_reg(od2) << 23); > + else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) > + hhi_update_bits(HHI_HDMI_PLL_CNTL, > + 3 << 18, pll_od_to_reg(od2) << 18); > > if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB)) > hhi_update_bits(HHI_HDMI_PLL_CNTL2, > @@ -456,6 +539,9 @@ void meson_hdmi_pll_set_params(struct meson_vpu_priv *priv, unsigned int m, > meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXL)) > hhi_update_bits(HHI_HDMI_PLL_CNTL3, > 3 << 19, pll_od_to_reg(od3) << 19); > + else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) > + hhi_update_bits(HHI_HDMI_PLL_CNTL, > + 3 << 20, pll_od_to_reg(od3) << 20); > } > > #define XTAL_FREQ 24000 > @@ -472,6 +558,7 @@ static unsigned int meson_hdmi_pll_get_m(struct meson_vpu_priv *priv, > > #define HDMI_FRAC_MAX_GXBB 4096 > #define HDMI_FRAC_MAX_GXL 1024 > +#define HDMI_FRAC_MAX_G12A 131072 > > static unsigned int meson_hdmi_pll_get_frac(struct meson_vpu_priv *priv, > unsigned int m, > @@ -488,6 +575,9 @@ static unsigned int meson_hdmi_pll_get_frac(struct meson_vpu_priv *priv, > parent_freq *= 2; > } > > + if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) > + frac_max = HDMI_FRAC_MAX_G12A; > + > /* We can have a perfect match !*/ > if (pll_freq / m == parent_freq && > pll_freq % m == 0) > @@ -519,6 +609,12 @@ static bool meson_hdmi_pll_validate_params(struct meson_vpu_priv *priv, > return false; > if (frac >= HDMI_FRAC_MAX_GXL) > return false; > + } else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) { > + /* Empiric supported min/max dividers */ > + if (m < 106 || m > 247) > + return false; > + if (frac >= HDMI_FRAC_MAX_G12A) > + return false; > } > > return true; > @@ -595,8 +691,10 @@ meson_vclk_set(struct meson_vpu_priv *priv, unsigned int pll_base_freq, > unsigned int od1, unsigned int od2, unsigned int od3, > unsigned int vid_pll_div, unsigned int vclk_div, > unsigned int hdmi_tx_div, unsigned int venc_div, > - bool hdmi_use_enci) > + bool hdmi_use_enci, bool vic_alternate_clock) > { > + unsigned int m = 0, frac = 0; > + > /* Set HDMI-TX sys clock */ > hhi_update_bits(HHI_HDMI_CLK_CNTL, > CTS_HDMI_SYS_SEL_MASK, 0); > @@ -611,34 +709,55 @@ meson_vclk_set(struct meson_vpu_priv *priv, unsigned int pll_base_freq, > } else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB)) { > switch (pll_base_freq) { > case 2970000: > - meson_hdmi_pll_set_params(priv, 0x3d, 0xe00, > - od1, od2, od3); > + m = 0x3d; > + frac = vic_alternate_clock ? 0xd02 : 0xe00; > break; > case 4320000: > - meson_hdmi_pll_set_params(priv, 0x5a, 0, > - od1, od2, od3); > + m = vic_alternate_clock ? 0x59 : 0x5a; > + frac = vic_alternate_clock ? 0xe8f : 0; > break; > case 5940000: > - meson_hdmi_pll_set_params(priv, 0x7b, 0xc00, > - od1, od2, od3); > + m = 0x7b; > + frac = vic_alternate_clock ? 0xa05 : 0xc00; > break; > } > + > + meson_hdmi_pll_set_params(priv, m, frac, od1, od2, od3); > } else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM) || > meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXL)) { > switch (pll_base_freq) { > case 2970000: > - meson_hdmi_pll_set_params(priv, 0x7b, 0x300, > - od1, od2, od3); > + m = 0x7b; > + frac = vic_alternate_clock ? 0x281 : 0x300; > + break; > + case 4320000: > + m = vic_alternate_clock ? 0xb3 : 0xb4; > + frac = vic_alternate_clock ? 0x347 : 0; > + break; > + case 5940000: > + m = 0xf7; > + frac = vic_alternate_clock ? 0x102 : 0x200; > + break; > + } > + > + meson_hdmi_pll_set_params(priv, m, frac, od1, od2, od3); > + } else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) { > + switch (pll_base_freq) { > + case 2970000: > + m = 0x7b; > + frac = vic_alternate_clock ? 0x140b4 : 0x18000; > break; > case 4320000: > - meson_hdmi_pll_set_params(priv, 0xb4, 0, > - od1, od2, od3); > + m = vic_alternate_clock ? 0xb3 : 0xb4; > + frac = vic_alternate_clock ? 0x1a3ee : 0; > break; > case 5940000: > - meson_hdmi_pll_set_params(priv, 0xf7, 0x200, > - od1, od2, od3); > + m = 0xf7; > + frac = vic_alternate_clock ? 0x8148 : 0x10000; > break; > } > + > + meson_hdmi_pll_set_params(priv, m, frac, od1, od2, od3); > } > > /* Setup vid_pll divider */ > @@ -803,6 +922,7 @@ static void meson_vclk_setup(struct meson_vpu_priv *priv, unsigned int target, > unsigned int vclk_freq, unsigned int venc_freq, > unsigned int dac_freq, bool hdmi_use_enci) > { > + bool vic_alternate_clock = false; > unsigned int freq; > unsigned int hdmi_tx_div; > unsigned int venc_div; > @@ -820,8 +940,7 @@ static void meson_vclk_setup(struct meson_vpu_priv *priv, unsigned int target, > * - encp encoder > */ > meson_vclk_set(priv, vclk_freq * 10, 0, 0, 0, > - VID_PLL_DIV_5, 2, 1, 1, false); > - > + VID_PLL_DIV_5, 2, 1, 1, false, false); > return; > } > > @@ -841,31 +960,35 @@ static void meson_vclk_setup(struct meson_vpu_priv *priv, unsigned int target, > return; > } > > - switch (vclk_freq) { > - case 54000: > - if (hdmi_use_enci) > - freq = MESON_VCLK_HDMI_ENCI_54000; > - else > - freq = MESON_VCLK_HDMI_DDR_54000; > - break; > - case 74250: > - freq = MESON_VCLK_HDMI_74250; > - break; > - case 148500: > - if (dac_freq != 148500) > - freq = MESON_VCLK_HDMI_DDR_148500; > - else > - freq = MESON_VCLK_HDMI_148500; > - break; > - case 297000: > - freq = MESON_VCLK_HDMI_297000; > - break; > - case 594000: > - freq = MESON_VCLK_HDMI_594000; > - break; > - default: > - printf("Fatal Error, invalid HDMI vclk freq %d\n", > - vclk_freq); > + for (freq = 0 ; params[freq].pixel_freq ; ++freq) { > + if (vclk_freq == params[freq].pixel_freq || > + vclk_freq == FREQ_1000_1001(params[freq].pixel_freq)) { > + if (vclk_freq != params[freq].pixel_freq) > + vic_alternate_clock = true; > + else > + vic_alternate_clock = false; > + > + if (freq == MESON_VCLK_HDMI_ENCI_54000 && > + !hdmi_use_enci) > + continue; > + > + if (freq == MESON_VCLK_HDMI_DDR_54000 && > + hdmi_use_enci) > + continue; > + > + if (freq == MESON_VCLK_HDMI_DDR_148500 && > + dac_freq == vclk_freq) > + continue; > + > + if (freq == MESON_VCLK_HDMI_148500 && > + dac_freq != vclk_freq) > + continue; > + break; > + } > + } > + > + if (!params[freq].pixel_freq) { > + pr_err("Fatal Error, invalid HDMI vclk freq %d\n", vclk_freq); > return; > } > > @@ -873,7 +996,7 @@ static void meson_vclk_setup(struct meson_vpu_priv *priv, unsigned int target, > params[freq].pll_od1, params[freq].pll_od2, > params[freq].pll_od3, params[freq].vid_pll_div, > params[freq].vclk_div, hdmi_tx_div, venc_div, > - hdmi_use_enci); > + hdmi_use_enci, vic_alternate_clock); > } > > void meson_vpu_setup_vclk(struct udevice *dev, > diff --git a/drivers/video/meson/meson_venc.c b/drivers/video/meson/meson_venc.c > index d137dde8e2..5da4b3f096 100644 > --- a/drivers/video/meson/meson_venc.c > +++ b/drivers/video/meson/meson_venc.c > @@ -23,7 +23,9 @@ enum meson_venc_source { > }; > > #define HHI_VDAC_CNTL0 0x2F4 /* 0xbd offset in data sheet */ > +#define HHI_VDAC_CNTL0_G12A 0x2EC /* 0xbb offset in data sheet */ > #define HHI_VDAC_CNTL1 0x2F8 /* 0xbe offset in data sheet */ > +#define HHI_VDAC_CNTL1_G12A 0x2F0 /* 0xbc offset in data sheet */ > > struct meson_cvbs_enci_mode { > unsigned int mode_tag; > @@ -175,7 +177,7 @@ union meson_hdmi_venc_mode meson_hdmi_enci_mode_480i = { > .hso_end = 129, > .vso_even = 3, > .vso_odd = 260, > - .macv_max_amp = 0x810b, > + .macv_max_amp = 0xb, > .video_prog_mode = 0xf0, > .video_mode = 0x8, > .sch_adjust = 0x20, > @@ -195,7 +197,7 @@ union meson_hdmi_venc_mode meson_hdmi_enci_mode_576i = { > .hso_end = 129, > .vso_even = 3, > .vso_odd = 260, > - .macv_max_amp = 8107, > + .macv_max_amp = 0x7, > .video_prog_mode = 0xff, > .video_mode = 0x13, > .sch_adjust = 0x28, > @@ -774,12 +776,13 @@ static void meson_venc_hdmi_mode_set(struct meson_vpu_priv *priv, > unsigned int eof_lines; > unsigned int sof_lines; > unsigned int vsync_lines; > + u32 reg; > > /* Use VENCI for 480i and 576i and double HDMI pixels */ > if (mode->flags & DISPLAY_FLAGS_DOUBLECLK) { > - venc_hdmi_latency = 1; > hdmi_repeat = true; > use_enci = true; > + venc_hdmi_latency = 1; > } > > meson_venc_hdmi_get_dmt_vmode(mode, &vmode_dmt); > @@ -850,8 +853,11 @@ static void meson_venc_hdmi_mode_set(struct meson_vpu_priv *priv, > unsigned int lines_f1; > > /* CVBS Filter settings */ > - writel(0x12, priv->io_base + _REG(ENCI_CFILT_CTRL)); > - writel(0x12, priv->io_base + _REG(ENCI_CFILT_CTRL2)); > + writel(ENCI_CFILT_CMPT_SEL_HIGH | 0x10, > + priv->io_base + _REG(ENCI_CFILT_CTRL)); > + writel(ENCI_CFILT_CMPT_CR_DLY(2) | > + ENCI_CFILT_CMPT_CB_DLY(1), > + priv->io_base + _REG(ENCI_CFILT_CTRL2)); > > /* Digital Video Select : Interlace, clk27 clk, external */ > writel(0, priv->io_base + _REG(VENC_DVI_SETTING)); > @@ -873,7 +879,8 @@ static void meson_venc_hdmi_mode_set(struct meson_vpu_priv *priv, > priv->io_base + _REG(ENCI_SYNC_VSO_ODDLN)); > > /* Macrovision max amplitude change */ > - writel(vmode->enci.macv_max_amp, > + writel(ENCI_MACV_MAX_AMP_ENABLE_CHANGE | > + ENCI_MACV_MAX_AMP_VAL(vmode->enci.macv_max_amp), > priv->io_base + _REG(ENCI_MACV_MAX_AMP)); > > /* Video mode */ > @@ -882,7 +889,8 @@ static void meson_venc_hdmi_mode_set(struct meson_vpu_priv *priv, > writel(vmode->enci.video_mode, > priv->io_base + _REG(ENCI_VIDEO_MODE)); > > - /* Advanced Video Mode : > + /* > + * Advanced Video Mode : > * Demux shifting 0x2 > * Blank line end at line17/22 > * High bandwidth Luma Filter > @@ -890,7 +898,10 @@ static void meson_venc_hdmi_mode_set(struct meson_vpu_priv *priv, > * Bypass luma low pass filter > * No macrovision on CSYNC > */ > - writel(0x26, priv->io_base + _REG(ENCI_VIDEO_MODE_ADV)); > + writel(ENCI_VIDEO_MODE_ADV_DMXMD(2) | > + ENCI_VIDEO_MODE_ADV_VBICTL_LINE_17_22 | > + ENCI_VIDEO_MODE_ADV_YBW_HIGH, > + priv->io_base + _REG(ENCI_VIDEO_MODE_ADV)); > > writel(vmode->enci.sch_adjust, > priv->io_base + _REG(ENCI_VIDEO_SCH)); > @@ -905,8 +916,17 @@ static void meson_venc_hdmi_mode_set(struct meson_vpu_priv *priv, > /* UNreset Interlaced TV Encoder */ > writel(0, priv->io_base + _REG(ENCI_DBG_PX_RST)); > > - /* Enable Vfifo2vd, Y_Cb_Y_Cr select */ > - writel(0x4e01, priv->io_base + _REG(ENCI_VFIFO2VD_CTL)); > + /* > + * Enable Vfifo2vd and set Y_Cb_Y_Cr: > + * Corresponding value: > + * Y => 00 or 10 > + * Cb => 01 > + * Cr => 11 > + * Ex: 0x4e => 01001110 would mean Cb/Y/Cr/Y > + */ > + writel(ENCI_VFIFO2VD_CTL_ENABLE | > + ENCI_VFIFO2VD_CTL_VD_SEL(0x4e), > + priv->io_base + _REG(ENCI_VFIFO2VD_CTL)); > > /* Timings */ > writel(vmode->enci.pixel_start, > @@ -928,7 +948,8 @@ static void meson_venc_hdmi_mode_set(struct meson_vpu_priv *priv, > meson_vpp_setup_mux(priv, MESON_VIU_VPP_MUX_ENCI); > > /* Interlace video enable */ > - writel(1, priv->io_base + _REG(ENCI_VIDEO_EN)); > + writel(ENCI_VIDEO_EN_ENABLE, > + priv->io_base + _REG(ENCI_VIDEO_EN)); > > lines_f0 = mode->vback_porch.typ + mode->vactive.typ + > mode->vback_porch.typ + mode->vsync_len.typ; > @@ -1177,7 +1198,8 @@ static void meson_venc_hdmi_mode_set(struct meson_vpu_priv *priv, > writel(1, priv->io_base + _REG(ENCP_VIDEO_EN)); > > /* Set DE signal's polarity is active high */ > - writel_bits(BIT(14), BIT(14), > + writel_bits(ENCP_VIDEO_MODE_DE_V_HIGH, > + ENCP_VIDEO_MODE_DE_V_HIGH, > priv->io_base + _REG(ENCP_VIDEO_MODE)); > > /* Program DE timing */ > @@ -1302,21 +1324,52 @@ static void meson_venc_hdmi_mode_set(struct meson_vpu_priv *priv, > meson_vpp_setup_mux(priv, MESON_VIU_VPP_MUX_ENCP); > } > > - writel((use_enci ? 1 : 2) | > - (mode->flags & DISPLAY_FLAGS_HSYNC_HIGH ? 1 << 2 : 0) | > - (mode->flags & DISPLAY_FLAGS_VSYNC_HIGH ? 1 << 3 : 0) | > - 4 << 5 | > - (venc_repeat ? 1 << 8 : 0) | > - (hdmi_repeat ? 1 << 12 : 0), > - priv->io_base + _REG(VPU_HDMI_SETTING)); > + /* Set VPU HDMI setting */ > + /* Select ENCP or ENCI data to HDMI */ > + if (use_enci) > + reg = VPU_HDMI_ENCI_DATA_TO_HDMI; > + else > + reg = VPU_HDMI_ENCP_DATA_TO_HDMI; > + > + /* Invert polarity of HSYNC from VENC */ > + if (mode->flags & DISPLAY_FLAGS_HSYNC_HIGH) > + reg |= VPU_HDMI_INV_HSYNC; > + > + /* Invert polarity of VSYNC from VENC */ > + if (mode->flags & DISPLAY_FLAGS_VSYNC_HIGH) > + reg |= VPU_HDMI_INV_VSYNC; > + > + /* Output data format: CbYCr */ > + reg |= VPU_HDMI_OUTPUT_CBYCR; > + > + /* > + * Write rate to the async FIFO between VENC and HDMI. > + * One write every 2 wr_clk. > + */ > + if (venc_repeat) > + reg |= VPU_HDMI_WR_RATE(2); > + > + /* > + * Read rate to the async FIFO between VENC and HDMI. > + * One read every 2 wr_clk. > + */ > + if (hdmi_repeat) > + reg |= VPU_HDMI_RD_RATE(2); > + > + writel(reg, priv->io_base + _REG(VPU_HDMI_SETTING)); > } > > static void meson_venci_cvbs_mode_set(struct meson_vpu_priv *priv, > struct meson_cvbs_enci_mode *mode) > { > + u32 reg; > + > /* CVBS Filter settings */ > - writel(0x12, priv->io_base + _REG(ENCI_CFILT_CTRL)); > - writel(0x12, priv->io_base + _REG(ENCI_CFILT_CTRL2)); > + writel(ENCI_CFILT_CMPT_SEL_HIGH | 0x10, > + priv->io_base + _REG(ENCI_CFILT_CTRL)); > + writel(ENCI_CFILT_CMPT_CR_DLY(2) | > + ENCI_CFILT_CMPT_CB_DLY(1), > + priv->io_base + _REG(ENCI_CFILT_CTRL2)); > > /* Digital Video Select : Interlace, clk27 clk, external */ > writel(0, priv->io_base + _REG(VENC_DVI_SETTING)); > @@ -1338,7 +1391,8 @@ static void meson_venci_cvbs_mode_set(struct meson_vpu_priv *priv, > priv->io_base + _REG(ENCI_SYNC_VSO_ODDLN)); > > /* Macrovision max amplitude change */ > - writel(0x8100 + mode->macv_max_amp, > + writel(ENCI_MACV_MAX_AMP_ENABLE_CHANGE | > + ENCI_MACV_MAX_AMP_VAL(mode->macv_max_amp), > priv->io_base + _REG(ENCI_MACV_MAX_AMP)); > > /* Video mode */ > @@ -1347,7 +1401,8 @@ static void meson_venci_cvbs_mode_set(struct meson_vpu_priv *priv, > writel(mode->video_mode, > priv->io_base + _REG(ENCI_VIDEO_MODE)); > > - /* Advanced Video Mode : > + /* > + * Advanced Video Mode : > * Demux shifting 0x2 > * Blank line end at line17/22 > * High bandwidth Luma Filter > @@ -1355,7 +1410,10 @@ static void meson_venci_cvbs_mode_set(struct meson_vpu_priv *priv, > * Bypass luma low pass filter > * No macrovision on CSYNC > */ > - writel(0x26, priv->io_base + _REG(ENCI_VIDEO_MODE_ADV)); > + writel(ENCI_VIDEO_MODE_ADV_DMXMD(2) | > + ENCI_VIDEO_MODE_ADV_VBICTL_LINE_17_22 | > + ENCI_VIDEO_MODE_ADV_YBW_HIGH, > + priv->io_base + _REG(ENCI_VIDEO_MODE_ADV)); > > writel(mode->sch_adjust, priv->io_base + _REG(ENCI_VIDEO_SCH)); > > @@ -1387,16 +1445,50 @@ static void meson_venci_cvbs_mode_set(struct meson_vpu_priv *priv, > /* UNreset Interlaced TV Encoder */ > writel(0, priv->io_base + _REG(ENCI_DBG_PX_RST)); > > - /* Enable Vfifo2vd, Y_Cb_Y_Cr select */ > - writel(0x4e01, priv->io_base + _REG(ENCI_VFIFO2VD_CTL)); > + /* > + * Enable Vfifo2vd and set Y_Cb_Y_Cr: > + * Corresponding value: > + * Y => 00 or 10 > + * Cb => 01 > + * Cr => 11 > + * Ex: 0x4e => 01001110 would mean Cb/Y/Cr/Y > + */ > + writel(ENCI_VFIFO2VD_CTL_ENABLE | > + ENCI_VFIFO2VD_CTL_VD_SEL(0x4e), > + priv->io_base + _REG(ENCI_VFIFO2VD_CTL)); > > /* Power UP Dacs */ > writel(0, priv->io_base + _REG(VENC_VDAC_SETTING)); > > /* Video Upsampling */ > - writel(0x0061, priv->io_base + _REG(VENC_UPSAMPLE_CTRL0)); > - writel(0x4061, priv->io_base + _REG(VENC_UPSAMPLE_CTRL1)); > - writel(0x5061, priv->io_base + _REG(VENC_UPSAMPLE_CTRL2)); > + /* > + * CTRL0, CTRL1 and CTRL2: > + * Filter0: input data sample every 2 cloks > + * Filter1: filtering and upsample enable > + */ > + reg = VENC_UPSAMPLE_CTRL_F0_2_CLK_RATIO | VENC_UPSAMPLE_CTRL_F1_EN | > + VENC_UPSAMPLE_CTRL_F1_UPSAMPLE_EN; > + > + /* > + * Upsample CTRL0: > + * Interlace High Bandwidth Luma > + */ > + writel(VENC_UPSAMPLE_CTRL_INTERLACE_HIGH_LUMA | reg, > + priv->io_base + _REG(VENC_UPSAMPLE_CTRL0)); > + > + /* > + * Upsample CTRL1: > + * Interlace Pb > + */ > + writel(VENC_UPSAMPLE_CTRL_INTERLACE_PB | reg, > + priv->io_base + _REG(VENC_UPSAMPLE_CTRL1)); > + > + /* > + * Upsample CTRL2: > + * Interlace R > + */ > + writel(VENC_UPSAMPLE_CTRL_INTERLACE_PR | reg, > + priv->io_base + _REG(VENC_UPSAMPLE_CTRL2)); > > /* Select Interlace Y DACs */ > writel(0, priv->io_base + _REG(VENC_VDAC_DACSEL0)); > @@ -1410,14 +1502,16 @@ static void meson_venci_cvbs_mode_set(struct meson_vpu_priv *priv, > meson_vpp_setup_mux(priv, MESON_VIU_VPP_MUX_ENCI); > > /* Enable ENCI FIFO */ > - writel(0x2000, priv->io_base + _REG(VENC_VDAC_FIFO_CTRL)); > + writel(VENC_VDAC_FIFO_EN_ENCI_ENABLE, > + priv->io_base + _REG(VENC_VDAC_FIFO_CTRL)); > > /* Select ENCI DACs 0, 1, 4, and 5 */ > writel(0x11, priv->io_base + _REG(ENCI_DACSEL_0)); > writel(0x11, priv->io_base + _REG(ENCI_DACSEL_1)); > > /* Interlace video enable */ > - writel(1, priv->io_base + _REG(ENCI_VIDEO_EN)); > + writel(ENCI_VIDEO_EN_ENABLE, > + priv->io_base + _REG(ENCI_VIDEO_EN)); > > /* Configure Video Saturation / Contrast / Brightness / Hue */ > writel(mode->video_saturation, > @@ -1430,7 +1524,8 @@ static void meson_venci_cvbs_mode_set(struct meson_vpu_priv *priv, > priv->io_base + _REG(ENCI_VIDEO_HUE)); > > /* Enable DAC0 Filter */ > - writel(0x1, priv->io_base + _REG(VENC_VDAC_DAC0_FILT_CTRL0)); > + writel(VENC_VDAC_DAC0_FILT_CTRL0_EN, > + priv->io_base + _REG(VENC_VDAC_DAC0_FILT_CTRL0)); > writel(0xfc48, priv->io_base + _REG(VENC_VDAC_DAC0_FILT_CTRL1)); > > /* 0 in Macrovision register 0 */ > @@ -1441,15 +1536,21 @@ static void meson_venci_cvbs_mode_set(struct meson_vpu_priv *priv, > priv->io_base + _REG(ENCI_SYNC_ADJ)); > > /* enable VDAC */ > - writel_bits(BIT(5), 0, priv->io_base + _REG(VENC_VDAC_DACSEL0)); > + writel_bits(VENC_VDAC_SEL_ATV_DMD, 0, > + priv->io_base + _REG(VENC_VDAC_DACSEL0)); > > if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB)) > hhi_write(HHI_VDAC_CNTL0, 1); > else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXL) || > meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM)) > hhi_write(HHI_VDAC_CNTL0, 0xf0001); > + else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) > + hhi_write(HHI_VDAC_CNTL0_G12A, 0x906001); > > - hhi_write(HHI_VDAC_CNTL1, 0); > + if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) > + hhi_write(HHI_VDAC_CNTL1_G12A, 0); > + else > + hhi_write(HHI_VDAC_CNTL1, 0); > } > > void meson_vpu_setup_venc(struct udevice *dev, > diff --git a/drivers/video/meson/meson_vpu.h b/drivers/video/meson/meson_vpu.h > index ef5f10eae3..3412dac052 100644 > --- a/drivers/video/meson/meson_vpu.h > +++ b/drivers/video/meson/meson_vpu.h > @@ -14,6 +14,7 @@ > #include <video.h> > #include <display.h> > #include <linux/io.h> > +#include <linux/bitfield.h> > #include "meson_registers.h" > > enum { > diff --git a/drivers/video/meson/meson_vpu_init.c b/drivers/video/meson/meson_vpu_init.c > index 92228b5ceb..12f8c4194a 100644 > --- a/drivers/video/meson/meson_vpu_init.c > +++ b/drivers/video/meson/meson_vpu_init.c > @@ -12,7 +12,9 @@ > > /* HHI Registers */ > #define HHI_VDAC_CNTL0 0x2F4 /* 0xbd offset in data sheet */ > +#define HHI_VDAC_CNTL0_G12A 0x2EC /* 0xbd offset in data sheet */ > #define HHI_VDAC_CNTL1 0x2F8 /* 0xbe offset in data sheet */ > +#define HHI_VDAC_CNTL1_G12A 0x2F0 /* 0xbe offset in data sheet */ > #define HHI_HDMI_PHY_CNTL0 0x3a0 /* 0xe8 offset in data sheet */ > > /* OSDx_CTRL_STAT2 */ > @@ -42,7 +44,7 @@ static void meson_vpp_write_scaling_filter_coefs(struct meson_vpu_priv *priv, > { > int i; > > - writel(is_horizontal ? BIT(8) : 0, > + writel(is_horizontal ? VPP_SCALE_HORIZONTAL_COEF : 0, > priv->io_base + _REG(VPP_OSD_SCALE_COEF_IDX)); > for (i = 0; i < 33; i++) > writel(coefs[i], > @@ -67,7 +69,7 @@ static void meson_vpp_write_vd_scaling_filter_coefs(struct meson_vpu_priv *priv, > { > int i; > > - writel(is_horizontal ? BIT(8) : 0, > + writel(is_horizontal ? VPP_SCALE_HORIZONTAL_COEF : 0, > priv->io_base + _REG(VPP_SCALE_COEF_IDX)); > for (i = 0; i < 33; i++) > writel(coefs[i], > @@ -112,6 +114,34 @@ static int eotf_bypass_coeff[EOTF_COEFF_SIZE] = { > EOTF_COEFF_RIGHTSHIFT /* right shift */ > }; > > +static void meson_viu_set_g12a_osd1_matrix(struct meson_vpu_priv *priv, > + int *m, bool csc_on) > +{ > + /* VPP WRAP OSD1 matrix */ > + writel(((m[0] & 0xfff) << 16) | (m[1] & 0xfff), > + priv->io_base + _REG(VPP_WRAP_OSD1_MATRIX_PRE_OFFSET0_1)); > + writel(m[2] & 0xfff, > + priv->io_base + _REG(VPP_WRAP_OSD1_MATRIX_PRE_OFFSET2)); > + writel(((m[3] & 0x1fff) << 16) | (m[4] & 0x1fff), > + priv->io_base + _REG(VPP_WRAP_OSD1_MATRIX_COEF00_01)); > + writel(((m[5] & 0x1fff) << 16) | (m[6] & 0x1fff), > + priv->io_base + _REG(VPP_WRAP_OSD1_MATRIX_COEF02_10)); > + writel(((m[7] & 0x1fff) << 16) | (m[8] & 0x1fff), > + priv->io_base + _REG(VPP_WRAP_OSD1_MATRIX_COEF11_12)); > + writel(((m[9] & 0x1fff) << 16) | (m[10] & 0x1fff), > + priv->io_base + _REG(VPP_WRAP_OSD1_MATRIX_COEF20_21)); > + writel((m[11] & 0x1fff) << 16, > + priv->io_base + _REG(VPP_WRAP_OSD1_MATRIX_COEF22)); > + > + writel(((m[18] & 0xfff) << 16) | (m[19] & 0xfff), > + priv->io_base + _REG(VPP_WRAP_OSD1_MATRIX_OFFSET0_1)); > + writel(m[20] & 0xfff, > + priv->io_base + _REG(VPP_WRAP_OSD1_MATRIX_OFFSET2)); > + > + writel_bits(BIT(0), csc_on ? BIT(0) : 0, > + priv->io_base + _REG(VPP_WRAP_OSD1_MATRIX_EN_CTRL)); > +} > + > static void meson_viu_set_osd_matrix(struct meson_vpu_priv *priv, > enum viu_matrix_sel_e m_select, > int *m, bool csc_on) > @@ -322,20 +352,47 @@ static void meson_viu_load_matrix(struct meson_vpu_priv *priv) > true); > } > > +static inline uint32_t meson_viu_osd_burst_length_reg(uint32_t length) > +{ > + u32 val = (((length & 0x80) % 24) / 12); > + > + return (((val & 0x3) << 10) | (((val & 0x4) >> 2) << 31)); > +} > + > void meson_vpu_init(struct udevice *dev) > { > struct meson_vpu_priv *priv = dev_get_priv(dev); > u32 reg; > > - /* vpu initialization */ > - writel(0x210000, priv->io_base + _REG(VPU_RDARB_MODE_L1C1)); > - writel(0x10000, priv->io_base + _REG(VPU_RDARB_MODE_L1C2)); > - writel(0x900000, priv->io_base + _REG(VPU_RDARB_MODE_L2C1)); > - writel(0x20000, priv->io_base + _REG(VPU_WRARB_MODE_L2C1)); > + /* > + * Slave dc0 and dc5 connected to master port 1. > + * By default other slaves are connected to master port 0. > + */ > + reg = VPU_RDARB_SLAVE_TO_MASTER_PORT(0, 1) | > + VPU_RDARB_SLAVE_TO_MASTER_PORT(5, 1); > + writel(reg, priv->io_base + _REG(VPU_RDARB_MODE_L1C1)); > + > + /* Slave dc0 connected to master port 1 */ > + reg = VPU_RDARB_SLAVE_TO_MASTER_PORT(0, 1); > + writel(reg, priv->io_base + _REG(VPU_RDARB_MODE_L1C2)); > + > + /* Slave dc4 and dc7 connected to master port 1 */ > + reg = VPU_RDARB_SLAVE_TO_MASTER_PORT(4, 1) | > + VPU_RDARB_SLAVE_TO_MASTER_PORT(7, 1); > + writel(reg, priv->io_base + _REG(VPU_RDARB_MODE_L2C1)); > + > + /* Slave dc1 connected to master port 1 */ > + reg = VPU_RDARB_SLAVE_TO_MASTER_PORT(1, 1); > + writel(reg, priv->io_base + _REG(VPU_WRARB_MODE_L2C1)); > > /* Disable CVBS VDAC */ > - hhi_write(HHI_VDAC_CNTL0, 0); > - hhi_write(HHI_VDAC_CNTL1, 8); > + if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) { > + hhi_write(HHI_VDAC_CNTL0_G12A, 0); > + hhi_write(HHI_VDAC_CNTL1_G12A, 8); > + } else { > + hhi_write(HHI_VDAC_CNTL0, 0); > + hhi_write(HHI_VDAC_CNTL1, 8); > + } > > /* Power Down Dacs */ > writel(0xff, priv->io_base + _REG(VENC_VDAC_SETTING)); > @@ -344,7 +401,9 @@ void meson_vpu_init(struct udevice *dev) > hhi_write(HHI_HDMI_PHY_CNTL0, 0); > > /* Disable HDMI */ > - writel_bits(0x3, 0, priv->io_base + _REG(VPU_HDMI_SETTING)); > + writel_bits(VPU_HDMI_ENCI_DATA_TO_HDMI | > + VPU_HDMI_ENCP_DATA_TO_HDMI, 0, > + priv->io_base + _REG(VPU_HDMI_SETTING)); > > /* Disable all encoders */ > writel(0, priv->io_base + _REG(ENCI_VIDEO_EN)); > @@ -360,43 +419,58 @@ void meson_vpu_init(struct udevice *dev) > } else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM)) { > writel_bits(0xff << 16, 0xff << 16, > priv->io_base + _REG(VIU_MISC_CTRL1)); > - writel(0x20000, priv->io_base + _REG(VPP_DOLBY_CTRL)); > + writel(VPP_PPS_DUMMY_DATA_MODE, > + priv->io_base + _REG(VPP_DOLBY_CTRL)); > writel(0x1020080, > priv->io_base + _REG(VPP_DUMMY_DATA1)); > - } > + } else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) > + writel(0xf, priv->io_base + _REG(DOLBY_PATH_CTRL)); > > /* Initialize vpu fifo control registers */ > - writel(readl(priv->io_base + _REG(VPP_OFIFO_SIZE)) | > - 0x77f, priv->io_base + _REG(VPP_OFIFO_SIZE)); > - writel(0x08080808, priv->io_base + _REG(VPP_HOLD_LINES)); > - > - /* Turn off preblend */ > - writel_bits(VPP_PREBLEND_ENABLE, 0, > - priv->io_base + _REG(VPP_MISC)); > - > - /* Turn off POSTBLEND */ > - writel_bits(VPP_POSTBLEND_ENABLE, 0, > - priv->io_base + _REG(VPP_MISC)); > - > - /* Force all planes off */ > - writel_bits(VPP_OSD1_POSTBLEND | VPP_OSD2_POSTBLEND | > - VPP_VD1_POSTBLEND | VPP_VD2_POSTBLEND | > - VPP_VD1_PREBLEND | VPP_VD2_PREBLEND, 0, > - priv->io_base + _REG(VPP_MISC)); > - > - /* Setup default VD settings */ > - writel(4096, > - priv->io_base + _REG(VPP_PREBLEND_VD1_H_START_END)); > - writel(4096, > - priv->io_base + _REG(VPP_BLEND_VD2_H_START_END)); > + if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) > + writel(VPP_OFIFO_SIZE_DEFAULT, > + priv->io_base + _REG(VPP_OFIFO_SIZE)); > + else > + writel_bits(VPP_OFIFO_SIZE_MASK, 0x77f, > + priv->io_base + _REG(VPP_OFIFO_SIZE)); > + writel(VPP_POSTBLEND_HOLD_LINES(4) | VPP_PREBLEND_HOLD_LINES(4), > + priv->io_base + _REG(VPP_HOLD_LINES)); > + > + if (!meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) { > + /* Turn off preblend */ > + writel_bits(VPP_PREBLEND_ENABLE, 0, > + priv->io_base + _REG(VPP_MISC)); > + > + /* Turn off POSTBLEND */ > + writel_bits(VPP_POSTBLEND_ENABLE, 0, > + priv->io_base + _REG(VPP_MISC)); > + > + /* Force all planes off */ > + writel_bits(VPP_OSD1_POSTBLEND | VPP_OSD2_POSTBLEND | > + VPP_VD1_POSTBLEND | VPP_VD2_POSTBLEND | > + VPP_VD1_PREBLEND | VPP_VD2_PREBLEND, 0, > + priv->io_base + _REG(VPP_MISC)); > + > + /* Setup default VD settings */ > + writel(4096, > + priv->io_base + _REG(VPP_PREBLEND_VD1_H_START_END)); > + writel(4096, > + priv->io_base + _REG(VPP_BLEND_VD2_H_START_END)); > + } > > /* Disable Scalers */ > writel(0, priv->io_base + _REG(VPP_OSD_SC_CTRL0)); > writel(0, priv->io_base + _REG(VPP_OSD_VSC_CTRL0)); > writel(0, priv->io_base + _REG(VPP_OSD_HSC_CTRL0)); > - writel(4 | (4 << 8) | BIT(15), > + > + writel(VPP_VSC_BANK_LENGTH(4) | VPP_HSC_BANK_LENGTH(4) | > + VPP_SC_VD_EN_ENABLE, > priv->io_base + _REG(VPP_SC_MISC)); > > + /* Enable minus black level for vadj1 */ > + writel(VPP_MINUS_BLACK_LVL_VADJ1_ENABLE, > + priv->io_base + _REG(VPP_VADJ_CTRL)); > + > /* Write in the proper filter coefficients. */ > meson_vpp_write_scaling_filter_coefs(priv, > vpp_filter_coefs_4point_bspline, false); > @@ -410,23 +484,31 @@ void meson_vpu_init(struct udevice *dev) > true); > > /* Disable OSDs */ > - writel_bits(BIT(0) | BIT(21), 0, > + writel_bits(VIU_OSD1_OSD_BLK_ENABLE | VIU_OSD1_OSD_ENABLE, 0, > priv->io_base + _REG(VIU_OSD1_CTRL_STAT)); > - writel_bits(BIT(0) | BIT(21), 0, > + writel_bits(VIU_OSD1_OSD_BLK_ENABLE | VIU_OSD1_OSD_ENABLE, 0, > priv->io_base + _REG(VIU_OSD2_CTRL_STAT)); > > /* On GXL/GXM, Use the 10bit HDR conversion matrix */ > if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM) || > meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXL)) > meson_viu_load_matrix(priv); > + else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) > + meson_viu_set_g12a_osd1_matrix(priv, RGB709_to_YUV709l_coeff, > + true); > > /* Initialize OSD1 fifo control register */ > - reg = BIT(0) | /* Urgent DDR request priority */ > - (4 << 5) | /* hold_fifo_lines */ > - (3 << 10) | /* burst length 64 */ > - (32 << 12) | /* fifo_depth_val: 32*8=256 */ > - (2 << 22) | /* 4 words in 1 burst */ > - (2 << 24); > + reg = VIU_OSD_DDR_PRIORITY_URGENT | > + VIU_OSD_HOLD_FIFO_LINES(4) | > + VIU_OSD_FIFO_DEPTH_VAL(32) | /* fifo_depth_val: 32*8=256 */ > + VIU_OSD_WORDS_PER_BURST(4) | /* 4 words in 1 burst */ > + VIU_OSD_FIFO_LIMITS(2); /* fifo_lim: 2*16=32 */ > + > + if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) > + reg |= meson_viu_osd_burst_length_reg(32); > + else > + reg |= meson_viu_osd_burst_length_reg(64); > + > writel(reg, priv->io_base + _REG(VIU_OSD1_FIFO_CTRL_STAT)); > writel(reg, priv->io_base + _REG(VIU_OSD2_FIFO_CTRL_STAT)); > > @@ -437,4 +519,39 @@ void meson_vpu_init(struct udevice *dev) > writel_bits(0xff << OSD_REPLACE_SHIFT, > 0xff << OSD_REPLACE_SHIFT, > priv->io_base + _REG(VIU_OSD2_CTRL_STAT2)); > + > + /* Disable VD1 AFBC */ > + /* di_mif0_en=0 mif0_to_vpp_en=0 di_mad_en=0 and afbc vd1 set=0*/ > + writel_bits(VIU_CTRL0_VD1_AFBC_MASK, 0, > + priv->io_base + _REG(VIU_MISC_CTRL0)); > + writel(0, priv->io_base + _REG(AFBC_ENABLE)); > + > + writel(0x00FF00C0, > + priv->io_base + _REG(VD1_IF0_LUMA_FIFO_SIZE)); > + writel(0x00FF00C0, > + priv->io_base + _REG(VD2_IF0_LUMA_FIFO_SIZE)); > + > + if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) { > + writel(VIU_OSD_BLEND_REORDER(0, 1) | > + VIU_OSD_BLEND_REORDER(1, 0) | > + VIU_OSD_BLEND_REORDER(2, 0) | > + VIU_OSD_BLEND_REORDER(3, 0) | > + VIU_OSD_BLEND_DIN_EN(1) | > + VIU_OSD_BLEND1_DIN3_BYPASS_TO_DOUT1 | > + VIU_OSD_BLEND1_DOUT_BYPASS_TO_BLEND2 | > + VIU_OSD_BLEND_DIN0_BYPASS_TO_DOUT0 | > + VIU_OSD_BLEND_BLEN2_PREMULT_EN(1) | > + VIU_OSD_BLEND_HOLD_LINES(4), > + priv->io_base + _REG(VIU_OSD_BLEND_CTRL)); > + writel(OSD_BLEND_PATH_SEL_ENABLE, > + priv->io_base + _REG(OSD1_BLEND_SRC_CTRL)); > + writel(OSD_BLEND_PATH_SEL_ENABLE, > + priv->io_base + _REG(OSD2_BLEND_SRC_CTRL)); > + writel(0, priv->io_base + _REG(VD1_BLEND_SRC_CTRL)); > + writel(0, priv->io_base + _REG(VD2_BLEND_SRC_CTRL)); > + writel(0, priv->io_base + _REG(VIU_OSD_BLEND_DUMMY_DATA0)); > + writel(0, priv->io_base + _REG(VIU_OSD_BLEND_DUMMY_ALPHA)); > + writel_bits(DOLBY_BYPASS_EN(0xc), DOLBY_BYPASS_EN(0xc), > + priv->io_base + _REG(DOLBY_PATH_CTRL)); > + } > } > ^ permalink raw reply [flat|nested] 19+ messages in thread
* [U-Boot] [PATCH 4/8] video: meson: sync with linux drm-misc tree 2019-08-30 12:09 ` [U-Boot] [PATCH 4/8] video: meson: sync with linux drm-misc tree Neil Armstrong 2019-10-09 15:12 ` Neil Armstrong @ 2019-10-10 20:48 ` Anatolij Gustschin 1 sibling, 0 replies; 19+ messages in thread From: Anatolij Gustschin @ 2019-10-10 20:48 UTC (permalink / raw) To: u-boot On Fri, 30 Aug 2019 14:09:24 +0200 Neil Armstrong narmstrong at baylibre.com wrote: > Synchronize the Amlogic Meson Video driver back with the latest > DRM misc tree, adding G12A platform support, from the latest commit: > 528a25d040bc ("drm: meson: use match data to detect vpu compatibility") > > The sync includes the following changes from Linux adapted to U-Boot: > - Add support for VIC alternate timings > - Switch PLL to 5.94GHz base for 297Mhz pixel clock > - Add registers for G12A SoC > - Add G12A Support for VPP setup > - Add G12A Support for VIU setup > - Add G12A support for OSD1 Plane > - Add G12A support for plane handling in CRTC driver > - Add G12A support for CVBS Encoder > - Add G12A Video Clock setup > - Add G12A support for the DW-HDMI Glue > - fix G12A HDMI PLL settings for 4K60 1000/1001 variations > - fix primary plane disabling > - fix G12A primary plane disabling > - mask value when writing bits relaxed > - crtc: drv: vpp: viu: venc: use proper macros instead of magic constants > - global clean-up > - add macro used to enable HDMI PLL > - venc: set the correct macrovision max amplitude value > > Signed-off-by: Neil Armstrong <narmstrong@baylibre.com> Reviewed-by: Anatolij Gustschin <agust@denx.de> -- Anatolij ^ permalink raw reply [flat|nested] 19+ messages in thread
* [U-Boot] [PATCH 5/8] video: meson: add compatible for Amlogic G12A 2019-08-30 12:09 [U-Boot] [PATCH 0/8] arm: meson: add Video support for G12A and SEI510 board Neil Armstrong ` (3 preceding siblings ...) 2019-08-30 12:09 ` [U-Boot] [PATCH 4/8] video: meson: sync with linux drm-misc tree Neil Armstrong @ 2019-08-30 12:09 ` Neil Armstrong 2019-10-10 18:22 ` Anatolij Gustschin 2019-08-30 12:09 ` [U-Boot] [PATCH 6/8] arm: meson: board-g12a: Setup VPU in fdt Neil Armstrong ` (3 subsequent siblings) 8 siblings, 1 reply; 19+ messages in thread From: Neil Armstrong @ 2019-08-30 12:09 UTC (permalink / raw) To: u-boot Finally add the Amlogic G12A SoC compatible for the VPU driver. Signed-off-by: Neil Armstrong <narmstrong@baylibre.com> --- drivers/video/meson/meson_vpu.c | 1 + drivers/video/meson/meson_vpu.h | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/video/meson/meson_vpu.c b/drivers/video/meson/meson_vpu.c index 34d35749eb..c3af9b013c 100644 --- a/drivers/video/meson/meson_vpu.c +++ b/drivers/video/meson/meson_vpu.c @@ -86,6 +86,7 @@ static const struct udevice_id meson_vpu_ids[] = { { .compatible = "amlogic,meson-gxbb-vpu", .data = VPU_COMPATIBLE_GXBB }, { .compatible = "amlogic,meson-gxl-vpu", .data = VPU_COMPATIBLE_GXL }, { .compatible = "amlogic,meson-gxm-vpu", .data = VPU_COMPATIBLE_GXM }, + { .compatible = "amlogic,meson-g12a-vpu", .data = VPU_COMPATIBLE_G12A }, { } }; diff --git a/drivers/video/meson/meson_vpu.h b/drivers/video/meson/meson_vpu.h index 3412dac052..0d9fddad2e 100644 --- a/drivers/video/meson/meson_vpu.h +++ b/drivers/video/meson/meson_vpu.h @@ -28,6 +28,7 @@ enum vpu_compatible { VPU_COMPATIBLE_GXBB = 0, VPU_COMPATIBLE_GXL = 1, VPU_COMPATIBLE_GXM = 2, + VPU_COMPATIBLE_G12A = 3, }; struct meson_vpu_priv { -- 2.22.0 ^ permalink raw reply related [flat|nested] 19+ messages in thread
* [U-Boot] [PATCH 5/8] video: meson: add compatible for Amlogic G12A 2019-08-30 12:09 ` [U-Boot] [PATCH 5/8] video: meson: add compatible for Amlogic G12A Neil Armstrong @ 2019-10-10 18:22 ` Anatolij Gustschin 0 siblings, 0 replies; 19+ messages in thread From: Anatolij Gustschin @ 2019-10-10 18:22 UTC (permalink / raw) To: u-boot On Fri, 30 Aug 2019 14:09:25 +0200 Neil Armstrong narmstrong at baylibre.com wrote: > Finally add the Amlogic G12A SoC compatible for the VPU driver. > > Signed-off-by: Neil Armstrong <narmstrong@baylibre.com> Reviewed-by: Anatolij Gustschin <agust@denx.de> -- Anatolij ^ permalink raw reply [flat|nested] 19+ messages in thread
* [U-Boot] [PATCH 6/8] arm: meson: board-g12a: Setup VPU in fdt 2019-08-30 12:09 [U-Boot] [PATCH 0/8] arm: meson: add Video support for G12A and SEI510 board Neil Armstrong ` (4 preceding siblings ...) 2019-08-30 12:09 ` [U-Boot] [PATCH 5/8] video: meson: add compatible for Amlogic G12A Neil Armstrong @ 2019-08-30 12:09 ` Neil Armstrong 2019-10-10 18:23 ` Anatolij Gustschin 2019-08-30 12:09 ` [U-Boot] [PATCH 7/8] ARM: dts: meson-g12a: add U-Boot specific DT for graphics Neil Armstrong ` (2 subsequent siblings) 8 siblings, 1 reply; 19+ messages in thread From: Neil Armstrong @ 2019-08-30 12:09 UTC (permalink / raw) To: u-boot If VIDEO_MESON is enabled, we need to setup the fdt for the framebuffer. Call meson_vpu_rsv_fb() which reserves the framebuffer memory region for EFI, and sets up simple-framebuffer nodes if simplefb support is enabled. Signed-off-by: Neil Armstrong <narmstrong@baylibre.com> --- arch/arm/mach-meson/board-g12a.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/arm/mach-meson/board-g12a.c b/arch/arm/mach-meson/board-g12a.c index 546b9f6039..24786df6cd 100644 --- a/arch/arm/mach-meson/board-g12a.c +++ b/arch/arm/mach-meson/board-g12a.c @@ -9,6 +9,7 @@ #include <asm/arch/eth.h> #include <asm/arch/g12a.h> #include <asm/arch/mem.h> +#include <asm/arch/meson-vpu.h> #include <asm/io.h> #include <asm/armv8/mmu.h> #include <linux/sizes.h> @@ -57,6 +58,10 @@ void meson_init_reserved_memory(void *fdt) /* Add BL32 reserved zone */ if (bl32_start && bl32_size) meson_board_add_reserved_memory(fdt, bl32_start, bl32_size); + +#if defined(CONFIG_VIDEO_MESON) + meson_vpu_rsv_fb(fdt); +#endif } phys_size_t get_effective_memsize(void) -- 2.22.0 ^ permalink raw reply related [flat|nested] 19+ messages in thread
* [U-Boot] [PATCH 6/8] arm: meson: board-g12a: Setup VPU in fdt 2019-08-30 12:09 ` [U-Boot] [PATCH 6/8] arm: meson: board-g12a: Setup VPU in fdt Neil Armstrong @ 2019-10-10 18:23 ` Anatolij Gustschin 0 siblings, 0 replies; 19+ messages in thread From: Anatolij Gustschin @ 2019-10-10 18:23 UTC (permalink / raw) To: u-boot On Fri, 30 Aug 2019 14:09:26 +0200 Neil Armstrong narmstrong at baylibre.com wrote: > If VIDEO_MESON is enabled, we need to setup the fdt for the framebuffer. > > Call meson_vpu_rsv_fb() which reserves the framebuffer memory region for > EFI, and sets up simple-framebuffer nodes if simplefb support is > enabled. > > Signed-off-by: Neil Armstrong <narmstrong@baylibre.com> Reviewed-by: Anatolij Gustschin <agust@denx.de> -- Anatolij ^ permalink raw reply [flat|nested] 19+ messages in thread
* [U-Boot] [PATCH 7/8] ARM: dts: meson-g12a: add U-Boot specific DT for graphics 2019-08-30 12:09 [U-Boot] [PATCH 0/8] arm: meson: add Video support for G12A and SEI510 board Neil Armstrong ` (5 preceding siblings ...) 2019-08-30 12:09 ` [U-Boot] [PATCH 6/8] arm: meson: board-g12a: Setup VPU in fdt Neil Armstrong @ 2019-08-30 12:09 ` Neil Armstrong 2019-10-10 18:25 ` Anatolij Gustschin 2019-08-30 12:09 ` [U-Boot] [PATCH 8/8] configs: sei510: enable Video Display support Neil Armstrong 2019-10-11 12:57 ` [U-Boot] [PATCH 0/8] arm: meson: add Video support for G12A and SEI510 board Neil Armstrong 8 siblings, 1 reply; 19+ messages in thread From: Neil Armstrong @ 2019-08-30 12:09 UTC (permalink / raw) To: u-boot Like the meson-gx support, add the U-Boot specific bits in DT to support graphics on G12A SoCs. Signed-off-by: Neil Armstrong <narmstrong@baylibre.com> --- arch/arm/dts/meson-g12a-sei510-u-boot.dtsi | 7 +++++ arch/arm/dts/meson-g12a-u-boot.dtsi | 29 +++++++++++++++++++ arch/arm/dts/meson-g12a-u200-u-boot.dtsi | 7 +++++ arch/arm/dts/meson-g12b-odroid-n2-u-boot.dtsi | 7 +++++ 4 files changed, 50 insertions(+) create mode 100644 arch/arm/dts/meson-g12a-sei510-u-boot.dtsi create mode 100644 arch/arm/dts/meson-g12a-u-boot.dtsi create mode 100644 arch/arm/dts/meson-g12a-u200-u-boot.dtsi create mode 100644 arch/arm/dts/meson-g12b-odroid-n2-u-boot.dtsi diff --git a/arch/arm/dts/meson-g12a-sei510-u-boot.dtsi b/arch/arm/dts/meson-g12a-sei510-u-boot.dtsi new file mode 100644 index 0000000000..fddffd628c --- /dev/null +++ b/arch/arm/dts/meson-g12a-sei510-u-boot.dtsi @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2019 BayLibre, SAS. + * Author: Neil Armstrong <narmstrong@baylibre.com> + */ + +#include "meson-g12a-u-boot.dtsi" diff --git a/arch/arm/dts/meson-g12a-u-boot.dtsi b/arch/arm/dts/meson-g12a-u-boot.dtsi new file mode 100644 index 0000000000..38fd3d3feb --- /dev/null +++ b/arch/arm/dts/meson-g12a-u-boot.dtsi @@ -0,0 +1,29 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2019 BayLibre, SAS. + * Author: Maxime Jourdan <mjourdan@baylibre.com> + */ + +/ { + soc { + u-boot,dm-pre-reloc; + }; +}; + +&canvas { + status = "disabled"; +}; + +&vpu { + reg = <0x0 0xff900000 0x0 0x100000>, + <0x0 0xff63c000 0x0 0x1000>, + <0x0 0xff638000 0x0 0x400>; + reg-names = "vpu", "hhi", "dmc"; + u-boot,dm-pre-reloc; +}; + +&hdmi_tx { + reg = <0x0 0x0 0x0 0x10000>, + <0x0 0x3c000 0x0 0x1000>; + reg-names = "hdmitx", "hhi"; +}; diff --git a/arch/arm/dts/meson-g12a-u200-u-boot.dtsi b/arch/arm/dts/meson-g12a-u200-u-boot.dtsi new file mode 100644 index 0000000000..fddffd628c --- /dev/null +++ b/arch/arm/dts/meson-g12a-u200-u-boot.dtsi @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2019 BayLibre, SAS. + * Author: Neil Armstrong <narmstrong@baylibre.com> + */ + +#include "meson-g12a-u-boot.dtsi" diff --git a/arch/arm/dts/meson-g12b-odroid-n2-u-boot.dtsi b/arch/arm/dts/meson-g12b-odroid-n2-u-boot.dtsi new file mode 100644 index 0000000000..fddffd628c --- /dev/null +++ b/arch/arm/dts/meson-g12b-odroid-n2-u-boot.dtsi @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2019 BayLibre, SAS. + * Author: Neil Armstrong <narmstrong@baylibre.com> + */ + +#include "meson-g12a-u-boot.dtsi" -- 2.22.0 ^ permalink raw reply related [flat|nested] 19+ messages in thread
* [U-Boot] [PATCH 7/8] ARM: dts: meson-g12a: add U-Boot specific DT for graphics 2019-08-30 12:09 ` [U-Boot] [PATCH 7/8] ARM: dts: meson-g12a: add U-Boot specific DT for graphics Neil Armstrong @ 2019-10-10 18:25 ` Anatolij Gustschin 0 siblings, 0 replies; 19+ messages in thread From: Anatolij Gustschin @ 2019-10-10 18:25 UTC (permalink / raw) To: u-boot On Fri, 30 Aug 2019 14:09:27 +0200 Neil Armstrong narmstrong at baylibre.com wrote: > Like the meson-gx support, add the U-Boot specific bits in DT > to support graphics on G12A SoCs. > > Signed-off-by: Neil Armstrong <narmstrong@baylibre.com> Reviewed-by: Anatolij Gustschin <agust@denx.de> -- Anatolij ^ permalink raw reply [flat|nested] 19+ messages in thread
* [U-Boot] [PATCH 8/8] configs: sei510: enable Video Display support 2019-08-30 12:09 [U-Boot] [PATCH 0/8] arm: meson: add Video support for G12A and SEI510 board Neil Armstrong ` (6 preceding siblings ...) 2019-08-30 12:09 ` [U-Boot] [PATCH 7/8] ARM: dts: meson-g12a: add U-Boot specific DT for graphics Neil Armstrong @ 2019-08-30 12:09 ` Neil Armstrong 2019-10-10 18:28 ` Anatolij Gustschin 2019-10-11 12:57 ` [U-Boot] [PATCH 0/8] arm: meson: add Video support for G12A and SEI510 board Neil Armstrong 8 siblings, 1 reply; 19+ messages in thread From: Neil Armstrong @ 2019-08-30 12:09 UTC (permalink / raw) To: u-boot Add the necessary config options to support BMP display over HDMI, and add a preboot command to load the BMP file from a predefined eMMC partition. Signed-off-by: Neil Armstrong <narmstrong@baylibre.com> --- configs/sei510_defconfig | 11 +++++++++++ include/configs/sei510.h | 12 ++++++++++++ 2 files changed, 23 insertions(+) diff --git a/configs/sei510_defconfig b/configs/sei510_defconfig index 5aea81d873..9eb205bc63 100644 --- a/configs/sei510_defconfig +++ b/configs/sei510_defconfig @@ -11,6 +11,9 @@ CONFIG_IDENT_STRING=" sei510" # CONFIG_PSCI_RESET is not set CONFIG_DEBUG_UART=y CONFIG_OF_BOARD_SETUP=y +CONFIG_USE_PREBOOT=y +CONFIG_PREBOOT="run load_logo" +# CONFIG_CONSOLE_MUX is not set CONFIG_MISC_INIT_R=y # CONFIG_DISPLAY_CPUINFO is not set # CONFIG_CMD_BDI is not set @@ -23,6 +26,7 @@ CONFIG_CMD_USB=y CONFIG_CMD_USB_MASS_STORAGE=y # CONFIG_CMD_SETEXPR is not set CONFIG_CMD_REGULATOR=y +CONFIG_CMD_BMP=y CONFIG_OF_CONTROL=y CONFIG_DEFAULT_DEVICE_TREE="meson-g12a-sei510" CONFIG_ENV_IS_IN_MMC=y @@ -33,6 +37,7 @@ CONFIG_FASTBOOT_FLASH=y CONFIG_FASTBOOT_FLASH_MMC_DEV=2 CONFIG_FASTBOOT_CMD_OEM_FORMAT=y CONFIG_DM_GPIO=y +# CONFIG_INPUT is not set CONFIG_DM_MMC=y CONFIG_MMC_MESON_GX=y CONFIG_PHY_ADDR_ENABLE=y @@ -42,6 +47,12 @@ CONFIG_ETH_DESIGNWARE=y CONFIG_MESON_G12A_USB_PHY=y CONFIG_PINCTRL=y CONFIG_PINCTRL_MESON_G12A=y +CONFIG_POWER_DOMAIN=y +CONFIG_MESON_GX_VPU_POWER_DOMAIN=y +CONFIG_DM_VIDEO=y +CONFIG_SYS_WHITE_ON_BLACK=y +CONFIG_VIDEO_MESON=y +CONFIG_VIDEO_DT_SIMPLEFB=y CONFIG_DM_REGULATOR=y CONFIG_DM_REGULATOR_FIXED=y CONFIG_DM_RESET=y diff --git a/include/configs/sei510.h b/include/configs/sei510.h index 9957902250..5bf982cada 100644 --- a/include/configs/sei510.h +++ b/include/configs/sei510.h @@ -14,6 +14,7 @@ #define CONFIG_ENV_SIZE 0x10000 #define CONFIG_ENV_OFFSET (-0x10000) +#define LOGO_UUID "43a3305d-150f-4cc9-bd3b-38fca8693846;" #define CACHE_UUID "99207ae6-5207-11e9-999e-6f77a3612069;" #define SYSTEM_UUID "99f9b7ac-5207-11e9-8507-c3c037e393f3;" #define VENDOR_UUID "9d082802-5207-11e9-954c-cbbce08ba108;" @@ -23,6 +24,7 @@ #define PARTS_DEFAULT \ "uuid_disk=${uuid_gpt_disk};" \ "name=boot,size=64M,bootable,uuid=${uuid_gpt_boot};" \ + "name=logo,size=2M,uuid=" LOGO_UUID \ "name=cache,size=256M,uuid=" CACHE_UUID \ "name=system,size=1536M,uuid=" SYSTEM_UUID \ "name=vendor,size=256M,uuid=" VENDOR_UUID \ @@ -113,12 +115,22 @@ func(RECOVERY, recovery, na) \ func(SYSTEM, system, na) \ +#define PREBOOT_LOAD_LOGO \ + "mmc dev ${mmcdev};" \ + "part start mmc ${mmcdev} ${logopart} boot_start;" \ + "part size mmc ${mmcdev} ${logopart} boot_size;" \ + "if mmc read ${loadaddr} ${boot_start} ${boot_size}; then " \ + "bmp display ${loadaddr} m m;" \ + "fi;" + #define CONFIG_EXTRA_ENV_SETTINGS \ "partitions=" PARTS_DEFAULT "\0" \ "mmcdev=2\0" \ "bootpart=1\0" \ + "logopart=2\0" \ "gpio_recovery=88\0" \ "check_button=gpio input ${gpio_recovery};test $? -eq 0;\0" \ + "load_logo=" PREBOOT_LOAD_LOGO "\0" \ "console=/dev/ttyAML0\0" \ "bootargs=no_console_suspend\0" \ "stdin=" STDIN_CFG "\0" \ -- 2.22.0 ^ permalink raw reply related [flat|nested] 19+ messages in thread
* [U-Boot] [PATCH 8/8] configs: sei510: enable Video Display support 2019-08-30 12:09 ` [U-Boot] [PATCH 8/8] configs: sei510: enable Video Display support Neil Armstrong @ 2019-10-10 18:28 ` Anatolij Gustschin 0 siblings, 0 replies; 19+ messages in thread From: Anatolij Gustschin @ 2019-10-10 18:28 UTC (permalink / raw) To: u-boot On Fri, 30 Aug 2019 14:09:28 +0200 Neil Armstrong narmstrong at baylibre.com wrote: > Add the necessary config options to support BMP display over HDMI, > and add a preboot command to load the BMP file from a predefined > eMMC partition. > > Signed-off-by: Neil Armstrong <narmstrong@baylibre.com> Reviewed-by: Anatolij Gustschin <agust@denx.de> -- Anatolij ^ permalink raw reply [flat|nested] 19+ messages in thread
* [U-Boot] [PATCH 0/8] arm: meson: add Video support for G12A and SEI510 board 2019-08-30 12:09 [U-Boot] [PATCH 0/8] arm: meson: add Video support for G12A and SEI510 board Neil Armstrong ` (7 preceding siblings ...) 2019-08-30 12:09 ` [U-Boot] [PATCH 8/8] configs: sei510: enable Video Display support Neil Armstrong @ 2019-10-11 12:57 ` Neil Armstrong 8 siblings, 0 replies; 19+ messages in thread From: Neil Armstrong @ 2019-10-11 12:57 UTC (permalink / raw) To: u-boot On 30/08/2019 14:09, Neil Armstrong wrote: > This patchset adds Amlogic G12A support for HDMI & Composite video output like > the Amlogic GXBB/GXL/GXM, by syncing from the latest Linux VPU DRM driver. > > It also adds VPU/VAPB/HDMI Clock & VPU Power Domain support. > > Finally it adds the necessary config to show a logo from a fastboot flashed > partition on the SEI510 board. > > U200 and Odroid-N2 config support will be added later. > > Neil Armstrong (8): > power: domain: meson-gx-pwrc: add G12A support > clk: meson: g12a: add support for VPU/HDMI clocks > video: meson: remove power domain get > video: meson: sync with linux drm-misc tree > video: meson: add compatible for Amlogic G12A > arm: meson: board-g12a: Setup VPU in fdt > ARM: dts: meson-g12a: add U-Boot specific DT for graphics > configs: sei510: enable Video Display support > > arch/arm/dts/meson-g12a-sei510-u-boot.dtsi | 7 + > arch/arm/dts/meson-g12a-u-boot.dtsi | 29 + > arch/arm/dts/meson-g12a-u200-u-boot.dtsi | 7 + > arch/arm/dts/meson-g12b-odroid-n2-u-boot.dtsi | 7 + > arch/arm/mach-meson/board-g12a.c | 5 + > configs/sei510_defconfig | 11 + > drivers/clk/meson/g12a.c | 620 +++++++++++++++++- > drivers/power/domain/meson-gx-pwrc-vpu.c | 155 ++++- > drivers/video/meson/meson_dw_hdmi.c | 61 +- > drivers/video/meson/meson_plane.c | 47 +- > drivers/video/meson/meson_registers.h | 373 ++++++++++- > drivers/video/meson/meson_vclk.c | 233 +++++-- > drivers/video/meson/meson_venc.c | 169 ++++- > drivers/video/meson/meson_vpu.c | 11 +- > drivers/video/meson/meson_vpu.h | 2 + > drivers/video/meson/meson_vpu_init.c | 205 ++++-- > include/configs/sei510.h | 12 + > 17 files changed, 1757 insertions(+), 197 deletions(-) > create mode 100644 arch/arm/dts/meson-g12a-sei510-u-boot.dtsi > create mode 100644 arch/arm/dts/meson-g12a-u-boot.dtsi > create mode 100644 arch/arm/dts/meson-g12a-u200-u-boot.dtsi > create mode 100644 arch/arm/dts/meson-g12b-odroid-n2-u-boot.dtsi > Applied to u-boot-amlogic ! ^ permalink raw reply [flat|nested] 19+ messages in thread
end of thread, other threads:[~2019-10-11 12:57 UTC | newest] Thread overview: 19+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2019-08-30 12:09 [U-Boot] [PATCH 0/8] arm: meson: add Video support for G12A and SEI510 board Neil Armstrong 2019-08-30 12:09 ` [U-Boot] [PATCH 1/8] power: domain: meson-gx-pwrc: add G12A support Neil Armstrong 2019-10-10 18:15 ` Anatolij Gustschin 2019-08-30 12:09 ` [U-Boot] [PATCH 2/8] clk: meson: g12a: add support for VPU/HDMI clocks Neil Armstrong 2019-10-10 18:15 ` Anatolij Gustschin 2019-08-30 12:09 ` [U-Boot] [PATCH 3/8] video: meson: remove power domain get Neil Armstrong 2019-10-10 18:15 ` Anatolij Gustschin 2019-08-30 12:09 ` [U-Boot] [PATCH 4/8] video: meson: sync with linux drm-misc tree Neil Armstrong 2019-10-09 15:12 ` Neil Armstrong 2019-10-10 20:48 ` Anatolij Gustschin 2019-08-30 12:09 ` [U-Boot] [PATCH 5/8] video: meson: add compatible for Amlogic G12A Neil Armstrong 2019-10-10 18:22 ` Anatolij Gustschin 2019-08-30 12:09 ` [U-Boot] [PATCH 6/8] arm: meson: board-g12a: Setup VPU in fdt Neil Armstrong 2019-10-10 18:23 ` Anatolij Gustschin 2019-08-30 12:09 ` [U-Boot] [PATCH 7/8] ARM: dts: meson-g12a: add U-Boot specific DT for graphics Neil Armstrong 2019-10-10 18:25 ` Anatolij Gustschin 2019-08-30 12:09 ` [U-Boot] [PATCH 8/8] configs: sei510: enable Video Display support Neil Armstrong 2019-10-10 18:28 ` Anatolij Gustschin 2019-10-11 12:57 ` [U-Boot] [PATCH 0/8] arm: meson: add Video support for G12A and SEI510 board Neil Armstrong
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox