drm/bridge: synopsys: dw-hdmi-qp: Don't re-training when switch color in frl mode

In the frl mode, hdmi output in fixed rate. Don't re-training
It can avoid the abnormal of 8/10 bit deep color switching, and
reduce the black screen time during switching, so that the user
experience is better.

Signed-off-by: Algea Cao <algea.cao@rock-chips.com>
Change-Id: I3207639fdfdbfda7bad26b151358cae7a79037d3
This commit is contained in:
Algea Cao
2022-06-02 11:52:59 +08:00
committed by Tao Huang
parent 727678768b
commit 69e9bf7101

View File

@@ -238,6 +238,7 @@ struct dw_hdmi_qp {
bool sink_is_hdmi;
bool sink_has_audio;
bool dclk_en;
bool frl_switch;
struct mutex mutex; /* for state below and previous_mode */
struct drm_connector *curr_conn;/* current connector (only valid when !disabled) */
@@ -1432,6 +1433,9 @@ static void hdmi_set_op_mode(struct dw_hdmi_qp *hdmi,
int frl_rate;
int i;
if (hdmi->frl_switch)
return;
/* set sink frl mode disable and wait sink ready */
hdmi_writel(hdmi, 0, FLT_CONFIG0);
if (dw_hdmi_support_scdc(hdmi, &connector->display_info))
@@ -1591,9 +1595,11 @@ static int dw_hdmi_qp_setup(struct dw_hdmi_qp *hdmi,
vmode->mtmdsclock /= 2;
dev_info(hdmi->dev, "final tmdsclk = %d\n", vmode->mtmdsclock);
ret = hdmi->phy.ops->init(hdmi, hdmi->phy.data, &hdmi->previous_mode);
if (ret)
return ret;
if (!hdmi->frl_switch) {
ret = hdmi->phy.ops->init(hdmi, hdmi->phy.data, &hdmi->previous_mode);
if (ret)
return ret;
}
if (hdmi->plat_data->set_grf_cfg)
hdmi->plat_data->set_grf_cfg(data);
@@ -1638,6 +1644,8 @@ static int dw_hdmi_qp_setup(struct dw_hdmi_qp *hdmi,
dev_info(hdmi->dev, "%s DVI mode\n", __func__);
}
hdmi->frl_switch = false;
return 0;
}
@@ -1925,12 +1933,12 @@ static int dw_hdmi_connector_atomic_check(struct drm_connector *connector,
if (IS_ERR(crtc_state))
return PTR_ERR(crtc_state);
mode = &crtc_state->mode;
/*
* If HDMI is enabled in uboot, it's need to record
* drm_display_mode and set phy status to enabled.
*/
if (!vmode->mpixelclock) {
crtc_state = drm_atomic_get_crtc_state(state, crtc);
if (hdmi->plat_data->get_enc_in_encoding)
hdmi->hdmi_data.enc_in_encoding =
hdmi->plat_data->get_enc_in_encoding(data);
@@ -1944,7 +1952,6 @@ static int dw_hdmi_connector_atomic_check(struct drm_connector *connector,
hdmi->hdmi_data.enc_out_bus_format =
hdmi->plat_data->get_output_bus_format(data);
mode = &crtc_state->mode;
if (hdmi->plat_data->split_mode) {
hdmi->plat_data->convert_to_origin_mode(mode);
mode->crtc_clock /= 2;
@@ -1981,6 +1988,8 @@ static int dw_hdmi_connector_atomic_check(struct drm_connector *connector,
return PTR_ERR(crtc_state);
crtc_state->mode_changed = true;
if (mode->clock > 600000)
hdmi->frl_switch = true;
}
return 0;
@@ -2092,6 +2101,8 @@ static void dw_hdmi_qp_bridge_mode_set(struct drm_bridge *bridge,
mutex_lock(&hdmi->mutex);
if (!drm_mode_equal(orig_mode, mode))
hdmi->frl_switch = false;
/* Store the display mode for plugin/DKMS poweron events */
memcpy(&hdmi->previous_mode, mode, sizeof(hdmi->previous_mode));
if (hdmi->plat_data->split_mode)
@@ -2120,7 +2131,7 @@ static void dw_hdmi_qp_bridge_atomic_disable(struct drm_bridge *bridge,
mutex_unlock(&hdmi->audio_mutex);
};
if (hdmi->phy.ops->disable)
if (hdmi->phy.ops->disable && !hdmi->frl_switch)
hdmi->phy.ops->disable(hdmi, hdmi->phy.data);
hdmi->disabled = true;
mutex_unlock(&hdmi->mutex);