Hi Inki,
This set of patches provides set of different fixes and enhancements for DECON -> HDMI path. It is based on: - my HDMI patches which are not yet merged[1], could you look at them by the way, they were posted about 5 months ago :) - IOMMU patches by Marek (for some mysterious reason HDMI path on 5433 works only with IOMMU enabled), - latest exynos-drm-next patches.
[1]: http://permalink.gmane.org/gmane.comp.video.dri.devel/140109
Regards Andrzej
Andrzej Hajda (7): drm/exynos/hdmi: fix PHY configuration sequence drm/exynos/hdmi: add PHY power off signal handling drm/exynos/hdmi: add core reset code drm/exynos/hdmi: remove registry dump drm/exynos/decon5433: fix DECON standalone update drm/exynos/decon5433: reset decon on start drm/exynos/decon5433: do not protect window in plane disable
drivers/gpu/drm/exynos/exynos5433_drm_decon.c | 22 +- drivers/gpu/drm/exynos/exynos_hdmi.c | 293 ++------------------------ 2 files changed, 29 insertions(+), 286 deletions(-)
Proper PHY configuration should be as follow: 1. set HDMI clock parents to OSCCLK. 2. reconfigure PHY. 3. set HDMI clock parents to PHY. 4. wait for PLL stabilization.
The patch fixes it and consolidates the code.
Signed-off-by: Andrzej Hajda a.hajda@samsung.com --- drivers/gpu/drm/exynos/exynos_hdmi.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-)
diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c index 839ad70..5c7dbfc 100644 --- a/drivers/gpu/drm/exynos/exynos_hdmi.c +++ b/drivers/gpu/drm/exynos/exynos_hdmi.c @@ -1657,15 +1657,11 @@ static void hdmi_mode_apply(struct hdmi_context *hdata) else hdmi_v14_mode_apply(hdata);
- hdmiphy_wait_for_pll(hdata); - hdmi_clk_set_parents(hdata, true); hdmi_start(hdata, true); }
static void hdmiphy_conf_reset(struct hdmi_context *hdata) { - hdmi_clk_set_parents(hdata, false); - hdmi_reg_writemask(hdata, HDMI_PHY_RSTOUT, ~0, HDMI_PHY_SW_RSTOUT); usleep_range(10000, 12000); hdmi_reg_writemask(hdata, HDMI_PHY_RSTOUT, 0, HDMI_PHY_SW_RSTOUT); @@ -1683,29 +1679,33 @@ static void hdmiphy_enable_mode_set(struct hdmi_context *hdata, bool enable) static void hdmiphy_conf_apply(struct hdmi_context *hdata) { int ret; - int i; + const u8 *phy_conf;
- i = hdmi_find_phy_conf(hdata, hdata->current_mode.clock * 1000); - if (i < 0) { + ret = hdmi_find_phy_conf(hdata, hdata->current_mode.clock * 1000); + if (ret < 0) { DRM_ERROR("failed to find hdmiphy conf\n"); return; } + phy_conf = hdata->drv_data->phy_confs.data[ret].conf; + + hdmi_clk_set_parents(hdata, false); + + hdmiphy_conf_reset(hdata);
hdmiphy_enable_mode_set(hdata, true); - ret = hdmiphy_reg_write_buf(hdata, 0, - hdata->drv_data->phy_confs.data[i].conf, 32); + ret = hdmiphy_reg_write_buf(hdata, 0, phy_conf, 32); if (ret) { DRM_ERROR("failed to configure hdmiphy\n"); return; } hdmiphy_enable_mode_set(hdata, false); - + hdmi_clk_set_parents(hdata, true); usleep_range(10000, 12000); + hdmiphy_wait_for_pll(hdata); }
static void hdmi_conf_apply(struct hdmi_context *hdata) { - hdmiphy_conf_reset(hdata); hdmiphy_conf_apply(hdata); hdmi_start(hdata, false); hdmi_conf_init(hdata);
HDMI-PHY power off bit defaults to 0 in older HDMI versions. In case of Exynos5433 it defaults to 1. To make code consistent across all versions this bit is always unset/set in power on/off sequences.
Signed-off-by: Andrzej Hajda a.hajda@samsung.com --- drivers/gpu/drm/exynos/exynos_hdmi.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c index 5c7dbfc..16951f3 100644 --- a/drivers/gpu/drm/exynos/exynos_hdmi.c +++ b/drivers/gpu/drm/exynos/exynos_hdmi.c @@ -1757,6 +1757,8 @@ static void hdmi_enable(struct drm_encoder *encoder)
hdmi_set_refclk(hdata, true);
+ hdmi_reg_writemask(hdata, HDMI_PHY_CON_0, 0, HDMI_PHY_POWER_OFF_EN); + hdmi_conf_apply(hdata);
hdata->powered = true; @@ -1789,6 +1791,8 @@ static void hdmi_disable(struct drm_encoder *encoder)
cancel_delayed_work(&hdata->hotplug_work);
+ hdmi_reg_writemask(hdata, HDMI_PHY_CON_0, ~0, HDMI_PHY_POWER_OFF_EN); + hdmi_set_refclk(hdata, false);
regmap_update_bits(hdata->pmureg, PMU_HDMI_PHY_CONTROL,
To ensure HDMI-PHY reprogramming will not affect HDMI the latter should be reset.
Signed-off-by: Andrzej Hajda a.hajda@samsung.com --- drivers/gpu/drm/exynos/exynos_hdmi.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c index 16951f3..6faa104 100644 --- a/drivers/gpu/drm/exynos/exynos_hdmi.c +++ b/drivers/gpu/drm/exynos/exynos_hdmi.c @@ -1662,6 +1662,10 @@ static void hdmi_mode_apply(struct hdmi_context *hdata)
static void hdmiphy_conf_reset(struct hdmi_context *hdata) { + hdmi_reg_writemask(hdata, HDMI_CORE_RSTOUT, 0, 1); + usleep_range(10000, 12000); + hdmi_reg_writemask(hdata, HDMI_CORE_RSTOUT, ~0, 1); + usleep_range(10000, 12000); hdmi_reg_writemask(hdata, HDMI_PHY_RSTOUT, ~0, HDMI_PHY_SW_RSTOUT); usleep_range(10000, 12000); hdmi_reg_writemask(hdata, HDMI_PHY_RSTOUT, 0, HDMI_PHY_SW_RSTOUT);
HDMI registry dump unnecessary spoils console and is not very helpful.
Signed-off-by: Andrzej Hajda a.hajda@samsung.com --- drivers/gpu/drm/exynos/exynos_hdmi.c | 263 ----------------------------------- 1 file changed, 263 deletions(-)
diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c index 6faa104..49a5902 100644 --- a/drivers/gpu/drm/exynos/exynos_hdmi.c +++ b/drivers/gpu/drm/exynos/exynos_hdmi.c @@ -716,268 +716,6 @@ static int hdmiphy_reg_write_buf(struct hdmi_context *hdata, } }
-static void hdmi_v13_regs_dump(struct hdmi_context *hdata, char *prefix) -{ -#define DUMPREG(reg_id) \ - DRM_DEBUG_KMS("%s:" #reg_id " = %08x\n", prefix, \ - readl(hdata->regs + reg_id)) - DRM_DEBUG_KMS("%s: ---- CONTROL REGISTERS ----\n", prefix); - DUMPREG(HDMI_INTC_FLAG); - DUMPREG(HDMI_INTC_CON); - DUMPREG(HDMI_HPD_STATUS); - DUMPREG(HDMI_V13_PHY_RSTOUT); - DUMPREG(HDMI_V13_PHY_VPLL); - DUMPREG(HDMI_V13_PHY_CMU); - DUMPREG(HDMI_V13_CORE_RSTOUT); - - DRM_DEBUG_KMS("%s: ---- CORE REGISTERS ----\n", prefix); - DUMPREG(HDMI_CON_0); - DUMPREG(HDMI_CON_1); - DUMPREG(HDMI_CON_2); - DUMPREG(HDMI_SYS_STATUS); - DUMPREG(HDMI_V13_PHY_STATUS); - DUMPREG(HDMI_STATUS_EN); - DUMPREG(HDMI_HPD); - DUMPREG(HDMI_MODE_SEL); - DUMPREG(HDMI_V13_HPD_GEN); - DUMPREG(HDMI_V13_DC_CONTROL); - DUMPREG(HDMI_V13_VIDEO_PATTERN_GEN); - - DRM_DEBUG_KMS("%s: ---- CORE SYNC REGISTERS ----\n", prefix); - DUMPREG(HDMI_H_BLANK_0); - DUMPREG(HDMI_H_BLANK_1); - DUMPREG(HDMI_V13_V_BLANK_0); - DUMPREG(HDMI_V13_V_BLANK_1); - DUMPREG(HDMI_V13_V_BLANK_2); - DUMPREG(HDMI_V13_H_V_LINE_0); - DUMPREG(HDMI_V13_H_V_LINE_1); - DUMPREG(HDMI_V13_H_V_LINE_2); - DUMPREG(HDMI_VSYNC_POL); - DUMPREG(HDMI_INT_PRO_MODE); - DUMPREG(HDMI_V13_V_BLANK_F_0); - DUMPREG(HDMI_V13_V_BLANK_F_1); - DUMPREG(HDMI_V13_V_BLANK_F_2); - DUMPREG(HDMI_V13_H_SYNC_GEN_0); - DUMPREG(HDMI_V13_H_SYNC_GEN_1); - DUMPREG(HDMI_V13_H_SYNC_GEN_2); - DUMPREG(HDMI_V13_V_SYNC_GEN_1_0); - DUMPREG(HDMI_V13_V_SYNC_GEN_1_1); - DUMPREG(HDMI_V13_V_SYNC_GEN_1_2); - DUMPREG(HDMI_V13_V_SYNC_GEN_2_0); - DUMPREG(HDMI_V13_V_SYNC_GEN_2_1); - DUMPREG(HDMI_V13_V_SYNC_GEN_2_2); - DUMPREG(HDMI_V13_V_SYNC_GEN_3_0); - DUMPREG(HDMI_V13_V_SYNC_GEN_3_1); - DUMPREG(HDMI_V13_V_SYNC_GEN_3_2); - - DRM_DEBUG_KMS("%s: ---- TG REGISTERS ----\n", prefix); - DUMPREG(HDMI_TG_CMD); - DUMPREG(HDMI_TG_H_FSZ_L); - DUMPREG(HDMI_TG_H_FSZ_H); - DUMPREG(HDMI_TG_HACT_ST_L); - DUMPREG(HDMI_TG_HACT_ST_H); - DUMPREG(HDMI_TG_HACT_SZ_L); - DUMPREG(HDMI_TG_HACT_SZ_H); - DUMPREG(HDMI_TG_V_FSZ_L); - DUMPREG(HDMI_TG_V_FSZ_H); - DUMPREG(HDMI_TG_VSYNC_L); - DUMPREG(HDMI_TG_VSYNC_H); - DUMPREG(HDMI_TG_VSYNC2_L); - DUMPREG(HDMI_TG_VSYNC2_H); - DUMPREG(HDMI_TG_VACT_ST_L); - DUMPREG(HDMI_TG_VACT_ST_H); - DUMPREG(HDMI_TG_VACT_SZ_L); - DUMPREG(HDMI_TG_VACT_SZ_H); - DUMPREG(HDMI_TG_FIELD_CHG_L); - DUMPREG(HDMI_TG_FIELD_CHG_H); - DUMPREG(HDMI_TG_VACT_ST2_L); - DUMPREG(HDMI_TG_VACT_ST2_H); - DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_L); - DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_H); - DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_L); - DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_H); - DUMPREG(HDMI_TG_FIELD_TOP_HDMI_L); - DUMPREG(HDMI_TG_FIELD_TOP_HDMI_H); - DUMPREG(HDMI_TG_FIELD_BOT_HDMI_L); - DUMPREG(HDMI_TG_FIELD_BOT_HDMI_H); -#undef DUMPREG -} - -static void hdmi_v14_regs_dump(struct hdmi_context *hdata, char *prefix) -{ - int i; - -#define DUMPREG(reg_id) \ - DRM_DEBUG_KMS("%s:" #reg_id " = %08x\n", prefix, \ - readl(hdata->regs + reg_id)) - - DRM_DEBUG_KMS("%s: ---- CONTROL REGISTERS ----\n", prefix); - DUMPREG(HDMI_INTC_CON); - DUMPREG(HDMI_INTC_FLAG); - DUMPREG(HDMI_HPD_STATUS); - DUMPREG(HDMI_INTC_CON_1); - DUMPREG(HDMI_INTC_FLAG_1); - DUMPREG(HDMI_PHY_STATUS_0); - DUMPREG(HDMI_PHY_STATUS_PLL); - DUMPREG(HDMI_PHY_CON_0); - DUMPREG(HDMI_V14_PHY_RSTOUT); - DUMPREG(HDMI_PHY_VPLL); - DUMPREG(HDMI_PHY_CMU); - DUMPREG(HDMI_CORE_RSTOUT); - - DRM_DEBUG_KMS("%s: ---- CORE REGISTERS ----\n", prefix); - DUMPREG(HDMI_CON_0); - DUMPREG(HDMI_CON_1); - DUMPREG(HDMI_CON_2); - DUMPREG(HDMI_SYS_STATUS); - DUMPREG(HDMI_PHY_STATUS_0); - DUMPREG(HDMI_STATUS_EN); - DUMPREG(HDMI_HPD); - DUMPREG(HDMI_MODE_SEL); - DUMPREG(HDMI_ENC_EN); - DUMPREG(HDMI_DC_CONTROL); - DUMPREG(HDMI_VIDEO_PATTERN_GEN); - - DRM_DEBUG_KMS("%s: ---- CORE SYNC REGISTERS ----\n", prefix); - DUMPREG(HDMI_H_BLANK_0); - DUMPREG(HDMI_H_BLANK_1); - DUMPREG(HDMI_V2_BLANK_0); - DUMPREG(HDMI_V2_BLANK_1); - DUMPREG(HDMI_V1_BLANK_0); - DUMPREG(HDMI_V1_BLANK_1); - DUMPREG(HDMI_V_LINE_0); - DUMPREG(HDMI_V_LINE_1); - DUMPREG(HDMI_H_LINE_0); - DUMPREG(HDMI_H_LINE_1); - DUMPREG(HDMI_HSYNC_POL); - - DUMPREG(HDMI_VSYNC_POL); - DUMPREG(HDMI_INT_PRO_MODE); - DUMPREG(HDMI_V_BLANK_F0_0); - DUMPREG(HDMI_V_BLANK_F0_1); - DUMPREG(HDMI_V_BLANK_F1_0); - DUMPREG(HDMI_V_BLANK_F1_1); - - DUMPREG(HDMI_H_SYNC_START_0); - DUMPREG(HDMI_H_SYNC_START_1); - DUMPREG(HDMI_H_SYNC_END_0); - DUMPREG(HDMI_H_SYNC_END_1); - - DUMPREG(HDMI_V_SYNC_LINE_BEF_2_0); - DUMPREG(HDMI_V_SYNC_LINE_BEF_2_1); - DUMPREG(HDMI_V_SYNC_LINE_BEF_1_0); - DUMPREG(HDMI_V_SYNC_LINE_BEF_1_1); - - DUMPREG(HDMI_V_SYNC_LINE_AFT_2_0); - DUMPREG(HDMI_V_SYNC_LINE_AFT_2_1); - DUMPREG(HDMI_V_SYNC_LINE_AFT_1_0); - DUMPREG(HDMI_V_SYNC_LINE_AFT_1_1); - - DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_2_0); - DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_2_1); - DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_1_0); - DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_1_1); - - DUMPREG(HDMI_V_BLANK_F2_0); - DUMPREG(HDMI_V_BLANK_F2_1); - DUMPREG(HDMI_V_BLANK_F3_0); - DUMPREG(HDMI_V_BLANK_F3_1); - DUMPREG(HDMI_V_BLANK_F4_0); - DUMPREG(HDMI_V_BLANK_F4_1); - DUMPREG(HDMI_V_BLANK_F5_0); - DUMPREG(HDMI_V_BLANK_F5_1); - - DUMPREG(HDMI_V_SYNC_LINE_AFT_3_0); - DUMPREG(HDMI_V_SYNC_LINE_AFT_3_1); - DUMPREG(HDMI_V_SYNC_LINE_AFT_4_0); - DUMPREG(HDMI_V_SYNC_LINE_AFT_4_1); - DUMPREG(HDMI_V_SYNC_LINE_AFT_5_0); - DUMPREG(HDMI_V_SYNC_LINE_AFT_5_1); - DUMPREG(HDMI_V_SYNC_LINE_AFT_6_0); - DUMPREG(HDMI_V_SYNC_LINE_AFT_6_1); - - DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_3_0); - DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_3_1); - DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_4_0); - DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_4_1); - DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_5_0); - DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_5_1); - DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_6_0); - DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_6_1); - - DUMPREG(HDMI_VACT_SPACE_1_0); - DUMPREG(HDMI_VACT_SPACE_1_1); - DUMPREG(HDMI_VACT_SPACE_2_0); - DUMPREG(HDMI_VACT_SPACE_2_1); - DUMPREG(HDMI_VACT_SPACE_3_0); - DUMPREG(HDMI_VACT_SPACE_3_1); - DUMPREG(HDMI_VACT_SPACE_4_0); - DUMPREG(HDMI_VACT_SPACE_4_1); - DUMPREG(HDMI_VACT_SPACE_5_0); - DUMPREG(HDMI_VACT_SPACE_5_1); - DUMPREG(HDMI_VACT_SPACE_6_0); - DUMPREG(HDMI_VACT_SPACE_6_1); - - DRM_DEBUG_KMS("%s: ---- TG REGISTERS ----\n", prefix); - DUMPREG(HDMI_TG_CMD); - DUMPREG(HDMI_TG_H_FSZ_L); - DUMPREG(HDMI_TG_H_FSZ_H); - DUMPREG(HDMI_TG_HACT_ST_L); - DUMPREG(HDMI_TG_HACT_ST_H); - DUMPREG(HDMI_TG_HACT_SZ_L); - DUMPREG(HDMI_TG_HACT_SZ_H); - DUMPREG(HDMI_TG_V_FSZ_L); - DUMPREG(HDMI_TG_V_FSZ_H); - DUMPREG(HDMI_TG_VSYNC_L); - DUMPREG(HDMI_TG_VSYNC_H); - DUMPREG(HDMI_TG_VSYNC2_L); - DUMPREG(HDMI_TG_VSYNC2_H); - DUMPREG(HDMI_TG_VACT_ST_L); - DUMPREG(HDMI_TG_VACT_ST_H); - DUMPREG(HDMI_TG_VACT_SZ_L); - DUMPREG(HDMI_TG_VACT_SZ_H); - DUMPREG(HDMI_TG_FIELD_CHG_L); - DUMPREG(HDMI_TG_FIELD_CHG_H); - DUMPREG(HDMI_TG_VACT_ST2_L); - DUMPREG(HDMI_TG_VACT_ST2_H); - DUMPREG(HDMI_TG_VACT_ST3_L); - DUMPREG(HDMI_TG_VACT_ST3_H); - DUMPREG(HDMI_TG_VACT_ST4_L); - DUMPREG(HDMI_TG_VACT_ST4_H); - DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_L); - DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_H); - DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_L); - DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_H); - DUMPREG(HDMI_TG_FIELD_TOP_HDMI_L); - DUMPREG(HDMI_TG_FIELD_TOP_HDMI_H); - DUMPREG(HDMI_TG_FIELD_BOT_HDMI_L); - DUMPREG(HDMI_TG_FIELD_BOT_HDMI_H); - DUMPREG(HDMI_TG_3D); - - DRM_DEBUG_KMS("%s: ---- PACKET REGISTERS ----\n", prefix); - DUMPREG(HDMI_AVI_CON); - DUMPREG(HDMI_AVI_HEADER0); - DUMPREG(HDMI_AVI_HEADER1); - DUMPREG(HDMI_AVI_HEADER2); - DUMPREG(HDMI_AVI_CHECK_SUM); - DUMPREG(HDMI_VSI_CON); - DUMPREG(HDMI_VSI_HEADER0); - DUMPREG(HDMI_VSI_HEADER1); - DUMPREG(HDMI_VSI_HEADER2); - for (i = 0; i < 7; ++i) - DUMPREG(HDMI_VSI_DATA(i)); - -#undef DUMPREG -} - -static void hdmi_regs_dump(struct hdmi_context *hdata, char *prefix) -{ - if (hdata->drv_data->type == HDMI_TYPE13) - hdmi_v13_regs_dump(hdata, prefix); - else - hdmi_v14_regs_dump(hdata, prefix); -} - static int hdmi_clk_enable_gates(struct hdmi_context *hdata) { int i, ret; @@ -1716,7 +1454,6 @@ static void hdmi_conf_apply(struct hdmi_context *hdata) hdmi_audio_init(hdata); hdmi_mode_apply(hdata); hdmi_audio_control(hdata, true); - hdmi_regs_dump(hdata, "start"); }
static void hdmi_mode_set(struct drm_encoder *encoder,
DECON should be updated after un-protecting windows and after changing output parameters, otherwise image is not displayed in case of HDMI path.
Signed-off-by: Andrzej Hajda a.hajda@samsung.com --- drivers/gpu/drm/exynos/exynos5433_drm_decon.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c index ab9154e..7fec656 100644 --- a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c +++ b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c @@ -191,6 +191,8 @@ static void decon_commit(struct exynos_drm_crtc *crtc)
/* enable output and display signal */ decon_set_bits(ctx, DECON_VIDCON0, VIDCON0_ENVID | VIDCON0_ENVID_F, ~0); + + decon_set_bits(ctx, DECON_UPDATE, STANDALONE_UPDATE_F, ~0); }
static void decon_win_set_pixfmt(struct decon_context *ctx, unsigned int win, @@ -316,9 +318,6 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc,
/* window enable */ decon_set_bits(ctx, DECON_WINCONx(win), WINCONx_ENWIN_F, ~0); - - /* standalone update */ - decon_set_bits(ctx, DECON_UPDATE, STANDALONE_UPDATE_F, ~0); }
static void decon_disable_plane(struct exynos_drm_crtc *crtc, @@ -336,9 +335,6 @@ static void decon_disable_plane(struct exynos_drm_crtc *crtc, decon_set_bits(ctx, DECON_WINCONx(win), WINCONx_ENWIN_F, 0);
decon_shadow_protect_win(ctx, win, false); - - /* standalone update */ - decon_set_bits(ctx, DECON_UPDATE, STANDALONE_UPDATE_F, ~0); }
static void decon_atomic_flush(struct exynos_drm_crtc *crtc) @@ -352,6 +348,9 @@ static void decon_atomic_flush(struct exynos_drm_crtc *crtc) for (i = ctx->first_win; i < WINDOWS_NR; i++) decon_shadow_protect_win(ctx, i, false);
+ /* standalone update */ + decon_set_bits(ctx, DECON_UPDATE, STANDALONE_UPDATE_F, ~0); + if (ctx->out_type == IFTYPE_I80) set_bit(BIT_WIN_UPDATED, &ctx->flags); } @@ -463,8 +462,10 @@ static void decon_clear_channels(struct exynos_drm_crtc *crtc) decon_shadow_protect_win(ctx, win, true); decon_set_bits(ctx, DECON_WINCONx(win), WINCONx_ENWIN_F, 0); decon_shadow_protect_win(ctx, win, false); - decon_set_bits(ctx, DECON_UPDATE, STANDALONE_UPDATE_F, ~0); } + + decon_set_bits(ctx, DECON_UPDATE, STANDALONE_UPDATE_F, ~0); + /* TODO: wait for possible vsync */ msleep(50);
Hi Andrzej,
2016년 03월 23일 22:15에 Andrzej Hajda 이(가) 쓴 글:
DECON should be updated after un-protecting windows and after changing output parameters, otherwise image is not displayed in case of HDMI path.
I'm not sure why STANDALONE_UPDATE_F bit should be updated after un-protecting windows and changing output parameters. The fields with _F prefix mean that these will be applied after vsync so we use protection window in case of all registers which affect display output so that they can be updated together.
Wouldn't there be other thing which affects HDMI output?
In addition, we would need another patch which updates TV relevant registers only in case of DECON-TV. DECON_UPDATE is a register for DECON-TV.
Thanks, Inki Dae
Signed-off-by: Andrzej Hajda a.hajda@samsung.com
drivers/gpu/drm/exynos/exynos5433_drm_decon.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c index ab9154e..7fec656 100644 --- a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c +++ b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c @@ -191,6 +191,8 @@ static void decon_commit(struct exynos_drm_crtc *crtc)
/* enable output and display signal */ decon_set_bits(ctx, DECON_VIDCON0, VIDCON0_ENVID | VIDCON0_ENVID_F, ~0);
- decon_set_bits(ctx, DECON_UPDATE, STANDALONE_UPDATE_F, ~0);
}
static void decon_win_set_pixfmt(struct decon_context *ctx, unsigned int win, @@ -316,9 +318,6 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc,
/* window enable */ decon_set_bits(ctx, DECON_WINCONx(win), WINCONx_ENWIN_F, ~0);
- /* standalone update */
- decon_set_bits(ctx, DECON_UPDATE, STANDALONE_UPDATE_F, ~0);
}
static void decon_disable_plane(struct exynos_drm_crtc *crtc, @@ -336,9 +335,6 @@ static void decon_disable_plane(struct exynos_drm_crtc *crtc, decon_set_bits(ctx, DECON_WINCONx(win), WINCONx_ENWIN_F, 0);
decon_shadow_protect_win(ctx, win, false);
- /* standalone update */
- decon_set_bits(ctx, DECON_UPDATE, STANDALONE_UPDATE_F, ~0);
}
static void decon_atomic_flush(struct exynos_drm_crtc *crtc) @@ -352,6 +348,9 @@ static void decon_atomic_flush(struct exynos_drm_crtc *crtc) for (i = ctx->first_win; i < WINDOWS_NR; i++) decon_shadow_protect_win(ctx, i, false);
- /* standalone update */
- decon_set_bits(ctx, DECON_UPDATE, STANDALONE_UPDATE_F, ~0);
- if (ctx->out_type == IFTYPE_I80) set_bit(BIT_WIN_UPDATED, &ctx->flags);
} @@ -463,8 +462,10 @@ static void decon_clear_channels(struct exynos_drm_crtc *crtc) decon_shadow_protect_win(ctx, win, true); decon_set_bits(ctx, DECON_WINCONx(win), WINCONx_ENWIN_F, 0); decon_shadow_protect_win(ctx, win, false);
}decon_set_bits(ctx, DECON_UPDATE, STANDALONE_UPDATE_F, ~0);
- decon_set_bits(ctx, DECON_UPDATE, STANDALONE_UPDATE_F, ~0);
- /* TODO: wait for possible vsync */ msleep(50);
On 04/12/2016 04:25 AM, Inki Dae wrote:
Hi Andrzej,
2016년 03월 23일 22:15에 Andrzej Hajda 이(가) 쓴 글:
DECON should be updated after un-protecting windows and after changing output parameters, otherwise image is not displayed in case of HDMI path.
I'm not sure why STANDALONE_UPDATE_F bit should be updated after un-protecting windows and changing output parameters. The fields with _F prefix mean that these will be applied after vsync so we use protection window in case of all registers which affect display output so that they can be updated together.
Wouldn't there be other thing which affects HDMI output?
In addition, we would need another patch which updates TV relevant registers only in case of DECON-TV. DECON_UPDATE is a register for DECON-TV.
DECON_UPDATE is present in both DECON and DECON-TV and in both cases have the same field STANDALONE_UPDATE_F.
Documentation for 5433 says:
When you modify the shadow attributed registers, set STANDALONE_UPDATE_F.
So it should be set after setting registers with _F suffix, but it has also _F suffix - contradiction. So I guess this _F suffix should not be treated too strictly in this case. Moreover the suffix has been removed in Exynos7420 - it is called just STANDALONE_UPDATE.
Anyway I am not sure what is exact purpose of this register and the changes proposed in the patch are rather results of multiple tests with hardware - documentation is rather poor on this subject.
I am also not sure why DECON works without it but DECON-TV does not, anyway I set it in both variants because documentation says so.
Regards Andrzej
Thanks, Inki Dae
Signed-off-by: Andrzej Hajda a.hajda@samsung.com
drivers/gpu/drm/exynos/exynos5433_drm_decon.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c index ab9154e..7fec656 100644 --- a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c +++ b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c @@ -191,6 +191,8 @@ static void decon_commit(struct exynos_drm_crtc *crtc)
/* enable output and display signal */ decon_set_bits(ctx, DECON_VIDCON0, VIDCON0_ENVID | VIDCON0_ENVID_F, ~0);
- decon_set_bits(ctx, DECON_UPDATE, STANDALONE_UPDATE_F, ~0);
}
static void decon_win_set_pixfmt(struct decon_context *ctx, unsigned int win, @@ -316,9 +318,6 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc,
/* window enable */ decon_set_bits(ctx, DECON_WINCONx(win), WINCONx_ENWIN_F, ~0);
- /* standalone update */
- decon_set_bits(ctx, DECON_UPDATE, STANDALONE_UPDATE_F, ~0);
}
static void decon_disable_plane(struct exynos_drm_crtc *crtc, @@ -336,9 +335,6 @@ static void decon_disable_plane(struct exynos_drm_crtc *crtc, decon_set_bits(ctx, DECON_WINCONx(win), WINCONx_ENWIN_F, 0);
decon_shadow_protect_win(ctx, win, false);
- /* standalone update */
- decon_set_bits(ctx, DECON_UPDATE, STANDALONE_UPDATE_F, ~0);
}
static void decon_atomic_flush(struct exynos_drm_crtc *crtc) @@ -352,6 +348,9 @@ static void decon_atomic_flush(struct exynos_drm_crtc *crtc) for (i = ctx->first_win; i < WINDOWS_NR; i++) decon_shadow_protect_win(ctx, i, false);
- /* standalone update */
- decon_set_bits(ctx, DECON_UPDATE, STANDALONE_UPDATE_F, ~0);
- if (ctx->out_type == IFTYPE_I80) set_bit(BIT_WIN_UPDATED, &ctx->flags);
} @@ -463,8 +462,10 @@ static void decon_clear_channels(struct exynos_drm_crtc *crtc) decon_shadow_protect_win(ctx, win, true); decon_set_bits(ctx, DECON_WINCONx(win), WINCONx_ENWIN_F, 0); decon_shadow_protect_win(ctx, win, false);
}decon_set_bits(ctx, DECON_UPDATE, STANDALONE_UPDATE_F, ~0);
- decon_set_bits(ctx, DECON_UPDATE, STANDALONE_UPDATE_F, ~0);
- /* TODO: wait for possible vsync */ msleep(50);
2016년 04월 12일 16:33에 Andrzej Hajda 이(가) 쓴 글:
On 04/12/2016 04:25 AM, Inki Dae wrote:
Hi Andrzej,
2016년 03월 23일 22:15에 Andrzej Hajda 이(가) 쓴 글:
DECON should be updated after un-protecting windows and after changing output parameters, otherwise image is not displayed in case of HDMI path.
I'm not sure why STANDALONE_UPDATE_F bit should be updated after un-protecting windows and changing output parameters. The fields with _F prefix mean that these will be applied after vsync so we use protection window in case of all registers which affect display output so that they can be updated together.
Wouldn't there be other thing which affects HDMI output?
In addition, we would need another patch which updates TV relevant registers only in case of DECON-TV. DECON_UPDATE is a register for DECON-TV.
DECON_UPDATE is present in both DECON and DECON-TV and in both cases have the same field STANDALONE_UPDATE_F.
Documentation for 5433 says:
When you modify the shadow attributed registers, set STANDALONE_UPDATE_F.
So it should be set after setting registers with _F suffix, but it has also _F suffix - contradiction. So I guess this _F suffix should not be treated too strictly in this case. Moreover the suffix has been removed in Exynos7420 - it is called just STANDALONE_UPDATE.
Indeed. I thought the register name has TV suffix so this register is for DECON-TV. However, without the register setting, DECON didn't work correctly - display not updated.
Anyway I am not sure what is exact purpose of this register and the changes proposed in the patch are rather results of multiple tests with hardware - documentation is rather poor on this subject.
I am also not sure why DECON works without it but DECON-TV does not, anyway I set it in both variants because documentation says so.
Ok, picked them up.
Thanks, Inki Dae
Regards Andrzej
Thanks, Inki Dae
Signed-off-by: Andrzej Hajda a.hajda@samsung.com
drivers/gpu/drm/exynos/exynos5433_drm_decon.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c index ab9154e..7fec656 100644 --- a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c +++ b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c @@ -191,6 +191,8 @@ static void decon_commit(struct exynos_drm_crtc *crtc)
/* enable output and display signal */ decon_set_bits(ctx, DECON_VIDCON0, VIDCON0_ENVID | VIDCON0_ENVID_F, ~0);
- decon_set_bits(ctx, DECON_UPDATE, STANDALONE_UPDATE_F, ~0);
}
static void decon_win_set_pixfmt(struct decon_context *ctx, unsigned int win, @@ -316,9 +318,6 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc,
/* window enable */ decon_set_bits(ctx, DECON_WINCONx(win), WINCONx_ENWIN_F, ~0);
- /* standalone update */
- decon_set_bits(ctx, DECON_UPDATE, STANDALONE_UPDATE_F, ~0);
}
static void decon_disable_plane(struct exynos_drm_crtc *crtc, @@ -336,9 +335,6 @@ static void decon_disable_plane(struct exynos_drm_crtc *crtc, decon_set_bits(ctx, DECON_WINCONx(win), WINCONx_ENWIN_F, 0);
decon_shadow_protect_win(ctx, win, false);
- /* standalone update */
- decon_set_bits(ctx, DECON_UPDATE, STANDALONE_UPDATE_F, ~0);
}
static void decon_atomic_flush(struct exynos_drm_crtc *crtc) @@ -352,6 +348,9 @@ static void decon_atomic_flush(struct exynos_drm_crtc *crtc) for (i = ctx->first_win; i < WINDOWS_NR; i++) decon_shadow_protect_win(ctx, i, false);
- /* standalone update */
- decon_set_bits(ctx, DECON_UPDATE, STANDALONE_UPDATE_F, ~0);
- if (ctx->out_type == IFTYPE_I80) set_bit(BIT_WIN_UPDATED, &ctx->flags);
} @@ -463,8 +462,10 @@ static void decon_clear_channels(struct exynos_drm_crtc *crtc) decon_shadow_protect_win(ctx, win, true); decon_set_bits(ctx, DECON_WINCONx(win), WINCONx_ENWIN_F, 0); decon_shadow_protect_win(ctx, win, false);
}decon_set_bits(ctx, DECON_UPDATE, STANDALONE_UPDATE_F, ~0);
- decon_set_bits(ctx, DECON_UPDATE, STANDALONE_UPDATE_F, ~0);
- /* TODO: wait for possible vsync */ msleep(50);
Resetting IP at starting ensures that DECON will be in known state regardless of changes by bootloader.
Signed-off-by: Andrzej Hajda a.hajda@samsung.com --- drivers/gpu/drm/exynos/exynos5433_drm_decon.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c index 7fec656..120efd8 100644 --- a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c +++ b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c @@ -400,6 +400,8 @@ static void decon_enable(struct exynos_drm_crtc *crtc)
set_bit(BIT_CLKS_ENABLED, &ctx->flags);
+ decon_swreset(ctx); + /* if vblank was enabled status, enable it again. */ if (test_and_clear_bit(BIT_IRQS_ENABLED, &ctx->flags)) decon_enable_vblank(ctx->crtc);
decon_atomic_begin and decon_atomic_flush protects all windows already.
Signed-off-by: Andrzej Hajda a.hajda@samsung.com --- drivers/gpu/drm/exynos/exynos5433_drm_decon.c | 5 ----- 1 file changed, 5 deletions(-)
diff --git a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c index 120efd8..c8c921c 100644 --- a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c +++ b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c @@ -329,12 +329,7 @@ static void decon_disable_plane(struct exynos_drm_crtc *crtc, if (test_bit(BIT_SUSPENDED, &ctx->flags)) return;
- decon_shadow_protect_win(ctx, win, true); - - /* window disable */ decon_set_bits(ctx, DECON_WINCONx(win), WINCONx_ENWIN_F, 0); - - decon_shadow_protect_win(ctx, win, false); }
static void decon_atomic_flush(struct exynos_drm_crtc *crtc)
Hi Andrzej,
2016년 03월 23일 22:15에 Andrzej Hajda 이(가) 쓴 글:
Hi Inki,
This set of patches provides set of different fixes and enhancements for DECON -> HDMI path. It is based on:
- my HDMI patches which are not yet merged[1], could you look at them by the way, they were posted about 5 months ago :)
Oops, really sorry. Will have a review ASAP.
Thanks, Inki Dae
- IOMMU patches by Marek (for some mysterious reason HDMI path on 5433 works only with IOMMU enabled),
- latest exynos-drm-next patches.
Regards Andrzej
Andrzej Hajda (7): drm/exynos/hdmi: fix PHY configuration sequence drm/exynos/hdmi: add PHY power off signal handling drm/exynos/hdmi: add core reset code drm/exynos/hdmi: remove registry dump drm/exynos/decon5433: fix DECON standalone update drm/exynos/decon5433: reset decon on start drm/exynos/decon5433: do not protect window in plane disable
drivers/gpu/drm/exynos/exynos5433_drm_decon.c | 22 +- drivers/gpu/drm/exynos/exynos_hdmi.c | 293 ++------------------------ 2 files changed, 29 insertions(+), 286 deletions(-)
2016년 03월 24일 10:07에 Inki Dae 이(가) 쓴 글:
Hi Andrzej,
2016년 03월 23일 22:15에 Andrzej Hajda 이(가) 쓴 글:
Hi Inki,
This set of patches provides set of different fixes and enhancements for DECON -> HDMI path. It is based on:
- my HDMI patches which are not yet merged[1], could you look at them by the way, they were posted about 5 months ago :)
Oops, really sorry. Will have a review ASAP.
I had already a review for this patch series and merged them to exynos-drm-next-todo branch, http://www.spinics.net/lists/dri-devel/msg98354.html
But I forgot to have a test. :)
Thanks, Inki Dae
Thanks, Inki Dae
- IOMMU patches by Marek (for some mysterious reason HDMI path on 5433 works only with IOMMU enabled),
- latest exynos-drm-next patches.
Regards Andrzej
Andrzej Hajda (7): drm/exynos/hdmi: fix PHY configuration sequence drm/exynos/hdmi: add PHY power off signal handling drm/exynos/hdmi: add core reset code drm/exynos/hdmi: remove registry dump drm/exynos/decon5433: fix DECON standalone update drm/exynos/decon5433: reset decon on start drm/exynos/decon5433: do not protect window in plane disable
drivers/gpu/drm/exynos/exynos5433_drm_decon.c | 22 +- drivers/gpu/drm/exynos/exynos_hdmi.c | 293 ++------------------------ 2 files changed, 29 insertions(+), 286 deletions(-)
dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
dri-devel@lists.freedesktop.org