diff --git a/msm/dsi/dsi_catalog.c b/msm/dsi/dsi_catalog.c index 36573e6772..fc686bd3b9 100644 --- a/msm/dsi/dsi_catalog.c +++ b/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; diff --git a/msm/dsi/dsi_catalog.h b/msm/dsi/dsi_catalog.h index 400e169846..cfd864bb59 100644 --- a/msm/dsi/dsi_catalog.h +++ b/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); diff --git a/msm/dsi/dsi_ctrl.c b/msm/dsi/dsi_ctrl.c index 7f861e002a..08ddfbe8d7 100644 --- a/msm/dsi/dsi_ctrl.c +++ b/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 { diff --git a/msm/dsi/dsi_ctrl_hw.h b/msm/dsi/dsi_ctrl_hw.h index 09ca165078..9e438baac4 100644 --- a/msm/dsi/dsi_ctrl_hw.h +++ b/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_ */ diff --git a/msm/dsi/dsi_ctrl_hw_cmn.c b/msm/dsi/dsi_ctrl_hw_cmn.c index c895420a34..340938e4f2 100644 --- a/msm/dsi/dsi_ctrl_hw_cmn.c +++ b/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); diff --git a/msm/dsi/dsi_defs.h b/msm/dsi/dsi_defs.h index 86ca54e8a1..a6dbb1081a 100644 --- a/msm/dsi/dsi_defs.h +++ b/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_ */ diff --git a/msm/dsi/dsi_display.c b/msm/dsi/dsi_display.c index b9806a42a1..fc9462cd0a 100644 --- a/msm/dsi/dsi_display.c +++ b/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( diff --git a/msm/dsi/dsi_drm.c b/msm/dsi/dsi_drm.c index 9494d0d931..19a41015ed 100644 --- a/msm/dsi/dsi_drm.c +++ b/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) { diff --git a/msm/dsi/dsi_panel.c b/msm/dsi/dsi_panel.c index 6ef7b9d038..d258aaba5d 100644 --- a/msm/dsi/dsi_panel.c +++ b/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; diff --git a/msm/msm_drv.h b/msm/msm_drv.h index 1843a53a76..c74468f896 100644 --- a/msm/msm_drv.h +++ b/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