Merge "disp: msm: add support for variable compression ratios"
Cette révision appartient à :

révisé par
Gerrit - the friendly Code Review server

révision
c89633ed36
@@ -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;
|
||||
}
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -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_ */
|
||||
|
@@ -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;
|
||||
|
@@ -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) {
|
||||
|
@@ -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);
|
||||
|
@@ -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;
|
||||
|
@@ -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];
|
||||
|
Référencer dans un nouveau ticket
Bloquer un utilisateur