mirror of
https://github.com/hardkernel/kernel_common_drivers.git
synced 2026-06-25 12:03:48 +09:00
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:
committed by
gerrit autosubmit
parent
46cd23b177
commit
6d9bf19bce
@@ -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
|
||||
*/
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user