disp: msm: sde: add new interface for RFI feature

Add a new connector range property and a new entry to the panel
capability blob to publish the list of supported RFI frequencies.
In addition, add the required functions to set, validate and update
DSI bit clock rate value to trigger an internal seamless mode switch
and reconfigure DSI clock and PLL.

Change-Id: I7d19cc369f8c5528709f2f20a51ef02180ebdea4
Signed-off-by: Amine Najahi <anajahi@codeaurora.org>
This commit is contained in:
Amine Najahi
2021-02-16 16:53:04 -05:00
committed by Gerrit - the friendly Code Review server
vanhempi 4c41c05d7c
commit d4def5bd8c
11 muutettua tiedostoa jossa 278 lisäystä ja 44 poistoa

Näytä tiedosto

@@ -342,7 +342,9 @@ static void dsi_bridge_mode_set(struct drm_bridge *bridge,
const struct drm_display_mode *mode,
const struct drm_display_mode *adjusted_mode)
{
struct dsi_bridge *c_bridge = to_dsi_bridge(bridge);
int rc = 0;
struct dsi_bridge *c_bridge = NULL;
struct dsi_display *display;
struct drm_connector *conn;
struct sde_connector_state *conn_state;
@@ -351,6 +353,18 @@ static void dsi_bridge_mode_set(struct drm_bridge *bridge,
return;
}
c_bridge = to_dsi_bridge(bridge);
if (!c_bridge) {
DSI_ERR("invalid dsi bridge\n");
return;
}
display = c_bridge->display;
if (!display || !display->drm_conn || !display->drm_conn->state) {
DSI_ERR("invalid display\n");
return;
}
memset(&(c_bridge->dsi_mode), 0x0, sizeof(struct dsi_display_mode));
convert_to_dsi_mode(adjusted_mode, &(c_bridge->dsi_mode));
conn = sde_encoder_get_connector(bridge->dev, bridge->encoder);
@@ -366,9 +380,11 @@ static void dsi_bridge_mode_set(struct drm_bridge *bridge,
msm_parse_mode_priv_info(&conn_state->msm_mode,
&(c_bridge->dsi_mode));
/* restore bit_clk_rate also for dynamic clk use cases */
c_bridge->dsi_mode.timing.clk_rate_hz =
dsi_drm_find_bit_clk_rate(c_bridge->display, adjusted_mode);
rc = dsi_display_restore_bit_clk(display, &c_bridge->dsi_mode);
if (rc) {
DSI_ERR("[%s] bit clk rate cannot be restored\n", display->name);
return;
}
DSI_DEBUG("clk_rate: %llu\n", c_bridge->dsi_mode.timing.clk_rate_hz);
}
@@ -436,6 +452,18 @@ static bool dsi_bridge_mode_fixup(struct drm_bridge *bridge,
dsi_mode.timing.dsc_enabled = dsi_mode.priv_info->dsc_enabled;
dsi_mode.timing.dsc = &dsi_mode.priv_info->dsc;
rc = dsi_display_restore_bit_clk(display, &dsi_mode);
if (rc) {
DSI_ERR("[%s] bit clk rate cannot be restored\n", display->name);
return false;
}
rc = dsi_display_update_dyn_bit_clk(display, &dsi_mode);
if (rc) {
DSI_ERR("[%s] failed to update bit clock\n", display->name);
return false;
}
rc = dsi_display_validate_mode(c_bridge->display, &dsi_mode,
DSI_VALIDATE_FLAG_ALLOW_ADJUST);
if (rc) {
@@ -517,33 +545,6 @@ u32 dsi_drm_get_dfps_maxfps(void *display)
return dfps_maxfps;
}
u64 dsi_drm_find_bit_clk_rate(void *display,
const struct drm_display_mode *drm_mode)
{
int i = 0, count = 0;
struct dsi_display *dsi_display = display;
struct dsi_display_mode *dsi_mode;
u64 bit_clk_rate = 0;
if (!dsi_display || !drm_mode)
return 0;
dsi_display_get_mode_count(dsi_display, &count);
for (i = 0; i < count; i++) {
dsi_mode = &dsi_display->modes[i];
if ((dsi_mode->timing.v_active == drm_mode->vdisplay) &&
(dsi_mode->timing.h_active == drm_mode->hdisplay) &&
(dsi_mode->pixel_clk_khz == drm_mode->clock) &&
(dsi_mode->timing.refresh_rate == drm_mode_vrefresh(drm_mode))) {
bit_clk_rate = dsi_mode->timing.clk_rate_hz;
break;
}
}
return bit_clk_rate;
}
int dsi_conn_get_mode_info(struct drm_connector *connector,
const struct drm_display_mode *drm_mode,
struct msm_mode_info *mode_info,
@@ -696,6 +697,11 @@ int dsi_conn_set_info_blob(struct drm_connector *connector,
sde_kms_info_add_keystr(info, "dyn bitclk support",
panel->dyn_clk_caps.dyn_clk_support ? "true" : "false");
if (panel->dyn_clk_caps.dyn_clk_support)
sde_kms_info_add_list(info, "dyn_bitclk_list",
panel->dyn_clk_caps.bit_clk_list,
panel->dyn_clk_caps.bit_clk_list_len);
switch (panel->phy_props.rotation) {
case DSI_PANEL_ROTATE_NONE:
sde_kms_info_add_keystr(info, "panel orientation", "none");
@@ -1288,3 +1294,42 @@ void dsi_conn_set_allowed_mode_switch(struct drm_connector *connector,
mode_idx++;
}
}
int dsi_conn_set_dyn_bit_clk(struct drm_connector *connector, uint64_t value)
{
int i;
bool is_valid = false;
struct sde_connector *c_conn = NULL;
struct sde_connector_state *c_state;
struct dsi_display *display;
struct dsi_dyn_clk_caps *dyn_clk_caps;
if (!connector) {
DSI_ERR("invalid connector\n");
return -EINVAL;
}
c_conn = to_sde_connector(connector);
c_state = to_sde_connector_state(connector->state);
display = (struct dsi_display *) c_conn->display;
dyn_clk_caps = &display->panel->dyn_clk_caps;
for (i = 0; i < dyn_clk_caps->bit_clk_list_len; i++) {
if (dyn_clk_caps->bit_clk_list[i] == value) {
is_valid = true;
break;
}
}
if (!is_valid) {
DSI_ERR("invalid dynamic bit clock rate selection %llu\n", value);
return -EINVAL;
}
display->dyn_bit_clk = value;
display->dyn_bit_clk_pending = true;
DSI_DEBUG("update dynamic bit clock rate to %llu\n", display->dyn_bit_clk);
return 0;
}