Merge "drm/msm/dsi-staging: update dsi clock calculations"
Cette révision appartient à :

révisé par
Gerrit - the friendly Code Review server

révision
d37cbd374b
@@ -824,18 +824,22 @@ int dsi_ctrl_pixel_format_to_bpp(enum dsi_pixel_format dst_format)
|
||||
}
|
||||
|
||||
static int dsi_ctrl_update_link_freqs(struct dsi_ctrl *dsi_ctrl,
|
||||
struct dsi_host_config *config, void *clk_handle)
|
||||
struct dsi_host_config *config, void *clk_handle,
|
||||
struct dsi_display_mode *mode)
|
||||
{
|
||||
int rc = 0;
|
||||
u32 num_of_lanes = 0;
|
||||
u32 bpp, refresh_rate = TICKS_IN_MICRO_SECOND;
|
||||
u32 bpp, frame_time_us;
|
||||
u64 h_period, v_period, bit_rate, pclk_rate, bit_rate_per_lane,
|
||||
byte_clk_rate;
|
||||
struct dsi_host_common_cfg *host_cfg = &config->common_config;
|
||||
struct dsi_mode_info *timing = &config->video_timing;
|
||||
u64 dsi_transfer_time_us = mode->priv_info->dsi_transfer_time_us;
|
||||
u64 min_dsi_clk_hz = mode->priv_info->min_dsi_clk_hz;
|
||||
|
||||
/* Get bits per pxl in desitnation format */
|
||||
/* Get bits per pxl in destination format */
|
||||
bpp = dsi_ctrl_pixel_format_to_bpp(host_cfg->dst_format);
|
||||
frame_time_us = mult_frac(1000, 1000, (timing->refresh_rate));
|
||||
|
||||
if (host_cfg->data_lanes & DSI_DATA_LANE_0)
|
||||
num_of_lanes++;
|
||||
@@ -846,18 +850,20 @@ static int dsi_ctrl_update_link_freqs(struct dsi_ctrl *dsi_ctrl,
|
||||
if (host_cfg->data_lanes & DSI_DATA_LANE_3)
|
||||
num_of_lanes++;
|
||||
|
||||
if (config->bit_clk_rate_hz_override == 0) {
|
||||
config->common_config.num_data_lanes = num_of_lanes;
|
||||
config->common_config.bpp = bpp;
|
||||
|
||||
if (config->bit_clk_rate_hz_override != 0) {
|
||||
bit_rate = config->bit_clk_rate_hz_override * num_of_lanes;
|
||||
} else if (config->panel_mode == DSI_OP_CMD_MODE) {
|
||||
/* Calculate the bit rate needed to match dsi transfer time */
|
||||
bit_rate = mult_frac(min_dsi_clk_hz, frame_time_us,
|
||||
dsi_transfer_time_us);
|
||||
bit_rate = bit_rate * num_of_lanes;
|
||||
} else {
|
||||
h_period = DSI_H_TOTAL_DSC(timing);
|
||||
v_period = DSI_V_TOTAL(timing);
|
||||
|
||||
if (config->panel_mode == DSI_OP_CMD_MODE)
|
||||
do_div(refresh_rate, timing->mdp_transfer_time_us);
|
||||
else
|
||||
refresh_rate = timing->refresh_rate;
|
||||
|
||||
bit_rate = h_period * v_period * refresh_rate * bpp;
|
||||
} else {
|
||||
bit_rate = config->bit_clk_rate_hz_override * num_of_lanes;
|
||||
bit_rate = h_period * v_period * timing->refresh_rate * bpp;
|
||||
}
|
||||
|
||||
bit_rate_per_lane = bit_rate;
|
||||
@@ -2863,7 +2869,8 @@ error:
|
||||
*/
|
||||
int dsi_ctrl_update_host_config(struct dsi_ctrl *ctrl,
|
||||
struct dsi_host_config *config,
|
||||
int flags, void *clk_handle)
|
||||
struct dsi_display_mode *mode, int flags,
|
||||
void *clk_handle)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
@@ -2881,9 +2888,10 @@ int dsi_ctrl_update_host_config(struct dsi_ctrl *ctrl,
|
||||
}
|
||||
|
||||
if (!(flags & (DSI_MODE_FLAG_SEAMLESS | DSI_MODE_FLAG_VRR))) {
|
||||
rc = dsi_ctrl_update_link_freqs(ctrl, config, clk_handle);
|
||||
rc = dsi_ctrl_update_link_freqs(ctrl, config, clk_handle,
|
||||
mode);
|
||||
if (rc) {
|
||||
pr_err("[%s] failed to update link frequencies, rc=%d\n",
|
||||
pr_err("[%s] failed to update link frequency, rc=%d\n",
|
||||
ctrl->name, rc);
|
||||
goto error;
|
||||
}
|
||||
|
@@ -324,6 +324,7 @@ int dsi_ctrl_validate_timing(struct dsi_ctrl *dsi_ctrl,
|
||||
* dsi_ctrl_update_host_config() - update dsi host configuration
|
||||
* @dsi_ctrl: DSI controller handle.
|
||||
* @config: DSI host configuration.
|
||||
* @mode: DSI host mode selected.
|
||||
* @flags: dsi_mode_flags modifying the behavior
|
||||
* @clk_handle: Clock handle for DSI clocks
|
||||
*
|
||||
@@ -335,7 +336,8 @@ int dsi_ctrl_validate_timing(struct dsi_ctrl *dsi_ctrl,
|
||||
*/
|
||||
int dsi_ctrl_update_host_config(struct dsi_ctrl *dsi_ctrl,
|
||||
struct dsi_host_config *config,
|
||||
int flags, void *clk_handle);
|
||||
struct dsi_display_mode *mode, int flags,
|
||||
void *clk_handle);
|
||||
|
||||
/**
|
||||
* dsi_ctrl_timing_db_update() - update only controller Timing DB
|
||||
|
@@ -28,6 +28,17 @@
|
||||
value;\
|
||||
})
|
||||
|
||||
#define DSI_H_ACTIVE_DSC(t) \
|
||||
({\
|
||||
u64 value;\
|
||||
if ((t)->dsc_enabled && (t)->dsc)\
|
||||
value = (t)->dsc->pclk_per_line;\
|
||||
else\
|
||||
value = (t)->h_active;\
|
||||
value;\
|
||||
})
|
||||
|
||||
|
||||
#define DSI_DEBUG_NAME_LEN 32
|
||||
#define display_for_each_ctrl(index, display) \
|
||||
for (index = 0; (index < (display)->ctrl_count) &&\
|
||||
@@ -370,8 +381,10 @@ struct dsi_panel_cmd_set {
|
||||
* @v_sync_polarity: Polarity of VSYNC (false is active low).
|
||||
* @refresh_rate: Refresh rate in Hz.
|
||||
* @clk_rate_hz: DSI bit clock rate per lane in Hz.
|
||||
* @min_dsi_clk_hz: Min DSI bit clock to transfer in vsync time.
|
||||
* @mdp_transfer_time_us: Specifies the mdp transfer time for command mode
|
||||
* panels in microseconds.
|
||||
* @dsi_transfer_time_us: Specifies dsi transfer time for command mode.
|
||||
* @dsc_enabled: DSC compression enabled.
|
||||
* @dsc: DSC compression configuration.
|
||||
* @roi_caps: Panel ROI capabilities.
|
||||
@@ -392,7 +405,9 @@ struct dsi_mode_info {
|
||||
|
||||
u32 refresh_rate;
|
||||
u64 clk_rate_hz;
|
||||
u64 min_dsi_clk_hz;
|
||||
u32 mdp_transfer_time_us;
|
||||
u32 dsi_transfer_time_us;
|
||||
bool dsc_enabled;
|
||||
struct msm_display_dsc_info *dsc;
|
||||
struct msm_roi_caps roi_caps;
|
||||
@@ -402,6 +417,8 @@ struct dsi_mode_info {
|
||||
* struct dsi_host_common_cfg - Host configuration common to video and cmd mode
|
||||
* @dst_format: Destination pixel format.
|
||||
* @data_lanes: Physical data lanes to be enabled.
|
||||
* @num_data_lanes: Number of physical data lanes.
|
||||
* @bpp: Number of bits per pixel.
|
||||
* @en_crc_check: Enable CRC checks.
|
||||
* @en_ecc_check: Enable ECC checks.
|
||||
* @te_mode: Source for TE signalling.
|
||||
@@ -427,6 +444,8 @@ struct dsi_mode_info {
|
||||
struct dsi_host_common_cfg {
|
||||
enum dsi_pixel_format dst_format;
|
||||
enum dsi_data_lanes data_lanes;
|
||||
u8 num_data_lanes;
|
||||
u8 bpp;
|
||||
bool en_crc_check;
|
||||
bool en_ecc_check;
|
||||
enum dsi_te_mode te_mode;
|
||||
@@ -529,7 +548,9 @@ struct dsi_host_config {
|
||||
* @panel_prefill_lines: Panel prefill lines for RSC
|
||||
* @mdp_transfer_time_us: Specifies the mdp transfer time for command mode
|
||||
* panels in microseconds.
|
||||
* @dsi_transfer_time_us: Specifies the dsi transfer time for cmd panels.
|
||||
* @clk_rate_hz: DSI bit clock per lane in hz.
|
||||
* @min_dsi_clk_hz: Min dsi clk per lane to transfer frame in vsync time.
|
||||
* @topology: Topology selected for the panel
|
||||
* @dsc: DSC compression info
|
||||
* @dsc_enabled: DSC compression enabled
|
||||
@@ -545,7 +566,9 @@ struct dsi_display_mode_priv_info {
|
||||
u32 panel_jitter_denom;
|
||||
u32 panel_prefill_lines;
|
||||
u32 mdp_transfer_time_us;
|
||||
u32 dsi_transfer_time_us;
|
||||
u64 clk_rate_hz;
|
||||
u64 min_dsi_clk_hz;
|
||||
|
||||
struct msm_display_topology topology;
|
||||
struct msm_display_dsc_info dsc;
|
||||
|
@@ -4005,7 +4005,8 @@ static int dsi_display_set_mode_sub(struct dsi_display *display,
|
||||
display_for_each_ctrl(i, display) {
|
||||
ctrl = &display->ctrl[i];
|
||||
rc = dsi_ctrl_update_host_config(ctrl->ctrl, &display->config,
|
||||
mode->dsi_mode_flags, display->dsi_clk_handle);
|
||||
mode, mode->dsi_mode_flags,
|
||||
display->dsi_clk_handle);
|
||||
if (rc) {
|
||||
pr_err("[%s] failed to update ctrl config, rc=%d\n",
|
||||
display->name, rc);
|
||||
@@ -5552,13 +5553,30 @@ int dsi_display_get_modes(struct dsi_display *display,
|
||||
memset(&panel_mode, 0, sizeof(panel_mode));
|
||||
|
||||
rc = dsi_panel_get_mode(display->panel, mode_idx,
|
||||
&panel_mode, topology_override);
|
||||
&panel_mode,
|
||||
topology_override);
|
||||
if (rc) {
|
||||
pr_err("[%s] failed to get mode idx %d from panel\n",
|
||||
display->name, mode_idx);
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Calculate dsi frame transfer time */
|
||||
if (display->panel->panel_mode == DSI_OP_CMD_MODE) {
|
||||
dsi_panel_calc_dsi_transfer_time(
|
||||
&display->panel->host_config,
|
||||
&panel_mode.timing);
|
||||
panel_mode.priv_info->dsi_transfer_time_us =
|
||||
panel_mode.timing.dsi_transfer_time_us;
|
||||
panel_mode.priv_info->min_dsi_clk_hz =
|
||||
panel_mode.timing.min_dsi_clk_hz;
|
||||
|
||||
panel_mode.priv_info->mdp_transfer_time_us =
|
||||
panel_mode.priv_info->dsi_transfer_time_us;
|
||||
panel_mode.timing.mdp_transfer_time_us =
|
||||
panel_mode.timing.dsi_transfer_time_us;
|
||||
}
|
||||
|
||||
if (display->ctrl_count > 1) { /* TODO: remove if */
|
||||
panel_mode.timing.h_active *= display->ctrl_count;
|
||||
panel_mode.timing.h_front_porch *= display->ctrl_count;
|
||||
@@ -5899,6 +5917,7 @@ int dsi_display_set_mode(struct dsi_display *display,
|
||||
{
|
||||
int rc = 0;
|
||||
struct dsi_display_mode adj_mode;
|
||||
struct dsi_mode_info timing;
|
||||
|
||||
if (!display || !mode || !display->panel) {
|
||||
pr_err("Invalid params\n");
|
||||
@@ -5908,6 +5927,7 @@ int dsi_display_set_mode(struct dsi_display *display,
|
||||
mutex_lock(&display->display_lock);
|
||||
|
||||
adj_mode = *mode;
|
||||
timing = adj_mode.timing;
|
||||
adjust_timing_by_ctrl_count(display, &adj_mode);
|
||||
|
||||
/*For dynamic DSI setting, use specified clock rate */
|
||||
@@ -5935,6 +5955,11 @@ int dsi_display_set_mode(struct dsi_display *display,
|
||||
}
|
||||
}
|
||||
|
||||
pr_info("mdp_transfer_time_us=%d us\n",
|
||||
adj_mode.priv_info->mdp_transfer_time_us);
|
||||
pr_info("hactive= %d,vactive= %d,fps=%d",timing.h_active,
|
||||
timing.v_active,timing.refresh_rate);
|
||||
|
||||
memcpy(display->panel->cur_mode, &adj_mode, sizeof(adj_mode));
|
||||
error:
|
||||
mutex_unlock(&display->display_lock);
|
||||
|
@@ -873,6 +873,8 @@ static int dsi_panel_parse_pixel_format(struct dsi_host_common_cfg *host,
|
||||
return rc;
|
||||
}
|
||||
|
||||
host->bpp = bpp;
|
||||
|
||||
switch (bpp) {
|
||||
case 3:
|
||||
fmt = DSI_PIXEL_FORMAT_RGB111;
|
||||
@@ -913,6 +915,7 @@ static int dsi_panel_parse_lane_states(struct dsi_host_common_cfg *host,
|
||||
{
|
||||
int rc = 0;
|
||||
bool lane_enabled;
|
||||
u32 num_of_lanes = 0;
|
||||
|
||||
lane_enabled = utils->read_bool(utils->data,
|
||||
"qcom,mdss-dsi-lane-0-state");
|
||||
@@ -930,6 +933,17 @@ static int dsi_panel_parse_lane_states(struct dsi_host_common_cfg *host,
|
||||
"qcom,mdss-dsi-lane-3-state");
|
||||
host->data_lanes |= (lane_enabled ? DSI_DATA_LANE_3 : 0);
|
||||
|
||||
if (host->data_lanes & DSI_DATA_LANE_0)
|
||||
num_of_lanes++;
|
||||
if (host->data_lanes & DSI_DATA_LANE_1)
|
||||
num_of_lanes++;
|
||||
if (host->data_lanes & DSI_DATA_LANE_2)
|
||||
num_of_lanes++;
|
||||
if (host->data_lanes & DSI_DATA_LANE_3)
|
||||
num_of_lanes++;
|
||||
|
||||
host->num_data_lanes = num_of_lanes;
|
||||
|
||||
if (host->data_lanes == 0) {
|
||||
pr_err("[%s] No data lanes are enabled, rc=%d\n", name, rc);
|
||||
rc = -EINVAL;
|
||||
@@ -3294,6 +3308,55 @@ void dsi_panel_put_mode(struct dsi_display_mode *mode)
|
||||
kfree(mode->priv_info);
|
||||
}
|
||||
|
||||
void dsi_panel_calc_dsi_transfer_time(struct dsi_host_common_cfg *config,
|
||||
struct dsi_mode_info *timing)
|
||||
{
|
||||
u32 frame_time_us,nslices;
|
||||
u64 min_bitclk, total_active_pixels, bits_per_line;
|
||||
struct msm_display_dsc_info *dsc = timing->dsc;
|
||||
|
||||
/* Packet overlead in bits,2 bytes header + 2 bytes checksum
|
||||
* + 1 byte dcs data command.
|
||||
*/
|
||||
const u32 packet_overhead = 56;
|
||||
|
||||
/* Default time between pingpong done to TE in microsecs */
|
||||
const u32 max_tx_threshold_time = 2166;
|
||||
|
||||
frame_time_us = mult_frac(1000, 1000, (timing->refresh_rate));
|
||||
|
||||
if (timing->dsc_enabled) {
|
||||
nslices = (timing->h_active)/(dsc->slice_width);
|
||||
/* (slice width x bit-per-pixel + packet overhead) x
|
||||
* number of slices x height x fps / lane
|
||||
*/
|
||||
bits_per_line = ((dsc->slice_width * dsc->bpp) +
|
||||
packet_overhead) * nslices;
|
||||
bits_per_line = bits_per_line / (config->num_data_lanes);
|
||||
|
||||
min_bitclk = (bits_per_line * timing->v_active *
|
||||
timing->refresh_rate);
|
||||
} else {
|
||||
total_active_pixels = ((DSI_H_ACTIVE_DSC(timing)
|
||||
* timing->v_active));
|
||||
/* calculate the actual bitclk needed to transfer the frame */
|
||||
min_bitclk = (total_active_pixels * (timing->refresh_rate) *
|
||||
(config->bpp)) / (config->num_data_lanes);
|
||||
}
|
||||
|
||||
timing->min_dsi_clk_hz = min_bitclk;
|
||||
|
||||
if (timing->clk_rate_hz) {
|
||||
/* adjust the transfer time proportionately for bit clk*/
|
||||
timing->dsi_transfer_time_us = mult_frac(frame_time_us,
|
||||
min_bitclk, timing->clk_rate_hz);
|
||||
} else {
|
||||
timing->dsi_transfer_time_us = frame_time_us -
|
||||
max_tx_threshold_time;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int dsi_panel_get_mode(struct dsi_panel *panel,
|
||||
u32 index, struct dsi_display_mode *mode,
|
||||
int topology_override)
|
||||
|
@@ -299,4 +299,7 @@ int dsi_panel_parse_esd_reg_read_configs(struct dsi_panel *panel);
|
||||
|
||||
void dsi_panel_ext_bridge_put(struct dsi_panel *panel);
|
||||
|
||||
void dsi_panel_calc_dsi_transfer_time(struct dsi_host_common_cfg *config,
|
||||
struct dsi_mode_info *timing);
|
||||
|
||||
#endif /* _DSI_PANEL_H_ */
|
||||
|
Référencer dans un nouveau ticket
Bloquer un utilisateur