Merge "disp: msm: add allowed_mode_switch blob property"
This commit is contained in:

committed by
Gerrit - the friendly Code Review server

commit
b0775fe9da
@@ -597,6 +597,7 @@ struct dsi_host_config {
|
||||
* @pclk_scale: pclk scale factor, target bpp to source bpp
|
||||
* @roi_caps: Panel ROI capabilities
|
||||
* @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_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_roi_caps roi_caps;
|
||||
bool widebus_support;
|
||||
u32 allowed_mode_switch;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@@ -523,6 +523,9 @@ int dsi_conn_get_mode_info(struct drm_connector *connector,
|
||||
sizeof(dsi_mode.priv_info->roi_caps));
|
||||
}
|
||||
|
||||
mode_info->allowed_mode_switches =
|
||||
dsi_mode.priv_info->allowed_mode_switch;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1084,3 +1087,99 @@ void dsi_drm_bridge_cleanup(struct dsi_bridge *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++;
|
||||
}
|
||||
}
|
||||
|
@@ -147,4 +147,12 @@ u64 dsi_drm_find_bit_clk_rate(void *display,
|
||||
int dsi_conn_prepare_commit(void *display,
|
||||
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_ */
|
||||
|
@@ -681,6 +681,7 @@ struct msm_display_topology {
|
||||
* @wide_bus_en: wide-bus mode cfg for interface module
|
||||
* @mdp_transfer_time_us Specifies the mdp transfer time for command mode
|
||||
* panels in microseconds.
|
||||
* @allowed_mode_switches: bit mask to indicate supported mode switch.
|
||||
*/
|
||||
struct msm_mode_info {
|
||||
uint32_t frame_rate;
|
||||
@@ -694,6 +695,7 @@ struct msm_mode_info {
|
||||
struct msm_roi_caps roi_caps;
|
||||
bool wide_bus_en;
|
||||
u32 mdp_transfer_time_us;
|
||||
u32 allowed_mode_switches;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@@ -2204,6 +2204,10 @@ static int sde_connector_fill_modes(struct drm_connector *connector,
|
||||
mode_count = drm_helper_probe_single_connector_modes(connector,
|
||||
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,
|
||||
connector->state,
|
||||
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",
|
||||
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)
|
||||
continue;
|
||||
|
||||
|
@@ -366,6 +366,14 @@ struct sde_connector_ops {
|
||||
* Returns: Zero on success
|
||||
*/
|
||||
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);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@@ -1653,6 +1653,7 @@ static int _sde_kms_setup_displays(struct drm_device *dev,
|
||||
.get_default_lms = dsi_display_get_default_lms,
|
||||
.cmd_receive = dsi_display_cmd_receive,
|
||||
.install_properties = NULL,
|
||||
.set_allowed_mode_switch = dsi_conn_set_allowed_mode_switch,
|
||||
};
|
||||
static const struct sde_connector_ops wb_ops = {
|
||||
.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,
|
||||
.cmd_receive = NULL,
|
||||
.install_properties = NULL,
|
||||
.set_allowed_mode_switch = NULL,
|
||||
};
|
||||
static const struct sde_connector_ops dp_ops = {
|
||||
.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,
|
||||
.cmd_receive = NULL,
|
||||
.install_properties = dp_connector_install_properties,
|
||||
.set_allowed_mode_switch = NULL,
|
||||
};
|
||||
struct msm_display_info info;
|
||||
struct drm_encoder *encoder;
|
||||
|
Reference in New Issue
Block a user