Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d37cbd37 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

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

parents bd03e365 f28b596a
Loading
Loading
Loading
Loading
+24 −16
Original line number Diff line number Diff line
@@ -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) {
		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;
	config->common_config.num_data_lanes = num_of_lanes;
	config->common_config.bpp = bpp;

		bit_rate = h_period * v_period * refresh_rate * bpp;
	} else {
	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);
		bit_rate = h_period * v_period * timing->refresh_rate * bpp;
	}

	bit_rate_per_lane = bit_rate;
@@ -2863,7 +2869,8 @@ int dsi_ctrl_host_deinit(struct dsi_ctrl *dsi_ctrl)
 */
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;
		}
+3 −1
Original line number Diff line number Diff line
@@ -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
+23 −0
Original line number Diff line number Diff line
@@ -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;
+27 −2
Original line number Diff line number Diff line
@@ -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);
+63 −0
Original line number Diff line number Diff line
@@ -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)
Loading