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

Commit ac182352 authored by Alexander Beykun's avatar Alexander Beykun Committed by Gerrit - the friendly Code Review server
Browse files

drm/msm/dsi-staging: add dsc support to dsi driver



Patch adds display stream compression support to dsi driver
for both video and command modes. Calculates dsc parameters
and sends PPS to the panel. Provides dsc configuration
settings to msm drm driver.

Change-Id: Ib5baf52e8ba5f5c3c9b6e439f86efd6d7c6397d1
Signed-off-by: default avatarAlexander Beykun <abeykun@codeaurora.org>
Signed-off-by: default avatarJeykumar Sankaran <jsanka@codeaurora.org>
Signed-off-by: default avatarPadmanabhan Komanduru <pkomandu@codeaurora.org>
parent dfbb37d2
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -393,6 +393,7 @@ bool mipi_dsi_packet_format_is_short(u8 type)
	case MIPI_DSI_DCS_SHORT_WRITE_PARAM:
	case MIPI_DSI_DCS_READ:
	case MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE:
	case MIPI_DSI_COMPRESSION_MODE:
		return true;
	}

@@ -424,6 +425,7 @@ bool mipi_dsi_packet_format_is_long(u8 type)
	case MIPI_DSI_PACKED_PIXEL_STREAM_18:
	case MIPI_DSI_PIXEL_STREAM_3BYTE_18:
	case MIPI_DSI_PACKED_PIXEL_STREAM_24:
	case MIPI_DSI_PPS:
		return true;
	}

+1 −2
Original line number Diff line number Diff line
@@ -139,9 +139,8 @@ void dsi_ctrl_hw_cmn_ctrl_en(struct dsi_ctrl_hw *ctrl, bool on);
void dsi_ctrl_hw_cmn_cmd_engine_en(struct dsi_ctrl_hw *ctrl, bool on);

void dsi_ctrl_hw_cmn_setup_cmd_stream(struct dsi_ctrl_hw *ctrl,
				     u32 width_in_pixels,
				     struct dsi_mode_info *mode,
				     u32 h_stride,
				     u32 height_in_lines,
				     u32 vc_id);
void dsi_ctrl_hw_cmn_phy_sw_reset(struct dsi_ctrl_hw *ctrl);
void dsi_ctrl_hw_cmn_soft_reset(struct dsi_ctrl_hw *ctrl);
+3 −5
Original line number Diff line number Diff line
@@ -751,7 +751,7 @@ static int dsi_ctrl_update_link_freqs(struct dsi_ctrl *dsi_ctrl,
	if (host_cfg->data_lanes & DSI_DATA_LANE_3)
		num_of_lanes++;

	h_period = DSI_H_TOTAL(timing);
	h_period = DSI_H_TOTAL_DSC(timing);
	v_period = DSI_V_TOTAL(timing);

	bit_rate = h_period * v_period * timing->refresh_rate * bpp * 8;
@@ -1576,9 +1576,8 @@ int dsi_ctrl_setup(struct dsi_ctrl *dsi_ctrl)
					&dsi_ctrl->host_config.u.cmd_engine);

		dsi_ctrl->hw.ops.setup_cmd_stream(&dsi_ctrl->hw,
				dsi_ctrl->host_config.video_timing.h_active,
				&dsi_ctrl->host_config.video_timing,
				dsi_ctrl->host_config.video_timing.h_active * 3,
				dsi_ctrl->host_config.video_timing.v_active,
				0x0);
		dsi_ctrl->hw.ops.cmd_engine_en(&dsi_ctrl->hw, true);
	} else {
@@ -1659,9 +1658,8 @@ int dsi_ctrl_host_init(struct dsi_ctrl *dsi_ctrl)
					&dsi_ctrl->host_config.u.cmd_engine);

		dsi_ctrl->hw.ops.setup_cmd_stream(&dsi_ctrl->hw,
				dsi_ctrl->host_config.video_timing.h_active,
				&dsi_ctrl->host_config.video_timing,
				dsi_ctrl->host_config.video_timing.h_active * 3,
				dsi_ctrl->host_config.video_timing.v_active,
				0x0);
	} else {
		dsi_ctrl->hw.ops.video_engine_setup(&dsi_ctrl->hw,
+3 −5
Original line number Diff line number Diff line
@@ -309,17 +309,15 @@ struct dsi_ctrl_hw_ops {
	/**
	 * setup_cmd_stream() - set up parameters for command pixel streams
	 * @ctrl:              Pointer to controller host hardware.
	 * @width_in_pixels:   Width of the stream in pixels.
	 * @mode:              Pointer to mode information.
	 * @h_stride:          Horizontal stride in bytes.
	 * @height_inLines:    Number of lines in the stream.
	 * @vc_id:             stream_id.
	 *
	 * Setup parameters for command mode pixel stream size.
	 */
	void (*setup_cmd_stream)(struct dsi_ctrl_hw *ctrl,
				 u32 width_in_pixels,
				 struct dsi_mode_info *mode,
				 u32 h_stride,
				 u32 height_in_lines,
				 u32 vc_id);

	/**
+69 −10
Original line number Diff line number Diff line
@@ -159,14 +159,36 @@ void dsi_ctrl_hw_cmn_set_video_timing(struct dsi_ctrl_hw *ctrl,
{
	u32 reg = 0;
	u32 hs_start = 0;
	u32 hs_end, active_h_start, active_h_end, h_total;
	u32 hs_end, active_h_start, active_h_end, h_total, width = 0;
	u32 vs_start = 0, vs_end = 0;
	u32 vpos_start = 0, vpos_end, active_v_start, active_v_end, v_total;

	if (mode->dsc_enabled && mode->dsc) {
		width = mode->dsc->pclk_per_line;
		reg = mode->dsc->bytes_per_pkt << 16;
		reg |= (0x0b << 8);    /* dtype of compressed image */
		/*
		 * pkt_per_line:
		 * 0 == 1 pkt
		 * 1 == 2 pkt
		 * 2 == 4 pkt
		 * 3 pkt is not support
		 */
		if (mode->dsc->pkt_per_line == 4)
			reg |= (mode->dsc->pkt_per_line - 2) << 6;
		else
			reg |= (mode->dsc->pkt_per_line - 1) << 6;
		reg |= mode->dsc->eol_byte_num << 4;
		reg |= 1;
		DSI_W32(ctrl, DSI_VIDEO_COMPRESSION_MODE_CTRL, reg);
	} else {
		width = mode->h_active;
	}

	hs_end = mode->h_sync_width;
	active_h_start = mode->h_sync_width + mode->h_back_porch;
	active_h_end = active_h_start + mode->h_active;
	h_total = (mode->h_sync_width + mode->h_back_porch + mode->h_active +
	active_h_end = active_h_start + width;
	h_total = (mode->h_sync_width + mode->h_back_porch + width +
		   mode->h_front_porch) - 1;

	vpos_end = mode->v_sync_width;
@@ -203,28 +225,65 @@ void dsi_ctrl_hw_cmn_set_video_timing(struct dsi_ctrl_hw *ctrl,
/**
 * setup_cmd_stream() - set up parameters for command pixel streams
 * @ctrl:              Pointer to controller host hardware.
 * @width_in_pixels:   Width of the stream in pixels.
 * @mode:              Pointer to mode information.
 * @h_stride:          Horizontal stride in bytes.
 * @height_inLines:    Number of lines in the stream.
 * @vc_id:             stream_id
 *
 * Setup parameters for command mode pixel stream size.
 */
void dsi_ctrl_hw_cmn_setup_cmd_stream(struct dsi_ctrl_hw *ctrl,
				     u32 width_in_pixels,
				     struct dsi_mode_info *mode,
				     u32 h_stride,
				     u32 height_in_lines,
				     u32 vc_id)
{
	u32 reg = 0;
	u32 width_final, stride_final;

	if (mode->dsc_enabled && mode->dsc) {
		u32 offset = 0;
		u32 reg_ctrl, reg_ctrl2;

		if (vc_id != 0)
			offset = 16;
		reg_ctrl = DSI_R32(ctrl, DSI_COMMAND_COMPRESSION_MODE_CTRL);
		reg_ctrl2 = DSI_R32(ctrl, DSI_COMMAND_COMPRESSION_MODE_CTRL2);
		width_final = mode->dsc->pclk_per_line;
		stride_final = width_final * (h_stride / mode->h_active);

	reg = (h_stride + 1) << 16;
		reg = 0x39 << 8;
		/*
		 * pkt_per_line:
		 * 0 == 1 pkt
		 * 1 == 2 pkt
		 * 2 == 4 pkt
		 * 3 pkt is not support
		 */
		if (mode->dsc->pkt_per_line == 4)
			reg |= (mode->dsc->pkt_per_line - 2) << 6;
		else
			reg |= (mode->dsc->pkt_per_line - 1) << 6;
		reg |= mode->dsc->eol_byte_num << 4;
		reg |= 1;

		reg_ctrl &= ~(0xFFFF << offset);
		reg_ctrl |= (reg << offset);
		reg_ctrl2 &= ~(0xFFFF << offset);
		reg_ctrl2 |= (mode->dsc->bytes_in_slice << offset);
		DSI_W32(ctrl, DSI_COMMAND_COMPRESSION_MODE_CTRL, reg_ctrl);
		DSI_W32(ctrl, DSI_COMMAND_COMPRESSION_MODE_CTRL2, reg_ctrl2);
	} else {
		width_final = mode->h_active;
		stride_final = h_stride;
	}

	reg = (stride_final + 1) << 16;
	reg |= (vc_id & 0x3) << 8;
	reg |= 0x39; /* packet data type */

	DSI_W32(ctrl, DSI_COMMAND_MODE_MDP_STREAM0_CTRL, reg);
	DSI_W32(ctrl, DSI_COMMAND_MODE_MDP_STREAM1_CTRL, reg);

	reg = (height_in_lines << 16) | width_in_pixels;
	reg = (mode->v_active << 16) | width_final;
	DSI_W32(ctrl, DSI_COMMAND_MODE_MDP_STREAM0_TOTAL, reg);
	DSI_W32(ctrl, DSI_COMMAND_MODE_MDP_STREAM1_TOTAL, reg);
}
Loading