Explorar el Código

disp: msm: dsi: add widebus support for DSI

From Lahaina onwards, for compressed DSI output, widebus should be enabled.
In widebus mode, 6 bytes of data are transmitted per pclk.
For uncompressed output, widebus must be disabled to transmit 3 bytes
of uncompressed data per pclk.

Change-Id: I7fc0bdb2e1678152d57b4cbb8295063a2ba8ae73
Signed-off-by: Rajkumar Subbiah <[email protected]>
Rajkumar Subbiah hace 5 años
padre
commit
56e041919c

+ 4 - 0
msm/dsi/dsi_catalog.c

@@ -163,7 +163,11 @@ int dsi_catalog_ctrl_setup(struct dsi_ctrl_hw *ctrl,
 	case DSI_CTRL_VERSION_2_2:
 	case DSI_CTRL_VERSION_2_3:
 	case DSI_CTRL_VERSION_2_4:
+		ctrl->phy_isolation_enabled = phy_isolation_enabled;
+		dsi_catalog_cmn_init(ctrl, version);
+		break;
 	case DSI_CTRL_VERSION_2_5:
+		ctrl->widebus_support = true;
 		ctrl->phy_isolation_enabled = phy_isolation_enabled;
 		dsi_catalog_cmn_init(ctrl, version);
 		break;

+ 1 - 1
msm/dsi/dsi_catalog.h

@@ -170,7 +170,7 @@ 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,
 				     struct dsi_mode_info *mode,
-				     u32 h_stride,
+				     struct dsi_host_common_cfg *cfg,
 				     u32 vc_id,
 				     struct dsi_rect *roi);
 void dsi_ctrl_hw_cmn_phy_sw_reset(struct dsi_ctrl_hw *ctrl);

+ 3 - 3
msm/dsi/dsi_ctrl.c

@@ -2255,7 +2255,7 @@ int dsi_ctrl_timing_setup(struct dsi_ctrl *dsi_ctrl)
 
 		dsi_ctrl->hw.ops.setup_cmd_stream(&dsi_ctrl->hw,
 				&dsi_ctrl->host_config.video_timing,
-				dsi_ctrl->host_config.video_timing.h_active * 3,
+				&dsi_ctrl->host_config.common_config,
 				0x0,
 				&dsi_ctrl->roi);
 		dsi_ctrl->hw.ops.cmd_engine_en(&dsi_ctrl->hw, true);
@@ -2714,7 +2714,7 @@ int dsi_ctrl_host_timing_update(struct dsi_ctrl *dsi_ctrl)
 		if (dsi_ctrl->hw.ops.setup_cmd_stream)
 			dsi_ctrl->hw.ops.setup_cmd_stream(&dsi_ctrl->hw,
 				&dsi_ctrl->host_config.video_timing,
-				dsi_ctrl->host_config.video_timing.h_active * 3,
+				&dsi_ctrl->host_config.common_config,
 				0x0, NULL);
 	} else {
 		DSI_CTRL_ERR(dsi_ctrl, "invalid panel mode for resolution switch\n");
@@ -2802,7 +2802,7 @@ int dsi_ctrl_host_init(struct dsi_ctrl *dsi_ctrl, bool is_splash_enabled)
 
 			dsi_ctrl->hw.ops.setup_cmd_stream(&dsi_ctrl->hw,
 				&dsi_ctrl->host_config.video_timing,
-				dsi_ctrl->host_config.video_timing.h_active * 3,
+				&dsi_ctrl->host_config.common_config,
 				0x0,
 				NULL);
 		} else {

+ 5 - 2
msm/dsi/dsi_ctrl_hw.h

@@ -432,14 +432,15 @@ struct dsi_ctrl_hw_ops {
 	 * setup_cmd_stream() - set up parameters for command pixel streams
 	 * @ctrl:              Pointer to controller host hardware.
 	 * @mode:              Pointer to mode information.
-	 * @h_stride:          Horizontal stride in bytes.
+	 * @cfg:               DSI host configuration that is common to both
+	 *                     video and command modes.
 	 * @vc_id:             stream_id.
 	 *
 	 * Setup parameters for command mode pixel stream size.
 	 */
 	void (*setup_cmd_stream)(struct dsi_ctrl_hw *ctrl,
 				 struct dsi_mode_info *mode,
-				 u32 h_stride,
+				 struct dsi_host_common_cfg *cfg,
 				 u32 vc_id,
 				 struct dsi_rect *roi);
 
@@ -850,6 +851,7 @@ struct dsi_ctrl_hw_ops {
  *                          dsi controller and run only dsi controller.
  * @null_insertion_enabled:  A boolean property to allow dsi controller to
  *                           insert null packet.
+ * @widebus_support:        48 bit wide data bus is supported.
  */
 struct dsi_ctrl_hw {
 	void __iomem *base;
@@ -870,6 +872,7 @@ struct dsi_ctrl_hw {
 
 	bool phy_isolation_enabled;
 	bool null_insertion_enabled;
+	bool widebus_support;
 };
 
 #endif /* _DSI_CTRL_HW_H_ */

+ 26 - 5
msm/dsi/dsi_ctrl_hw_cmn.c

@@ -342,6 +342,16 @@ void dsi_ctrl_hw_cmn_set_video_timing(struct dsi_ctrl_hw *ctrl,
 		reg |= eol_byte_num << 4;
 		reg |= 1;
 		DSI_W32(ctrl, DSI_VIDEO_COMPRESSION_MODE_CTRL, reg);
+
+		if (ctrl->widebus_support) {
+			reg = DSI_R32(ctrl, DSI_VIDEO_MODE_CTRL);
+			reg |= BIT(25);
+			DSI_W32(ctrl, DSI_VIDEO_MODE_CTRL, reg);
+		}
+
+		mode->h_active = DIV_ROUND_UP(mode->h_active *
+				mode->pclk_scale.numer,
+				mode->pclk_scale.denom);
 	} else {
 		width = mode->h_active;
 	}
@@ -388,14 +398,15 @@ 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.
  * @mode:              Pointer to mode information.
- * @h_stride:          Horizontal stride in bytes.
+ * @cfg:               DSI host configuration that is common to both
+ *                     video and command modes.
  * @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,
 				     struct dsi_mode_info *mode,
-				     u32 h_stride,
+				     struct dsi_host_common_cfg *cfg,
 				     u32 vc_id,
 				     struct dsi_rect *roi)
 {
@@ -421,7 +432,7 @@ void dsi_ctrl_hw_cmn_setup_cmd_stream(struct dsi_ctrl_hw *ctrl,
 
 		sde_dsc_populate_dsc_private_params(&dsc, intf_ip_w);
 
-		width_final = dsc.pclk_per_line;
+		width_final = dsc.bytes_per_pkt * dsc.pkt_per_line;
 		stride_final = dsc.bytes_per_pkt;
 		pkt_per_line = dsc.pkt_per_line;
 		eol_byte_num = dsc.eol_byte_num;
@@ -436,7 +447,7 @@ void dsi_ctrl_hw_cmn_setup_cmd_stream(struct dsi_ctrl_hw *ctrl,
 
 		sde_vdc_intf_prog_params(&vdc, intf_ip_w);
 
-		width_final = vdc.pclk_per_line;
+		width_final = vdc.bytes_per_pkt * vdc.pkt_per_line;
 		stride_final = vdc.bytes_per_pkt;
 		pkt_per_line = vdc.pkt_per_line;
 		eol_byte_num = vdc.eol_byte_num;
@@ -447,13 +458,23 @@ void dsi_ctrl_hw_cmn_setup_cmd_stream(struct dsi_ctrl_hw *ctrl,
 		height_final = roi->h;
 	} else {
 		width_final = mode->h_active;
-		stride_final = h_stride;
+		stride_final = mode->h_active * 3;
 		height_final = mode->v_active;
 	}
 
 	if (dsi_compression_enabled(mode)) {
 		pic_width = roi ? roi->w : mode->h_active;
 		height_final = roi ? roi->h : mode->v_active;
+
+		if (ctrl->widebus_support) {
+			width_final = DIV_ROUND_UP(width_final, 6);
+			reg = DSI_R32(ctrl, DSI_COMMAND_MODE_MDP_CTRL2);
+			reg |= BIT(20);
+			DSI_W32(ctrl, DSI_COMMAND_MODE_MDP_CTRL2, reg);
+		} else {
+			width_final = DIV_ROUND_UP(width_final, 3);
+		}
+
 		reg_ctrl = DSI_R32(ctrl, DSI_COMMAND_COMPRESSION_MODE_CTRL);
 		reg_ctrl2 = DSI_R32(ctrl, DSI_COMMAND_COMPRESSION_MODE_CTRL2);
 

+ 14 - 2
msm/dsi/dsi_defs.h

@@ -16,6 +16,8 @@
 #define DSI_V_TOTAL(t) (((t)->v_active) + ((t)->v_back_porch) + \
 			((t)->v_sync_width) + ((t)->v_front_porch))
 
+#define DSI_H_SCALE(h, s) (DIV_ROUND_UP((h) * (s)->numer, (s)->denom))
+
 #define DSI_DEBUG_NAME_LEN		32
 #define display_for_each_ctrl(index, display) \
 	for (index = 0; (index < (display)->ctrl_count) &&\
@@ -398,6 +400,7 @@ struct dsi_panel_cmd_set {
  * @vdc_enabled:      VDC compression enabled.
  * @dsc:              DSC compression configuration.
  * @vdc:              VDC compression configuration.
+ * @pclk_scale:       pclk scale factor, target bpp to source bpp
  * @roi_caps:         Panel ROI capabilities.
  */
 struct dsi_mode_info {
@@ -423,6 +426,7 @@ struct dsi_mode_info {
 	bool vdc_enabled;
 	struct msm_display_dsc_info *dsc;
 	struct msm_display_vdc_info *vdc;
+	struct msm_ratio pclk_scale;
 	struct msm_roi_caps roi_caps;
 };
 
@@ -585,7 +589,9 @@ struct dsi_host_config {
  * @vdc:                  VDC compression info
  * @dsc_enabled:          DSC compression enabled
  * @vdc_enabled:          VDC compression enabled
+ * @pclk_scale:           pclk scale factor, target bpp to source bpp
  * @roi_caps:		  Panel ROI capabilities
+ * @widebus_support       48 bit wide data bus is supported by hw
  */
 struct dsi_display_mode_priv_info {
 	struct dsi_panel_cmd_set cmd_sets[DSI_CMD_SET_MAX];
@@ -606,7 +612,9 @@ struct dsi_display_mode_priv_info {
 	struct msm_display_vdc_info vdc;
 	bool dsc_enabled;
 	bool vdc_enabled;
+	struct msm_ratio pclk_scale;
 	struct msm_roi_caps roi_caps;
+	bool widebus_support;
 };
 
 /**
@@ -738,8 +746,12 @@ static inline u64 dsi_h_active_dce(struct dsi_mode_info *mode)
 
 static inline u64 dsi_h_total_dce(struct dsi_mode_info *mode)
 {
-	return dsi_h_active_dce(mode) + mode->h_back_porch +
-		mode->h_sync_width + mode->h_front_porch;
+	u64 h_total = dsi_h_active_dce(mode);
+
+	h_total += DSI_H_SCALE(mode->h_back_porch, &mode->pclk_scale) +
+			DSI_H_SCALE(mode->h_front_porch, &mode->pclk_scale) +
+			DSI_H_SCALE(mode->h_sync_width, &mode->pclk_scale);
+	return h_total;
 }
 
 #endif /* _DSI_DEFS_H_ */

+ 5 - 1
msm/dsi/dsi_display.c

@@ -5277,7 +5277,7 @@ end:
 
 int dsi_display_dev_remove(struct platform_device *pdev)
 {
-	int rc = 0i, i = 0;
+	int rc = 0, i = 0;
 	struct dsi_display *display;
 	struct dsi_display_ctrl *ctrl;
 
@@ -6143,6 +6143,10 @@ int dsi_display_get_modes(struct dsi_display *display,
 
 		is_cmd_mode = (display_mode.panel_mode == DSI_OP_CMD_MODE);
 
+		/* Setup widebus support */
+		display_mode.priv_info->widebus_support =
+				ctrl->ctrl->hw.widebus_support;
+
 		/* Calculate dsi frame transfer time */
 		if (is_cmd_mode) {
 			dsi_panel_calc_dsi_transfer_time(

+ 10 - 11
msm/dsi/dsi_drm.c

@@ -58,6 +58,9 @@ static void convert_to_dsi_mode(const struct drm_display_mode *drm_mode,
 	if (dsi_mode->priv_info) {
 		dsi_mode->timing.dsc_enabled = dsi_mode->priv_info->dsc_enabled;
 		dsi_mode->timing.dsc = &dsi_mode->priv_info->dsc;
+		dsi_mode->timing.vdc_enabled = dsi_mode->priv_info->vdc_enabled;
+		dsi_mode->timing.vdc = &dsi_mode->priv_info->vdc;
+		dsi_mode->timing.pclk_scale = dsi_mode->priv_info->pclk_scale;
 	}
 
 	if (msm_is_mode_seamless(drm_mode))
@@ -470,7 +473,6 @@ int dsi_conn_get_mode_info(struct drm_connector *connector,
 {
 	struct dsi_display_mode dsi_mode;
 	struct dsi_mode_info *timing;
-	int chroma_format;
 	int src_bpp, tar_bpp;
 
 	if (!drm_mode || !mode_info)
@@ -497,26 +499,23 @@ int dsi_conn_get_mode_info(struct drm_connector *connector,
 			sizeof(struct msm_display_topology));
 
 	mode_info->comp_info.comp_type = MSM_DISPLAY_COMPRESSION_NONE;
+
 	if (dsi_mode.priv_info->dsc_enabled) {
-		chroma_format = dsi_mode.priv_info->dsc.chroma_format;
 		mode_info->comp_info.comp_type = MSM_DISPLAY_COMPRESSION_DSC;
 		memcpy(&mode_info->comp_info.dsc_info, &dsi_mode.priv_info->dsc,
 			sizeof(dsi_mode.priv_info->dsc));
-		tar_bpp = dsi_mode.priv_info->dsc.config.bits_per_pixel >> 4;
-		src_bpp = msm_get_src_bpc(chroma_format,
-			dsi_mode.priv_info->dsc.config.bits_per_component);
-		mode_info->comp_info.comp_ratio = mult_frac(1, src_bpp,
-				tar_bpp);
 	} else if (dsi_mode.priv_info->vdc_enabled) {
-		chroma_format = dsi_mode.priv_info->vdc.chroma_format;
 		mode_info->comp_info.comp_type = MSM_DISPLAY_COMPRESSION_VDC;
 		memcpy(&mode_info->comp_info.vdc_info, &dsi_mode.priv_info->vdc,
 			sizeof(dsi_mode.priv_info->vdc));
-		tar_bpp = dsi_mode.priv_info->vdc.bits_per_pixel >> 4;
-		src_bpp = msm_get_src_bpc(chroma_format,
-			dsi_mode.priv_info->vdc.bits_per_component);
+	}
+
+	if (mode_info->comp_info.comp_type) {
+		tar_bpp = dsi_mode.priv_info->pclk_scale.numer;
+		src_bpp = dsi_mode.priv_info->pclk_scale.denom;
 		mode_info->comp_info.comp_ratio = mult_frac(1, src_bpp,
 				tar_bpp);
+		mode_info->wide_bus_en = dsi_mode.priv_info->widebus_support;
 	}
 
 	if (dsi_mode.priv_info->roi_caps.enabled) {

+ 18 - 0
msm/dsi/dsi_panel.c

@@ -728,6 +728,10 @@ static int dsi_panel_parse_timing(struct dsi_mode_info *mode,
 	mode->clk_rate_hz = !rc ? tmp64 : 0;
 	display_mode->priv_info->clk_rate_hz = mode->clk_rate_hz;
 
+	mode->pclk_scale.numer = 1;
+	mode->pclk_scale.denom = 1;
+	display_mode->priv_info->pclk_scale = mode->pclk_scale;
+
 	rc = utils->read_u32(utils->data, "qcom,mdss-mdp-transfer-time-us",
 				&mode->mdp_transfer_time_us);
 	if (!rc)
@@ -2416,8 +2420,15 @@ static int dsi_panel_parse_dsc_params(struct dsi_display_mode *mode,
 		goto error;
 	}
 
+	priv_info->pclk_scale.numer =
+			priv_info->dsc.config.bits_per_pixel >> 4;
+	priv_info->pclk_scale.denom = msm_get_src_bpc(
+			priv_info->dsc.chroma_format,
+			priv_info->dsc.config.bits_per_component);
+
 	mode->timing.dsc_enabled = true;
 	mode->timing.dsc = &priv_info->dsc;
+	mode->timing.pclk_scale = priv_info->pclk_scale;
 
 error:
 	return rc;
@@ -2595,8 +2606,15 @@ static int dsi_panel_parse_vdc_params(struct dsi_display_mode *mode,
 		goto error;
 	}
 
+	priv_info->pclk_scale.numer =
+			priv_info->vdc.bits_per_pixel >> 4;
+	priv_info->pclk_scale.denom = msm_get_src_bpc(
+			priv_info->vdc.chroma_format,
+			priv_info->vdc.bits_per_component);
+
 	mode->timing.vdc_enabled = true;
 	mode->timing.vdc = &priv_info->vdc;
+	mode->timing.pclk_scale = priv_info->pclk_scale;
 
 error:
 	return rc;

+ 10 - 0
msm/msm_drv.h

@@ -290,6 +290,16 @@ enum panel_op_mode {
 	MSM_DISPLAY_MODE_MAX,
 };
 
+/**
+ * struct msm_ratio - integer ratio
+ * @numer: numerator
+ * @denom: denominator
+ */
+struct msm_ratio {
+	uint32_t numer;
+	uint32_t denom;
+};
+
 /**
  * enum msm_event_wait - type of HW events to wait for
  * @MSM_ENC_COMMIT_DONE - wait for the driver to flush the registers to HW