Merge "disp: msm: add allowed_mode_switch blob property"

This commit is contained in:
qctecmdr
2020-09-12 00:11:58 -07:00
committed by Gerrit - the friendly Code Review server
7 changed files with 129 additions and 0 deletions

View File

@@ -597,6 +597,7 @@ struct dsi_host_config {
* @pclk_scale: pclk scale factor, target bpp to source bpp * @pclk_scale: pclk scale factor, target bpp to source bpp
* @roi_caps: Panel ROI capabilities * @roi_caps: Panel ROI capabilities
* @widebus_support 48 bit wide data bus is supported by hw * @widebus_support 48 bit wide data bus is supported by hw
* @allowed_mode_switch: BIT mask to mark allowed mode switches
*/ */
struct dsi_display_mode_priv_info { struct dsi_display_mode_priv_info {
struct dsi_panel_cmd_set cmd_sets[DSI_CMD_SET_MAX]; struct dsi_panel_cmd_set cmd_sets[DSI_CMD_SET_MAX];
@@ -620,6 +621,7 @@ struct dsi_display_mode_priv_info {
struct msm_ratio pclk_scale; struct msm_ratio pclk_scale;
struct msm_roi_caps roi_caps; struct msm_roi_caps roi_caps;
bool widebus_support; bool widebus_support;
u32 allowed_mode_switch;
}; };
/** /**

View File

@@ -523,6 +523,9 @@ int dsi_conn_get_mode_info(struct drm_connector *connector,
sizeof(dsi_mode.priv_info->roi_caps)); sizeof(dsi_mode.priv_info->roi_caps));
} }
mode_info->allowed_mode_switches =
dsi_mode.priv_info->allowed_mode_switch;
return 0; return 0;
} }
@@ -1084,3 +1087,99 @@ void dsi_drm_bridge_cleanup(struct dsi_bridge *bridge)
kfree(bridge); kfree(bridge);
} }
static bool is_valid_poms_switch(struct dsi_display_mode *mode_a,
struct dsi_display_mode *mode_b)
{
/*
* POMS cannot happen in conjunction with any other type of mode set.
* Check to ensure FPS remains same between the modes and also
* resolution.
*/
return((mode_a->timing.refresh_rate == mode_b->timing.refresh_rate) &&
(mode_a->timing.v_active == mode_b->timing.v_active) &&
(mode_a->timing.h_active == mode_b->timing.h_active));
}
void dsi_conn_set_allowed_mode_switch(struct drm_connector *connector,
void *display)
{
u32 mode_idx = 0, cmp_mode_idx = 0;
struct drm_display_mode *drm_mode, *cmp_drm_mode;
struct dsi_display_mode dsi_mode, *panel_dsi_mode, *cmp_panel_dsi_mode;
struct list_head *mode_list = &connector->modes;
struct dsi_display *disp = display;
struct dsi_panel *panel;
int mode_count, rc = 0;
struct dsi_display_mode_priv_info *dsi_mode_info, *cmp_dsi_mode_info;
bool allow_switch = false;
if (!disp || !disp->panel) {
DSI_ERR("invalid parameters");
return;
}
panel = disp->panel;
mode_count = panel->num_display_modes;
list_for_each_entry(drm_mode, &connector->modes, head) {
convert_to_dsi_mode(drm_mode, &dsi_mode);
rc = dsi_display_find_mode(display, &dsi_mode, &panel_dsi_mode);
if (rc)
return;
dsi_mode_info = panel_dsi_mode->priv_info;
dsi_mode_info->allowed_mode_switch |= BIT(mode_idx);
if (mode_idx == mode_count - 1)
break;
mode_list = mode_list->next;
cmp_mode_idx = 1;
list_for_each_entry(cmp_drm_mode, mode_list, head) {
convert_to_dsi_mode(cmp_drm_mode, &dsi_mode);
rc = dsi_display_find_mode(display, &dsi_mode,
&cmp_panel_dsi_mode);
if (rc)
return;
cmp_dsi_mode_info = cmp_panel_dsi_mode->priv_info;
allow_switch = false;
/*
* FPS switch among video modes, is only supported
* if DFPS or dynamic clocks are specified.
* Reject any mode switches between video mode timing
* nodes if support for those features is not present.
*/
if (panel_dsi_mode->panel_mode ==
cmp_panel_dsi_mode->panel_mode) {
if (panel_dsi_mode->panel_mode ==
DSI_OP_CMD_MODE)
allow_switch = true;
else if (panel->dfps_caps.dfps_support ||
panel->dyn_clk_caps.dyn_clk_support)
allow_switch = true;
} else {
if (is_valid_poms_switch(panel_dsi_mode,
cmp_panel_dsi_mode))
allow_switch = true;
}
if (allow_switch) {
dsi_mode_info->allowed_mode_switch |=
BIT(mode_idx + cmp_mode_idx);
cmp_dsi_mode_info->allowed_mode_switch |=
BIT(mode_idx);
}
if ((mode_idx + cmp_mode_idx) >= mode_count - 1)
break;
cmp_mode_idx++;
}
mode_idx++;
}
}

View File

@@ -147,4 +147,12 @@ u64 dsi_drm_find_bit_clk_rate(void *display,
int dsi_conn_prepare_commit(void *display, int dsi_conn_prepare_commit(void *display,
struct msm_display_conn_params *params); struct msm_display_conn_params *params);
/**
* dsi_set_allowed_mode_switch - set allowed mode switch bitmask
* @connector: Pointer to drm connector structure
* @display: Pointer to private display structure
*/
void dsi_conn_set_allowed_mode_switch(struct drm_connector *connector,
void *display);
#endif /* _DSI_DRM_H_ */ #endif /* _DSI_DRM_H_ */

View File

@@ -681,6 +681,7 @@ struct msm_display_topology {
* @wide_bus_en: wide-bus mode cfg for interface module * @wide_bus_en: wide-bus mode cfg for interface module
* @mdp_transfer_time_us Specifies the mdp transfer time for command mode * @mdp_transfer_time_us Specifies the mdp transfer time for command mode
* panels in microseconds. * panels in microseconds.
* @allowed_mode_switches: bit mask to indicate supported mode switch.
*/ */
struct msm_mode_info { struct msm_mode_info {
uint32_t frame_rate; uint32_t frame_rate;
@@ -694,6 +695,7 @@ struct msm_mode_info {
struct msm_roi_caps roi_caps; struct msm_roi_caps roi_caps;
bool wide_bus_en; bool wide_bus_en;
u32 mdp_transfer_time_us; u32 mdp_transfer_time_us;
u32 allowed_mode_switches;
}; };
/** /**

View File

@@ -2204,6 +2204,10 @@ static int sde_connector_fill_modes(struct drm_connector *connector,
mode_count = drm_helper_probe_single_connector_modes(connector, mode_count = drm_helper_probe_single_connector_modes(connector,
max_width, max_height); max_width, max_height);
if (sde_conn->ops.set_allowed_mode_switch)
sde_conn->ops.set_allowed_mode_switch(connector,
sde_conn->display);
rc = sde_connector_set_blob_data(connector, rc = sde_connector_set_blob_data(connector,
connector->state, connector->state,
CONNECTOR_PROP_MODE_INFO); CONNECTOR_PROP_MODE_INFO);
@@ -2554,6 +2558,9 @@ static int sde_connector_populate_mode_info(struct drm_connector *conn,
sde_kms_info_add_keyint(info, "mdp_transfer_time_us", sde_kms_info_add_keyint(info, "mdp_transfer_time_us",
mode_info.mdp_transfer_time_us); mode_info.mdp_transfer_time_us);
sde_kms_info_add_keyint(info, "allowed_mode_switch",
mode_info.allowed_mode_switches);
if (!mode_info.roi_caps.num_roi) if (!mode_info.roi_caps.num_roi)
continue; continue;

View File

@@ -366,6 +366,14 @@ struct sde_connector_ops {
* Returns: Zero on success * Returns: Zero on success
*/ */
int (*install_properties)(void *display, struct drm_connector *conn); int (*install_properties)(void *display, struct drm_connector *conn);
/**
* set_allowed_mode_switch - set allowed_mode_switch flag
* @connector: Pointer to drm connector structure
* @display: Pointer to private display structure
*/
void (*set_allowed_mode_switch)(struct drm_connector *connector,
void *display);
}; };
/** /**

View File

@@ -1653,6 +1653,7 @@ static int _sde_kms_setup_displays(struct drm_device *dev,
.get_default_lms = dsi_display_get_default_lms, .get_default_lms = dsi_display_get_default_lms,
.cmd_receive = dsi_display_cmd_receive, .cmd_receive = dsi_display_cmd_receive,
.install_properties = NULL, .install_properties = NULL,
.set_allowed_mode_switch = dsi_conn_set_allowed_mode_switch,
}; };
static const struct sde_connector_ops wb_ops = { static const struct sde_connector_ops wb_ops = {
.post_init = sde_wb_connector_post_init, .post_init = sde_wb_connector_post_init,
@@ -1671,6 +1672,7 @@ static int _sde_kms_setup_displays(struct drm_device *dev,
.get_panel_vfp = NULL, .get_panel_vfp = NULL,
.cmd_receive = NULL, .cmd_receive = NULL,
.install_properties = NULL, .install_properties = NULL,
.set_allowed_mode_switch = NULL,
}; };
static const struct sde_connector_ops dp_ops = { static const struct sde_connector_ops dp_ops = {
.post_init = dp_connector_post_init, .post_init = dp_connector_post_init,
@@ -1691,6 +1693,7 @@ static int _sde_kms_setup_displays(struct drm_device *dev,
.update_pps = dp_connector_update_pps, .update_pps = dp_connector_update_pps,
.cmd_receive = NULL, .cmd_receive = NULL,
.install_properties = dp_connector_install_properties, .install_properties = dp_connector_install_properties,
.set_allowed_mode_switch = NULL,
}; };
struct msm_display_info info; struct msm_display_info info;
struct drm_encoder *encoder; struct drm_encoder *encoder;