diff --git a/msm/dsi/dsi_display.c b/msm/dsi/dsi_display.c index 5286d17910..484e84e2ef 100644 --- a/msm/dsi/dsi_display.c +++ b/msm/dsi/dsi_display.c @@ -7237,8 +7237,9 @@ int dsi_display_enable(struct dsi_display *display) } /* Block sending pps command if modeset is due to fps difference */ - if ((mode->priv_info->dsc_enabled) && - !(mode->dsi_mode_flags & DSI_MODE_FLAG_DMS_FPS)) { + if ((mode->priv_info->dsc_enabled || + mode->priv_info->vdc_enabled) && + !(mode->dsi_mode_flags & DSI_MODE_FLAG_DMS_FPS)) { rc = dsi_panel_update_pps(display->panel); if (rc) { DSI_ERR("[%s] panel pps cmd update failed, rc=%d\n", @@ -7406,7 +7407,7 @@ int dsi_display_update_pps(char *pps_cmd, void *disp) display = disp; mutex_lock(&display->display_lock); - memcpy(display->panel->dsc_pps_cmd, pps_cmd, DSI_CMD_PPS_SIZE); + memcpy(display->panel->dce_pps_cmd, pps_cmd, DSI_CMD_PPS_SIZE); mutex_unlock(&display->display_lock); return 0; diff --git a/msm/dsi/dsi_panel.c b/msm/dsi/dsi_panel.c index 09f30b2dec..dba1112380 100644 --- a/msm/dsi/dsi_panel.c +++ b/msm/dsi/dsi_panel.c @@ -34,26 +34,37 @@ #define DEFAULT_PANEL_PREFILL_LINES 25 #define MIN_PREFILL_LINES 35 - -int dsi_dsc_create_pps_buf_cmd(struct msm_display_dsc_info *dsc, char *buf, - int pps_id, u32 size) +static void dsi_dce_prepare_pps_header(char *buf, u32 pps_delay_ms) { char *bp; - char *dbgbp; - u32 header_size = 7; - dbgbp = buf; bp = buf; /* First 7 bytes are cmd header */ *bp++ = 0x0A; *bp++ = 1; *bp++ = 0; *bp++ = 0; - *bp++ = dsc->pps_delay_ms; + *bp++ = pps_delay_ms; *bp++ = 0; *bp++ = 128; +} - return sde_dsc_create_pps_buf_cmd(dsc, bp, pps_id, size - header_size); +static int dsi_dsc_create_pps_buf_cmd(struct msm_display_dsc_info *dsc, + char *buf, int pps_id, u32 size) +{ + dsi_dce_prepare_pps_header(buf, dsc->pps_delay_ms); + buf += DSI_CMD_PPS_HDR_SIZE; + return sde_dsc_create_pps_buf_cmd(dsc, buf, pps_id, + size); +} + +static int dsi_vdc_create_pps_buf_cmd(struct msm_display_vdc_info *vdc, + char *buf, int pps_id, u32 size) +{ + dsi_dce_prepare_pps_header(buf, vdc->pps_delay_ms); + buf += DSI_CMD_PPS_HDR_SIZE; + return sde_vdc_create_pps_buf_cmd(vdc, buf, pps_id, + size); } static int dsi_panel_vreg_get(struct dsi_panel *panel) @@ -3771,17 +3782,22 @@ int dsi_panel_update_pps(struct dsi_panel *panel) set = &priv_info->cmd_sets[DSI_CMD_SET_PPS]; - rc = dsi_dsc_create_pps_buf_cmd(&priv_info->dsc, panel->dsc_pps_cmd, 0, - DSI_CMD_PPS_SIZE); - if (rc) { - DSI_ERR("failed to create pps cmd, rc=%d\n", rc); - goto error; - } - rc = dsi_panel_create_cmd_packets(panel->dsc_pps_cmd, - DSI_CMD_PPS_SIZE, 1, set->cmds); - if (rc) { - DSI_ERR("failed to create cmd packets, rc=%d\n", rc); - goto error; + if (priv_info->dsc_enabled) + dsi_dsc_create_pps_buf_cmd(&priv_info->dsc, + panel->dce_pps_cmd, 0, + DSI_CMD_PPS_SIZE - DSI_CMD_PPS_HDR_SIZE); + else if (priv_info->vdc_enabled) + dsi_vdc_create_pps_buf_cmd(&priv_info->vdc, + panel->dce_pps_cmd, 0, + DSI_CMD_PPS_SIZE - DSI_CMD_PPS_HDR_SIZE); + + if (priv_info->dsc_enabled || priv_info->vdc_enabled) { + rc = dsi_panel_create_cmd_packets(panel->dce_pps_cmd, + DSI_CMD_PPS_SIZE, 1, set->cmds); + if (rc) { + DSI_ERR("failed to create cmd packets, rc=%d\n", rc); + goto error; + } } rc = dsi_panel_tx_cmd_set(panel, DSI_CMD_SET_PPS); diff --git a/msm/dsi/dsi_panel.h b/msm/dsi/dsi_panel.h index f5a38bcc7d..4b10e457a2 100644 --- a/msm/dsi/dsi_panel.h +++ b/msm/dsi/dsi_panel.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. */ #ifndef _DSI_PANEL_H_ @@ -26,6 +26,7 @@ #define MAX_SV_BL_SCALE_LEVEL 65535 #define DSI_CMD_PPS_SIZE 135 +#define DSI_CMD_PPS_HDR_SIZE 7 #define DSI_MODE_MAX 32 enum dsi_panel_rotation { @@ -198,7 +199,7 @@ struct dsi_panel { bool te_using_watchdog_timer; u32 qsync_min_fps; - char dsc_pps_cmd[DSI_CMD_PPS_SIZE]; + char dce_pps_cmd[DSI_CMD_PPS_SIZE]; enum dsi_dms_mode dms_mode; bool sync_broadcast_en; diff --git a/msm/sde_vdc_helper.c b/msm/sde_vdc_helper.c index 9272289883..15b35648c1 100644 --- a/msm/sde_vdc_helper.c +++ b/msm/sde_vdc_helper.c @@ -790,3 +790,168 @@ int sde_vdc_populate_config(struct msm_display_vdc_info *vdc_info, return ret; } + +int sde_vdc_create_pps_buf_cmd(struct msm_display_vdc_info *vdc_info, + char *buf, int pps_id, u32 len) +{ + char *bp = buf; + u32 i; + u32 slice_num_bits_ub, slice_num_bits_ldw; + + if (len < SDE_VDC_PPS_SIZE) + return -EINVAL; + + memset(buf, 0, len); + /* b0 */ + *bp++ = vdc_info->version_major; + /* b1 */ + *bp++ = vdc_info->version_minor; + /* b2 */ + *bp++ = vdc_info->version_release; + /* b3 */ + *bp++ = (pps_id & 0xff); /* pps1 */ + /* b4-b5 */ + *bp++ = ((vdc_info->frame_width >> 8) & 0xff); + *bp++ = (vdc_info->frame_width & 0x0ff); + /* b6-b7 */ + *bp++ = ((vdc_info->frame_height >> 8) & 0xff); + *bp++ = (vdc_info->frame_height & 0x0ff); + /* b8-b9 */ + *bp++ = ((vdc_info->slice_width >> 8) & 0xff); + *bp++ = (vdc_info->slice_width & 0x0ff); + /* b10-b11 */ + *bp++ = ((vdc_info->slice_height >> 8) & 0xff); + *bp++ = (vdc_info->slice_height & 0x0ff); + /* b12-b15 */ + *bp++ = ((vdc_info->slice_num_px >> 24) & 0xff); + *bp++ = ((vdc_info->slice_num_px >> 16) & 0xff); + *bp++ = ((vdc_info->slice_num_px >> 8) & 0xff); + *bp++ = (vdc_info->slice_num_px & 0x0ff); + /* b16-b17 */ + *bp++ = ((vdc_info->bits_per_pixel >> 8) & 0x3); + *bp++ = (vdc_info->bits_per_pixel & 0xff); + /* b18 */ + bp++; /* reserved */ + /* b19 */ + *bp++ = ((((vdc_info->bits_per_component - 8) >> 1) & 0x3) << 4)| + ((vdc_info->source_color_space & 0x3) << 2)| + (vdc_info->chroma_format & 0x3); + /* b20-b21 */ + bp++; /* reserved */ + bp++; /* reserved */ + + /* b22-b23 */ + *bp++ = ((vdc_info->chunk_size >> 8) & 0xff); + *bp++ = (vdc_info->chunk_size & 0x0ff); + + /* b24-b25 */ + bp++; /* reserved */ + bp++; /* reserved */ + + /* b26-b27 */ + *bp++ = ((vdc_info->rc_buffer_init_size >> 8) & 0xff); + *bp++ = (vdc_info->rc_buffer_init_size & 0x0ff); + + /* b28 */ + *bp++ = vdc_info->rc_stuffing_bits; + + /* b29 */ + *bp++ = vdc_info->rc_init_tx_delay; + + /* b30-b31 */ + *bp++ = ((vdc_info->rc_buffer_max_size >> 8) & 0xff); + *bp++ = (vdc_info->rc_buffer_max_size & 0x0ff); + + /* b32-b35 */ + *bp++ = ((vdc_info->rc_target_rate_threshold >> 24) & 0xff); + *bp++ = ((vdc_info->rc_target_rate_threshold >> 16) & 0xff); + *bp++ = ((vdc_info->rc_target_rate_threshold >> 8) & 0xff); + *bp++ = (vdc_info->rc_target_rate_threshold & 0x0ff); + + /* b36 */ + *bp++ = vdc_info->rc_tar_rate_scale; + /* b37 */ + *bp++ = vdc_info->rc_buffer_fullness_scale; + + /* b38-b39 */ + *bp++ = ((vdc_info->rc_fullness_offset_thresh >> 8) & 0xff); + *bp++ = (vdc_info->rc_fullness_offset_thresh & 0x0ff); + + /* b40-b42 */ + *bp++ = ((vdc_info->rc_fullness_offset_slope >> 16) & 0xff); + *bp++ = ((vdc_info->rc_fullness_offset_slope >> 8) & 0xff); + *bp++ = ((vdc_info->rc_fullness_offset_slope) & 0xff); + + /* b43 */ + *bp++ = (RC_TARGET_RATE_EXTRA_FTBLS & 0x0f); + /* b44 */ + *bp++ = vdc_info->flatqp_vf_fbls; + /* b45 */ + *bp++ = vdc_info->flatqp_vf_nbls; + /* b46 */ + *bp++ = vdc_info->flatqp_sw_fbls; + /* b47 */ + *bp++ = vdc_info->flatqp_sw_nbls; + + /* b48-b55 */ + for (i = 0; i < VDC_FLAT_QP_LUT_SIZE; i++) + *bp++ = vdc_info->flatness_qp_lut[i]; + + /* b56-b63 */ + for (i = 0; i < VDC_MAX_QP_LUT_SIZE; i++) + *bp++ = vdc_info->max_qp_lut[i]; + + /* b64-b79 */ + for (i = 0; i < VDC_TAR_DEL_LUT_SIZE; i++) + *bp++ = vdc_info->tar_del_lut[i]; + + /* b80 */ + bp++; /* reserved */ + + /* b81 */ + *bp++ = (((vdc_info->mppf_bpc_r_y & 0xf) << 4) | + (vdc_info->mppf_bpc_g_cb & 0xf)); + /* b82 */ + *bp++ = (((vdc_info->mppf_bpc_b_cr & 0xf) << 4) | + (vdc_info->mppf_bpc_y & 0xf)); + /* b83 */ + *bp++ = (((vdc_info->mppf_bpc_co & 0xf) << 4) | + (vdc_info->mppf_bpc_cg & 0xf)); + + /* b84 */ + bp++; /* reserved */ + /* b85 */ + bp++; /* reserved */ + /* b86 */ + bp++; /* reserved */ + + /* b87 */ + *bp++ = SSM_MAX_SE_SIZE; + + /* b88 */ + bp++; /* reserved */ + /* b89 */ + bp++; /* reserved */ + /* b90 */ + bp++; /* reserved */ + + /* b91 */ + slice_num_bits_ub = (vdc_info->slice_num_bits >> 32); + *bp++ = (slice_num_bits_ub & 0x0ff); + /* b92-b95 */ + slice_num_bits_ldw = (u32)vdc_info->slice_num_bits; + *bp++ = ((slice_num_bits_ldw >> 24) & 0xff); + *bp++ = ((slice_num_bits_ldw >> 16) & 0xff); + *bp++ = ((slice_num_bits_ldw >> 8) & 0xff); + *bp++ = (slice_num_bits_ldw & 0x0ff); + + /* b96 */ + bp++; + /* b97 */ + *bp++ = vdc_info->chunk_adj_bits; + /* b98-b99 */ + *bp++ = ((vdc_info->num_extra_mux_bits >> 8) & 0xff); + *bp++ = (vdc_info->num_extra_mux_bits & 0x0ff); + + return 0; +} diff --git a/msm/sde_vdc_helper.h b/msm/sde_vdc_helper.h index d72716d1af..a8102874f0 100644 --- a/msm/sde_vdc_helper.h +++ b/msm/sde_vdc_helper.h @@ -42,8 +42,20 @@ #define NUM_ACTIVE_HS 1 #define MAX_PIXELS_PER_HS_LINE 5120 +#define SDE_VDC_PPS_SIZE 128 + +/** + * sde_vdc_populate_config - populates the VDC encoder parameters + * for a given panel configuration + */ int sde_vdc_populate_config(struct msm_display_vdc_info *vdc_info, int intf_width, int traffic_mode); -#endif /* __SDE_VDC_HELPER_H__ */ +/** + * sde_vdc_create_pps_buf_cmd- creates the PPS buffer from the VDC + * parameters according to the VDC specification + */ +int sde_vdc_create_pps_buf_cmd(struct msm_display_vdc_info *vdc_info, + char *buf, int pps_id, u32 size); +#endif /* __SDE_VDC_HELPER_H__ */