Merge "disp: msm: add allowed_mode_switch blob property"

Этот коммит содержится в:
qctecmdr
2020-09-12 00:11:58 -07:00
коммит произвёл Gerrit - the friendly Code Review server
родитель e253a5d57d 03f9c40e7d
Коммит b0775fe9da
7 изменённых файлов: 129 добавлений и 0 удалений

Просмотреть файл

@@ -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_ */