mirror of
https://github.com/Fishwaldo/build.git
synced 2025-07-23 05:18:55 +00:00
Adapted rk322x-dev to kernel 5.8.y Added ssv6x5x driver to legacy kernel, rk322x-config now allows the user to select which driver load at boot Added esp8089 kernel module, device tree overlay and detection in rk322x-config script Fixed some indentation Added reset button binding Added sdcard debounce Fixes indentation, added device tree overlay for high-leakage cpus Added support for bluetooth device tree overlay and realtek systemd service for rk322x targets
1825 lines
64 KiB
Text
1825 lines
64 KiB
Text
diff --git a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c
|
|
index 9ca20c947283..b0ac1d3ee390 100644
|
|
--- a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c
|
|
+++ b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c
|
|
@@ -790,8 +790,8 @@ static int inno_hdmi_phy_rk3328_clk_set_rate(struct clk_hw *hw,
|
|
RK3328_PRE_PLL_POWER_DOWN);
|
|
|
|
/* Configure pre-pll */
|
|
- inno_update_bits(inno, 0xa0, RK3228_PCLK_VCO_DIV_5_MASK,
|
|
- RK3228_PCLK_VCO_DIV_5(cfg->vco_div_5_en));
|
|
+ inno_update_bits(inno, 0xa0, RK3328_PCLK_VCO_DIV_5_MASK,
|
|
+ RK3328_PCLK_VCO_DIV_5(cfg->vco_div_5_en));
|
|
inno_write(inno, 0xa1, RK3328_PRE_PLL_PRE_DIV(cfg->prediv));
|
|
|
|
val = RK3328_SPREAD_SPECTRUM_MOD_DISABLE;
|
|
--
|
|
2.17.1
|
|
|
|
|
|
From 0ae81f8167f59ad2c781dc51f2b2fa3e0c9f976b Mon Sep 17 00:00:00 2001
|
|
From: Jonas Karlman <jonas@kwiboo.se>
|
|
Date: Fri, 20 Dec 2019 08:12:42 +0000
|
|
Subject: [PATCH] phy/rockchip: inno-hdmi: round fractal pixclock in rk3328
|
|
recalc_rate
|
|
|
|
inno_hdmi_phy_rk3328_clk_recalc_rate() is returning a rate not found
|
|
in the pre pll config table when the fractal divider is used.
|
|
This can prevent proper power_on because a tmdsclock for the new rate
|
|
is not found in the pre pll config table.
|
|
|
|
Fix this by saving and returning a rounded pixel rate that exist
|
|
in the pre pll config table.
|
|
|
|
Fixes: 53706a116863 ("phy: add Rockchip Innosilicon hdmi phy")
|
|
Signed-off-by: Zheng Yang <zhengyang@rock-chips.com>
|
|
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
|
|
---
|
|
drivers/phy/rockchip/phy-rockchip-inno-hdmi.c | 8 +++++---
|
|
1 file changed, 5 insertions(+), 3 deletions(-)
|
|
|
|
diff --git a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c
|
|
index b0ac1d3ee390..093d2334e8cd 100644
|
|
--- a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c
|
|
+++ b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c
|
|
@@ -745,10 +745,12 @@ unsigned long inno_hdmi_phy_rk3328_clk_recalc_rate(struct clk_hw *hw,
|
|
do_div(vco, (nd * (no_a == 1 ? no_b : no_a) * no_d * 2));
|
|
}
|
|
|
|
- inno->pixclock = vco;
|
|
- dev_dbg(inno->dev, "%s rate %lu\n", __func__, inno->pixclock);
|
|
+ inno->pixclock = DIV_ROUND_CLOSEST((unsigned long)vco, 1000) * 1000;
|
|
|
|
- return vco;
|
|
+ dev_dbg(inno->dev, "%s rate %lu vco %llu\n",
|
|
+ __func__, inno->pixclock, vco);
|
|
+
|
|
+ return inno->pixclock;
|
|
}
|
|
|
|
static long inno_hdmi_phy_rk3328_clk_round_rate(struct clk_hw *hw,
|
|
--
|
|
2.17.1
|
|
|
|
|
|
From fcb6a75bac484bec5443241965757b2d7cf99182 Mon Sep 17 00:00:00 2001
|
|
From: Jonas Karlman <jonas@kwiboo.se>
|
|
Date: Fri, 20 Dec 2019 08:12:42 +0000
|
|
Subject: [PATCH] phy/rockchip: inno-hdmi: remove unused no_c from rk3328
|
|
recalc_rate
|
|
|
|
no_c is not used in any calculation, lets remove it.
|
|
|
|
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
|
|
---
|
|
drivers/phy/rockchip/phy-rockchip-inno-hdmi.c | 5 +----
|
|
1 file changed, 1 insertion(+), 4 deletions(-)
|
|
|
|
diff --git a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c
|
|
index 093d2334e8cd..06db69c8373e 100644
|
|
--- a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c
|
|
+++ b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c
|
|
@@ -714,7 +714,7 @@ unsigned long inno_hdmi_phy_rk3328_clk_recalc_rate(struct clk_hw *hw,
|
|
{
|
|
struct inno_hdmi_phy *inno = to_inno_hdmi_phy(hw);
|
|
unsigned long frac;
|
|
- u8 nd, no_a, no_b, no_c, no_d;
|
|
+ u8 nd, no_a, no_b, no_d;
|
|
u64 vco;
|
|
u16 nf;
|
|
|
|
@@ -737,9 +737,6 @@ unsigned long inno_hdmi_phy_rk3328_clk_recalc_rate(struct clk_hw *hw,
|
|
no_b = inno_read(inno, 0xa5) & RK3328_PRE_PLL_PCLK_DIV_B_MASK;
|
|
no_b >>= RK3328_PRE_PLL_PCLK_DIV_B_SHIFT;
|
|
no_b += 2;
|
|
- no_c = inno_read(inno, 0xa6) & RK3328_PRE_PLL_PCLK_DIV_C_MASK;
|
|
- no_c >>= RK3328_PRE_PLL_PCLK_DIV_C_SHIFT;
|
|
- no_c = 1 << no_c;
|
|
no_d = inno_read(inno, 0xa6) & RK3328_PRE_PLL_PCLK_DIV_D_MASK;
|
|
|
|
do_div(vco, (nd * (no_a == 1 ? no_b : no_a) * no_d * 2));
|
|
--
|
|
2.17.1
|
|
|
|
|
|
From 8da78b0cf0c522be59656ed24a0018bd2fbea5a8 Mon Sep 17 00:00:00 2001
|
|
From: Jonas Karlman <jonas@kwiboo.se>
|
|
Date: Fri, 20 Dec 2019 08:12:42 +0000
|
|
Subject: [PATCH] phy/rockchip: inno-hdmi: do not power on rk3328 post pll on
|
|
reg write
|
|
|
|
inno_write is used to configure 0xaa reg, that also hold the
|
|
POST_PLL_POWER_DOWN bit.
|
|
When POST_PLL_REFCLK_SEL_TMDS is configured the power down bit is not
|
|
taken into consideration.
|
|
|
|
Fix this by keeping the power down bit until configuration is complete.
|
|
Also reorder the reg write order for consistency.
|
|
|
|
Fixes: 53706a116863 ("phy: add Rockchip Innosilicon hdmi phy")
|
|
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
|
|
---
|
|
drivers/phy/rockchip/phy-rockchip-inno-hdmi.c | 6 ++++--
|
|
1 file changed, 4 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c
|
|
index 06db69c8373e..3a59a6da0440 100644
|
|
--- a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c
|
|
+++ b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c
|
|
@@ -1020,9 +1020,10 @@ inno_hdmi_phy_rk3328_power_on(struct inno_hdmi_phy *inno,
|
|
|
|
inno_write(inno, 0xac, RK3328_POST_PLL_FB_DIV_7_0(cfg->fbdiv));
|
|
if (cfg->postdiv == 1) {
|
|
- inno_write(inno, 0xaa, RK3328_POST_PLL_REFCLK_SEL_TMDS);
|
|
inno_write(inno, 0xab, RK3328_POST_PLL_FB_DIV_8(cfg->fbdiv) |
|
|
RK3328_POST_PLL_PRE_DIV(cfg->prediv));
|
|
+ inno_write(inno, 0xaa, RK3328_POST_PLL_REFCLK_SEL_TMDS |
|
|
+ RK3328_POST_PLL_POWER_DOWN);
|
|
} else {
|
|
v = (cfg->postdiv / 2) - 1;
|
|
v &= RK3328_POST_PLL_POST_DIV_MASK;
|
|
@@ -1030,7 +1031,8 @@ inno_hdmi_phy_rk3328_power_on(struct inno_hdmi_phy *inno,
|
|
inno_write(inno, 0xab, RK3328_POST_PLL_FB_DIV_8(cfg->fbdiv) |
|
|
RK3328_POST_PLL_PRE_DIV(cfg->prediv));
|
|
inno_write(inno, 0xaa, RK3328_POST_PLL_POST_DIV_ENABLE |
|
|
- RK3328_POST_PLL_REFCLK_SEL_TMDS);
|
|
+ RK3328_POST_PLL_REFCLK_SEL_TMDS |
|
|
+ RK3328_POST_PLL_POWER_DOWN);
|
|
}
|
|
|
|
for (v = 0; v < 14; v++)
|
|
--
|
|
2.17.1
|
|
|
|
|
|
From 790af1279068ad1cc4ef471d90050570a850f426 Mon Sep 17 00:00:00 2001
|
|
From: Jonas Karlman <jonas@kwiboo.se>
|
|
Date: Fri, 20 Dec 2019 08:12:42 +0000
|
|
Subject: [PATCH] phy/rockchip: inno-hdmi: force set_rate on power_on
|
|
|
|
Regular 8-bit and Deep Color video formats mainly differ in TMDS rate and
|
|
not in pixel clock rate.
|
|
When the hdmiphy clock is configured with the same pixel clock rate using
|
|
clk_set_rate() the clock framework do not signal the hdmi phy driver
|
|
to set_rate when switching between 8-bit and Deep Color.
|
|
This result in pre/post pll not being re-configured when switching between
|
|
regular 8-bit and Deep Color video formats.
|
|
|
|
Fix this by calling set_rate in power_on to force pre pll re-configuration.
|
|
|
|
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
|
|
---
|
|
drivers/phy/rockchip/phy-rockchip-inno-hdmi.c | 13 +++++++++++++
|
|
1 file changed, 13 insertions(+)
|
|
|
|
diff --git a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c
|
|
index 3a59a6da0440..3719309ad0d0 100644
|
|
--- a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c
|
|
+++ b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c
|
|
@@ -245,6 +245,7 @@ struct inno_hdmi_phy {
|
|
struct clk_hw hw;
|
|
struct clk *phyclk;
|
|
unsigned long pixclock;
|
|
+ unsigned long tmdsclock;
|
|
};
|
|
|
|
struct pre_pll_config {
|
|
@@ -485,6 +486,8 @@ static int inno_hdmi_phy_power_on(struct phy *phy)
|
|
|
|
dev_dbg(inno->dev, "Inno HDMI PHY Power On\n");
|
|
|
|
+ inno->plat_data->clk_ops->set_rate(&inno->hw, inno->pixclock, 24000000);
|
|
+
|
|
ret = clk_prepare_enable(inno->phyclk);
|
|
if (ret)
|
|
return ret;
|
|
@@ -509,6 +512,8 @@ static int inno_hdmi_phy_power_off(struct phy *phy)
|
|
|
|
clk_disable_unprepare(inno->phyclk);
|
|
|
|
+ inno->tmdsclock = 0;
|
|
+
|
|
dev_dbg(inno->dev, "Inno HDMI PHY Power Off\n");
|
|
|
|
return 0;
|
|
@@ -628,6 +633,9 @@ static int inno_hdmi_phy_rk3228_clk_set_rate(struct clk_hw *hw,
|
|
dev_dbg(inno->dev, "%s rate %lu tmdsclk %lu\n",
|
|
__func__, rate, tmdsclock);
|
|
|
|
+ if (inno->pixclock == rate && inno->tmdsclock == tmdsclock)
|
|
+ return 0;
|
|
+
|
|
cfg = inno_hdmi_phy_get_pre_pll_cfg(inno, rate);
|
|
if (IS_ERR(cfg))
|
|
return PTR_ERR(cfg);
|
|
@@ -670,6 +678,7 @@ static int inno_hdmi_phy_rk3228_clk_set_rate(struct clk_hw *hw,
|
|
}
|
|
|
|
inno->pixclock = rate;
|
|
+ inno->tmdsclock = tmdsclock;
|
|
|
|
return 0;
|
|
}
|
|
@@ -781,6 +790,9 @@ static int inno_hdmi_phy_rk3328_clk_set_rate(struct clk_hw *hw,
|
|
dev_dbg(inno->dev, "%s rate %lu tmdsclk %lu\n",
|
|
__func__, rate, tmdsclock);
|
|
|
|
+ if (inno->pixclock == rate && inno->tmdsclock == tmdsclock)
|
|
+ return 0;
|
|
+
|
|
cfg = inno_hdmi_phy_get_pre_pll_cfg(inno, rate);
|
|
if (IS_ERR(cfg))
|
|
return PTR_ERR(cfg);
|
|
@@ -820,6 +832,7 @@ static int inno_hdmi_phy_rk3328_clk_set_rate(struct clk_hw *hw,
|
|
}
|
|
|
|
inno->pixclock = rate;
|
|
+ inno->tmdsclock = tmdsclock;
|
|
|
|
return 0;
|
|
}
|
|
--
|
|
2.17.1
|
|
|
|
|
|
From 852eb17bca3ae36762eb2975bb9a5642cf0865d8 Mon Sep 17 00:00:00 2001
|
|
From: Jonas Karlman <jonas@kwiboo.se>
|
|
Date: Sat, 21 Dec 2019 23:52:16 +0000
|
|
Subject: [PATCH] drm/rockchip: vop: limit resolution width to 3840
|
|
|
|
Using a destination width that is more then 3840 pixels
|
|
is not supported in scl_vop_cal_scl_fac().
|
|
|
|
Work around this limitation by filtering all modes with
|
|
a width above 3840.
|
|
|
|
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
|
|
---
|
|
drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 10 ++++++++++
|
|
1 file changed, 10 insertions(+)
|
|
|
|
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
|
|
index d04b3492bdac..f181897cbfad 100644
|
|
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
|
|
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
|
|
@@ -1036,6 +1036,15 @@ static void vop_crtc_disable_vblank(struct drm_crtc *crtc)
|
|
spin_unlock_irqrestore(&vop->irq_lock, flags);
|
|
}
|
|
|
|
+enum drm_mode_status vop_crtc_mode_valid(struct drm_crtc *crtc,
|
|
+ const struct drm_display_mode *mode)
|
|
+{
|
|
+ if (mode->hdisplay > 3840)
|
|
+ return MODE_BAD_HVALUE;
|
|
+
|
|
+ return MODE_OK;
|
|
+}
|
|
+
|
|
static bool vop_crtc_mode_fixup(struct drm_crtc *crtc,
|
|
const struct drm_display_mode *mode,
|
|
struct drm_display_mode *adjusted_mode)
|
|
@@ -1377,6 +1386,7 @@ static void vop_crtc_atomic_flush(struct drm_crtc *crtc,
|
|
}
|
|
|
|
static const struct drm_crtc_helper_funcs vop_crtc_helper_funcs = {
|
|
+ .mode_valid = vop_crtc_mode_valid,
|
|
.mode_fixup = vop_crtc_mode_fixup,
|
|
.atomic_check = vop_crtc_atomic_check,
|
|
.atomic_begin = vop_crtc_atomic_begin,
|
|
--
|
|
2.17.1
|
|
|
|
|
|
From 1f18ed83f51df960be0688db39b086b9a58ef7d1 Mon Sep 17 00:00:00 2001
|
|
From: Jonas Karlman <jonas@kwiboo.se>
|
|
Date: Sun, 22 Dec 2019 12:43:36 +0000
|
|
Subject: [PATCH] drm/rockchip: dw-hdmi: allow high tmds bit rates
|
|
|
|
Prepare support for High TMDS Bit Rates used by HDMI2.0 display modes.
|
|
|
|
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
|
|
---
|
|
drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 2 ++
|
|
1 file changed, 2 insertions(+)
|
|
|
|
diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
|
|
index 7f56d8c3491d..fae38b323a0c 100644
|
|
--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
|
|
+++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
|
|
@@ -318,6 +318,8 @@ static int dw_hdmi_rockchip_genphy_init(struct dw_hdmi *dw_hdmi, void *data,
|
|
{
|
|
struct rockchip_hdmi *hdmi = (struct rockchip_hdmi *)data;
|
|
|
|
+ dw_hdmi_set_high_tmds_clock_ratio(dw_hdmi);
|
|
+
|
|
return phy_power_on(hdmi->phy);
|
|
}
|
|
|
|
--
|
|
2.17.1
|
|
|
|
|
|
From d8ee714e54380f7b09dd088944f5c030aa1ee320 Mon Sep 17 00:00:00 2001
|
|
From: Jonas Karlman <jonas@kwiboo.se>
|
|
Date: Sun, 22 Dec 2019 12:35:16 +0000
|
|
Subject: [PATCH] drm/rockchip: dw-hdmi: require valid vpll clock rate on
|
|
rk3228/rk3328
|
|
|
|
RK3228/RK3328 can only support clock rates defined in the pre pll table.
|
|
Lets validate the mode clock rate against the pre pll config and filter
|
|
out any mode with a clock rate returning error from clk_round_rate().
|
|
|
|
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
|
|
---
|
|
drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 17 +++++++++++++++++
|
|
1 file changed, 17 insertions(+)
|
|
|
|
diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
|
|
index fae38b323a0c..45fcdce3f27f 100644
|
|
--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
|
|
+++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
|
|
@@ -245,6 +245,22 @@ static void dw_hdmi_rockchip_encoder_disable(struct drm_encoder *encoder)
|
|
{
|
|
}
|
|
|
|
+static enum drm_mode_status
|
|
+dw_hdmi_rockchip_encoder_mode_valid(struct drm_encoder *encoder,
|
|
+ const struct drm_display_mode *mode)
|
|
+{
|
|
+ struct rockchip_hdmi *hdmi = to_rockchip_hdmi(encoder);
|
|
+ long rate;
|
|
+
|
|
+ if (hdmi->vpll_clk) {
|
|
+ rate = clk_round_rate(hdmi->vpll_clk, mode->clock * 1000);
|
|
+ if (rate < 0)
|
|
+ return MODE_CLOCK_RANGE;
|
|
+ }
|
|
+
|
|
+ return MODE_OK;
|
|
+}
|
|
+
|
|
static bool
|
|
dw_hdmi_rockchip_encoder_mode_fixup(struct drm_encoder *encoder,
|
|
const struct drm_display_mode *mode,
|
|
@@ -306,6 +322,7 @@ dw_hdmi_rockchip_encoder_atomic_check(struct drm_encoder *encoder,
|
|
}
|
|
|
|
static const struct drm_encoder_helper_funcs dw_hdmi_rockchip_encoder_helper_funcs = {
|
|
+ .mode_valid = dw_hdmi_rockchip_encoder_mode_valid,
|
|
.mode_fixup = dw_hdmi_rockchip_encoder_mode_fixup,
|
|
.mode_set = dw_hdmi_rockchip_encoder_mode_set,
|
|
.enable = dw_hdmi_rockchip_encoder_enable,
|
|
--
|
|
2.17.1
|
|
|
|
|
|
From f305ae2094370127c797a4af3772bd9ff4e8dfc2 Mon Sep 17 00:00:00 2001
|
|
From: Jonas Karlman <jonas@kwiboo.se>
|
|
Date: Sun, 22 Dec 2019 23:42:45 +0000
|
|
Subject: [PATCH] clk: rockchip: set parent rate for DCLK_VOP clock on rk3228
|
|
|
|
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
|
|
---
|
|
drivers/clk/rockchip/clk-rk3228.c | 2 +-
|
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
|
|
diff --git a/drivers/clk/rockchip/clk-rk3228.c b/drivers/clk/rockchip/clk-rk3228.c
|
|
index d17cfb7a3ff4..25f79af22cb8 100644
|
|
--- a/drivers/clk/rockchip/clk-rk3228.c
|
|
+++ b/drivers/clk/rockchip/clk-rk3228.c
|
|
@@ -410,7 +410,7 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = {
|
|
RK2928_CLKSEL_CON(29), 0, 3, DFLAGS),
|
|
DIV(0, "sclk_vop_pre", "sclk_vop_src", 0,
|
|
RK2928_CLKSEL_CON(27), 8, 8, DFLAGS),
|
|
- MUX(DCLK_VOP, "dclk_vop", mux_dclk_vop_p, 0,
|
|
+ MUX(DCLK_VOP, "dclk_vop", mux_dclk_vop_p, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
|
|
RK2928_CLKSEL_CON(27), 1, 1, MFLAGS),
|
|
|
|
FACTOR(0, "xin12m", "xin24m", 0, 1, 2),
|
|
--
|
|
2.17.1
|
|
|
|
|
|
From 69f1bbcbc9c02c34f4fda49191ccae1f9dac410e Mon Sep 17 00:00:00 2001
|
|
From: Jonas Karlman <jonas@kwiboo.se>
|
|
Date: Sun, 15 Dec 2019 10:05:46 +0000
|
|
Subject: [PATCH] arm64: dts: rockchip: increase vop clock rate on rk3328
|
|
|
|
The VOP on RK3328 needs to run faster in order to procude a proper
|
|
3840x2160 signal.
|
|
|
|
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
|
|
---
|
|
arch/arm64/boot/dts/rockchip/rk3328.dtsi | 4 ++--
|
|
1 file changed, 2 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
|
|
index bc9186f66d9c..d4cfb1066c5a 100644
|
|
--- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi
|
|
+++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
|
|
@@ -834,8 +834,8 @@
|
|
<0>, <24000000>,
|
|
<24000000>, <24000000>,
|
|
<15000000>, <15000000>,
|
|
- <100000000>, <100000000>,
|
|
- <100000000>, <100000000>,
|
|
+ <300000000>, <100000000>,
|
|
+ <400000000>, <100000000>,
|
|
<50000000>, <100000000>,
|
|
<100000000>, <100000000>,
|
|
<50000000>, <50000000>,
|
|
--
|
|
2.17.1
|
|
|
|
|
|
From 2aeb955b7a259182df7c2244531abd4bf233f60b Mon Sep 17 00:00:00 2001
|
|
From: Jonas Karlman <jonas@kwiboo.se>
|
|
Date: Sun, 22 Dec 2019 23:43:40 +0000
|
|
Subject: [PATCH] arm64: dts: rockchip: add vpll clock to hdmi node on rk3328
|
|
|
|
Add the hdmiphy clock as the vpll in hdmi node.
|
|
|
|
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
|
|
---
|
|
arch/arm64/boot/dts/rockchip/rk3328.dtsi | 2 ++
|
|
1 file changed, 2 insertions(+)
|
|
|
|
diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
|
|
index d4cfb1066c5a..991d2a830887 100644
|
|
--- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi
|
|
+++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
|
|
@@ -750,9 +750,11 @@
|
|
<GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
|
|
clocks = <&cru PCLK_HDMI>,
|
|
<&cru SCLK_HDMI_SFC>,
|
|
+ <&hdmiphy>,
|
|
<&cru SCLK_RTC32K>;
|
|
clock-names = "iahb",
|
|
"isfr",
|
|
+ "vpll",
|
|
"cec";
|
|
phys = <&hdmiphy>;
|
|
phy-names = "hdmi";
|
|
--
|
|
2.17.1
|
|
|
|
|
|
From a972a8f4fbc0db4c71fcf2d7eb1c1dcc31a8d089 Mon Sep 17 00:00:00 2001
|
|
From: Jonas Karlman <jonas@kwiboo.se>
|
|
Date: Sun, 22 Dec 2019 23:43:58 +0000
|
|
Subject: [PATCH] ARM: dts: rockchip: add vpll clock to hdmi node on rk3228
|
|
|
|
Add the hdmiphy clock as the vpll in hdmi node.
|
|
|
|
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
|
|
---
|
|
arch/arm/boot/dts/rk322x.dtsi | 4 ++--
|
|
1 file changed, 2 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/arch/arm/boot/dts/rk322x.dtsi b/arch/arm/boot/dts/rk322x.dtsi
|
|
index 4e90efdc9630..1e31f6898797 100644
|
|
--- a/arch/arm/boot/dts/rk322x.dtsi
|
|
+++ b/arch/arm/boot/dts/rk322x.dtsi
|
|
@@ -639,8 +639,8 @@
|
|
interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
|
|
assigned-clocks = <&cru SCLK_HDMI_PHY>;
|
|
assigned-clock-parents = <&hdmi_phy>;
|
|
- clocks = <&cru SCLK_HDMI_HDCP>, <&cru PCLK_HDMI_CTRL>, <&cru SCLK_HDMI_CEC>;
|
|
- clock-names = "isfr", "iahb", "cec";
|
|
+ clocks = <&cru SCLK_HDMI_HDCP>, <&cru PCLK_HDMI_CTRL>, <&hdmi_phy>, <&cru SCLK_HDMI_CEC>;
|
|
+ clock-names = "isfr", "iahb", "vpll", "cec";
|
|
pinctrl-names = "default";
|
|
pinctrl-0 = <&hdmii2c_xfer &hdmi_hpd &hdmi_cec>;
|
|
resets = <&cru SRST_HDMI_P>;
|
|
--
|
|
2.17.1
|
|
|
|
|
|
From ad13781b15e2a4657e52147461565b99e16dca65 Mon Sep 17 00:00:00 2001
|
|
From: Jonas Karlman <jonas@kwiboo.se>
|
|
Date: Sun, 22 Dec 2019 10:42:02 +0000
|
|
Subject: [PATCH] drm/rockchip: dw-hdmi: limit tmds to 340mhz on rk3228/rk3328
|
|
|
|
RK3228/RK3328 does not provide a stable hdmi signal at TMDS rates
|
|
above 371.25MHz (340MHz pixel clock).
|
|
|
|
Limit the pixel clock rate to 340MHz to provide a stable signal.
|
|
Also limit the pixel clock to the display reported max tmds clock.
|
|
|
|
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
|
|
---
|
|
drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 22 +++++++++++++++++++--
|
|
1 file changed, 20 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
|
|
index 45fcdce3f27f..66c14df4a680 100644
|
|
--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
|
|
+++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
|
|
@@ -237,6 +237,24 @@ dw_hdmi_rockchip_mode_valid(struct drm_connector *connector,
|
|
return (valid) ? MODE_OK : MODE_BAD;
|
|
}
|
|
|
|
+static enum drm_mode_status
|
|
+dw_hdmi_rk3228_mode_valid(struct drm_connector *connector,
|
|
+ const struct drm_display_mode *mode)
|
|
+{
|
|
+ struct drm_display_info *info = &connector->display_info;
|
|
+ int max_tmds_clock = max(info->max_tmds_clock, 165000);
|
|
+ int clock = mode->clock;
|
|
+
|
|
+ if (connector->ycbcr_420_allowed && drm_mode_is_420(info, mode) &&
|
|
+ (info->color_formats & DRM_COLOR_FORMAT_YCRCB420))
|
|
+ clock /= 2;
|
|
+
|
|
+ if (clock > max_tmds_clock || clock > 340000)
|
|
+ return MODE_CLOCK_HIGH;
|
|
+
|
|
+ return MODE_OK;
|
|
+}
|
|
+
|
|
static const struct drm_encoder_funcs dw_hdmi_rockchip_encoder_funcs = {
|
|
.destroy = drm_encoder_cleanup,
|
|
};
|
|
@@ -424,7 +442,7 @@ static struct rockchip_hdmi_chip_data rk3228_chip_data = {
|
|
};
|
|
|
|
static const struct dw_hdmi_plat_data rk3228_hdmi_drv_data = {
|
|
- .mode_valid = dw_hdmi_rockchip_mode_valid,
|
|
+ .mode_valid = dw_hdmi_rk3228_mode_valid,
|
|
.mpll_cfg = rockchip_mpll_cfg,
|
|
.cur_ctr = rockchip_cur_ctr,
|
|
.phy_config = rockchip_phy_config,
|
|
@@ -461,7 +479,7 @@ static struct rockchip_hdmi_chip_data rk3328_chip_data = {
|
|
};
|
|
|
|
static const struct dw_hdmi_plat_data rk3328_hdmi_drv_data = {
|
|
- .mode_valid = dw_hdmi_rockchip_mode_valid,
|
|
+ .mode_valid = dw_hdmi_rk3228_mode_valid,
|
|
.mpll_cfg = rockchip_mpll_cfg,
|
|
.cur_ctr = rockchip_cur_ctr,
|
|
.phy_config = rockchip_phy_config,
|
|
--
|
|
2.17.1
|
|
|
|
|
|
From 8e950f0d07a1cea3ad58bd654c91a747d2902c6c Mon Sep 17 00:00:00 2001
|
|
From: Jonas Karlman <jonas@kwiboo.se>
|
|
Date: Sun, 22 Dec 2019 10:42:27 +0000
|
|
Subject: [PATCH] drm/rockchip: dw-hdmi: remove unused plat_data on
|
|
rk3228/rk3328
|
|
|
|
mpll_cfg/cur_ctr/phy_config is not used when phy_force_vendor is true,
|
|
lets remove them.
|
|
|
|
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
|
|
---
|
|
drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 6 ------
|
|
1 file changed, 6 deletions(-)
|
|
|
|
diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
|
|
index 66c14df4a680..a813299e97a2 100644
|
|
--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
|
|
+++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
|
|
@@ -443,9 +443,6 @@ static struct rockchip_hdmi_chip_data rk3228_chip_data = {
|
|
|
|
static const struct dw_hdmi_plat_data rk3228_hdmi_drv_data = {
|
|
.mode_valid = dw_hdmi_rk3228_mode_valid,
|
|
- .mpll_cfg = rockchip_mpll_cfg,
|
|
- .cur_ctr = rockchip_cur_ctr,
|
|
- .phy_config = rockchip_phy_config,
|
|
.phy_data = &rk3228_chip_data,
|
|
.phy_ops = &rk3228_hdmi_phy_ops,
|
|
.phy_name = "inno_dw_hdmi_phy2",
|
|
@@ -480,9 +477,6 @@ static struct rockchip_hdmi_chip_data rk3328_chip_data = {
|
|
|
|
static const struct dw_hdmi_plat_data rk3328_hdmi_drv_data = {
|
|
.mode_valid = dw_hdmi_rk3228_mode_valid,
|
|
- .mpll_cfg = rockchip_mpll_cfg,
|
|
- .cur_ctr = rockchip_cur_ctr,
|
|
- .phy_config = rockchip_phy_config,
|
|
.phy_data = &rk3328_chip_data,
|
|
.phy_ops = &rk3328_hdmi_phy_ops,
|
|
.phy_name = "inno_dw_hdmi_phy2",
|
|
--
|
|
2.17.1
|
|
|
|
|
|
From 34326d29065869cc262b2f1644310ec9417dac29 Mon Sep 17 00:00:00 2001
|
|
From: Algea Cao <algea.cao@rock-chips.com>
|
|
Date: Fri, 18 May 2018 14:32:08 +0800
|
|
Subject: [PATCH] phy/rockchip: inno-hdmi: Support more pre-pll configuration
|
|
|
|
Adding the following freq cfg in 8-bit and 10-bit color depth:
|
|
|
|
{
|
|
40000000, 65000000, 71000000, 83500000, 85750000,
|
|
88750000, 108000000, 119000000, 162000000
|
|
}
|
|
|
|
New freq has been validated by quantumdata 980.
|
|
|
|
For some freq which can't be got by only using integer freq div,
|
|
frac freq div is needed, Such as 88.75Mhz 10-bit. But The actual
|
|
freq is different from the target freq, We must try to narrow
|
|
the gap between them. RK322X only support integer freq div.
|
|
|
|
The VCO of pre-PLL must be more than 2Ghz, otherwise PLL may be
|
|
unlocked.
|
|
|
|
Signed-off-by: Algea Cao <algea.cao@rock-chips.com>
|
|
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
|
|
---
|
|
drivers/phy/rockchip/phy-rockchip-inno-hdmi.c | 74 ++++++++++++-------
|
|
1 file changed, 49 insertions(+), 25 deletions(-)
|
|
|
|
diff --git a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c
|
|
index 3719309ad0d0..bb8bdf5e3301 100644
|
|
--- a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c
|
|
+++ b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c
|
|
@@ -291,32 +291,56 @@ struct inno_hdmi_phy_drv_data {
|
|
const struct phy_config *phy_cfg_table;
|
|
};
|
|
|
|
+/*
|
|
+ * If only using integer freq div can't get frequency we want, frac
|
|
+ * freq div is needed. For example, pclk 88.75 Mhz and tmdsclk
|
|
+ * 110.9375 Mhz must use frac div 0xF00000. The actual frequency is different
|
|
+ * from the target frequency. Such as the tmds clock 110.9375 Mhz,
|
|
+ * the actual tmds clock we get is 110.93719 Mhz. It is important
|
|
+ * to note that RK322X platforms do not support frac div.
|
|
+ */
|
|
static const struct pre_pll_config pre_pll_cfg_table[] = {
|
|
- { 27000000, 27000000, 1, 90, 3, 2, 2, 10, 3, 3, 4, 0, 0},
|
|
- { 27000000, 33750000, 1, 90, 1, 3, 3, 10, 3, 3, 4, 0, 0},
|
|
- { 40000000, 40000000, 1, 80, 2, 2, 2, 12, 2, 2, 2, 0, 0},
|
|
- { 59341000, 59341000, 1, 98, 3, 1, 2, 1, 3, 3, 4, 0, 0xE6AE6B},
|
|
- { 59400000, 59400000, 1, 99, 3, 1, 1, 1, 3, 3, 4, 0, 0},
|
|
- { 59341000, 74176250, 1, 98, 0, 3, 3, 1, 3, 3, 4, 0, 0xE6AE6B},
|
|
- { 59400000, 74250000, 1, 99, 1, 2, 2, 1, 3, 3, 4, 0, 0},
|
|
- { 74176000, 74176000, 1, 98, 1, 2, 2, 1, 2, 3, 4, 0, 0xE6AE6B},
|
|
- { 74250000, 74250000, 1, 99, 1, 2, 2, 1, 2, 3, 4, 0, 0},
|
|
- { 74176000, 92720000, 4, 494, 1, 2, 2, 1, 3, 3, 4, 0, 0x816817},
|
|
- { 74250000, 92812500, 4, 495, 1, 2, 2, 1, 3, 3, 4, 0, 0},
|
|
- {148352000, 148352000, 1, 98, 1, 1, 1, 1, 2, 2, 2, 0, 0xE6AE6B},
|
|
- {148500000, 148500000, 1, 99, 1, 1, 1, 1, 2, 2, 2, 0, 0},
|
|
- {148352000, 185440000, 4, 494, 0, 2, 2, 1, 3, 2, 2, 0, 0x816817},
|
|
- {148500000, 185625000, 4, 495, 0, 2, 2, 1, 3, 2, 2, 0, 0},
|
|
- {296703000, 296703000, 1, 98, 0, 1, 1, 1, 0, 2, 2, 0, 0xE6AE6B},
|
|
- {297000000, 297000000, 1, 99, 0, 1, 1, 1, 0, 2, 2, 0, 0},
|
|
- {296703000, 370878750, 4, 494, 1, 2, 0, 1, 3, 1, 1, 0, 0x816817},
|
|
- {297000000, 371250000, 4, 495, 1, 2, 0, 1, 3, 1, 1, 0, 0},
|
|
- {593407000, 296703500, 1, 98, 0, 1, 1, 1, 0, 2, 1, 0, 0xE6AE6B},
|
|
- {594000000, 297000000, 1, 99, 0, 1, 1, 1, 0, 2, 1, 0, 0},
|
|
- {593407000, 370879375, 4, 494, 1, 2, 0, 1, 3, 1, 1, 1, 0x816817},
|
|
- {594000000, 371250000, 4, 495, 1, 2, 0, 1, 3, 1, 1, 1, 0},
|
|
- {593407000, 593407000, 1, 98, 0, 2, 0, 1, 0, 1, 1, 0, 0xE6AE6B},
|
|
- {594000000, 594000000, 1, 99, 0, 2, 0, 1, 0, 1, 1, 0, 0},
|
|
+ { 27000000, 27000000, 1, 90, 3, 2, 2, 10, 3, 3, 4, 0, 0},
|
|
+ { 27000000, 33750000, 1, 90, 1, 3, 3, 10, 3, 3, 4, 0, 0},
|
|
+ { 40000000, 40000000, 1, 80, 2, 2, 2, 12, 2, 2, 2, 0, 0},
|
|
+ { 40000000, 50000000, 1, 100, 2, 2, 2, 1, 0, 0, 15, 0, 0},
|
|
+ { 59341000, 59341000, 1, 98, 3, 1, 2, 1, 3, 3, 4, 0, 0xE6AE6B},
|
|
+ { 59400000, 59400000, 1, 99, 3, 1, 1, 1, 3, 3, 4, 0, 0},
|
|
+ { 59341000, 74176250, 1, 98, 0, 3, 3, 1, 3, 3, 4, 0, 0xE6AE6B},
|
|
+ { 59400000, 74250000, 1, 99, 1, 2, 2, 1, 3, 3, 4, 0, 0},
|
|
+ { 65000000, 65000000, 1, 130, 2, 2, 2, 1, 0, 0, 12, 0, 0},
|
|
+ { 65000000, 81250000, 3, 325, 0, 3, 3, 1, 0, 0, 10, 0, 0},
|
|
+ { 71000000, 71000000, 3, 284, 0, 3, 3, 1, 0, 0, 8, 0, 0},
|
|
+ { 71000000, 88750000, 3, 355, 0, 3, 3, 1, 0, 0, 10, 0, 0},
|
|
+ { 74176000, 74176000, 1, 98, 1, 2, 2, 1, 2, 3, 4, 0, 0xE6AE6B},
|
|
+ { 74250000, 74250000, 1, 99, 1, 2, 2, 1, 2, 3, 4, 0, 0},
|
|
+ { 74176000, 92720000, 4, 494, 1, 2, 2, 1, 3, 3, 4, 0, 0x816817},
|
|
+ { 74250000, 92812500, 4, 495, 1, 2, 2, 1, 3, 3, 4, 0, 0},
|
|
+ { 83500000, 83500000, 2, 167, 2, 1, 1, 1, 0, 0, 6, 0, 0},
|
|
+ { 83500000, 104375000, 1, 104, 2, 1, 1, 1, 1, 0, 5, 0, 0x600000},
|
|
+ { 85750000, 85750000, 3, 343, 0, 3, 3, 1, 0, 0, 8, 0, 0},
|
|
+ { 88750000, 88750000, 3, 355, 0, 3, 3, 1, 0, 0, 8, 0, 0},
|
|
+ { 88750000, 110937500, 1, 110, 2, 1, 1, 1, 1, 0, 5, 0, 0xF00000},
|
|
+ {108000000, 108000000, 1, 90, 3, 0, 0, 1, 0, 0, 5, 0, 0},
|
|
+ {108000000, 135000000, 1, 90, 0, 2, 2, 1, 0, 0, 5, 0, 0},
|
|
+ {119000000, 119000000, 1, 119, 2, 1, 1, 1, 0, 0, 6, 0, 0},
|
|
+ {119000000, 148750000, 1, 99, 0, 2, 2, 1, 0, 0, 5, 0, 0x2AAAAA},
|
|
+ {148352000, 148352000, 1, 98, 1, 1, 1, 1, 2, 2, 2, 0, 0xE6AE6B},
|
|
+ {148500000, 148500000, 1, 99, 1, 1, 1, 1, 2, 2, 2, 0, 0},
|
|
+ {148352000, 185440000, 4, 494, 0, 2, 2, 1, 3, 2, 2, 0, 0x816817},
|
|
+ {148500000, 185625000, 4, 495, 0, 2, 2, 1, 3, 2, 2, 0, 0},
|
|
+ {162000000, 162000000, 1, 108, 0, 2, 2, 1, 0, 0, 4, 0, 0},
|
|
+ {162000000, 202500000, 1, 135, 0, 2, 2, 1, 0, 0, 5, 0, 0},
|
|
+ {296703000, 296703000, 1, 98, 0, 1, 1, 1, 0, 2, 2, 0, 0xE6AE6B},
|
|
+ {297000000, 297000000, 1, 99, 0, 1, 1, 1, 0, 2, 2, 0, 0},
|
|
+ {296703000, 370878750, 4, 494, 1, 2, 0, 1, 3, 1, 1, 0, 0x816817},
|
|
+ {297000000, 371250000, 4, 495, 1, 2, 0, 1, 3, 1, 1, 0, 0},
|
|
+ {593407000, 296703500, 1, 98, 0, 1, 1, 1, 0, 2, 1, 0, 0xE6AE6B},
|
|
+ {594000000, 297000000, 1, 99, 0, 1, 1, 1, 0, 2, 1, 0, 0},
|
|
+ {593407000, 370879375, 4, 494, 1, 2, 0, 1, 3, 1, 1, 1, 0x816817},
|
|
+ {594000000, 371250000, 4, 495, 1, 2, 0, 1, 3, 1, 1, 1, 0},
|
|
+ {593407000, 593407000, 1, 98, 0, 2, 0, 1, 0, 1, 1, 0, 0xE6AE6B},
|
|
+ {594000000, 594000000, 1, 99, 0, 2, 0, 1, 0, 1, 1, 0, 0},
|
|
{ /* sentinel */ }
|
|
};
|
|
|
|
--
|
|
2.17.1
|
|
|
|
|
|
From e63e0475c82b77a9e255b1dd354df20e02a73390 Mon Sep 17 00:00:00 2001
|
|
From: Jonas Karlman <jonas@kwiboo.se>
|
|
Date: Fri, 20 Dec 2019 08:12:43 +0000
|
|
Subject: [PATCH] WIP: drm/bridge: dw-hdmi: limit mode and bus format to
|
|
max_tmds_clock
|
|
|
|
---
|
|
drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 121 ++++++++++++++--------
|
|
1 file changed, 78 insertions(+), 43 deletions(-)
|
|
|
|
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
|
|
index cc39b544ae6e..66e3fed23f4b 100644
|
|
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
|
|
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
|
|
@@ -1854,6 +1854,21 @@ static void hdmi_config_drm_infoframe(struct dw_hdmi *hdmi)
|
|
HDMI_FC_PACKET_TX_EN_DRM_MASK, HDMI_FC_PACKET_TX_EN);
|
|
}
|
|
|
|
+static unsigned int
|
|
+hdmi_get_tmdsclock(unsigned int bus_format, unsigned int pixelclock)
|
|
+{
|
|
+ int color_depth = hdmi_bus_fmt_color_depth(bus_format);
|
|
+ unsigned int tmdsclock = pixelclock;
|
|
+
|
|
+ if (!hdmi_bus_fmt_is_yuv422(bus_format) && color_depth > 8)
|
|
+ tmdsclock = (u64)pixelclock * color_depth / 8;
|
|
+
|
|
+ if (hdmi_bus_fmt_is_yuv420(bus_format))
|
|
+ tmdsclock /= 2;
|
|
+
|
|
+ return tmdsclock;
|
|
+}
|
|
+
|
|
static void hdmi_av_composer(struct dw_hdmi *hdmi,
|
|
const struct drm_display_mode *mode)
|
|
{
|
|
@@ -1863,28 +1878,12 @@ static void hdmi_av_composer(struct dw_hdmi *hdmi,
|
|
int hblank, vblank, h_de_hs, v_de_vs, hsync_len, vsync_len;
|
|
unsigned int vdisplay, hdisplay;
|
|
|
|
- vmode->mtmdsclock = vmode->mpixelclock = mode->clock * 1000;
|
|
+ vmode->mpixelclock = mode->clock * 1000;
|
|
+ vmode->mtmdsclock =
|
|
+ hdmi_get_tmdsclock(hdmi->hdmi_data.enc_out_bus_format,
|
|
+ vmode->mpixelclock);
|
|
|
|
dev_dbg(hdmi->dev, "final pixclk = %d\n", vmode->mpixelclock);
|
|
-
|
|
- if (!hdmi_bus_fmt_is_yuv422(hdmi->hdmi_data.enc_out_bus_format)) {
|
|
- switch (hdmi_bus_fmt_color_depth(
|
|
- hdmi->hdmi_data.enc_out_bus_format)) {
|
|
- case 16:
|
|
- vmode->mtmdsclock = (u64)vmode->mpixelclock * 2;
|
|
- break;
|
|
- case 12:
|
|
- vmode->mtmdsclock = (u64)vmode->mpixelclock * 3 / 2;
|
|
- break;
|
|
- case 10:
|
|
- vmode->mtmdsclock = (u64)vmode->mpixelclock * 5 / 4;
|
|
- break;
|
|
- }
|
|
- }
|
|
-
|
|
- if (hdmi_bus_fmt_is_yuv420(hdmi->hdmi_data.enc_out_bus_format))
|
|
- vmode->mtmdsclock /= 2;
|
|
-
|
|
dev_dbg(hdmi->dev, "final tmdsclk = %d\n", vmode->mtmdsclock);
|
|
|
|
/* Set up HDMI_FC_INVIDCONF */
|
|
@@ -2511,8 +2510,21 @@ static const struct drm_connector_helper_funcs dw_hdmi_connector_helper_funcs =
|
|
* - MEDIA_BUS_FMT_RGB888_1X24,
|
|
*/
|
|
|
|
-/* Can return a maximum of 12 possible output formats for a mode/connector */
|
|
-#define MAX_OUTPUT_SEL_FORMATS 12
|
|
+static bool is_tmds_allowed(struct drm_display_info *info,
|
|
+ struct drm_display_mode *mode,
|
|
+ u32 bus_format)
|
|
+{
|
|
+ unsigned long tmdsclock = hdmi_get_tmdsclock(bus_format, mode->clock);
|
|
+ int max_tmds_clock = max(info->max_tmds_clock, 165000);
|
|
+
|
|
+ if (max_tmds_clock >= tmdsclock)
|
|
+ return true;
|
|
+
|
|
+ return false;
|
|
+}
|
|
+
|
|
+/* Can return a maximum of 16 possible output formats for a mode/connector */
|
|
+#define MAX_OUTPUT_SEL_FORMATS 16
|
|
|
|
static u32 *dw_hdmi_bridge_atomic_get_output_bus_fmts(struct drm_bridge *bridge,
|
|
struct drm_bridge_state *bridge_state,
|
|
@@ -2524,8 +2536,6 @@ static u32 *dw_hdmi_bridge_atomic_get_output_bus_fmts(struct drm_bridge *bridge,
|
|
struct drm_display_info *info = &conn->display_info;
|
|
struct drm_display_mode *mode = &crtc_state->mode;
|
|
u8 max_bpc = conn_state->max_requested_bpc;
|
|
- bool is_hdmi2_sink = info->hdmi.scdc.supported ||
|
|
- (info->color_formats & DRM_COLOR_FORMAT_YCRCB420);
|
|
u32 *output_fmts;
|
|
int i = 0;
|
|
|
|
@@ -2540,29 +2550,33 @@ static u32 *dw_hdmi_bridge_atomic_get_output_bus_fmts(struct drm_bridge *bridge,
|
|
* If the current mode enforces 4:2:0, force the output but format
|
|
* to 4:2:0 and do not add the YUV422/444/RGB formats
|
|
*/
|
|
- if (conn->ycbcr_420_allowed &&
|
|
- (drm_mode_is_420_only(info, mode) ||
|
|
- (is_hdmi2_sink && drm_mode_is_420_also(info, mode)))) {
|
|
+ if (conn->ycbcr_420_allowed && drm_mode_is_420(info, mode) &&
|
|
+ (info->color_formats & DRM_COLOR_FORMAT_YCRCB420)) {
|
|
|
|
/* Order bus formats from 16bit to 8bit if supported */
|
|
if (max_bpc >= 16 && info->bpc == 16 &&
|
|
- (info->hdmi.y420_dc_modes & DRM_EDID_YCBCR420_DC_48))
|
|
+ (info->hdmi.y420_dc_modes & DRM_EDID_YCBCR420_DC_48) &&
|
|
+ is_tmds_allowed(info, mode, MEDIA_BUS_FMT_UYYVYY16_0_5X48))
|
|
output_fmts[i++] = MEDIA_BUS_FMT_UYYVYY16_0_5X48;
|
|
|
|
if (max_bpc >= 12 && info->bpc >= 12 &&
|
|
- (info->hdmi.y420_dc_modes & DRM_EDID_YCBCR420_DC_36))
|
|
+ (info->hdmi.y420_dc_modes & DRM_EDID_YCBCR420_DC_36) &&
|
|
+ is_tmds_allowed(info, mode, MEDIA_BUS_FMT_UYYVYY12_0_5X36))
|
|
output_fmts[i++] = MEDIA_BUS_FMT_UYYVYY12_0_5X36;
|
|
|
|
if (max_bpc >= 10 && info->bpc >= 10 &&
|
|
- (info->hdmi.y420_dc_modes & DRM_EDID_YCBCR420_DC_30))
|
|
+ (info->hdmi.y420_dc_modes & DRM_EDID_YCBCR420_DC_30) &&
|
|
+ is_tmds_allowed(info, mode, MEDIA_BUS_FMT_UYYVYY10_0_5X30))
|
|
output_fmts[i++] = MEDIA_BUS_FMT_UYYVYY10_0_5X30;
|
|
|
|
/* Default 8bit fallback */
|
|
- output_fmts[i++] = MEDIA_BUS_FMT_UYYVYY8_0_5X24;
|
|
+ if (is_tmds_allowed(info, mode, MEDIA_BUS_FMT_UYYVYY8_0_5X24))
|
|
+ output_fmts[i++] = MEDIA_BUS_FMT_UYYVYY8_0_5X24;
|
|
|
|
*num_output_fmts = i;
|
|
|
|
- return output_fmts;
|
|
+ if (drm_mode_is_420_only(info, mode))
|
|
+ return output_fmts;
|
|
}
|
|
|
|
/*
|
|
@@ -2571,40 +2585,51 @@ static u32 *dw_hdmi_bridge_atomic_get_output_bus_fmts(struct drm_bridge *bridge,
|
|
*/
|
|
|
|
if (max_bpc >= 16 && info->bpc == 16) {
|
|
- if (info->color_formats & DRM_COLOR_FORMAT_YCRCB444)
|
|
+ if ((info->color_formats & DRM_COLOR_FORMAT_YCRCB444) &&
|
|
+ is_tmds_allowed(info, mode, MEDIA_BUS_FMT_YUV16_1X48))
|
|
output_fmts[i++] = MEDIA_BUS_FMT_YUV16_1X48;
|
|
|
|
- output_fmts[i++] = MEDIA_BUS_FMT_RGB161616_1X48;
|
|
+ if (is_tmds_allowed(info, mode, MEDIA_BUS_FMT_RGB161616_1X48))
|
|
+ output_fmts[i++] = MEDIA_BUS_FMT_RGB161616_1X48;
|
|
}
|
|
|
|
if (max_bpc >= 12 && info->bpc >= 12) {
|
|
- if (info->color_formats & DRM_COLOR_FORMAT_YCRCB422)
|
|
+ if ((info->color_formats & DRM_COLOR_FORMAT_YCRCB422) &&
|
|
+ is_tmds_allowed(info, mode, MEDIA_BUS_FMT_UYVY12_1X24))
|
|
output_fmts[i++] = MEDIA_BUS_FMT_UYVY12_1X24;
|
|
|
|
- if (info->color_formats & DRM_COLOR_FORMAT_YCRCB444)
|
|
+ if ((info->color_formats & DRM_COLOR_FORMAT_YCRCB444) &&
|
|
+ is_tmds_allowed(info, mode, MEDIA_BUS_FMT_YUV12_1X36))
|
|
output_fmts[i++] = MEDIA_BUS_FMT_YUV12_1X36;
|
|
|
|
- output_fmts[i++] = MEDIA_BUS_FMT_RGB121212_1X36;
|
|
+ if (is_tmds_allowed(info, mode, MEDIA_BUS_FMT_RGB121212_1X36))
|
|
+ output_fmts[i++] = MEDIA_BUS_FMT_RGB121212_1X36;
|
|
}
|
|
|
|
if (max_bpc >= 10 && info->bpc >= 10) {
|
|
- if (info->color_formats & DRM_COLOR_FORMAT_YCRCB422)
|
|
+ if ((info->color_formats & DRM_COLOR_FORMAT_YCRCB422) &&
|
|
+ is_tmds_allowed(info, mode, MEDIA_BUS_FMT_UYVY10_1X20))
|
|
output_fmts[i++] = MEDIA_BUS_FMT_UYVY10_1X20;
|
|
|
|
- if (info->color_formats & DRM_COLOR_FORMAT_YCRCB444)
|
|
+ if ((info->color_formats & DRM_COLOR_FORMAT_YCRCB444) &&
|
|
+ is_tmds_allowed(info, mode, MEDIA_BUS_FMT_YUV10_1X30))
|
|
output_fmts[i++] = MEDIA_BUS_FMT_YUV10_1X30;
|
|
|
|
- output_fmts[i++] = MEDIA_BUS_FMT_RGB101010_1X30;
|
|
+ if (is_tmds_allowed(info, mode, MEDIA_BUS_FMT_RGB101010_1X30))
|
|
+ output_fmts[i++] = MEDIA_BUS_FMT_RGB101010_1X30;
|
|
}
|
|
|
|
- if (info->color_formats & DRM_COLOR_FORMAT_YCRCB422)
|
|
+ if ((info->color_formats & DRM_COLOR_FORMAT_YCRCB422) &&
|
|
+ is_tmds_allowed(info, mode, MEDIA_BUS_FMT_UYVY8_1X16))
|
|
output_fmts[i++] = MEDIA_BUS_FMT_UYVY8_1X16;
|
|
|
|
- if (info->color_formats & DRM_COLOR_FORMAT_YCRCB444)
|
|
+ if ((info->color_formats & DRM_COLOR_FORMAT_YCRCB444) &&
|
|
+ is_tmds_allowed(info, mode, MEDIA_BUS_FMT_YUV8_1X24))
|
|
output_fmts[i++] = MEDIA_BUS_FMT_YUV8_1X24;
|
|
|
|
/* Default 8bit RGB fallback */
|
|
- output_fmts[i++] = MEDIA_BUS_FMT_RGB888_1X24;
|
|
+ if (is_tmds_allowed(info, mode, MEDIA_BUS_FMT_RGB888_1X24))
|
|
+ output_fmts[i++] = MEDIA_BUS_FMT_RGB888_1X24;
|
|
|
|
*num_output_fmts = i;
|
|
|
|
@@ -2811,12 +2836,22 @@ dw_hdmi_bridge_mode_valid(struct drm_bridge *bridge,
|
|
{
|
|
struct dw_hdmi *hdmi = bridge->driver_private;
|
|
struct drm_connector *connector = &hdmi->connector;
|
|
+ struct drm_display_info *info = &connector->display_info;
|
|
enum drm_mode_status mode_status = MODE_OK;
|
|
+ int max_tmds_clock = max(info->max_tmds_clock, 165000);
|
|
+ int clock = mode->clock;
|
|
|
|
/* We don't support double-clocked modes */
|
|
if (mode->flags & DRM_MODE_FLAG_DBLCLK)
|
|
return MODE_BAD;
|
|
|
|
+ if (connector->ycbcr_420_allowed && drm_mode_is_420(info, mode) &&
|
|
+ (info->color_formats & DRM_COLOR_FORMAT_YCRCB420))
|
|
+ clock /= 2;
|
|
+
|
|
+ if (clock > max_tmds_clock)
|
|
+ return MODE_CLOCK_HIGH;
|
|
+
|
|
if (hdmi->plat_data->mode_valid)
|
|
mode_status = hdmi->plat_data->mode_valid(connector, mode);
|
|
|
|
--
|
|
2.17.1
|
|
|
|
|
|
From 5c3bbae0afe43b4856b9c9e344bb7eea3702e4f0 Mon Sep 17 00:00:00 2001
|
|
From: Jonas Karlman <jonas@kwiboo.se>
|
|
Date: Sat, 21 Dec 2019 06:23:52 +0000
|
|
Subject: [PATCH] WIP: drm/bridge: dw-hdmi: do not enable csc for yuv2yuv
|
|
|
|
---
|
|
drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 12 +++++++++++-
|
|
1 file changed, 11 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
|
|
index 66e3fed23f4b..df1789cd8712 100644
|
|
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
|
|
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
|
|
@@ -966,6 +966,14 @@ static void hdmi_video_sample(struct dw_hdmi *hdmi)
|
|
|
|
static int is_color_space_conversion(struct dw_hdmi *hdmi)
|
|
{
|
|
+ if (hdmi_bus_fmt_is_yuv444(hdmi->hdmi_data.enc_in_bus_format) &&
|
|
+ hdmi_bus_fmt_is_yuv422(hdmi->hdmi_data.enc_out_bus_format))
|
|
+ return 0;
|
|
+
|
|
+ if (hdmi_bus_fmt_is_yuv422(hdmi->hdmi_data.enc_in_bus_format) &&
|
|
+ hdmi_bus_fmt_is_yuv444(hdmi->hdmi_data.enc_out_bus_format))
|
|
+ return 0;
|
|
+
|
|
return hdmi->hdmi_data.enc_in_bus_format != hdmi->hdmi_data.enc_out_bus_format;
|
|
}
|
|
|
|
@@ -2050,7 +2058,9 @@ static void dw_hdmi_enable_video_path(struct dw_hdmi *hdmi)
|
|
hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
|
|
|
|
/* Enable csc path */
|
|
- if (is_color_space_conversion(hdmi)) {
|
|
+ if (is_color_space_conversion(hdmi) ||
|
|
+ is_color_space_decimation(hdmi) ||
|
|
+ is_color_space_interpolation(hdmi)) {
|
|
hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_CSCCLK_DISABLE;
|
|
hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
|
|
}
|
|
--
|
|
2.17.1
|
|
|
|
|
|
From fd86f78d28a4b6c5fc7440e42916f3f86a7797a4 Mon Sep 17 00:00:00 2001
|
|
From: Jonas Karlman <jonas@kwiboo.se>
|
|
Date: Fri, 20 Dec 2019 08:12:42 +0000
|
|
Subject: [PATCH] drm/rockchip: dw-hdmi: add bridge and switch to
|
|
drm_bridge_funcs
|
|
|
|
Switch the dw-hdmi driver to drm_bridge_funcs by implementing
|
|
a new local bridge, connecting it to the dw-hdmi bridge.
|
|
|
|
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
|
|
---
|
|
drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 65 ++++++++++-----------
|
|
1 file changed, 31 insertions(+), 34 deletions(-)
|
|
|
|
diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
|
|
index a813299e97a2..8bc42090d0a3 100644
|
|
--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
|
|
+++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
|
|
@@ -67,6 +67,7 @@ struct rockchip_hdmi {
|
|
struct device *dev;
|
|
struct regmap *regmap;
|
|
struct drm_encoder encoder;
|
|
+ struct drm_bridge bridge;
|
|
const struct rockchip_hdmi_chip_data *chip_data;
|
|
struct clk *vpll_clk;
|
|
struct clk *grf_clk;
|
|
@@ -259,15 +260,11 @@ static const struct drm_encoder_funcs dw_hdmi_rockchip_encoder_funcs = {
|
|
.destroy = drm_encoder_cleanup,
|
|
};
|
|
|
|
-static void dw_hdmi_rockchip_encoder_disable(struct drm_encoder *encoder)
|
|
-{
|
|
-}
|
|
-
|
|
static enum drm_mode_status
|
|
-dw_hdmi_rockchip_encoder_mode_valid(struct drm_encoder *encoder,
|
|
- const struct drm_display_mode *mode)
|
|
+dw_hdmi_rockchip_bridge_mode_valid(struct drm_bridge *bridge,
|
|
+ const struct drm_display_mode *mode)
|
|
{
|
|
- struct rockchip_hdmi *hdmi = to_rockchip_hdmi(encoder);
|
|
+ struct rockchip_hdmi *hdmi = to_rockchip_hdmi(bridge);
|
|
long rate;
|
|
|
|
if (hdmi->vpll_clk) {
|
|
@@ -279,26 +276,20 @@ dw_hdmi_rockchip_encoder_mode_valid(struct drm_encoder *encoder,
|
|
return MODE_OK;
|
|
}
|
|
|
|
-static bool
|
|
-dw_hdmi_rockchip_encoder_mode_fixup(struct drm_encoder *encoder,
|
|
- const struct drm_display_mode *mode,
|
|
- struct drm_display_mode *adj_mode)
|
|
-{
|
|
- return true;
|
|
-}
|
|
-
|
|
-static void dw_hdmi_rockchip_encoder_mode_set(struct drm_encoder *encoder,
|
|
- struct drm_display_mode *mode,
|
|
- struct drm_display_mode *adj_mode)
|
|
+static void
|
|
+dw_hdmi_rockchip_bridge_mode_set(struct drm_bridge *bridge,
|
|
+ const struct drm_display_mode *mode,
|
|
+ const struct drm_display_mode *adjusted_mode)
|
|
{
|
|
- struct rockchip_hdmi *hdmi = to_rockchip_hdmi(encoder);
|
|
+ struct rockchip_hdmi *hdmi = to_rockchip_hdmi(bridge);
|
|
|
|
- clk_set_rate(hdmi->vpll_clk, adj_mode->clock * 1000);
|
|
+ clk_set_rate(hdmi->vpll_clk, adjusted_mode->clock * 1000);
|
|
}
|
|
|
|
-static void dw_hdmi_rockchip_encoder_enable(struct drm_encoder *encoder)
|
|
+static void dw_hdmi_rockchip_bridge_enable(struct drm_bridge *bridge)
|
|
{
|
|
- struct rockchip_hdmi *hdmi = to_rockchip_hdmi(encoder);
|
|
+ struct rockchip_hdmi *hdmi = to_rockchip_hdmi(bridge);
|
|
+ struct drm_encoder *encoder = bridge->encoder;
|
|
u32 val;
|
|
int ret;
|
|
|
|
@@ -327,9 +318,10 @@ static void dw_hdmi_rockchip_encoder_enable(struct drm_encoder *encoder)
|
|
}
|
|
|
|
static int
|
|
-dw_hdmi_rockchip_encoder_atomic_check(struct drm_encoder *encoder,
|
|
- struct drm_crtc_state *crtc_state,
|
|
- struct drm_connector_state *conn_state)
|
|
+dw_hdmi_rockchip_bridge_atomic_check(struct drm_bridge *bridge,
|
|
+ struct drm_bridge_state *bridge_state,
|
|
+ struct drm_crtc_state *crtc_state,
|
|
+ struct drm_connector_state *conn_state)
|
|
{
|
|
struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state);
|
|
|
|
@@ -339,13 +331,11 @@ dw_hdmi_rockchip_encoder_atomic_check(struct drm_encoder *encoder,
|
|
return 0;
|
|
}
|
|
|
|
-static const struct drm_encoder_helper_funcs dw_hdmi_rockchip_encoder_helper_funcs = {
|
|
- .mode_valid = dw_hdmi_rockchip_encoder_mode_valid,
|
|
- .mode_fixup = dw_hdmi_rockchip_encoder_mode_fixup,
|
|
- .mode_set = dw_hdmi_rockchip_encoder_mode_set,
|
|
- .enable = dw_hdmi_rockchip_encoder_enable,
|
|
- .disable = dw_hdmi_rockchip_encoder_disable,
|
|
- .atomic_check = dw_hdmi_rockchip_encoder_atomic_check,
|
|
+static const struct drm_bridge_funcs dw_hdmi_rockchip_bridge_funcs = {
|
|
+ .mode_valid = dw_hdmi_rockchip_bridge_mode_valid,
|
|
+ .mode_set = dw_hdmi_rockchip_bridge_mode_set,
|
|
+ .enable = dw_hdmi_rockchip_bridge_enable,
|
|
+ .atomic_check = dw_hdmi_rockchip_bridge_atomic_check,
|
|
};
|
|
|
|
static int dw_hdmi_rockchip_genphy_init(struct dw_hdmi *dw_hdmi, void *data,
|
|
@@ -523,6 +513,7 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master,
|
|
struct dw_hdmi_plat_data *plat_data;
|
|
const struct of_device_id *match;
|
|
struct drm_device *drm = data;
|
|
+ struct drm_bridge *next_bridge;
|
|
struct drm_encoder *encoder;
|
|
struct rockchip_hdmi *hdmi;
|
|
int ret;
|
|
@@ -576,13 +567,15 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master,
|
|
return ret;
|
|
}
|
|
|
|
- drm_encoder_helper_add(encoder, &dw_hdmi_rockchip_encoder_helper_funcs);
|
|
drm_encoder_init(drm, encoder, &dw_hdmi_rockchip_encoder_funcs,
|
|
DRM_MODE_ENCODER_TMDS, NULL);
|
|
|
|
+ hdmi->bridge.funcs = &dw_hdmi_rockchip_bridge_funcs;
|
|
+ drm_bridge_attach(encoder, &hdmi->bridge, NULL);
|
|
+
|
|
platform_set_drvdata(pdev, hdmi);
|
|
|
|
- hdmi->hdmi = dw_hdmi_bind(pdev, encoder, plat_data);
|
|
+ hdmi->hdmi = dw_hdmi_probe(pdev, plat_data);
|
|
|
|
/*
|
|
* If dw_hdmi_bind() fails we'll never call dw_hdmi_unbind(),
|
|
@@ -594,6 +587,10 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master,
|
|
clk_disable_unprepare(hdmi->vpll_clk);
|
|
}
|
|
|
|
+ next_bridge = of_drm_find_bridge(pdev->dev.of_node);
|
|
+ if (next_bridge)
|
|
+ drm_bridge_attach(encoder, next_bridge, &hdmi->bridge);
|
|
+
|
|
return ret;
|
|
}
|
|
|
|
--
|
|
2.17.1
|
|
|
|
|
|
From 1e915225fe362b6ab98bec9bc71c62315347eccb Mon Sep 17 00:00:00 2001
|
|
From: Jonas Karlman <jonas@kwiboo.se>
|
|
Date: Fri, 20 Dec 2019 08:12:42 +0000
|
|
Subject: [PATCH] drm/rockchip: dw-hdmi: enable bridge bus format negotiation
|
|
|
|
Enable bridge format negotiation by implementing
|
|
atomic_get_input_bus_fmts and support for 8-bit RGB 4:4:4.
|
|
|
|
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
|
|
---
|
|
drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 35 +++++++++++++++++++++
|
|
1 file changed, 35 insertions(+)
|
|
|
|
diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
|
|
index 8bc42090d0a3..83a22a061e52 100644
|
|
--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
|
|
+++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
|
|
@@ -317,6 +317,16 @@ static void dw_hdmi_rockchip_bridge_enable(struct drm_bridge *bridge)
|
|
ret ? "LIT" : "BIG");
|
|
}
|
|
|
|
+static bool is_rgb(u32 format)
|
|
+{
|
|
+ switch (format) {
|
|
+ case MEDIA_BUS_FMT_RGB888_1X24:
|
|
+ return true;
|
|
+ default:
|
|
+ return false;
|
|
+ }
|
|
+}
|
|
+
|
|
static int
|
|
dw_hdmi_rockchip_bridge_atomic_check(struct drm_bridge *bridge,
|
|
struct drm_bridge_state *bridge_state,
|
|
@@ -331,11 +341,36 @@ dw_hdmi_rockchip_bridge_atomic_check(struct drm_bridge *bridge,
|
|
return 0;
|
|
}
|
|
|
|
+static u32 *dw_hdmi_rockchip_get_input_bus_fmts(struct drm_bridge *bridge,
|
|
+ struct drm_bridge_state *bridge_state,
|
|
+ struct drm_crtc_state *crtc_state,
|
|
+ struct drm_connector_state *conn_state,
|
|
+ u32 output_fmt,
|
|
+ unsigned int *num_input_fmts)
|
|
+{
|
|
+ u32 *input_fmt;
|
|
+
|
|
+ *num_input_fmts = 0;
|
|
+
|
|
+ if (!is_rgb(output_fmt))
|
|
+ return NULL;
|
|
+
|
|
+ input_fmt = kzalloc(sizeof(*input_fmt), GFP_KERNEL);
|
|
+ if (!input_fmt)
|
|
+ return NULL;
|
|
+
|
|
+ *num_input_fmts = 1;
|
|
+ *input_fmt = output_fmt;
|
|
+
|
|
+ return input_fmt;
|
|
+}
|
|
+
|
|
static const struct drm_bridge_funcs dw_hdmi_rockchip_bridge_funcs = {
|
|
.mode_valid = dw_hdmi_rockchip_bridge_mode_valid,
|
|
.mode_set = dw_hdmi_rockchip_bridge_mode_set,
|
|
.enable = dw_hdmi_rockchip_bridge_enable,
|
|
.atomic_check = dw_hdmi_rockchip_bridge_atomic_check,
|
|
+ .atomic_get_input_bus_fmts = dw_hdmi_rockchip_get_input_bus_fmts,
|
|
};
|
|
|
|
static int dw_hdmi_rockchip_genphy_init(struct dw_hdmi *dw_hdmi, void *data,
|
|
--
|
|
2.17.1
|
|
|
|
|
|
From b4cbb8eae8f3a5dbdbb844d59dfd7c979a88f66a Mon Sep 17 00:00:00 2001
|
|
From: Jonas Karlman <jonas@kwiboo.se>
|
|
Date: Fri, 20 Dec 2019 08:12:42 +0000
|
|
Subject: [PATCH] WIP: drm/rockchip: dw_hdmi: add 10-bit rgb bus format
|
|
|
|
---
|
|
drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 41 +++++++++++++++++++++
|
|
drivers/gpu/drm/rockchip/rockchip_drm_drv.h | 2 +
|
|
drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 10 ++++-
|
|
3 files changed, 52 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
|
|
index 83a22a061e52..3c8a95cd38dc 100644
|
|
--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
|
|
+++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
|
|
@@ -76,6 +76,7 @@ struct rockchip_hdmi {
|
|
};
|
|
|
|
#define to_rockchip_hdmi(x) container_of(x, struct rockchip_hdmi, x)
|
|
+#define to_crtc_state(x) container_of(x, struct drm_crtc_state, x)
|
|
|
|
static const struct dw_hdmi_mpll_config rockchip_mpll_cfg[] = {
|
|
{
|
|
@@ -282,6 +283,11 @@ dw_hdmi_rockchip_bridge_mode_set(struct drm_bridge *bridge,
|
|
const struct drm_display_mode *adjusted_mode)
|
|
{
|
|
struct rockchip_hdmi *hdmi = to_rockchip_hdmi(bridge);
|
|
+ struct drm_crtc_state *crtc_state = to_crtc_state(adjusted_mode);
|
|
+ struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state);
|
|
+
|
|
+ if (hdmi->phy)
|
|
+ phy_set_bus_width(hdmi->phy, s->bus_width);
|
|
|
|
clk_set_rate(hdmi->vpll_clk, adjusted_mode->clock * 1000);
|
|
}
|
|
@@ -320,6 +326,7 @@ static void dw_hdmi_rockchip_bridge_enable(struct drm_bridge *bridge)
|
|
static bool is_rgb(u32 format)
|
|
{
|
|
switch (format) {
|
|
+ case MEDIA_BUS_FMT_RGB101010_1X30:
|
|
case MEDIA_BUS_FMT_RGB888_1X24:
|
|
return true;
|
|
default:
|
|
@@ -327,6 +334,16 @@ static bool is_rgb(u32 format)
|
|
}
|
|
}
|
|
|
|
+static bool is_10bit(u32 format)
|
|
+{
|
|
+ switch (format) {
|
|
+ case MEDIA_BUS_FMT_RGB101010_1X30:
|
|
+ return true;
|
|
+ default:
|
|
+ return false;
|
|
+ }
|
|
+}
|
|
+
|
|
static int
|
|
dw_hdmi_rockchip_bridge_atomic_check(struct drm_bridge *bridge,
|
|
struct drm_bridge_state *bridge_state,
|
|
@@ -334,9 +351,24 @@ dw_hdmi_rockchip_bridge_atomic_check(struct drm_bridge *bridge,
|
|
struct drm_connector_state *conn_state)
|
|
{
|
|
struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state);
|
|
+ struct drm_atomic_state *state = bridge_state->base.state;
|
|
+ struct drm_crtc_state *old_crtc_state;
|
|
+ struct rockchip_crtc_state *old_state;
|
|
+ u32 format = bridge_state->output_bus_cfg.format;
|
|
|
|
s->output_mode = ROCKCHIP_OUT_MODE_AAAA;
|
|
s->output_type = DRM_MODE_CONNECTOR_HDMIA;
|
|
+ s->output_bpc = 10;
|
|
+ s->bus_format = format;
|
|
+ s->bus_width = is_10bit(format) ? 10 : 8;
|
|
+
|
|
+ old_crtc_state = drm_atomic_get_old_crtc_state(state, conn_state->crtc);
|
|
+ if (old_crtc_state && !crtc_state->mode_changed) {
|
|
+ old_state = to_rockchip_crtc_state(old_crtc_state);
|
|
+ if (s->bus_format != old_state->bus_format ||
|
|
+ s->bus_width != old_state->bus_width)
|
|
+ crtc_state->mode_changed = true;
|
|
+ }
|
|
|
|
return 0;
|
|
}
|
|
@@ -348,10 +380,19 @@ static u32 *dw_hdmi_rockchip_get_input_bus_fmts(struct drm_bridge *bridge,
|
|
u32 output_fmt,
|
|
unsigned int *num_input_fmts)
|
|
{
|
|
+ struct rockchip_hdmi *hdmi = to_rockchip_hdmi(bridge);
|
|
+ struct drm_encoder *encoder = bridge->encoder;
|
|
u32 *input_fmt;
|
|
+ bool has_10bit = true;
|
|
|
|
*num_input_fmts = 0;
|
|
|
|
+ if (drm_of_encoder_active_endpoint_id(hdmi->dev->of_node, encoder))
|
|
+ has_10bit = false;
|
|
+
|
|
+ if (!has_10bit && is_10bit(output_fmt))
|
|
+ return NULL;
|
|
+
|
|
if (!is_rgb(output_fmt))
|
|
return NULL;
|
|
|
|
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
|
|
index c5b06048124e..af1b85d8f7ee 100644
|
|
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
|
|
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
|
|
@@ -30,6 +30,8 @@ struct rockchip_crtc_state {
|
|
int output_mode;
|
|
int output_bpc;
|
|
int output_flags;
|
|
+ u32 bus_format;
|
|
+ int bus_width;
|
|
};
|
|
#define to_rockchip_crtc_state(s) \
|
|
container_of(s, struct rockchip_crtc_state, base)
|
|
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
|
|
index f181897cbfad..e59213d3ea62 100644
|
|
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
|
|
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
|
|
@@ -1402,13 +1402,21 @@ static void vop_crtc_destroy(struct drm_crtc *crtc)
|
|
|
|
static struct drm_crtc_state *vop_crtc_duplicate_state(struct drm_crtc *crtc)
|
|
{
|
|
- struct rockchip_crtc_state *rockchip_state;
|
|
+ struct rockchip_crtc_state *rockchip_state, *s;
|
|
+
|
|
+ if (WARN_ON(!crtc->state))
|
|
+ return NULL;
|
|
|
|
rockchip_state = kzalloc(sizeof(*rockchip_state), GFP_KERNEL);
|
|
if (!rockchip_state)
|
|
return NULL;
|
|
|
|
__drm_atomic_helper_crtc_duplicate_state(crtc, &rockchip_state->base);
|
|
+
|
|
+ s = to_rockchip_crtc_state(crtc->state);
|
|
+ rockchip_state->bus_format = s->bus_format;
|
|
+ rockchip_state->bus_width = s->bus_width;
|
|
+
|
|
return &rockchip_state->base;
|
|
}
|
|
|
|
--
|
|
2.17.1
|
|
|
|
|
|
From 9fedc6efc787bddfad71c6145cf3cbee49ea257d Mon Sep 17 00:00:00 2001
|
|
From: Jonas Karlman <jonas@kwiboo.se>
|
|
Date: Fri, 20 Dec 2019 08:12:43 +0000
|
|
Subject: [PATCH] WIP: drm/rockchip: add yuv444 support
|
|
|
|
---
|
|
drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 29 ++++++++++++++++++++-
|
|
drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 29 +++++++++++++++++++++
|
|
drivers/gpu/drm/rockchip/rockchip_drm_vop.h | 5 ++++
|
|
drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 10 +++++++
|
|
4 files changed, 72 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
|
|
index 3c8a95cd38dc..9b3c2318ce0e 100644
|
|
--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
|
|
+++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
|
|
@@ -61,6 +61,7 @@ struct rockchip_hdmi_chip_data {
|
|
int lcdsel_grf_reg;
|
|
u32 lcdsel_big;
|
|
u32 lcdsel_lit;
|
|
+ bool ycbcr_444_allowed;
|
|
};
|
|
|
|
struct rockchip_hdmi {
|
|
@@ -334,10 +335,22 @@ static bool is_rgb(u32 format)
|
|
}
|
|
}
|
|
|
|
+static bool is_yuv444(u32 format)
|
|
+{
|
|
+ switch (format) {
|
|
+ case MEDIA_BUS_FMT_YUV10_1X30:
|
|
+ case MEDIA_BUS_FMT_YUV8_1X24:
|
|
+ return true;
|
|
+ default:
|
|
+ return false;
|
|
+ }
|
|
+}
|
|
+
|
|
static bool is_10bit(u32 format)
|
|
{
|
|
switch (format) {
|
|
case MEDIA_BUS_FMT_RGB101010_1X30:
|
|
+ case MEDIA_BUS_FMT_YUV10_1X30:
|
|
return true;
|
|
default:
|
|
return false;
|
|
@@ -354,12 +367,22 @@ dw_hdmi_rockchip_bridge_atomic_check(struct drm_bridge *bridge,
|
|
struct drm_atomic_state *state = bridge_state->base.state;
|
|
struct drm_crtc_state *old_crtc_state;
|
|
struct rockchip_crtc_state *old_state;
|
|
+ struct drm_bridge *next_bridge;
|
|
+ struct drm_bridge_state *next_bridge_state;
|
|
u32 format = bridge_state->output_bus_cfg.format;
|
|
|
|
s->output_mode = ROCKCHIP_OUT_MODE_AAAA;
|
|
s->output_type = DRM_MODE_CONNECTOR_HDMIA;
|
|
s->output_bpc = 10;
|
|
s->bus_format = format;
|
|
+
|
|
+ next_bridge = drm_bridge_get_next_bridge(bridge);
|
|
+ if (next_bridge) {
|
|
+ next_bridge_state = drm_atomic_get_new_bridge_state(state,
|
|
+ next_bridge);
|
|
+ format = next_bridge_state->output_bus_cfg.format;
|
|
+ }
|
|
+
|
|
s->bus_width = is_10bit(format) ? 10 : 8;
|
|
|
|
old_crtc_state = drm_atomic_get_old_crtc_state(state, conn_state->crtc);
|
|
@@ -393,7 +416,10 @@ static u32 *dw_hdmi_rockchip_get_input_bus_fmts(struct drm_bridge *bridge,
|
|
if (!has_10bit && is_10bit(output_fmt))
|
|
return NULL;
|
|
|
|
- if (!is_rgb(output_fmt))
|
|
+ if (is_yuv444(output_fmt)) {
|
|
+ if (!hdmi->chip_data->ycbcr_444_allowed)
|
|
+ return NULL;
|
|
+ } else if (!is_rgb(output_fmt))
|
|
return NULL;
|
|
|
|
input_fmt = kzalloc(sizeof(*input_fmt), GFP_KERNEL);
|
|
@@ -539,6 +565,7 @@ static const struct dw_hdmi_phy_ops rk3328_hdmi_phy_ops = {
|
|
|
|
static struct rockchip_hdmi_chip_data rk3328_chip_data = {
|
|
.lcdsel_grf_reg = -1,
|
|
+ .ycbcr_444_allowed = true,
|
|
};
|
|
|
|
static const struct dw_hdmi_plat_data rk3328_hdmi_drv_data = {
|
|
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
|
|
index e59213d3ea62..5bf833ea8ce2 100644
|
|
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
|
|
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
|
|
@@ -274,6 +274,17 @@ static enum vop_data_format vop_convert_format(uint32_t format)
|
|
}
|
|
}
|
|
|
|
+static bool is_yuv_output(uint32_t bus_format)
|
|
+{
|
|
+ switch (bus_format) {
|
|
+ case MEDIA_BUS_FMT_YUV8_1X24:
|
|
+ case MEDIA_BUS_FMT_YUV10_1X30:
|
|
+ return true;
|
|
+ default:
|
|
+ return false;
|
|
+ }
|
|
+}
|
|
+
|
|
static uint16_t scl_vop_cal_scale(enum scale_mode mode, uint32_t src,
|
|
uint32_t dst, bool is_horizontal,
|
|
int vsu_mode, int *vskiplines)
|
|
@@ -1181,6 +1192,7 @@ static void vop_crtc_atomic_enable(struct drm_crtc *crtc,
|
|
u16 vact_end = vact_st + vdisplay;
|
|
uint32_t pin_pol, val;
|
|
int dither_bpc = s->output_bpc ? s->output_bpc : 10;
|
|
+ bool yuv_output = is_yuv_output(s->bus_format);
|
|
int ret;
|
|
|
|
if (old_state && old_state->self_refresh_active) {
|
|
@@ -1254,6 +1266,8 @@ static void vop_crtc_atomic_enable(struct drm_crtc *crtc,
|
|
!(vop_data->feature & VOP_FEATURE_OUTPUT_RGB10))
|
|
s->output_mode = ROCKCHIP_OUT_MODE_P888;
|
|
|
|
+ VOP_REG_SET(vop, common, dsp_data_swap, yuv_output ? 2 : 0);
|
|
+
|
|
if (s->output_mode == ROCKCHIP_OUT_MODE_AAAA && dither_bpc <= 8)
|
|
VOP_REG_SET(vop, common, pre_dither_down, 1);
|
|
else
|
|
@@ -1269,6 +1283,21 @@ static void vop_crtc_atomic_enable(struct drm_crtc *crtc,
|
|
|
|
VOP_REG_SET(vop, common, out_mode, s->output_mode);
|
|
|
|
+ VOP_REG_SET(vop, common, overlay_mode, yuv_output);
|
|
+ VOP_REG_SET(vop, common, dsp_out_yuv, yuv_output);
|
|
+
|
|
+ /*
|
|
+ * Background color is 10bit depth if vop version >= 3.5
|
|
+ */
|
|
+ if (!yuv_output)
|
|
+ val = 0;
|
|
+ else if (VOP_MAJOR(vop_data->version) == 3 &&
|
|
+ VOP_MINOR(vop_data->version) >= 5)
|
|
+ val = 0x20010200;
|
|
+ else
|
|
+ val = 0x801080;
|
|
+ VOP_REG_SET(vop, common, dsp_background, val);
|
|
+
|
|
VOP_REG_SET(vop, modeset, htotal_pw, (htotal << 16) | hsync_len);
|
|
val = hact_st << 16;
|
|
val |= hact_end;
|
|
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
|
|
index 0b3d18c457b2..9393cf12b1db 100644
|
|
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
|
|
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
|
|
@@ -77,6 +77,11 @@ struct vop_common {
|
|
struct vop_reg mmu_en;
|
|
struct vop_reg out_mode;
|
|
struct vop_reg standby;
|
|
+
|
|
+ struct vop_reg overlay_mode;
|
|
+ struct vop_reg dsp_data_swap;
|
|
+ struct vop_reg dsp_out_yuv;
|
|
+ struct vop_reg dsp_background;
|
|
};
|
|
|
|
struct vop_misc {
|
|
diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
|
|
index 7a9d979c8d5d..b99e902d949e 100644
|
|
--- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
|
|
+++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
|
|
@@ -606,6 +606,11 @@ static const struct vop_common rk3288_common = {
|
|
.dsp_blank = VOP_REG(RK3288_DSP_CTRL0, 0x3, 18),
|
|
.out_mode = VOP_REG(RK3288_DSP_CTRL0, 0xf, 0),
|
|
.cfg_done = VOP_REG_SYNC(RK3288_REG_CFG_DONE, 0x1, 0),
|
|
+
|
|
+ .overlay_mode = VOP_REG(RK3288_SYS_CTRL, 0x1, 16),
|
|
+ .dsp_data_swap = VOP_REG(RK3288_DSP_CTRL0, 0x1f, 12),
|
|
+ .dsp_out_yuv = VOP_REG(RK3288_POST_SCL_CTRL, 0x1, 2),
|
|
+ .dsp_background = VOP_REG(RK3288_DSP_BG, 0xffffffff, 0),
|
|
};
|
|
|
|
/*
|
|
@@ -914,6 +919,11 @@ static const struct vop_common rk3328_common = {
|
|
.dsp_blank = VOP_REG(RK3328_DSP_CTRL0, 0x3, 18),
|
|
.out_mode = VOP_REG(RK3328_DSP_CTRL0, 0xf, 0),
|
|
.cfg_done = VOP_REG_SYNC(RK3328_REG_CFG_DONE, 0x1, 0),
|
|
+
|
|
+ .overlay_mode = VOP_REG(RK3328_SYS_CTRL, 0x1, 16),
|
|
+ .dsp_data_swap = VOP_REG(RK3328_DSP_CTRL0, 0x1f, 12),
|
|
+ .dsp_out_yuv = VOP_REG(RK3328_POST_SCL_CTRL, 0x1, 2),
|
|
+ .dsp_background = VOP_REG(RK3328_DSP_BG, 0xffffffff, 0),
|
|
};
|
|
|
|
static const struct vop_intr rk3328_vop_intr = {
|
|
--
|
|
2.17.1
|
|
|
|
|
|
From 111c35c19a742d7b76b6f548103f8b561c45a186 Mon Sep 17 00:00:00 2001
|
|
From: Jonas Karlman <jonas@kwiboo.se>
|
|
Date: Fri, 20 Dec 2019 08:12:43 +0000
|
|
Subject: [PATCH] WIP: drm/rockchip: add yuv420 support
|
|
|
|
---
|
|
drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 22 +++++++++++++++++++++
|
|
drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 18 ++++++++++++++++-
|
|
drivers/gpu/drm/rockchip/rockchip_drm_vop.h | 10 ++++++----
|
|
drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 2 ++
|
|
4 files changed, 47 insertions(+), 5 deletions(-)
|
|
|
|
diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
|
|
index 9b3c2318ce0e..eb405cb3d1f6 100644
|
|
--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
|
|
+++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
|
|
@@ -346,9 +346,21 @@ static bool is_yuv444(u32 format)
|
|
}
|
|
}
|
|
|
|
+static bool is_yuv420(u32 format)
|
|
+{
|
|
+ switch (format) {
|
|
+ case MEDIA_BUS_FMT_UYYVYY10_0_5X30:
|
|
+ case MEDIA_BUS_FMT_UYYVYY8_0_5X24:
|
|
+ return true;
|
|
+ default:
|
|
+ return false;
|
|
+ }
|
|
+}
|
|
+
|
|
static bool is_10bit(u32 format)
|
|
{
|
|
switch (format) {
|
|
+ case MEDIA_BUS_FMT_UYYVYY10_0_5X30:
|
|
case MEDIA_BUS_FMT_RGB101010_1X30:
|
|
case MEDIA_BUS_FMT_YUV10_1X30:
|
|
return true;
|
|
@@ -385,6 +397,11 @@ dw_hdmi_rockchip_bridge_atomic_check(struct drm_bridge *bridge,
|
|
|
|
s->bus_width = is_10bit(format) ? 10 : 8;
|
|
|
|
+ if (is_yuv420(format)) {
|
|
+ s->output_mode = ROCKCHIP_OUT_MODE_YUV420;
|
|
+ s->bus_width /= 2;
|
|
+ }
|
|
+
|
|
old_crtc_state = drm_atomic_get_old_crtc_state(state, conn_state->crtc);
|
|
if (old_crtc_state && !crtc_state->mode_changed) {
|
|
old_state = to_rockchip_crtc_state(old_crtc_state);
|
|
@@ -405,6 +422,7 @@ static u32 *dw_hdmi_rockchip_get_input_bus_fmts(struct drm_bridge *bridge,
|
|
{
|
|
struct rockchip_hdmi *hdmi = to_rockchip_hdmi(bridge);
|
|
struct drm_encoder *encoder = bridge->encoder;
|
|
+ struct drm_connector *connector = conn_state->connector;
|
|
u32 *input_fmt;
|
|
bool has_10bit = true;
|
|
|
|
@@ -419,6 +437,9 @@ static u32 *dw_hdmi_rockchip_get_input_bus_fmts(struct drm_bridge *bridge,
|
|
if (is_yuv444(output_fmt)) {
|
|
if (!hdmi->chip_data->ycbcr_444_allowed)
|
|
return NULL;
|
|
+ } else if (is_yuv420(output_fmt)) {
|
|
+ if (!connector->ycbcr_420_allowed)
|
|
+ return NULL;
|
|
} else if (!is_rgb(output_fmt))
|
|
return NULL;
|
|
|
|
@@ -575,6 +596,7 @@ static const struct dw_hdmi_plat_data rk3328_hdmi_drv_data = {
|
|
.phy_name = "inno_dw_hdmi_phy2",
|
|
.phy_force_vendor = true,
|
|
.use_drm_infoframe = true,
|
|
+ .ycbcr_420_allowed = true,
|
|
};
|
|
|
|
static struct rockchip_hdmi_chip_data rk3399_chip_data = {
|
|
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
|
|
index 5bf833ea8ce2..b8c0d2fcc52a 100644
|
|
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
|
|
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
|
|
@@ -275,6 +275,19 @@ static enum vop_data_format vop_convert_format(uint32_t format)
|
|
}
|
|
|
|
static bool is_yuv_output(uint32_t bus_format)
|
|
+{
|
|
+ switch (bus_format) {
|
|
+ case MEDIA_BUS_FMT_YUV8_1X24:
|
|
+ case MEDIA_BUS_FMT_YUV10_1X30:
|
|
+ case MEDIA_BUS_FMT_UYYVYY8_0_5X24:
|
|
+ case MEDIA_BUS_FMT_UYYVYY10_0_5X30:
|
|
+ return true;
|
|
+ default:
|
|
+ return false;
|
|
+ }
|
|
+}
|
|
+
|
|
+static bool has_uv_swapped(uint32_t bus_format)
|
|
{
|
|
switch (bus_format) {
|
|
case MEDIA_BUS_FMT_YUV8_1X24:
|
|
@@ -1266,7 +1279,7 @@ static void vop_crtc_atomic_enable(struct drm_crtc *crtc,
|
|
!(vop_data->feature & VOP_FEATURE_OUTPUT_RGB10))
|
|
s->output_mode = ROCKCHIP_OUT_MODE_P888;
|
|
|
|
- VOP_REG_SET(vop, common, dsp_data_swap, yuv_output ? 2 : 0);
|
|
+ VOP_REG_SET(vop, common, dsp_data_swap, has_uv_swapped(s->bus_format) ? 2 : 0);
|
|
|
|
if (s->output_mode == ROCKCHIP_OUT_MODE_AAAA && dither_bpc <= 8)
|
|
VOP_REG_SET(vop, common, pre_dither_down, 1);
|
|
@@ -1283,6 +1296,9 @@ static void vop_crtc_atomic_enable(struct drm_crtc *crtc,
|
|
|
|
VOP_REG_SET(vop, common, out_mode, s->output_mode);
|
|
|
|
+ VOP_REG_SET(vop, common, dclk_ddr,
|
|
+ s->output_mode == ROCKCHIP_OUT_MODE_YUV420 ? 1 : 0);
|
|
+
|
|
VOP_REG_SET(vop, common, overlay_mode, yuv_output);
|
|
VOP_REG_SET(vop, common, dsp_out_yuv, yuv_output);
|
|
|
|
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
|
|
index 9393cf12b1db..89fe8d5c7721 100644
|
|
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
|
|
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
|
|
@@ -79,6 +79,7 @@ struct vop_common {
|
|
struct vop_reg standby;
|
|
|
|
struct vop_reg overlay_mode;
|
|
+ struct vop_reg dclk_ddr;
|
|
struct vop_reg dsp_data_swap;
|
|
struct vop_reg dsp_out_yuv;
|
|
struct vop_reg dsp_background;
|
|
@@ -230,11 +231,12 @@ struct vop_data {
|
|
/*
|
|
* display output interface supported by rockchip lcdc
|
|
*/
|
|
-#define ROCKCHIP_OUT_MODE_P888 0
|
|
-#define ROCKCHIP_OUT_MODE_P666 1
|
|
-#define ROCKCHIP_OUT_MODE_P565 2
|
|
+#define ROCKCHIP_OUT_MODE_P888 0
|
|
+#define ROCKCHIP_OUT_MODE_P666 1
|
|
+#define ROCKCHIP_OUT_MODE_P565 2
|
|
+#define ROCKCHIP_OUT_MODE_YUV420 14
|
|
/* for use special outface */
|
|
-#define ROCKCHIP_OUT_MODE_AAAA 15
|
|
+#define ROCKCHIP_OUT_MODE_AAAA 15
|
|
|
|
/* output flags */
|
|
#define ROCKCHIP_OUTPUT_DSI_DUAL BIT(0)
|
|
diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
|
|
index b99e902d949e..73d24c6bbf05 100644
|
|
--- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
|
|
+++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
|
|
@@ -608,6 +608,7 @@ static const struct vop_common rk3288_common = {
|
|
.cfg_done = VOP_REG_SYNC(RK3288_REG_CFG_DONE, 0x1, 0),
|
|
|
|
.overlay_mode = VOP_REG(RK3288_SYS_CTRL, 0x1, 16),
|
|
+ .dclk_ddr = VOP_REG(RK3288_DSP_CTRL0, 0x1, 8),
|
|
.dsp_data_swap = VOP_REG(RK3288_DSP_CTRL0, 0x1f, 12),
|
|
.dsp_out_yuv = VOP_REG(RK3288_POST_SCL_CTRL, 0x1, 2),
|
|
.dsp_background = VOP_REG(RK3288_DSP_BG, 0xffffffff, 0),
|
|
@@ -921,6 +922,7 @@ static const struct vop_common rk3328_common = {
|
|
.cfg_done = VOP_REG_SYNC(RK3328_REG_CFG_DONE, 0x1, 0),
|
|
|
|
.overlay_mode = VOP_REG(RK3328_SYS_CTRL, 0x1, 16),
|
|
+ .dclk_ddr = VOP_REG(RK3328_DSP_CTRL0, 0x1, 8),
|
|
.dsp_data_swap = VOP_REG(RK3328_DSP_CTRL0, 0x1f, 12),
|
|
.dsp_out_yuv = VOP_REG(RK3328_POST_SCL_CTRL, 0x1, 2),
|
|
.dsp_background = VOP_REG(RK3328_DSP_BG, 0xffffffff, 0),
|
|
--
|
|
2.17.1
|
|
|
|
|
|
From a8f40af332f87e74015d578a14e4491d1e0c9291 Mon Sep 17 00:00:00 2001
|
|
From: Jonas Karlman <jonas@kwiboo.se>
|
|
Date: Sun, 8 Dec 2019 23:49:00 +0000
|
|
Subject: [PATCH] WIP: drm/bridge: dw-hdmi: signal default quant range
|
|
|
|
---
|
|
drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 3 +++
|
|
1 file changed, 3 insertions(+)
|
|
|
|
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
|
|
index df1789cd8712..14a1131cfc21 100644
|
|
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
|
|
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
|
|
@@ -1673,6 +1673,9 @@ static void hdmi_config_AVI(struct dw_hdmi *hdmi, struct drm_display_mode *mode)
|
|
HDMI_EXTENDED_COLORIMETRY_XV_YCC_601;
|
|
}
|
|
|
|
+ drm_hdmi_avi_infoframe_quant_range(&frame, &hdmi->connector, mode,
|
|
+ drm_default_rgb_quant_range(mode));
|
|
+
|
|
drm_hdmi_avi_infoframe_content_type(&frame, conn_state);
|
|
|
|
hdmi_infoframe_log(KERN_INFO, hdmi->dev, (union hdmi_infoframe *)&frame);
|
|
--
|
|
2.17.1
|
|
|
|
|
|
From aa34fb23453ea76f533d0af601ec0ce5ee9d8312 Mon Sep 17 00:00:00 2001
|
|
From: Jonas Karlman <jonas@kwiboo.se>
|
|
Date: Fri, 20 Dec 2019 08:12:43 +0000
|
|
Subject: [PATCH] WIP: drm/bridge: dw-hdmi: use avmute during modeset
|
|
|
|
---
|
|
drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 4 ++++
|
|
drivers/gpu/drm/bridge/synopsys/dw-hdmi.h | 4 ++++
|
|
2 files changed, 8 insertions(+)
|
|
|
|
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
|
|
index 14a1131cfc21..6344c8aac13e 100644
|
|
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
|
|
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
|
|
@@ -2328,10 +2328,14 @@ static void dw_hdmi_poweron(struct dw_hdmi *hdmi)
|
|
hdmi->bridge_is_on = true;
|
|
dw_hdmi_get_edid(&hdmi->connector);
|
|
dw_hdmi_setup(hdmi, &hdmi->previous_mode);
|
|
+
|
|
+ hdmi_writeb(hdmi, HDMI_FC_GCP_CLEAR_AVMUTE, HDMI_FC_GCP);
|
|
}
|
|
|
|
static void dw_hdmi_poweroff(struct dw_hdmi *hdmi)
|
|
{
|
|
+ hdmi_writeb(hdmi, HDMI_FC_GCP_SET_AVMUTE, HDMI_FC_GCP);
|
|
+
|
|
if (hdmi->phy.enabled) {
|
|
hdmi->phy.ops->disable(hdmi, hdmi->phy.data);
|
|
hdmi->phy.enabled = false;
|
|
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h
|
|
index 27a91128d0cc..3810326794cc 100644
|
|
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h
|
|
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h
|
|
@@ -842,6 +842,10 @@ enum {
|
|
HDMI_FC_AVICONF3_QUANT_RANGE_LIMITED = 0x00,
|
|
HDMI_FC_AVICONF3_QUANT_RANGE_FULL = 0x04,
|
|
|
|
+/* HDMI_FC_GCP */
|
|
+ HDMI_FC_GCP_SET_AVMUTE = 0x2,
|
|
+ HDMI_FC_GCP_CLEAR_AVMUTE = 0x1,
|
|
+
|
|
/* FC_DBGFORCE field values */
|
|
HDMI_FC_DBGFORCE_FORCEAUDIO = 0x10,
|
|
HDMI_FC_DBGFORCE_FORCEVIDEO = 0x1,
|
|
--
|
|
2.17.1
|
|
|