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
|
* @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;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -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++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -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_ */
|
||||||
|
@@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -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;
|
||||||
|
|
||||||
|
@@ -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);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -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;
|
||||||
|
Reference in New Issue
Block a user