This is MT8173 HDMI 4K support PATCH v3, based on 4.7-rc1.
In order to support HDMI 4K on MT8173, we have to make some modifications. 1) Make sure that mtk_hdmi_send_infoframe is sent successfully. 2) Enhance the HDMI driving current to improve performance. 3) Make sure that pixel clock is 297MHz when resolution is 4K.
Changes since v2: - Remove the change about preparation for MT2701 support.
Changes since v1: - According to the suggestion from philipp, We use the new dpi0_sel rate set method. - calls clk_set_rate to set the dpi0_sel according to the pixel clock. - Remove the direct access to all the intermediate clock part. - Remove the intermediate tvdpll_d* clocks in dts. - According to suggestion from CK, we rename the clock parse function and remove it from mtk_dpi_conf struct. - Merges the hdmi Pll set rate for pixel clock greater than 165MHz and smaller parts.
The PATCH depends on the following patch: https://patchwork.kernel.org/patch/9249445/ (arm64: dts: mt8173: add mmsel clocks for 4K support)
Junzhi Zhao (3): drm/mediatek: do mtk_hdmi_send_infoframe after HDMI clock enable drm/mediatek: enhance the HDMI driving current drm/mediatek: fix the wrong pixel clock when resolution is 4K
drivers/gpu/drm/mediatek/mtk_dpi.c | 8 +++-- drivers/gpu/drm/mediatek/mtk_hdmi.c | 17 ++++++---- drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c | 42 +++++++++++++++++------- 3 files changed, 47 insertions(+), 20 deletions(-)
From: Junzhi Zhao junzhi.zhao@mediatek.com
The mtk_hdmi_send_infoframe have to be run after PLL and PIXEL clock of HDMI enable. Make sure that HDMI inforframes can be sent successfully.
Signed-off-by: Junzhi Zhao junzhi.zhao@mediatek.com Signed-off-by: Bibby Hsieh bibby.hsieh@mediatek.com --- drivers/gpu/drm/mediatek/mtk_hdmi.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c index ba812ef..33b2c9d 100644 --- a/drivers/gpu/drm/mediatek/mtk_hdmi.c +++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c @@ -1133,12 +1133,6 @@ static int mtk_hdmi_output_set_display_mode(struct mtk_hdmi *hdmi, phy_power_on(hdmi->phy); mtk_hdmi_aud_output_config(hdmi, mode);
- mtk_hdmi_setup_audio_infoframe(hdmi); - mtk_hdmi_setup_avi_infoframe(hdmi, mode); - mtk_hdmi_setup_spd_infoframe(hdmi, "mediatek", "On-chip HDMI"); - if (mode->flags & DRM_MODE_FLAG_3D_MASK) - mtk_hdmi_setup_vendor_specific_infoframe(hdmi, mode); - mtk_hdmi_hw_vid_black(hdmi, false); mtk_hdmi_hw_aud_unmute(hdmi); mtk_hdmi_hw_send_av_unmute(hdmi); @@ -1401,6 +1395,16 @@ static void mtk_hdmi_bridge_pre_enable(struct drm_bridge *bridge) hdmi->powered = true; }
+static void mtk_hdmi_send_infoframe(struct mtk_hdmi *hdmi, + struct drm_display_mode *mode) +{ + mtk_hdmi_setup_audio_infoframe(hdmi); + mtk_hdmi_setup_avi_infoframe(hdmi, mode); + mtk_hdmi_setup_spd_infoframe(hdmi, "mediatek", "On-chip HDMI"); + if (mode->flags & DRM_MODE_FLAG_3D_MASK) + mtk_hdmi_setup_vendor_specific_infoframe(hdmi, mode); +} + static void mtk_hdmi_bridge_enable(struct drm_bridge *bridge) { struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge); @@ -1409,6 +1413,7 @@ static void mtk_hdmi_bridge_enable(struct drm_bridge *bridge) clk_prepare_enable(hdmi->clk[MTK_HDMI_CLK_HDMI_PLL]); clk_prepare_enable(hdmi->clk[MTK_HDMI_CLK_HDMI_PIXEL]); phy_power_on(hdmi->phy); + mtk_hdmi_send_infoframe(hdmi, &hdmi->mode);
hdmi->enabled = true; }
From: Junzhi Zhao junzhi.zhao@mediatek.com
In order to improve 4K resolution performance, we have to enhance the HDMI driving current when clock rate is greater than 165MHz.
Signed-off-by: Junzhi Zhao junzhi.zhao@mediatek.com Signed-off-by: Bibby Hsieh bibby.hsieh@mediatek.com --- drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c | 42 +++++++++++++++++------- 1 file changed, 30 insertions(+), 12 deletions(-)
diff --git a/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c b/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c index 8a24754..51cb9cf 100644 --- a/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c +++ b/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c @@ -265,6 +265,9 @@ static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate, struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw); unsigned int pre_div; unsigned int div; + unsigned int pre_ibias; + unsigned int hdmi_ibias; + unsigned int imp_en;
dev_dbg(hdmi_phy->dev, "%s: %lu Hz, parent: %lu Hz\n", __func__, rate, parent_rate); @@ -298,18 +301,31 @@ static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate, (0x1 << PLL_BR_SHIFT), RG_HDMITX_PLL_BP | RG_HDMITX_PLL_BC | RG_HDMITX_PLL_BR); - mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON3, RG_HDMITX_PRD_IMP_EN); + if (rate < 165000000) { + mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON3, + RG_HDMITX_PRD_IMP_EN); + pre_ibias = 0x3; + imp_en = 0x0; + hdmi_ibias = hdmi_phy->ibias; + } else { + mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON3, + RG_HDMITX_PRD_IMP_EN); + pre_ibias = 0x6; + imp_en = 0xf; + hdmi_ibias = hdmi_phy->ibias_up; + } mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON4, - (0x3 << PRD_IBIAS_CLK_SHIFT) | - (0x3 << PRD_IBIAS_D2_SHIFT) | - (0x3 << PRD_IBIAS_D1_SHIFT) | - (0x3 << PRD_IBIAS_D0_SHIFT), + (pre_ibias << PRD_IBIAS_CLK_SHIFT) | + (pre_ibias << PRD_IBIAS_D2_SHIFT) | + (pre_ibias << PRD_IBIAS_D1_SHIFT) | + (pre_ibias << PRD_IBIAS_D0_SHIFT), RG_HDMITX_PRD_IBIAS_CLK | RG_HDMITX_PRD_IBIAS_D2 | RG_HDMITX_PRD_IBIAS_D1 | RG_HDMITX_PRD_IBIAS_D0); mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON3, - (0x0 << DRV_IMP_EN_SHIFT), RG_HDMITX_DRV_IMP_EN); + (imp_en << DRV_IMP_EN_SHIFT), + RG_HDMITX_DRV_IMP_EN); mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON6, (hdmi_phy->drv_imp_clk << DRV_IMP_CLK_SHIFT) | (hdmi_phy->drv_imp_d2 << DRV_IMP_D2_SHIFT) | @@ -318,12 +334,14 @@ static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate, RG_HDMITX_DRV_IMP_CLK | RG_HDMITX_DRV_IMP_D2 | RG_HDMITX_DRV_IMP_D1 | RG_HDMITX_DRV_IMP_D0); mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON5, - (hdmi_phy->ibias << DRV_IBIAS_CLK_SHIFT) | - (hdmi_phy->ibias << DRV_IBIAS_D2_SHIFT) | - (hdmi_phy->ibias << DRV_IBIAS_D1_SHIFT) | - (hdmi_phy->ibias << DRV_IBIAS_D0_SHIFT), - RG_HDMITX_DRV_IBIAS_CLK | RG_HDMITX_DRV_IBIAS_D2 | - RG_HDMITX_DRV_IBIAS_D1 | RG_HDMITX_DRV_IBIAS_D0); + (hdmi_ibias << DRV_IBIAS_CLK_SHIFT) | + (hdmi_ibias << DRV_IBIAS_D2_SHIFT) | + (hdmi_ibias << DRV_IBIAS_D1_SHIFT) | + (hdmi_ibias << DRV_IBIAS_D0_SHIFT), + RG_HDMITX_DRV_IBIAS_CLK | + RG_HDMITX_DRV_IBIAS_D2 | + RG_HDMITX_DRV_IBIAS_D1 | + RG_HDMITX_DRV_IBIAS_D0); return 0; }
From: Junzhi Zhao junzhi.zhao@mediatek.com
Pixel clock should be 297MHz when resolution is 4K.
Signed-off-by: Junzhi Zhao junzhi.zhao@mediatek.com Signed-off-by: Bibby Hsieh bibby.hsieh@mediatek.com --- drivers/gpu/drm/mediatek/mtk_dpi.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c index d05ca79..a90af59 100644 --- a/drivers/gpu/drm/mediatek/mtk_dpi.c +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c @@ -438,10 +438,14 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi, }
pix_rate = 1000UL * mode->clock; - if (mode->clock <= 74000) + if (mode->clock <= 27000) + factor = 16 * 3; + else if (mode->clock <= 74250) factor = 8 * 3; - else + else if (mode->clock <= 167000) factor = 4 * 3; + else + factor = 2 * 3; pll_rate = pix_rate * factor;
dev_dbg(dpi->dev, "Want PLL %lu Hz, pixel clock %lu Hz\n",
Am Donnerstag, den 04.08.2016, 10:38 +0800 schrieb Bibby Hsieh:
From: Junzhi Zhao junzhi.zhao@mediatek.com
Pixel clock should be 297MHz when resolution is 4K.
Signed-off-by: Junzhi Zhao junzhi.zhao@mediatek.com Signed-off-by: Bibby Hsieh bibby.hsieh@mediatek.com
drivers/gpu/drm/mediatek/mtk_dpi.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c index d05ca79..a90af59 100644 --- a/drivers/gpu/drm/mediatek/mtk_dpi.c +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c @@ -438,10 +438,14 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi, }
pix_rate = 1000UL * mode->clock;
- if (mode->clock <= 74000)
- if (mode->clock <= 27000)
factor = 16 * 3;
- else if (mode->clock <= 74250) factor = 8 * 3;
- else
else if (mode->clock <= 167000) factor = 4 * 3;
else
factor = 2 * 3;
pll_rate = pix_rate * factor;
dev_dbg(dpi->dev, "Want PLL %lu Hz, pixel clock %lu Hz\n",
Could you add a comment why this also changes the 74 MHz limit to 74.25 MHz and that adds a factor 16*3 for clocks <= 27 MHz ?
regards Philipp
Hi, Philipp,
On Thu, 2016-08-11 at 09:15 +0200, Philipp Zabel wrote:
Am Donnerstag, den 04.08.2016, 10:38 +0800 schrieb Bibby Hsieh:
From: Junzhi Zhao junzhi.zhao@mediatek.com
Pixel clock should be 297MHz when resolution is 4K.
Signed-off-by: Junzhi Zhao junzhi.zhao@mediatek.com Signed-off-by: Bibby Hsieh bibby.hsieh@mediatek.com
drivers/gpu/drm/mediatek/mtk_dpi.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c index d05ca79..a90af59 100644 --- a/drivers/gpu/drm/mediatek/mtk_dpi.c +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c @@ -438,10 +438,14 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi, }
pix_rate = 1000UL * mode->clock;
- if (mode->clock <= 74000)
- if (mode->clock <= 27000)
factor = 16 * 3;
- else if (mode->clock <= 74250) factor = 8 * 3;
- else
else if (mode->clock <= 167000) factor = 4 * 3;
else
factor = 2 * 3;
pll_rate = pix_rate * factor;
dev_dbg(dpi->dev, "Want PLL %lu Hz, pixel clock %lu Hz\n",
Could you add a comment why this also changes the 74 MHz limit to 74.25 MHz and that adds a factor 16*3 for clocks <= 27 MHz ?
Because the valid range of tvdpll is from 1GHz to 2GHz, so, we have to make the clock to fit that.
regards Philipp
dri-devel@lists.freedesktop.org