mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-09 21:59:12 -04:00
Merge "disp: msm: dsi: add widebus support for DSI"
This commit is contained in:
commit
7f3ea3bfbb
17 changed files with 244 additions and 85 deletions
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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_ */
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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_ */
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -2635,7 +2635,6 @@ static void sde_encoder_virt_enable(struct drm_encoder *drm_enc)
|
|||
|
||||
phys->comp_type = comp_info->comp_type;
|
||||
phys->comp_ratio = comp_info->comp_ratio;
|
||||
phys->wide_bus_en = sde_enc->mode_info.wide_bus_en;
|
||||
phys->frame_trigger_mode = sde_enc->frame_trigger_mode;
|
||||
phys->poms_align_vsync = disp_info->poms_align_vsync;
|
||||
if (phys->comp_type == MSM_DISPLAY_COMPRESSION_DSC) {
|
||||
|
|
@ -2643,7 +2642,15 @@ static void sde_encoder_virt_enable(struct drm_encoder *drm_enc)
|
|||
comp_info->dsc_info.pclk_per_line;
|
||||
phys->dsc_extra_disp_width =
|
||||
comp_info->dsc_info.extra_width;
|
||||
phys->dce_bytes_per_line =
|
||||
comp_info->dsc_info.bytes_per_pkt *
|
||||
comp_info->dsc_info.pkt_per_line;
|
||||
} else if (phys->comp_type == MSM_DISPLAY_COMPRESSION_VDC) {
|
||||
phys->dce_bytes_per_line =
|
||||
comp_info->vdc_info.bytes_per_pkt *
|
||||
comp_info->vdc_info.pkt_per_line;
|
||||
}
|
||||
|
||||
if (phys != sde_enc->cur_master) {
|
||||
/**
|
||||
* on DMS request, the encoder will be enabled
|
||||
|
|
|
|||
|
|
@ -550,4 +550,20 @@ static inline struct sde_kms *sde_encoder_get_kms(struct drm_encoder *drm_enc)
|
|||
|
||||
return to_sde_kms(priv->kms);
|
||||
}
|
||||
|
||||
/*
|
||||
* sde_encoder_is_widebus_enabled - check if widebus is enabled for current mode
|
||||
* @drm_enc: Pointer to drm encoder structure
|
||||
* @Return: true if widebus is enabled for current mode
|
||||
*/
|
||||
static inline bool sde_encoder_is_widebus_enabled(struct drm_encoder *drm_enc)
|
||||
{
|
||||
struct sde_encoder_virt *sde_enc;
|
||||
|
||||
if (!drm_enc)
|
||||
return false;
|
||||
|
||||
sde_enc = to_sde_encoder_virt(drm_enc);
|
||||
return sde_enc->mode_info.wide_bus_en;
|
||||
}
|
||||
#endif /* __SDE_ENCODER_H__ */
|
||||
|
|
|
|||
|
|
@ -270,8 +270,8 @@ struct sde_encoder_irq {
|
|||
* @comp_ratio: Compression ratio
|
||||
* @dsc_extra_pclk_cycle_cnt: Extra pclk cycle count for DSC over DP
|
||||
* @dsc_extra_disp_width: Additional display width for DSC over DP
|
||||
* @wide_bus_en: Wide-bus configuraiton
|
||||
* @poms_align_vsync: poms with vsync aligned
|
||||
* @dce_bytes_per_line: Compressed bytes per line
|
||||
* @enc_spinlock: Virtual-Encoder-Wide Spin Lock for IRQ purposes
|
||||
* @enable_state: Enable state tracking
|
||||
* @vblank_refcount: Reference count of vblank request
|
||||
|
|
@ -317,8 +317,8 @@ struct sde_encoder_phys {
|
|||
u32 comp_ratio;
|
||||
u32 dsc_extra_pclk_cycle_cnt;
|
||||
u32 dsc_extra_disp_width;
|
||||
bool wide_bus_en;
|
||||
bool poms_align_vsync;
|
||||
u32 dce_bytes_per_line;
|
||||
spinlock_t *enc_spinlock;
|
||||
enum sde_enc_enable_state enable_state;
|
||||
struct mutex *vblank_ctl_lock;
|
||||
|
|
@ -758,6 +758,7 @@ void sde_encoder_helper_phys_disable(struct sde_encoder_phys *phys_enc,
|
|||
|
||||
/**
|
||||
* sde_encoder_helper_setup_misr - helper function to setup misr
|
||||
* @phys_enc: Pointer to physical encoder structure
|
||||
* @enable: enable/disable flag
|
||||
* @frame_count: frame count for misr
|
||||
*/
|
||||
|
|
@ -766,6 +767,7 @@ void sde_encoder_helper_setup_misr(struct sde_encoder_phys *phys_enc,
|
|||
|
||||
/**
|
||||
* sde_encoder_helper_collect_misr - helper function to collect misr
|
||||
* @phys_enc: Pointer to physical encoder structure
|
||||
* @nonblock: blocking/non-blocking flag
|
||||
* @misr_value: pointer to misr value
|
||||
* @Return: zero on success
|
||||
|
|
|
|||
|
|
@ -1146,6 +1146,10 @@ static void sde_encoder_phys_cmd_enable_helper(
|
|||
(phys_enc->comp_type !=
|
||||
MSM_DISPLAY_COMPRESSION_NONE), false);
|
||||
|
||||
if (hw_intf->ops.enable_wide_bus)
|
||||
hw_intf->ops.enable_wide_bus(hw_intf,
|
||||
sde_encoder_is_widebus_enabled(phys_enc->parent));
|
||||
|
||||
/*
|
||||
* For pp-split, skip setting the flush bit for the slave intf, since
|
||||
* both intfs use same ctl and HW will only flush the master.
|
||||
|
|
|
|||
|
|
@ -78,17 +78,8 @@ static void drm_mode_to_intf_timing_params(
|
|||
* <----------------- [hv]sync_end ------->
|
||||
* <---------------------------- [hv]total ------------->
|
||||
*/
|
||||
timing->width = mode->hdisplay; /* active width */
|
||||
|
||||
if (phys_enc->hw_intf->cap->type != INTF_DP) {
|
||||
if ((vid_enc->base.comp_type == MSM_DISPLAY_COMPRESSION_DSC) ||
|
||||
(vid_enc->base.comp_type ==
|
||||
MSM_DISPLAY_COMPRESSION_VDC))
|
||||
timing->width = DIV_ROUND_UP(timing->width,
|
||||
vid_enc->base.comp_ratio);
|
||||
}
|
||||
|
||||
timing->poms_align_vsync = phys_enc->poms_align_vsync;
|
||||
timing->width = mode->hdisplay; /* active width */
|
||||
timing->height = mode->vdisplay; /* active height */
|
||||
timing->xres = timing->width;
|
||||
timing->yres = timing->height;
|
||||
|
|
@ -104,8 +95,11 @@ static void drm_mode_to_intf_timing_params(
|
|||
timing->underflow_clr = 0xff;
|
||||
timing->hsync_skew = mode->hskew;
|
||||
timing->v_front_porch_fixed = vid_enc->base.vfp_cached;
|
||||
if (vid_enc->base.comp_type != MSM_DISPLAY_COMPRESSION_NONE)
|
||||
|
||||
if (vid_enc->base.comp_type != MSM_DISPLAY_COMPRESSION_NONE) {
|
||||
timing->compression_en = true;
|
||||
timing->dce_bytes_per_line = vid_enc->base.dce_bytes_per_line;
|
||||
}
|
||||
|
||||
/* DSI controller cannot handle active-low sync signals. */
|
||||
if (phys_enc->hw_intf->cap->type == INTF_DSI) {
|
||||
|
|
@ -122,7 +116,7 @@ static void drm_mode_to_intf_timing_params(
|
|||
timing->v_front_porch = 0;
|
||||
}
|
||||
|
||||
timing->wide_bus_en = vid_enc->base.wide_bus_en;
|
||||
timing->wide_bus_en = sde_encoder_is_widebus_enabled(phys_enc->parent);
|
||||
|
||||
/*
|
||||
* for DP, divide the horizonal parameters by 2 when
|
||||
|
|
@ -148,6 +142,22 @@ static void drm_mode_to_intf_timing_params(
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* for DSI, if compression is enabled, then divide the horizonal active
|
||||
* timing parameters by compression ratio.
|
||||
*/
|
||||
if ((phys_enc->hw_intf->cap->type != INTF_DP) &&
|
||||
((vid_enc->base.comp_type ==
|
||||
MSM_DISPLAY_COMPRESSION_DSC) ||
|
||||
(vid_enc->base.comp_type ==
|
||||
MSM_DISPLAY_COMPRESSION_VDC))) {
|
||||
// adjust active dimensions
|
||||
timing->width = DIV_ROUND_UP(timing->width,
|
||||
vid_enc->base.comp_ratio);
|
||||
timing->xres = DIV_ROUND_UP(timing->xres,
|
||||
vid_enc->base.comp_ratio);
|
||||
}
|
||||
|
||||
/*
|
||||
* For edp only:
|
||||
* DISPLAY_V_START = (VBP * HCYCLE) + HBP
|
||||
|
|
|
|||
|
|
@ -197,88 +197,112 @@ static void sde_hw_intf_setup_timing_engine(struct sde_hw_intf *ctx,
|
|||
u32 hsync_period, vsync_period;
|
||||
u32 display_v_start, display_v_end;
|
||||
u32 hsync_start_x, hsync_end_x;
|
||||
u32 hsync_data_start_x, hsync_data_end_x;
|
||||
u32 active_h_start, active_h_end;
|
||||
u32 active_v_start, active_v_end;
|
||||
u32 active_hctl, display_hctl, hsync_ctl;
|
||||
u32 polarity_ctl, den_polarity, hsync_polarity, vsync_polarity;
|
||||
u32 panel_format;
|
||||
u32 intf_cfg, intf_cfg2;
|
||||
u32 intf_cfg, intf_cfg2 = 0;
|
||||
u32 display_data_hctl = 0, active_data_hctl = 0;
|
||||
u32 data_width;
|
||||
bool dp_intf = false;
|
||||
|
||||
/* read interface_cfg */
|
||||
intf_cfg = SDE_REG_READ(c, INTF_CONFIG);
|
||||
hsync_period = p->hsync_pulse_width + p->h_back_porch + p->width +
|
||||
p->h_front_porch;
|
||||
vsync_period = p->vsync_pulse_width + p->v_back_porch + p->height +
|
||||
p->v_front_porch;
|
||||
|
||||
display_v_start = ((p->vsync_pulse_width + p->v_back_porch) *
|
||||
hsync_period) + p->hsync_skew;
|
||||
display_v_end = ((vsync_period - p->v_front_porch) * hsync_period) +
|
||||
p->hsync_skew - 1;
|
||||
|
||||
hsync_start_x = p->h_back_porch + p->hsync_pulse_width;
|
||||
hsync_end_x = hsync_period - p->h_front_porch - 1;
|
||||
|
||||
if (ctx->cap->type == INTF_EDP || ctx->cap->type == INTF_DP)
|
||||
dp_intf = true;
|
||||
|
||||
if (p->width != p->xres) {
|
||||
active_h_start = hsync_start_x;
|
||||
active_h_end = active_h_start + p->xres - 1;
|
||||
} else {
|
||||
active_h_start = 0;
|
||||
active_h_end = 0;
|
||||
}
|
||||
hsync_period = p->hsync_pulse_width + p->h_back_porch + p->width +
|
||||
p->h_front_porch;
|
||||
vsync_period = p->vsync_pulse_width + p->v_back_porch + p->height +
|
||||
p->v_front_porch;
|
||||
|
||||
if (p->height != p->yres) {
|
||||
active_v_start = display_v_start;
|
||||
active_v_end = active_v_start + (p->yres * hsync_period) - 1;
|
||||
} else {
|
||||
active_v_start = 0;
|
||||
active_v_end = 0;
|
||||
}
|
||||
|
||||
if (active_h_end) {
|
||||
active_hctl = (active_h_end << 16) | active_h_start;
|
||||
intf_cfg |= BIT(29); /* ACTIVE_H_ENABLE */
|
||||
} else {
|
||||
active_hctl = 0;
|
||||
}
|
||||
|
||||
if (active_v_end)
|
||||
intf_cfg |= BIT(30); /* ACTIVE_V_ENABLE */
|
||||
display_v_start = ((p->vsync_pulse_width + p->v_back_porch) *
|
||||
hsync_period) + p->hsync_skew;
|
||||
display_v_end = ((vsync_period - p->v_front_porch) * hsync_period) +
|
||||
p->hsync_skew - 1;
|
||||
|
||||
hsync_ctl = (hsync_period << 16) | p->hsync_pulse_width;
|
||||
display_hctl = (hsync_end_x << 16) | hsync_start_x;
|
||||
|
||||
if (dp_intf) {
|
||||
active_h_start = hsync_start_x;
|
||||
active_h_end = active_h_start + p->xres - 1;
|
||||
active_v_start = display_v_start;
|
||||
active_v_end = active_v_start + (p->yres * hsync_period) - 1;
|
||||
hsync_start_x = p->h_back_porch + p->hsync_pulse_width;
|
||||
hsync_end_x = hsync_period - p->h_front_porch - 1;
|
||||
|
||||
display_v_start += p->hsync_pulse_width + p->h_back_porch;
|
||||
/*
|
||||
* DATA_HCTL_EN controls data timing which can be different from
|
||||
* video timing. It is recommended to enable it for all cases, except
|
||||
* if compression is enabled in 1 pixel per clock mode
|
||||
*/
|
||||
if (!p->compression_en || p->wide_bus_en)
|
||||
intf_cfg2 |= BIT(4);
|
||||
|
||||
active_hctl = (active_h_end << 16) | active_h_start;
|
||||
display_hctl = active_hctl;
|
||||
if (p->wide_bus_en)
|
||||
intf_cfg2 |= BIT(0);
|
||||
|
||||
/*
|
||||
* If widebus is disabled:
|
||||
* For uncompressed stream, the data is valid for the entire active
|
||||
* window period.
|
||||
* For compressed stream, data is valid for a shorter time period
|
||||
* inside the active window depending on the compression ratio.
|
||||
*
|
||||
* If widebus is enabled:
|
||||
* For uncompressed stream, data is valid for only half the active
|
||||
* window, since the data rate is doubled in this mode.
|
||||
* p->width holds the adjusted width for DP but unadjusted width for DSI
|
||||
* For compressed stream, data validity window needs to be adjusted for
|
||||
* compression ratio and then further halved.
|
||||
*/
|
||||
data_width = p->width;
|
||||
|
||||
if (p->compression_en) {
|
||||
data_width = DIV_ROUND_UP(p->dce_bytes_per_line, 3);
|
||||
|
||||
if (p->wide_bus_en)
|
||||
data_width >>= 1;
|
||||
} else if (!dp_intf && p->wide_bus_en) {
|
||||
data_width = p->width >> 1;
|
||||
} else {
|
||||
data_width = p->width;
|
||||
}
|
||||
|
||||
intf_cfg2 = 0;
|
||||
hsync_data_start_x = hsync_start_x;
|
||||
hsync_data_end_x = hsync_start_x + data_width - 1;
|
||||
|
||||
display_hctl = (hsync_end_x << 16) | hsync_start_x;
|
||||
display_data_hctl = (hsync_data_end_x << 16) | hsync_data_start_x;
|
||||
|
||||
if (dp_intf) {
|
||||
// DP timing adjustment
|
||||
display_v_start += p->hsync_pulse_width + p->h_back_porch;
|
||||
display_v_end -= p->h_front_porch;
|
||||
}
|
||||
|
||||
intf_cfg |= BIT(29); /* ACTIVE_H_ENABLE */
|
||||
intf_cfg |= BIT(30); /* ACTIVE_V_ENABLE */
|
||||
active_h_start = hsync_start_x;
|
||||
active_h_end = active_h_start + p->xres - 1;
|
||||
active_v_start = display_v_start;
|
||||
active_v_end = active_v_start + (p->yres * hsync_period) - 1;
|
||||
|
||||
active_hctl = (active_h_end << 16) | active_h_start;
|
||||
|
||||
if (dp_intf) {
|
||||
display_hctl = active_hctl;
|
||||
|
||||
if (p->compression_en) {
|
||||
active_data_hctl = (hsync_start_x +
|
||||
p->extra_dto_cycles) << 16;
|
||||
active_data_hctl += hsync_start_x;
|
||||
|
||||
display_data_hctl = active_data_hctl;
|
||||
}
|
||||
}
|
||||
|
||||
_check_and_set_comp_bit(ctx, p->dsc_4hs_merge, p->compression_en,
|
||||
&intf_cfg2);
|
||||
|
||||
if (dp_intf && p->compression_en) {
|
||||
active_data_hctl = (hsync_start_x + p->extra_dto_cycles) << 16;
|
||||
active_data_hctl += hsync_start_x;
|
||||
|
||||
display_data_hctl = active_data_hctl;
|
||||
|
||||
intf_cfg2 |= BIT(4);
|
||||
}
|
||||
|
||||
den_polarity = 0;
|
||||
if (ctx->cap->type == INTF_HDMI) {
|
||||
hsync_polarity = p->yres >= 720 ? 0 : 1;
|
||||
|
|
@ -730,6 +754,24 @@ static void sde_hw_intf_enable_compressed_input(struct sde_hw_intf *intf,
|
|||
SDE_REG_WRITE(c, INTF_CONFIG2, intf_cfg2);
|
||||
}
|
||||
|
||||
static void sde_hw_intf_enable_wide_bus(struct sde_hw_intf *intf,
|
||||
bool enable)
|
||||
{
|
||||
struct sde_hw_blk_reg_map *c;
|
||||
u32 intf_cfg2;
|
||||
|
||||
if (!intf)
|
||||
return;
|
||||
|
||||
c = &intf->hw;
|
||||
intf_cfg2 = SDE_REG_READ(c, INTF_CONFIG2);
|
||||
intf_cfg2 &= ~BIT(0);
|
||||
|
||||
intf_cfg2 |= enable ? BIT(0) : 0;
|
||||
|
||||
SDE_REG_WRITE(c, INTF_CONFIG2, intf_cfg2);
|
||||
}
|
||||
|
||||
static void _setup_intf_ops(struct sde_hw_intf_ops *ops,
|
||||
unsigned long cap)
|
||||
{
|
||||
|
|
@ -745,6 +787,7 @@ static void _setup_intf_ops(struct sde_hw_intf_ops *ops,
|
|||
ops->avr_trigger = sde_hw_intf_avr_trigger;
|
||||
ops->avr_ctrl = sde_hw_intf_avr_ctrl;
|
||||
ops->enable_compressed_input = sde_hw_intf_enable_compressed_input;
|
||||
ops->enable_wide_bus = sde_hw_intf_enable_wide_bus;
|
||||
|
||||
if (cap & BIT(SDE_INTF_INPUT_CTRL))
|
||||
ops->bind_pingpong_blk = sde_hw_intf_bind_pingpong_blk;
|
||||
|
|
|
|||
|
|
@ -33,11 +33,12 @@ struct intf_timing_params {
|
|||
u32 underflow_clr;
|
||||
u32 hsync_skew;
|
||||
u32 v_front_porch_fixed;
|
||||
bool wide_bus_en; /* for DP only */
|
||||
bool wide_bus_en;
|
||||
bool compression_en;
|
||||
u32 extra_dto_cycles; /* for DP only */
|
||||
bool dsc_4hs_merge; /* DSC 4HS merge */
|
||||
bool poms_align_vsync; /* poms with vsync aligned */
|
||||
u32 dce_bytes_per_line;
|
||||
};
|
||||
|
||||
struct intf_prog_fetch {
|
||||
|
|
@ -199,6 +200,11 @@ struct sde_hw_intf_ops {
|
|||
*/
|
||||
int (*check_and_reset_tearcheck)(struct sde_hw_intf *intf,
|
||||
struct intf_tear_status *status);
|
||||
|
||||
/**
|
||||
* Enable processing of 2 pixels per clock
|
||||
*/
|
||||
void (*enable_wide_bus)(struct sde_hw_intf *intf, bool enable);
|
||||
};
|
||||
|
||||
struct sde_hw_intf {
|
||||
|
|
|
|||
Loading…
Reference in a new issue