|
@@ -6868,6 +6868,57 @@ static void _dsi_display_populate_bit_clks(struct dsi_display *display, int star
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static int dsi_display_mode_dyn_clk_cpy(struct dsi_display *display,
|
|
|
|
+ struct dsi_display_mode *src, struct dsi_display_mode *dst)
|
|
|
|
+{
|
|
|
|
+ int rc = 0;
|
|
|
|
+ u32 count = 0;
|
|
|
|
+ struct dsi_dyn_clk_caps *dyn_clk_caps;
|
|
|
|
+ struct msm_dyn_clk_list *bit_clk_list;
|
|
|
|
+
|
|
|
|
+ dyn_clk_caps = &(display->panel->dyn_clk_caps);
|
|
|
|
+ if (!dyn_clk_caps->dyn_clk_support)
|
|
|
|
+ return rc;
|
|
|
|
+
|
|
|
|
+ count = dst->priv_info->bit_clk_list.count;
|
|
|
|
+ bit_clk_list = &dst->priv_info->bit_clk_list;
|
|
|
|
+ bit_clk_list->front_porches =
|
|
|
|
+ kcalloc(count, sizeof(u32), GFP_KERNEL);
|
|
|
|
+ if (!bit_clk_list->front_porches) {
|
|
|
|
+ DSI_ERR("failed to allocate space for front porch list\n");
|
|
|
|
+ rc = -ENOMEM;
|
|
|
|
+ goto error;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ bit_clk_list->rates =
|
|
|
|
+ kcalloc(count, sizeof(u32), GFP_KERNEL);
|
|
|
|
+ if (!bit_clk_list->rates) {
|
|
|
|
+ DSI_ERR("failed to allocate space for rates list\n");
|
|
|
|
+ rc = -ENOMEM;
|
|
|
|
+ goto error;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ memcpy(bit_clk_list->rates, src->priv_info->bit_clk_list.rates,
|
|
|
|
+ count*sizeof(u32));
|
|
|
|
+
|
|
|
|
+ bit_clk_list->pixel_clks_khz =
|
|
|
|
+ kcalloc(count, sizeof(u32), GFP_KERNEL);
|
|
|
|
+ if (!bit_clk_list->pixel_clks_khz) {
|
|
|
|
+ DSI_ERR("failed to allocate space for pixel clocks list\n");
|
|
|
|
+ rc = -ENOMEM;
|
|
|
|
+ goto error;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return rc;
|
|
|
|
+
|
|
|
|
+error:
|
|
|
|
+ kfree(bit_clk_list->rates);
|
|
|
|
+ kfree(bit_clk_list->front_porches);
|
|
|
|
+ kfree(bit_clk_list->pixel_clks_khz);
|
|
|
|
+
|
|
|
|
+ return rc;
|
|
|
|
+}
|
|
|
|
+
|
|
int dsi_display_restore_bit_clk(struct dsi_display *display, struct dsi_display_mode *mode)
|
|
int dsi_display_restore_bit_clk(struct dsi_display *display, struct dsi_display_mode *mode)
|
|
{
|
|
{
|
|
int i;
|
|
int i;
|
|
@@ -6967,6 +7018,7 @@ int dsi_display_get_modes(struct dsi_display *display,
|
|
int topology_override = NO_OVERRIDE;
|
|
int topology_override = NO_OVERRIDE;
|
|
bool is_preferred = false;
|
|
bool is_preferred = false;
|
|
u32 frame_threshold_us = ctrl->ctrl->frame_threshold_time_us;
|
|
u32 frame_threshold_us = ctrl->ctrl->frame_threshold_time_us;
|
|
|
|
+ struct msm_dyn_clk_list *bit_clk_list;
|
|
|
|
|
|
memset(&display_mode, 0, sizeof(display_mode));
|
|
memset(&display_mode, 0, sizeof(display_mode));
|
|
|
|
|
|
@@ -7060,10 +7112,24 @@ int dsi_display_get_modes(struct dsi_display *display,
|
|
* Qsync min fps for the mode will be populated in the timing info
|
|
* Qsync min fps for the mode will be populated in the timing info
|
|
* in dsi_panel_get_mode function.
|
|
* in dsi_panel_get_mode function.
|
|
*/
|
|
*/
|
|
- sub_mode->priv_info->qsync_min_fps = sub_mode->timing.qsync_min_fps;
|
|
|
|
|
|
+ display_mode.priv_info->qsync_min_fps = sub_mode->timing.qsync_min_fps;
|
|
if (!dfps_caps.dfps_support || !support_video_mode)
|
|
if (!dfps_caps.dfps_support || !support_video_mode)
|
|
continue;
|
|
continue;
|
|
|
|
|
|
|
|
+ sub_mode->priv_info = kmemdup(display_mode.priv_info,
|
|
|
|
+ sizeof(*sub_mode->priv_info), GFP_KERNEL);
|
|
|
|
+ if (!sub_mode->priv_info) {
|
|
|
|
+ rc = -ENOMEM;
|
|
|
|
+ goto error;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ rc = dsi_display_mode_dyn_clk_cpy(display,
|
|
|
|
+ &display_mode, sub_mode);
|
|
|
|
+ if (rc) {
|
|
|
|
+ DSI_ERR("unable to copy dyn clock list\n");
|
|
|
|
+ goto error;
|
|
|
|
+ }
|
|
|
|
+
|
|
sub_mode->mode_idx += (array_idx - 1);
|
|
sub_mode->mode_idx += (array_idx - 1);
|
|
curr_refresh_rate = sub_mode->timing.refresh_rate;
|
|
curr_refresh_rate = sub_mode->timing.refresh_rate;
|
|
sub_mode->timing.refresh_rate = dfps_caps.dfps_list[i];
|
|
sub_mode->timing.refresh_rate = dfps_caps.dfps_list[i];
|
|
@@ -7086,6 +7152,17 @@ int dsi_display_get_modes(struct dsi_display *display,
|
|
/* Set first timing sub mode as preferred mode */
|
|
/* Set first timing sub mode as preferred mode */
|
|
display->modes[start].is_preferred = true;
|
|
display->modes[start].is_preferred = true;
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ bit_clk_list = &display_mode.priv_info->bit_clk_list;
|
|
|
|
+ if (support_video_mode && dfps_caps.dfps_support) {
|
|
|
|
+ if (dyn_clk_caps->dyn_clk_support) {
|
|
|
|
+ kfree(bit_clk_list->rates);
|
|
|
|
+ kfree(bit_clk_list->front_porches);
|
|
|
|
+ kfree(bit_clk_list->pixel_clks_khz);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ kfree(display_mode.priv_info);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
if (dsc_modes && nondsc_modes)
|
|
if (dsc_modes && nondsc_modes)
|