|
@@ -6678,12 +6678,11 @@ static void _dsi_display_populate_bit_clks(struct dsi_display *display,
|
|
src = &display->modes[i];
|
|
src = &display->modes[i];
|
|
if (!src)
|
|
if (!src)
|
|
return;
|
|
return;
|
|
- /*
|
|
|
|
- * TODO: currently setting the first bit rate in
|
|
|
|
- * the list as preferred rate. But ideally should
|
|
|
|
- * be based on user or device tree preferrence.
|
|
|
|
- */
|
|
|
|
- src->timing.clk_rate_hz = dyn_clk_caps->bit_clk_list[0];
|
|
|
|
|
|
+
|
|
|
|
+ if (!src->priv_info->bit_clk_list.count)
|
|
|
|
+ continue;
|
|
|
|
+
|
|
|
|
+ src->timing.clk_rate_hz = src->priv_info->bit_clk_list.rates[0];
|
|
|
|
|
|
dsi_display_adjust_mode_timing(display, src, lanes, bpp);
|
|
dsi_display_adjust_mode_timing(display, src, lanes, bpp);
|
|
|
|
|
|
@@ -6726,6 +6725,37 @@ static void _dsi_display_populate_bit_clks(struct dsi_display *display,
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+int dsi_display_restore_bit_clk(struct dsi_display *display, struct dsi_display_mode *mode)
|
|
|
|
+{
|
|
|
|
+ int i;
|
|
|
|
+ u32 clk_rate_hz = 0;
|
|
|
|
+
|
|
|
|
+ if (!display || !mode || !mode->priv_info) {
|
|
|
|
+ DSI_ERR("invalid arguments\n");
|
|
|
|
+ return -EINVAL;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ clk_rate_hz = display->cached_clk_rate;
|
|
|
|
+
|
|
|
|
+ if (mode->priv_info->bit_clk_list.count) {
|
|
|
|
+ /* use first entry as the default bit clk rate */
|
|
|
|
+ clk_rate_hz = mode->priv_info->bit_clk_list.rates[0];
|
|
|
|
+
|
|
|
|
+ for (i = 0; i < mode->priv_info->bit_clk_list.count; i++) {
|
|
|
|
+ if (display->dyn_bit_clk == mode->priv_info->bit_clk_list.rates[i])
|
|
|
|
+ clk_rate_hz = display->dyn_bit_clk;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ mode->timing.clk_rate_hz = clk_rate_hz;
|
|
|
|
+ mode->priv_info->clk_rate_hz = clk_rate_hz;
|
|
|
|
+
|
|
|
|
+ SDE_EVT32(clk_rate_hz, display->cached_clk_rate, display->dyn_bit_clk);
|
|
|
|
+ DSI_DEBUG("clk_rate_hz:%u, cached_clk_rate:%u, dyn_bit_clk:%u\n",
|
|
|
|
+ clk_rate_hz, display->cached_clk_rate, display->dyn_bit_clk);
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
void dsi_display_put_mode(struct dsi_display *display,
|
|
void dsi_display_put_mode(struct dsi_display *display,
|
|
struct dsi_display_mode *mode)
|
|
struct dsi_display_mode *mode)
|
|
{
|
|
{
|
|
@@ -7237,9 +7267,11 @@ int dsi_display_set_mode(struct dsi_display *display,
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- /*For dynamic DSI setting, use specified clock rate */
|
|
|
|
- if (display->cached_clk_rate > 0)
|
|
|
|
- adj_mode.priv_info->clk_rate_hz = display->cached_clk_rate;
|
|
|
|
|
|
+ rc = dsi_display_restore_bit_clk(display, &adj_mode);
|
|
|
|
+ if (rc) {
|
|
|
|
+ DSI_ERR("[%s] bit clk rate cannot be restored\n", display->name);
|
|
|
|
+ goto error;
|
|
|
|
+ }
|
|
|
|
|
|
rc = dsi_display_validate_mode_set(display, &adj_mode, flags);
|
|
rc = dsi_display_validate_mode_set(display, &adj_mode, flags);
|
|
if (rc) {
|
|
if (rc) {
|
|
@@ -7253,11 +7285,13 @@ int dsi_display_set_mode(struct dsi_display *display,
|
|
goto error;
|
|
goto error;
|
|
}
|
|
}
|
|
|
|
|
|
- DSI_INFO("mdp_transfer_time=%d, hactive=%d, vactive=%d, fps=%d\n",
|
|
|
|
|
|
+ DSI_INFO("mdp_transfer_time=%d, hactive=%d, vactive=%d, fps=%d, clk_rate=%llu\n",
|
|
adj_mode.priv_info->mdp_transfer_time_us,
|
|
adj_mode.priv_info->mdp_transfer_time_us,
|
|
- timing.h_active, timing.v_active, timing.refresh_rate);
|
|
|
|
|
|
+ timing.h_active, timing.v_active, timing.refresh_rate,
|
|
|
|
+ adj_mode.priv_info->clk_rate_hz);
|
|
SDE_EVT32(adj_mode.priv_info->mdp_transfer_time_us,
|
|
SDE_EVT32(adj_mode.priv_info->mdp_transfer_time_us,
|
|
- timing.h_active, timing.v_active, timing.refresh_rate);
|
|
|
|
|
|
+ timing.h_active, timing.v_active, timing.refresh_rate,
|
|
|
|
+ adj_mode.priv_info->clk_rate_hz);
|
|
|
|
|
|
memcpy(display->panel->cur_mode, &adj_mode, sizeof(adj_mode));
|
|
memcpy(display->panel->cur_mode, &adj_mode, sizeof(adj_mode));
|
|
error:
|
|
error:
|
|
@@ -8366,6 +8400,67 @@ int dsi_display_update_pps(char *pps_cmd, void *disp)
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+int dsi_display_update_dyn_bit_clk(struct dsi_display *display,
|
|
|
|
+ struct dsi_display_mode *mode)
|
|
|
|
+{
|
|
|
|
+ struct dsi_dyn_clk_caps *dyn_clk_caps;
|
|
|
|
+ struct dsi_host_common_cfg *host_cfg;
|
|
|
|
+ int bpp, lanes = 0;
|
|
|
|
+
|
|
|
|
+ if (!display || !mode) {
|
|
|
|
+ DSI_ERR("invalid arguments\n");
|
|
|
|
+ return -EINVAL;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ dyn_clk_caps = &(display->panel->dyn_clk_caps);
|
|
|
|
+ if (!dyn_clk_caps->dyn_clk_support) {
|
|
|
|
+ DSI_DEBUG("dynamic bit clock support not enabled\n");
|
|
|
|
+ return 0;
|
|
|
|
+ } else if (!display->dyn_bit_clk_pending) {
|
|
|
|
+ DSI_DEBUG("dynamic bit clock rate not updated\n");
|
|
|
|
+ return 0;
|
|
|
|
+ } else if (!display->dyn_bit_clk) {
|
|
|
|
+ DSI_DEBUG("dynamic bit clock rate cleared\n");
|
|
|
|
+ return 0;
|
|
|
|
+ } else if (display->dyn_bit_clk < mode->priv_info->min_dsi_clk_hz) {
|
|
|
|
+ DSI_ERR("dynamic bit clock rate %llu smaller than minimum value:%llu\n",
|
|
|
|
+ display->dyn_bit_clk, mode->priv_info->min_dsi_clk_hz);
|
|
|
|
+ return -EINVAL;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /* update mode clk rate with user value */
|
|
|
|
+ mode->timing.clk_rate_hz = display->dyn_bit_clk;
|
|
|
|
+ mode->priv_info->clk_rate_hz = display->dyn_bit_clk;
|
|
|
|
+
|
|
|
|
+ host_cfg = &(display->panel->host_config);
|
|
|
|
+ bpp = dsi_pixel_format_to_bpp(host_cfg->dst_format);
|
|
|
|
+
|
|
|
|
+ if (host_cfg->data_lanes & DSI_DATA_LANE_0)
|
|
|
|
+ lanes++;
|
|
|
|
+ if (host_cfg->data_lanes & DSI_DATA_LANE_1)
|
|
|
|
+ lanes++;
|
|
|
|
+ if (host_cfg->data_lanes & DSI_DATA_LANE_2)
|
|
|
|
+ lanes++;
|
|
|
|
+ if (host_cfg->data_lanes & DSI_DATA_LANE_3)
|
|
|
|
+ lanes++;
|
|
|
|
+
|
|
|
|
+ dsi_display_adjust_mode_timing(display, mode, lanes, bpp);
|
|
|
|
+
|
|
|
|
+ /* adjust pixel clock based on dynamic bit clock */
|
|
|
|
+ mode->pixel_clk_khz = div_u64(mode->timing.clk_rate_hz * lanes, bpp);
|
|
|
|
+ do_div(mode->pixel_clk_khz, 1000);
|
|
|
|
+ mode->pixel_clk_khz *= display->ctrl_count;
|
|
|
|
+
|
|
|
|
+ SDE_EVT32(display->dyn_bit_clk, mode->priv_info->min_dsi_clk_hz, mode->pixel_clk_khz);
|
|
|
|
+ DSI_DEBUG("dynamic bit clk:%u, min dsi clk:%llu, lanes:%d, bpp:%d, pck:%d Khz\n",
|
|
|
|
+ display->dyn_bit_clk, mode->priv_info->min_dsi_clk_hz, lanes, bpp,
|
|
|
|
+ mode->pixel_clk_khz);
|
|
|
|
+
|
|
|
|
+ display->dyn_bit_clk_pending = false;
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
int dsi_display_dump_clks_state(struct dsi_display *display)
|
|
int dsi_display_dump_clks_state(struct dsi_display *display)
|
|
{
|
|
{
|
|
int rc = 0;
|
|
int rc = 0;
|