drm: set to dummy mode when setting mode is invalid [1/1]

PD#SWPL-101380

Problem:
dummy_l is not set before drm suspend, when resume
drm will re-set hdmitx mode failed.

Solution:
For drm didnot validate mode when drm resume, drm
check if mode valid in atomic_modeset and switch to
dummy to keep vsync when got invalid hdmitx mode.

Verify:
Ohm

Test:
mode_setting

Change-Id: I1b330a7c28427750c89093b2ad7cfe53b85833c6
Signed-off-by: congyang.huang <congyang.huang@amlogic.com>
This commit is contained in:
congyang.huang
2022-11-25 17:38:48 +08:00
committed by gerrit autosubmit
parent 46cd23b177
commit 6d9bf19bce
2 changed files with 43 additions and 15 deletions
+18 -8
View File
@@ -121,6 +121,7 @@ static struct drm_crtc_state *meson_crtc_duplicate_state(struct drm_crtc *crtc)
new_state->crtc_hdr_enable = cur_state->crtc_hdr_enable;
new_state->crtc_eotf_by_property_flag = cur_state->crtc_eotf_by_property_flag;
new_state->eotf_type_by_property = cur_state->eotf_type_by_property;
new_state->vmode = cur_state->vmode;
/*reset dynamic info.*/
if (amcrtc->priv->logo_show_done)
@@ -163,6 +164,7 @@ static void meson_crtc_reset(struct drm_crtc *crtc)
crtc->state = &meson_crtc_state->base;
crtc->state->crtc = crtc;
meson_crtc_state->vmode = VMODE_INVALID;
meson_crtc_init_hdr_preference(meson_crtc_state);
}
@@ -415,8 +417,9 @@ static void am_meson_crtc_atomic_enable(struct drm_crtc *crtc,
adjusted_mode->name);
return;
}
DRM_INFO("%s: %s, %s, %d\n", __func__, adjusted_mode->name,
old_mode->name, meson_crtc_state->uboot_mode_init);
DRM_INFO("%s: new[%s], old[%s], vmode[%d], uboot[%d]\n",
__func__, adjusted_mode->name, old_mode->name,
meson_crtc_state->vmode, meson_crtc_state->uboot_mode_init);
adjusted_vrefresh = drm_mode_vrefresh(adjusted_mode);
if (!priv->compat_mode) {
@@ -460,12 +463,17 @@ static void am_meson_crtc_atomic_enable(struct drm_crtc *crtc,
name = brr_name;
}
mode = vout_func_validate_vmode(amcrtc->vout_index, name, 0);
if (mode == VMODE_MAX) {
DRM_ERROR("no matched vout mode\n");
return;
if (meson_crtc_state->vmode == VMODE_INVALID) {
meson_crtc_state->vmode = vout_func_validate_vmode(amcrtc->vout_index, name, 0);
if (meson_crtc_state->vmode == VMODE_MAX) {
DRM_ERROR("no matched vout mode\n");
return;
}
}
mode = meson_crtc_state->vmode;
DRM_INFO(" %s final vmode %s, %d\n", __func__, name, mode);
if (mode == VMODE_DUMMY_ENCL ||
mode == VMODE_DUMMY_ENCI ||
mode == VMODE_DUMMY_ENCP) {
@@ -490,8 +498,6 @@ static void am_meson_crtc_atomic_enable(struct drm_crtc *crtc,
vout_func_update_viu(amcrtc->vout_index);
}
meson_crtc_state->vmode = mode;
memcpy(&pipeline->subs[amcrtc->crtc_index].mode, adjusted_mode,
sizeof(struct drm_display_mode));
@@ -508,6 +514,8 @@ static void am_meson_crtc_atomic_disable(struct drm_crtc *crtc,
struct drm_display_mode *adjusted_mode = &crtc->state->adjusted_mode;
struct drm_crtc_state *old_crtc_state;
struct drm_display_mode *old_mode;
struct am_meson_crtc_state *meson_crtc_state =
to_am_meson_crtc_state(crtc->state);
enum vmode_e mode;
DRM_INFO("%s:in\n", __func__);
@@ -534,6 +542,8 @@ static void am_meson_crtc_atomic_disable(struct drm_crtc *crtc,
crtc->state->event = NULL;
}
disable_irq(amcrtc->irq);
meson_crtc_state->vmode = VMODE_INVALID;
/* disable output by config null
* Todo: replace or delete it if have new method
*/
+25 -7
View File
@@ -1385,11 +1385,33 @@ void meson_hdmitx_encoder_atomic_mode_set(struct drm_encoder *encoder,
struct drm_display_mode *adj_mode = &crtc_state->adjusted_mode;
struct am_hdmi_tx *hdmitx = encoder_to_am_hdmi(encoder);
bool update_attr = false;
char *modename = adj_mode->name;
enum vmode_e vout_mode;
bool bvalid_vmode = false;
DRM_DEBUG("%s[%d]: enter\n", __func__, __LINE__);
if (crtc_state->vrr_enabled)
meson_hdmitx_cal_brr(hdmitx, meson_crtc_state, adj_mode);
/* check if hdmi can support this mode. if not, set vmode to dummy*/
vout_mode = validate_vmode(modename, 0);
DRM_DEBUG(" %s validate vmode %s, %x\n", __func__, modename, vout_mode);
if (vout_mode != VMODE_HDMI) {
if (meson_crtc_state->vmode == VMODE_HDMI)
meson_crtc_state->vmode = VMODE_INVALID;
DRM_ERROR("no matched hdmi mode\n");
return;
}
bvalid_vmode = hdmitx->hdmitx_dev->test_attr(modename, "rgb,8bit");
if (!bvalid_vmode) {
DRM_ERROR("mode %s NOT supporteds\n", modename);
vout_mode = validate_vmode(dummy_mode.name, 0);
}
meson_crtc_state->vmode = vout_mode;
DRM_INFO("%s update %s vmode %x\n", __func__, modename, vout_mode);
if (am_hdmi_info.android_path)
return;
@@ -1495,13 +1517,9 @@ void meson_hdmitx_encoder_atomic_enable(struct drm_encoder *encoder,
struct am_meson_crtc *amcrtc = to_am_meson_crtc(encoder->crtc);
enum vmode_e vmode = meson_crtc_state->vmode;
if (vmode == VMODE_HDMI) {
DRM_INFO("[%s]\n", __func__);
} else {
if (vmode == (VMODE_HDMI | VMODE_INIT_BIT_MASK))
am_hdmi_info.hdmitx_on = 1;
DRM_INFO("[%s] vmode:%d\n", __func__, vmode);
DRM_DEBUG("%s[%d]\n", __func__, __LINE__);
if ((vmode & VMODE_MODE_BIT_MASK) != VMODE_HDMI) {
DRM_INFO("[%s] fail! vmode:%d\n", __func__, vmode);
return;
}