Merge "drm/msm/dsi-staging: update dsi clock calculations"

Cette révision appartient à :
qctecmdr
2019-05-23 16:40:53 -07:00
révisé par Gerrit - the friendly Code Review server
révision d37cbd374b
6 fichiers modifiés avec 143 ajouts et 19 suppressions

Voir le fichier

@@ -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;
}

Voir le fichier

@@ -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

Voir le fichier

@@ -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;

Voir le fichier

@@ -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);

Voir le fichier

@@ -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)

Voir le fichier

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