Merge "disp: msm: add support for variable compression ratios"

Cette révision appartient à :
qctecmdr
2020-02-03 00:11:10 -08:00
révisé par Gerrit - the friendly Code Review server
révision c89633ed36
34 fichiers modifiés avec 3035 ajouts et 217 suppressions

Voir le fichier

@@ -913,7 +913,7 @@ static int dsi_ctrl_update_link_freqs(struct dsi_ctrl *dsi_ctrl,
do_div(bit_rate, dsi_transfer_time_us);
bit_rate = bit_rate * num_of_lanes;
} else {
h_period = DSI_H_TOTAL_DSC(timing);
h_period = dsi_h_total_dce(timing);
v_period = DSI_V_TOTAL(timing);
bit_rate = h_period * v_period * timing->refresh_rate * bpp;
}

Voir le fichier

@@ -14,6 +14,7 @@
#include "dsi_catalog.h"
#include "sde_dbg.h"
#include "sde_dsc_helper.h"
#include "sde_vdc_helper.h"
#define MMSS_MISC_CLAMP_REG_OFF 0x0014
#define DSI_CTRL_DYNAMIC_FORCE_ON (0x23F|BIT(8)|BIT(9)|BIT(11)|BIT(21))
@@ -22,6 +23,22 @@
#define DSI_CTRL_DMA_LINK_SEL (BIT(12)|BIT(13))
#define DSI_CTRL_MDP0_LINK_SEL (BIT(20)|BIT(22))
static bool dsi_dsc_compression_enabled(struct dsi_mode_info *mode)
{
return (mode->dsc_enabled && mode->dsc);
}
static bool dsi_vdc_compression_enabled(struct dsi_mode_info *mode)
{
return (mode->vdc_enabled && mode->vdc);
}
static bool dsi_compression_enabled(struct dsi_mode_info *mode)
{
return (dsi_dsc_compression_enabled(mode) ||
dsi_vdc_compression_enabled(mode));
}
/* Unsupported formats default to RGB888 */
static const u8 cmd_mode_format_map[DSI_PIXEL_FORMAT_MAX] = {
0x6, 0x7, 0x8, 0x8, 0x0, 0x3, 0x4 };
@@ -263,6 +280,33 @@ void dsi_ctrl_hw_cmn_set_timing_db(struct dsi_ctrl_hw *ctrl,
SDE_EVT32(ctrl->index, enable);
}
/**
* get_dce_params() - get the dce params
* @mode: mode information.
* @width: width to be filled up
* @bytes_per_pkt: Bytes per packet to be filled up
* @pkt_per_line: Packet per line parameter
* @eol_byte_num: End-of-line byte number
*
* Get the compression parameters based on compression type.
*/
static void dsi_ctrl_hw_cmn_get_vid_dce_params(struct dsi_mode_info *mode,
u32 *width, u32 *bytes_per_pkt, u32 *pkt_per_line,
u32 *eol_byte_num)
{
if (dsi_dsc_compression_enabled(mode)) {
*width = mode->dsc->pclk_per_line;
*bytes_per_pkt = mode->dsc->bytes_per_pkt;
*pkt_per_line = mode->dsc->pkt_per_line;
*eol_byte_num = mode->dsc->eol_byte_num;
} else if (dsi_vdc_compression_enabled(mode)) {
*width = mode->vdc->pclk_per_line;
*bytes_per_pkt = mode->vdc->bytes_per_pkt;
*pkt_per_line = mode->vdc->pkt_per_line;
*eol_byte_num = mode->vdc->eol_byte_num;
}
}
/**
* set_video_timing() - set up the timing for video frame
* @ctrl: Pointer to controller host hardware.
@@ -276,25 +320,26 @@ 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, width = 0;
u32 bytes_per_pkt, pkt_per_line, eol_byte_num;
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 */
if (dsi_compression_enabled(mode)) {
dsi_ctrl_hw_cmn_get_vid_dce_params(mode,
&width, &bytes_per_pkt,
&pkt_per_line, &eol_byte_num);
reg = bytes_per_pkt << 16;
/* data type of compressed image */
reg |= (0x0b << 8);
/*
* pkt_per_line:
* 0 == 1 pkt
* 1 == 2 pkt
* 2 == 4 pkt
* 3 pkt is not support
* 3 pkt is not supported
*/
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 |= (pkt_per_line >> 1) << 6;
reg |= eol_byte_num << 4;
reg |= 1;
DSI_W32(ctrl, DSI_VIDEO_COMPRESSION_MODE_CTRL, reg);
} else {
@@ -358,52 +403,44 @@ void dsi_ctrl_hw_cmn_setup_cmd_stream(struct dsi_ctrl_hw *ctrl,
u32 height_final;
u32 stream_total = 0, stream_ctrl = 0;
u32 reg_ctrl = 0, reg_ctrl2 = 0, data = 0;
u32 reg = 0, offset = 0;
int pic_width, this_frame_slices, intf_ip_w;
u32 pkt_per_line, eol_byte_num, bytes_in_slice;
if (roi && (!roi->w || !roi->h))
return;
if (mode->dsc_enabled && mode->dsc) {
u32 reg = 0;
u32 offset = 0;
int pic_width, this_frame_slices, intf_ip_w;
if (dsi_dsc_compression_enabled(mode)) {
struct msm_display_dsc_info dsc;
memcpy(&dsc, mode->dsc, sizeof(dsc));
pic_width = roi ? roi->w : mode->h_active;
memcpy(&dsc, mode->dsc, sizeof(dsc));
this_frame_slices = pic_width / dsc.config.slice_width;
intf_ip_w = this_frame_slices * dsc.config.slice_width;
sde_dsc_populate_dsc_private_params(&dsc, intf_ip_w);
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 = dsc.pclk_per_line;
stride_final = dsc.bytes_per_pkt;
height_final = roi ? roi->h : mode->v_active;
pkt_per_line = dsc.pkt_per_line;
eol_byte_num = dsc.eol_byte_num;
bytes_in_slice = dsc.bytes_in_slice;
} else if (dsi_vdc_compression_enabled(mode)) {
struct msm_display_vdc_info vdc;
reg = 0x39 << 8;
/*
* pkt_per_line:
* 0 == 1 pkt
* 1 == 2 pkt
* 2 == 4 pkt
* 3 pkt is not support
*/
if (dsc.pkt_per_line == 4)
reg |= (dsc.pkt_per_line - 2) << 6;
else
reg |= (dsc.pkt_per_line - 1) << 6;
reg |= dsc.eol_byte_num << 4;
reg |= 1;
pic_width = roi ? roi->w : mode->h_active;
memcpy(&vdc, mode->vdc, sizeof(vdc));
this_frame_slices = pic_width / vdc.slice_width;
intf_ip_w = this_frame_slices * vdc.slice_width;
reg_ctrl &= ~(0xFFFF << offset);
reg_ctrl |= (reg << offset);
reg_ctrl2 &= ~(0xFFFF << offset);
reg_ctrl2 |= (dsc.bytes_in_slice << offset);
sde_vdc_intf_prog_params(&vdc, intf_ip_w);
DSI_CTRL_HW_DBG(ctrl, "reg_ctrl 0x%x reg_ctrl2 0x%x\n",
reg_ctrl, reg_ctrl2);
width_final = vdc.pclk_per_line;
stride_final = vdc.bytes_per_pkt;
pkt_per_line = vdc.pkt_per_line;
eol_byte_num = vdc.eol_byte_num;
bytes_in_slice = vdc.bytes_in_slice;
} else if (roi) {
width_final = roi->w;
stride_final = roi->w * 3;
@@ -414,6 +451,36 @@ void dsi_ctrl_hw_cmn_setup_cmd_stream(struct dsi_ctrl_hw *ctrl,
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;
reg_ctrl = DSI_R32(ctrl, DSI_COMMAND_COMPRESSION_MODE_CTRL);
reg_ctrl2 = DSI_R32(ctrl, DSI_COMMAND_COMPRESSION_MODE_CTRL2);
if (vc_id != 0)
offset = 16;
reg = 0x39 << 8;
/*
* pkt_per_line:
* 0 == 1 pkt
* 1 == 2 pkt
* 2 == 4 pkt
* 3 pkt is not supported
*/
reg |= (pkt_per_line >> 1) << 6;
reg |= eol_byte_num << 4;
reg |= 1;
reg_ctrl &= ~(0xFFFF << offset);
reg_ctrl |= (reg << offset);
reg_ctrl2 &= ~(0xFFFF << offset);
reg_ctrl2 |= (bytes_in_slice << offset);
DSI_CTRL_HW_DBG(ctrl, "reg_ctrl 0x%x reg_ctrl2 0x%x\n",
reg_ctrl, reg_ctrl2);
}
/* HS Timer value */
DSI_W32(ctrl, DSI_HS_TIMER_CTRL, 0x3FD08);

Voir le fichier

@@ -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_DEFS_H_
@@ -16,29 +16,6 @@
#define DSI_V_TOTAL(t) (((t)->v_active) + ((t)->v_back_porch) + \
((t)->v_sync_width) + ((t)->v_front_porch))
#define DSI_H_TOTAL_DSC(t) \
({\
u64 value;\
if ((t)->dsc_enabled && (t)->dsc)\
value = (t)->dsc->pclk_per_line;\
else\
value = (t)->h_active;\
value = value + (t)->h_back_porch + (t)->h_sync_width +\
(t)->h_front_porch;\
value;\
})
#define DSI_H_ACTIVE_DSC(t) \
({\
u64 value;\
if ((t)->dsc_enabled && (t)->dsc)\
value = (t)->dsc->pclk_per_line;\
else\
value = (t)->h_active;\
value;\
})
#define DSI_DEBUG_NAME_LEN 32
#define display_for_each_ctrl(index, display) \
for (index = 0; (index < (display)->ctrl_count) &&\
@@ -402,7 +379,9 @@ struct dsi_panel_cmd_set {
* panels in microseconds.
* @dsi_transfer_time_us: Specifies dsi transfer time for command mode.
* @dsc_enabled: DSC compression enabled.
* @vdc_enabled: VDC compression enabled.
* @dsc: DSC compression configuration.
* @vdc: VDC compression configuration.
* @roi_caps: Panel ROI capabilities.
*/
struct dsi_mode_info {
@@ -425,7 +404,9 @@ struct dsi_mode_info {
u32 mdp_transfer_time_us;
u32 dsi_transfer_time_us;
bool dsc_enabled;
bool vdc_enabled;
struct msm_display_dsc_info *dsc;
struct msm_display_vdc_info *vdc;
struct msm_roi_caps roi_caps;
};
@@ -583,7 +564,9 @@ struct dsi_host_config {
* @min_dsi_clk_hz: Min dsi clk per lane to transfer frame in vsync time.
* @topology: Topology selected for the panel
* @dsc: DSC compression info
* @vdc: VDC compression info
* @dsc_enabled: DSC compression enabled
* @vdc_enabled: VDC compression enabled
* @roi_caps: Panel ROI capabilities
*/
struct dsi_display_mode_priv_info {
@@ -602,7 +585,9 @@ struct dsi_display_mode_priv_info {
struct msm_display_topology topology;
struct msm_display_dsc_info dsc;
struct msm_display_vdc_info vdc;
bool dsc_enabled;
bool vdc_enabled;
struct msm_roi_caps roi_caps;
};
@@ -718,4 +703,25 @@ static inline int dsi_pixel_format_to_bpp(enum dsi_pixel_format fmt)
}
return 24;
}
static inline u64 dsi_h_active_dce(struct dsi_mode_info *mode)
{
u64 h_active = 0;
if (mode->dsc_enabled && mode->dsc)
h_active = mode->dsc->pclk_per_line;
else if (mode->vdc_enabled && mode->vdc)
h_active = mode->vdc->pclk_per_line;
else
h_active = mode->h_active;
return h_active;
}
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;
}
#endif /* _DSI_DEFS_H_ */

Voir le fichier

@@ -3964,7 +3964,7 @@ static void _dsi_display_calc_pipe_delay(struct dsi_display *display,
hr_bit_to_esc_ratio = ((dsi_ctrl->clk_freq.byte_clk_rate * 4 * 1000) /
esc_clk_rate_hz);
hsync_period = DSI_H_TOTAL_DSC(&mode->timing);
hsync_period = dsi_h_total_dce(&mode->timing);
delay->pipe_delay = (hsync_period + 1) / pclk_to_esc_ratio;
if (!display->panel->video_config.eof_bllp_lp11_en)
delay->pipe_delay += (17 / pclk_to_esc_ratio) +
@@ -4367,7 +4367,7 @@ static int dsi_display_get_dfps_timing(struct dsi_display *display,
rc = dsi_display_dfps_calc_front_porch(
curr_refresh_rate,
timing->refresh_rate,
DSI_H_TOTAL_DSC(timing),
dsi_h_total_dce(timing),
DSI_V_TOTAL(timing),
timing->v_front_porch,
&adj_mode->timing.v_front_porch);
@@ -4378,7 +4378,7 @@ static int dsi_display_get_dfps_timing(struct dsi_display *display,
curr_refresh_rate,
timing->refresh_rate,
DSI_V_TOTAL(timing),
DSI_H_TOTAL_DSC(timing),
dsi_h_total_dce(timing),
timing->h_front_porch,
&adj_mode->timing.h_front_porch);
if (!rc)
@@ -7241,8 +7241,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",
@@ -7410,7 +7411,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;

Voir le fichier

@@ -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.
*/
@@ -472,6 +472,8 @@ 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)
return -EINVAL;
@@ -498,11 +500,25 @@ int dsi_conn_get_mode_info(struct drm_connector *connector,
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));
mode_info->comp_info.comp_ratio =
MSM_DISPLAY_COMPRESSION_RATIO_3_TO_1;
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);
mode_info->comp_info.comp_ratio = mult_frac(1, src_bpp,
tar_bpp);
}
if (dsi_mode.priv_info->roi_caps.enabled) {

Voir le fichier

@@ -14,6 +14,7 @@
#include "dsi_ctrl_hw.h"
#include "dsi_parser.h"
#include "sde_dsc_helper.h"
#include "sde_vdc_helper.h"
/**
* topology is currently defined by a set of following 3 values:
@@ -33,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)
@@ -2183,7 +2195,7 @@ static int dsi_panel_parse_phy_timing(struct dsi_display_mode *mode,
* function dsi_panel_calc_dsi_transfer_time( )
* as we set it based on dsi clock or mdp transfer time.
*/
pixel_clk_khz = (DSI_H_TOTAL_DSC(&mode->timing) *
pixel_clk_khz = (dsi_h_total_dce(&mode->timing) *
DSI_V_TOTAL(&mode->timing) *
mode->timing.refresh_rate);
do_div(pixel_clk_khz, 1000);
@@ -2317,6 +2329,26 @@ static int dsi_panel_parse_dsc_params(struct dsi_display_mode *mode,
}
priv_info->dsc.config.bits_per_pixel = data << 4;
rc = utils->read_u32(utils->data, "qcom,src-chroma-format",
&data);
if (rc) {
DSI_DEBUG("failed to parse qcom,src-chroma-format\n");
rc = 0;
data = MSM_CHROMA_444;
}
priv_info->dsc.chroma_format = data;
rc = utils->read_u32(utils->data, "qcom,src-color-space",
&data);
if (rc) {
DSI_DEBUG("failed to parse qcom,src-color-space\n");
rc = 0;
data = MSM_RGB;
}
priv_info->dsc.source_color_space = data;
priv_info->dsc.config.block_pred_enable = utils->read_bool(utils->data,
"qcom,mdss-dsc-block-prediction-enable");
@@ -2345,6 +2377,185 @@ error:
return rc;
}
static int dsi_panel_parse_vdc_params(struct dsi_display_mode *mode,
struct dsi_parser_utils *utils, int traffic_mode, int panel_mode)
{
u32 data;
int rc = -EINVAL;
const char *compression;
struct dsi_display_mode_priv_info *priv_info;
int intf_width;
if (!mode || !mode->priv_info)
return -EINVAL;
priv_info = mode->priv_info;
priv_info->vdc_enabled = false;
compression = utils->get_property(utils->data,
"qcom,compression-mode", NULL);
if (compression && !strcmp(compression, "vdc"))
priv_info->vdc_enabled = true;
if (!priv_info->vdc_enabled) {
DSI_DEBUG("vdc compression is not enabled for the mode\n");
return 0;
}
priv_info->vdc.panel_mode = panel_mode;
priv_info->vdc.traffic_mode = traffic_mode;
rc = utils->read_u32(utils->data, "qcom,vdc-version", &data);
if (rc) {
priv_info->vdc.version_major = 0x1;
priv_info->vdc.version_minor = 0x1;
priv_info->vdc.version_release = 0x0;
rc = 0;
} else {
/* BITS[0..3] provides minor version and BITS[4..7] provide
* major version information
*/
priv_info->vdc.version_major = (data >> 4) & 0x0F;
priv_info->vdc.version_minor = data & 0x0F;
if ((priv_info->vdc.version_major != 0x1) &&
((priv_info->vdc.version_minor
!= 0x1))) {
DSI_ERR("%s:unsupported major:%d minor:%d version\n",
__func__,
priv_info->vdc.version_major,
priv_info->vdc.version_minor
);
rc = -EINVAL;
goto error;
}
}
rc = utils->read_u32(utils->data, "qcom,vdc-version-release", &data);
if (rc) {
priv_info->vdc.version_release = 0x0;
rc = 0;
} else {
priv_info->vdc.version_release = data & 0xff;
/* only one release version is supported */
if (priv_info->vdc.version_release != 0x0) {
DSI_ERR("unsupported vdc release version %d\n",
priv_info->vdc.version_release);
rc = -EINVAL;
goto error;
}
}
DSI_INFO("vdc major: 0x%x minor : 0x%x release : 0x%x\n",
priv_info->vdc.version_major,
priv_info->vdc.version_minor,
priv_info->vdc.version_release);
rc = utils->read_u32(utils->data, "qcom,vdc-slice-height", &data);
if (rc) {
DSI_ERR("failed to parse qcom,vdc-slice-height\n");
goto error;
}
priv_info->vdc.slice_height = data;
/* slice height should be atleast 16 lines */
if (priv_info->vdc.slice_height < 16) {
DSI_ERR("invalid slice height %d\n",
priv_info->vdc.slice_height);
rc = -EINVAL;
goto error;
}
rc = utils->read_u32(utils->data, "qcom,vdc-slice-width", &data);
if (rc) {
DSI_ERR("failed to parse qcom,vdc-slice-width\n");
goto error;
}
priv_info->vdc.slice_width = data;
/*
* slide-width should be multiple of 8
* slice-width should be atlease 64 pixels
*/
if ((priv_info->vdc.slice_width & 7) ||
(priv_info->vdc.slice_width < 64)) {
DSI_ERR("invalid slice width:%d\n", priv_info->vdc.slice_width);
rc = -EINVAL;
goto error;
}
rc = utils->read_u32(utils->data, "qcom,vdc-slice-per-pkt", &data);
if (rc) {
DSI_ERR("failed to parse qcom,vdc-slice-per-pkt\n");
goto error;
} else if (!data || (data > 2)) {
DSI_ERR("invalid vdc slice-per-pkt:%d\n", data);
rc = -EINVAL;
goto error;
}
intf_width = mode->timing.h_active;
priv_info->vdc.slice_per_pkt = data;
priv_info->vdc.frame_width = mode->timing.h_active;
priv_info->vdc.frame_height = mode->timing.v_active;
rc = utils->read_u32(utils->data, "qcom,vdc-bit-per-component",
&data);
if (rc) {
DSI_ERR("failed to parse qcom,vdc-bit-per-component\n");
goto error;
}
priv_info->vdc.bits_per_component = data;
rc = utils->read_u32(utils->data, "qcom,mdss-pps-delay-ms", &data);
if (rc) {
DSI_DEBUG("pps-delay-ms not specified, defaulting to 0\n");
data = 0;
}
priv_info->vdc.pps_delay_ms = data;
rc = utils->read_u32(utils->data, "qcom,vdc-bit-per-pixel",
&data);
if (rc) {
DSI_ERR("failed to parse qcom,vdc-bit-per-pixel\n");
goto error;
}
priv_info->vdc.bits_per_pixel = data << 4;
rc = utils->read_u32(utils->data, "qcom,src-chroma-format",
&data);
if (rc) {
DSI_DEBUG("failed to parse qcom,src-chroma-format\n");
rc = 0;
data = MSM_CHROMA_444;
}
priv_info->vdc.chroma_format = data;
rc = utils->read_u32(utils->data, "qcom,src-color-space",
&data);
if (rc) {
DSI_DEBUG("failed to parse qcom,src-color-space\n");
rc = 0;
data = MSM_RGB;
}
priv_info->vdc.source_color_space = data;
rc = sde_vdc_populate_config(&priv_info->vdc,
intf_width, traffic_mode);
if (rc) {
DSI_DEBUG("failed populating vdc config\n");
rc = -EINVAL;
goto error;
}
mode->timing.vdc_enabled = true;
mode->timing.vdc = &priv_info->vdc;
error:
return rc;
}
static int dsi_panel_parse_hdr_config(struct dsi_panel *panel)
{
int rc = 0;
@@ -3293,7 +3504,7 @@ void dsi_panel_calc_dsi_transfer_time(struct dsi_host_common_cfg *config,
min_bitclk_hz = (bits_per_line * timing->v_active *
timing->refresh_rate);
} else {
total_active_pixels = ((DSI_H_ACTIVE_DSC(timing)
total_active_pixels = ((dsi_h_active_dce(timing)
* timing->v_active));
/* calculate the actual bitclk needed to transfer the frame */
min_bitclk_hz = (total_active_pixels * (timing->refresh_rate) *
@@ -3370,6 +3581,8 @@ int dsi_panel_get_mode(struct dsi_panel *panel,
struct dsi_display_mode_priv_info *prv_info;
u32 child_idx = 0;
int rc = 0, num_timings;
int traffic_mode;
int panel_mode;
void *utils_data = NULL;
if (!panel || !mode) {
@@ -3404,6 +3617,8 @@ int dsi_panel_get_mode(struct dsi_panel *panel,
}
utils_data = utils->data;
traffic_mode = panel->video_config.traffic_mode;
panel_mode = panel->panel_mode;
dsi_for_each_child_node(timings_np, child_np) {
if (index != child_idx++)
@@ -3423,6 +3638,13 @@ int dsi_panel_get_mode(struct dsi_panel *panel,
goto parse_fail;
}
rc = dsi_panel_parse_vdc_params(mode, utils, traffic_mode,
panel_mode);
if (rc) {
DSI_ERR("failed to parse vdc params, rc=%d\n", rc);
goto parse_fail;
}
rc = dsi_panel_parse_topology(prv_info, utils,
topology_override);
if (rc) {
@@ -3507,6 +3729,9 @@ int dsi_panel_get_host_cfg_for_mode(struct dsi_panel *panel,
config->video_timing.dsc_enabled = mode->priv_info->dsc_enabled;
config->video_timing.dsc = &mode->priv_info->dsc;
config->video_timing.vdc_enabled = mode->priv_info->vdc_enabled;
config->video_timing.vdc = &mode->priv_info->vdc;
if (dyn_clk_caps->dyn_clk_support)
config->bit_clk_rate_hz_override = mode->timing.clk_rate_hz;
else
@@ -3560,17 +3785,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);

Voir le fichier

@@ -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;

Voir le fichier

@@ -661,7 +661,7 @@ int dsi_phy_hw_calculate_timing_params(struct dsi_phy_hw *phy,
struct phy_timing_ops *ops = phy->ops.timing_ops;
memset(&desc, 0x0, sizeof(desc));
h_total = DSI_H_TOTAL_DSC(mode);
h_total = dsi_h_total_dce(mode);
v_total = DSI_V_TOTAL(mode);
bpp = bits_per_pixel[host->dst_format];