msm: mdss: Add support for FrameBuffer Compression(FBC)
MDSS supports FBC 1.0 and FBC 2.0. Add MDP and DSI configurations
for FBC.
Change-Id: Ia265a726e6660cc349808862ddbbcd380d9840fd
diff --git a/platform/msm_shared/mdp5.c b/platform/msm_shared/mdp5.c
old mode 100644
new mode 100755
index 1c0f1aa..df6f22d
--- a/platform/msm_shared/mdp5.c
+++ b/platform/msm_shared/mdp5.c
@@ -356,11 +356,12 @@
{
uint32_t hsync_period, vsync_period;
uint32_t hsync_start_x, hsync_end_x;
- uint32_t display_hctl, active_hctl, hsync_ctl, display_vstart, display_vend;
+ uint32_t display_hctl, hsync_ctl, display_vstart, display_vend;
uint32_t mdss_mdp_intf_off;
uint32_t adjust_xres = 0;
struct lcdc_panel_info *lcdc = NULL;
+ struct intf_timing_params itp = {0};
if (pinfo == NULL)
return ERR_INVALID_ARGS;
@@ -384,41 +385,58 @@
writel(BIT(5), MDP_REG_PPB0_CNTL);
}
+ if (!pinfo->fbc.enabled || !pinfo->fbc.comp_ratio)
+ pinfo->fbc.comp_ratio = 1;
+
+ itp.xres = (adjust_xres / pinfo->fbc.comp_ratio);
+ itp.yres = pinfo->yres;
+ itp.width =((adjust_xres + pinfo->lcdc.xres_pad) / pinfo->fbc.comp_ratio);
+ itp.height = pinfo->yres + pinfo->lcdc.yres_pad;
+ itp.h_back_porch = pinfo->lcdc.h_back_porch;
+ itp.h_front_porch = pinfo->lcdc.h_front_porch;
+ itp.v_back_porch = pinfo->lcdc.v_back_porch;
+ itp.v_front_porch = pinfo->lcdc.v_front_porch;
+ itp.hsync_pulse_width = pinfo->lcdc.h_pulse_width;
+ itp.vsync_pulse_width = pinfo->lcdc.v_pulse_width;
+
+ itp.border_clr = pinfo->lcdc.border_clr;
+ itp.underflow_clr = pinfo->lcdc.underflow_clr;
+ itp.hsync_skew = pinfo->lcdc.hsync_skew;
+
+
mdss_mdp_intf_off = intf_base + mdss_mdp_intf_offset();
- hsync_period = lcdc->h_pulse_width +
- lcdc->h_back_porch +
- adjust_xres + lcdc->xres_pad + lcdc->h_front_porch;
- vsync_period = (lcdc->v_pulse_width +
- lcdc->v_back_porch +
- pinfo->yres + lcdc->yres_pad +
- lcdc->v_front_porch);
+ hsync_period = itp.hsync_pulse_width + itp.h_back_porch +
+ itp.width + itp.h_front_porch;
+
+ vsync_period = itp.vsync_pulse_width + itp.v_back_porch +
+ itp.height + itp.v_front_porch;
hsync_start_x =
- lcdc->h_pulse_width +
- lcdc->h_back_porch;
+ itp.hsync_pulse_width +
+ itp.h_back_porch;
hsync_end_x =
- hsync_period - lcdc->h_front_porch - 1;
+ hsync_period - itp.h_front_porch - 1;
- display_vstart = (lcdc->v_pulse_width +
- lcdc->v_back_porch)
- * hsync_period + lcdc->hsync_skew;
- display_vend = ((vsync_period - lcdc->v_front_porch) * hsync_period)
- +lcdc->hsync_skew - 1;
+ display_vstart = (itp.vsync_pulse_width +
+ itp.v_back_porch)
+ * hsync_period + itp.hsync_skew;
+ display_vend = ((vsync_period - itp.v_front_porch) * hsync_period)
+ + itp.hsync_skew - 1;
if (intf_base == MDP_INTF_0_BASE) { /* eDP */
- display_vstart += lcdc->h_pulse_width + lcdc->h_back_porch;
- display_vend -= lcdc->h_front_porch;
+ display_vstart += itp.hsync_pulse_width + itp.h_back_porch;
+ display_vend -= itp.h_front_porch;
}
- hsync_ctl = (hsync_period << 16) | lcdc->h_pulse_width;
+ hsync_ctl = (hsync_period << 16) | itp.hsync_pulse_width;
display_hctl = (hsync_end_x << 16) | hsync_start_x;
writel(hsync_ctl, MDP_HSYNC_CTL + mdss_mdp_intf_off);
writel(vsync_period*hsync_period, MDP_VSYNC_PERIOD_F0 +
mdss_mdp_intf_off);
writel(0x00, MDP_VSYNC_PERIOD_F1 + mdss_mdp_intf_off);
- writel(lcdc->v_pulse_width*hsync_period,
+ writel(itp.vsync_pulse_width*hsync_period,
MDP_VSYNC_PULSE_WIDTH_F0 +
mdss_mdp_intf_off);
writel(0x00, MDP_VSYNC_PULSE_WIDTH_F1 + mdss_mdp_intf_off);
@@ -507,6 +525,57 @@
}
}
+void mdss_fbc_cfg(struct msm_panel_info *pinfo)
+{
+ uint32_t mode = 0;
+ uint32_t budget_ctl = 0;
+ uint32_t lossy_mode = 0;
+ uint32_t xres;
+ struct fbc_panel_info *fbc;
+ uint32_t enc_mode;
+
+ fbc = &pinfo->fbc;
+ xres = pinfo->xres;
+
+ if (!pinfo->fbc.enabled)
+ return;
+
+ if (pinfo->mipi.dual_dsi)
+ xres /= 2;
+
+ /* enc_mode defines FBC version. 0 = FBC 1.0 and 1 = FBC 2.0 */
+ enc_mode = (fbc->comp_ratio == 2) ? 0 : 1;
+
+ mode = ((xres) << 16) | (enc_mode) << 9 | ((fbc->comp_mode) << 8) |
+ ((fbc->qerr_enable) << 7) | ((fbc->cd_bias) << 4) |
+ ((fbc->pat_enable) << 3) | ((fbc->vlc_enable) << 2) |
+ ((fbc->bflc_enable) << 1) | 1;
+
+ dprintf(SPEW, "xres = %d, comp_mode %d, qerr_enable = %d, cd_bias = %d\n",
+ xres, fbc->comp_mode, fbc->qerr_enable, fbc->cd_bias);
+ dprintf(SPEW, "pat_enable %d, vlc_enable = %d, bflc_enable\n",
+ fbc->pat_enable, fbc->vlc_enable, fbc->bflc_enable);
+
+ budget_ctl = ((fbc->line_x_budget) << 12) |
+ ((fbc->block_x_budget) << 8) | fbc->block_budget;
+
+ lossy_mode = ((fbc->lossless_mode_thd) << 16) |
+ ((fbc->lossy_mode_thd) << 8) |
+ ((fbc->lossy_rgb_thd) << 4) | fbc->lossy_mode_idx;
+
+ writel(mode, MDP_PP_0_BASE + MDSS_MDP_REG_PP_FBC_MODE);
+ writel(budget_ctl, MDP_PP_0_BASE + MDSS_MDP_REG_PP_FBC_BUDGET_CTL);
+ writel(lossy_mode, MDP_PP_0_BASE + MDSS_MDP_REG_PP_FBC_LOSSY_MODE);
+
+ if (pinfo->mipi.dual_dsi) {
+ writel(mode, MDP_PP_1_BASE + MDSS_MDP_REG_PP_FBC_MODE);
+ writel(budget_ctl, MDP_PP_1_BASE +
+ MDSS_MDP_REG_PP_FBC_BUDGET_CTL);
+ writel(lossy_mode, MDP_PP_1_BASE +
+ MDSS_MDP_REG_PP_FBC_LOSSY_MODE);
+ }
+}
+
void mdss_qos_remapper_setup(void)
{
uint32_t mdp_hw_rev = readl(MDP_HW_REV);
@@ -627,6 +696,8 @@
/*If dst_split is enabled only intf 2 needs to be enabled.
CTL_1 path should not be set since CTL_0 itself is going
to split after DSPP block*/
+ if (pinfo->fbc.enabled)
+ mdss_fbc_cfg(pinfo);
if (pinfo->mipi.dual_dsi) {
if (!pinfo->lcdc.dst_split) {
@@ -771,6 +842,9 @@
reg = 0x21f00 | mdss_mdp_ctl_out_sel(pinfo, 1);
writel(reg, MDP_CTL_0_BASE + CTL_TOP);
+ if (pinfo->fbc.enabled)
+ mdss_fbc_cfg(pinfo);
+
if (pinfo->mipi.dual_dsi) {
writel(0x213F, MDP_INTF_2_BASE + MDP_PANEL_FORMAT + mdss_mdp_intf_off);
reg = 0x21f00 | mdss_mdp_ctl_out_sel(pinfo, 0);