Merge "disp: msm: sde: add line insertion support for sspp"
Esse commit está contido em:

commit de
Gerrit - the friendly Code Review server

commit
04ddb3a852
@@ -499,6 +499,8 @@ struct dsi_split_link_config {
|
||||
* cmd it points to the line after TE.
|
||||
* @dma_sched_window: Determines the width of the window during the
|
||||
* DSI command will be sent by the HW.
|
||||
* @vpadding: panel stacking height.
|
||||
* @line_insertion_enable: line insertion support enable.
|
||||
*/
|
||||
struct dsi_host_common_cfg {
|
||||
enum dsi_pixel_format dst_format;
|
||||
@@ -526,6 +528,8 @@ struct dsi_host_common_cfg {
|
||||
u32 byte_intf_clk_div;
|
||||
u32 dma_sched_line;
|
||||
u32 dma_sched_window;
|
||||
u32 vpadding;
|
||||
bool line_insertion_enable;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@@ -641,6 +641,12 @@ int dsi_conn_get_mode_info(struct drm_connector *connector,
|
||||
mode_info->qsync_min_fps = dsi_mode->timing.qsync_min_fps;
|
||||
mode_info->wd_jitter = dsi_mode->priv_info->wd_jitter;
|
||||
|
||||
if (dsi_display->panel)
|
||||
mode_info->vpadding = dsi_display->panel->host_config.vpadding;
|
||||
if (mode_info->vpadding < drm_mode->vdisplay) {
|
||||
mode_info->vpadding = 0;
|
||||
dsi_display->panel->host_config.line_insertion_enable = 0;
|
||||
}
|
||||
memcpy(&mode_info->topology, &dsi_mode->priv_info->topology,
|
||||
sizeof(struct msm_display_topology));
|
||||
|
||||
|
@@ -1179,7 +1179,8 @@ static int dsi_panel_parse_misc_host_config(struct dsi_host_common_cfg *host,
|
||||
host->dma_sched_window = 0;
|
||||
else
|
||||
host->dma_sched_window = window;
|
||||
|
||||
rc = utils->read_u32(utils->data, "qcom,vert-padding-value", &host->vpadding);
|
||||
host->line_insertion_enable = (rc || host->vpadding <= 0) ? false : true;
|
||||
DSI_DEBUG("[%s] DMA scheduling parameters Line: %d Window: %d\n", name,
|
||||
host->dma_sched_line, host->dma_sched_window);
|
||||
return 0;
|
||||
|
@@ -800,6 +800,7 @@ struct msm_display_wd_jitter_config {
|
||||
* @dyn_clk_list: List of dynamic clock rates for RFI.
|
||||
* @qsync_min_fps: qsync min fps rate
|
||||
* @wd_jitter: Info for WD jitter.
|
||||
* @vpadding: panel stacking height
|
||||
*/
|
||||
struct msm_mode_info {
|
||||
uint32_t frame_rate;
|
||||
@@ -822,6 +823,7 @@ struct msm_mode_info {
|
||||
struct msm_dyn_clk_list dyn_clk_list;
|
||||
u32 qsync_min_fps;
|
||||
struct msm_display_wd_jitter_config wd_jitter;
|
||||
u32 vpadding;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@@ -3461,3 +3461,20 @@ int sde_connector_event_notify(struct drm_connector *connector, uint32_t type,
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool sde_connector_is_line_insertion_supported(struct sde_connector *sde_conn)
|
||||
{
|
||||
struct dsi_display *display = NULL;
|
||||
|
||||
if (!sde_conn)
|
||||
return false;
|
||||
|
||||
if (sde_conn->connector_type != DRM_MODE_CONNECTOR_DSI)
|
||||
return false;
|
||||
|
||||
display = (struct dsi_display *)sde_conn->display;
|
||||
if (!display || !display->panel)
|
||||
return false;
|
||||
|
||||
return display->panel->host_config.line_insertion_enable;
|
||||
}
|
||||
|
@@ -1275,4 +1275,12 @@ int sde_connector_esd_status(struct drm_connector *connector);
|
||||
const char *sde_conn_get_topology_name(struct drm_connector *conn,
|
||||
struct msm_display_topology topology);
|
||||
|
||||
/*
|
||||
* sde_connector_is_line_insertion_supported - get line insertion
|
||||
* feature bit value from panel
|
||||
* @sde_conn: Pointer to sde connector structure
|
||||
* @Return: line insertion support status
|
||||
*/
|
||||
bool sde_connector_is_line_insertion_supported(struct sde_connector *sde_conn);
|
||||
|
||||
#endif /* _SDE_CONNECTOR_H_ */
|
||||
|
@@ -795,6 +795,22 @@ static void _sde_crtc_setup_blend_cfg(struct sde_crtc_mixer *mixer,
|
||||
format->alpha_enable, fg_alpha, bg_alpha, blend_op);
|
||||
}
|
||||
|
||||
static void _sde_crtc_calc_split_dim_layer_yh_param(struct drm_crtc *crtc, u16 *y, u16 *h)
|
||||
{
|
||||
u32 padding_y = 0, padding_start = 0, padding_height = 0;
|
||||
struct sde_crtc_state *cstate;
|
||||
|
||||
cstate = to_sde_crtc_state(crtc->state);
|
||||
if (!cstate->line_insertion.panel_line_insertion_enable)
|
||||
return;
|
||||
|
||||
sde_crtc_calc_vpadding_param(crtc->state, *y, *h, &padding_y,
|
||||
&padding_start, &padding_height);
|
||||
|
||||
*y = padding_y;
|
||||
*h = padding_height;
|
||||
}
|
||||
|
||||
static void _sde_crtc_setup_dim_layer_cfg(struct drm_crtc *crtc,
|
||||
struct sde_crtc *sde_crtc, struct sde_crtc_mixer *mixer,
|
||||
struct sde_hw_dim_layer *dim_layer)
|
||||
@@ -853,6 +869,11 @@ static void _sde_crtc_setup_dim_layer_cfg(struct drm_crtc *crtc,
|
||||
cstate->lm_roi[i].y;
|
||||
}
|
||||
|
||||
/* update dim layer rect for panel stacking crtc */
|
||||
if (cstate->line_insertion.padding_height)
|
||||
_sde_crtc_calc_split_dim_layer_yh_param(crtc, &split_dim_layer.rect.y,
|
||||
&split_dim_layer.rect.h);
|
||||
|
||||
SDE_EVT32(DRMID(crtc), dim_layer->stage,
|
||||
cstate->lm_roi[i].x,
|
||||
cstate->lm_roi[i].y,
|
||||
@@ -1394,6 +1415,100 @@ static int _sde_crtc_check_rois(struct drm_crtc *crtc,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u32 _sde_crtc_calc_gcd(u32 a, u32 b)
|
||||
{
|
||||
if (b == 0)
|
||||
return a;
|
||||
|
||||
return _sde_crtc_calc_gcd(b, a % b);
|
||||
}
|
||||
|
||||
static int _sde_crtc_check_panel_stacking(struct drm_crtc *crtc, struct drm_crtc_state *state)
|
||||
{
|
||||
struct sde_kms *kms;
|
||||
struct sde_crtc *sde_crtc;
|
||||
struct sde_crtc_state *sde_crtc_state;
|
||||
struct drm_connector *conn;
|
||||
struct msm_mode_info mode_info;
|
||||
struct drm_display_mode *adj_mode = &state->adjusted_mode;
|
||||
struct msm_sub_mode sub_mode;
|
||||
u32 gcd = 0, num_of_active_lines = 0, num_of_dummy_lines = 0;
|
||||
int rc;
|
||||
struct drm_encoder *encoder;
|
||||
const u32 max_encoder_cnt = 1;
|
||||
u32 encoder_cnt = 0;
|
||||
|
||||
kms = _sde_crtc_get_kms(crtc);
|
||||
if (!kms || !kms->catalog) {
|
||||
SDE_ERROR("invalid kms\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
sde_crtc = to_sde_crtc(crtc);
|
||||
sde_crtc_state = to_sde_crtc_state(state);
|
||||
/* panel stacking only support single connector */
|
||||
drm_for_each_encoder_mask(encoder, crtc->dev, state->encoder_mask)
|
||||
encoder_cnt++;
|
||||
|
||||
if (!kms->catalog->has_line_insertion || !state->mode_changed ||
|
||||
encoder_cnt > max_encoder_cnt) {
|
||||
SDE_DEBUG("no line insertion support mode change %d enc cnt %d\n",
|
||||
state->mode_changed, encoder_cnt);
|
||||
sde_crtc_state->line_insertion.padding_height = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
conn = sde_crtc_state->connectors[0];
|
||||
rc = sde_connector_get_mode_info(conn, adj_mode, &sub_mode, &mode_info);
|
||||
if (rc) {
|
||||
SDE_ERROR("failed to get mode info %d\n", rc);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!mode_info.vpadding) {
|
||||
sde_crtc_state->line_insertion.padding_height = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (mode_info.vpadding < state->mode.vdisplay) {
|
||||
SDE_ERROR("padding height %d is less than vdisplay %d\n",
|
||||
mode_info.vpadding, state->mode.vdisplay);
|
||||
return -EINVAL;
|
||||
} else if (mode_info.vpadding == state->mode.vdisplay) {
|
||||
SDE_DEBUG("padding height %d is equal to the vdisplay %d\n",
|
||||
mode_info.vpadding, state->mode.vdisplay);
|
||||
sde_crtc_state->line_insertion.padding_height = 0;
|
||||
return 0;
|
||||
} else if (mode_info.vpadding == sde_crtc_state->line_insertion.padding_height) {
|
||||
return 0; /* skip calculation if already cached */
|
||||
}
|
||||
|
||||
gcd = _sde_crtc_calc_gcd(mode_info.vpadding, state->mode.vdisplay);
|
||||
if (!gcd) {
|
||||
SDE_ERROR("zero gcd found for padding height %d %d\n",
|
||||
mode_info.vpadding, state->mode.vdisplay);
|
||||
return -EINVAL;
|
||||
}
|
||||
num_of_active_lines = state->mode.vdisplay;
|
||||
do_div(num_of_active_lines, gcd);
|
||||
num_of_dummy_lines = mode_info.vpadding;
|
||||
do_div(num_of_dummy_lines, gcd);
|
||||
num_of_dummy_lines = num_of_dummy_lines - num_of_active_lines;
|
||||
|
||||
if (num_of_active_lines > MAX_VPADDING_RATIO_M ||
|
||||
num_of_dummy_lines > MAX_VPADDING_RATIO_N) {
|
||||
SDE_ERROR("unsupported panel stacking pattern %d:%d", num_of_active_lines,
|
||||
num_of_dummy_lines);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
sde_crtc_state->line_insertion.padding_active = num_of_active_lines;
|
||||
sde_crtc_state->line_insertion.padding_dummy = num_of_dummy_lines;
|
||||
sde_crtc_state->line_insertion.padding_height = mode_info.vpadding;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void _sde_crtc_program_lm_output_roi(struct drm_crtc *crtc)
|
||||
{
|
||||
struct sde_crtc *sde_crtc;
|
||||
@@ -3587,6 +3702,26 @@ static void _sde_crtc_setup_mixer_for_encoder(
|
||||
}
|
||||
}
|
||||
|
||||
bool sde_crtc_is_line_insertion_supported(struct drm_crtc *crtc)
|
||||
{
|
||||
struct drm_encoder *enc = NULL;
|
||||
struct sde_kms *kms;
|
||||
|
||||
if (!crtc)
|
||||
return false;
|
||||
|
||||
kms = _sde_crtc_get_kms(crtc);
|
||||
if (!kms->catalog->has_line_insertion)
|
||||
return false;
|
||||
|
||||
list_for_each_entry(enc, &crtc->dev->mode_config.encoder_list, head) {
|
||||
if (enc->crtc == crtc)
|
||||
return sde_encoder_is_line_insertion_supported(enc);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void _sde_crtc_setup_mixers(struct drm_crtc *crtc)
|
||||
{
|
||||
struct sde_crtc *sde_crtc = to_sde_crtc(crtc);
|
||||
@@ -4821,6 +4956,8 @@ static void sde_crtc_enable(struct drm_crtc *crtc,
|
||||
SDE_DEBUG("crtc%d\n", crtc->base.id);
|
||||
SDE_EVT32_VERBOSE(DRMID(crtc));
|
||||
sde_crtc = to_sde_crtc(crtc);
|
||||
cstate->line_insertion.panel_line_insertion_enable =
|
||||
sde_crtc_is_line_insertion_supported(crtc);
|
||||
|
||||
/*
|
||||
* Avoid drm_crtc_vblank_on during seamless DMS case
|
||||
@@ -5639,6 +5776,13 @@ static int _sde_crtc_atomic_check(struct drm_crtc *crtc,
|
||||
crtc->base.id, rc);
|
||||
goto end;
|
||||
}
|
||||
|
||||
rc = _sde_crtc_check_panel_stacking(crtc, state);
|
||||
if (rc) {
|
||||
SDE_ERROR("crtc%d failed panel stacking check %d\n",
|
||||
crtc->base.id, rc);
|
||||
goto end;
|
||||
}
|
||||
end:
|
||||
kfree(pstates);
|
||||
kfree(multirect_plane);
|
||||
@@ -7876,3 +8020,46 @@ void _sde_crtc_vm_release_notify(struct drm_crtc *crtc)
|
||||
|
||||
sde_crtc_event_notify(crtc, DRM_EVENT_VM_RELEASE, &val, sizeof(uint32_t));
|
||||
}
|
||||
|
||||
void sde_crtc_calc_vpadding_param(struct drm_crtc_state *state, u32 crtc_y, uint32_t crtc_h,
|
||||
u32 *padding_y, u32 *padding_start, u32 *padding_height)
|
||||
{
|
||||
struct sde_kms *kms;
|
||||
struct sde_crtc_state *cstate = to_sde_crtc_state(state);
|
||||
u32 y_remain, y_start, y_end;
|
||||
u32 m, n;
|
||||
|
||||
kms = _sde_crtc_get_kms(state->crtc);
|
||||
if (!kms || !kms->catalog) {
|
||||
SDE_ERROR("invalid kms or catalog\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!kms->catalog->has_line_insertion)
|
||||
return;
|
||||
|
||||
if (!cstate->line_insertion.padding_active) {
|
||||
SDE_ERROR("zero padding active value\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Computation logic to add number of dummy and active line at
|
||||
* precise position on display
|
||||
*/
|
||||
m = cstate->line_insertion.padding_active;
|
||||
n = m + cstate->line_insertion.padding_dummy;
|
||||
if (m == 0)
|
||||
return;
|
||||
|
||||
y_remain = crtc_y % m;
|
||||
y_start = y_remain + crtc_y / m * n;
|
||||
y_end = (((crtc_y + crtc_h - 1) / m) * n) + ((crtc_y + crtc_h - 1) % m);
|
||||
*padding_y = y_start;
|
||||
*padding_start = m - y_remain;
|
||||
*padding_height = y_end - y_start + 1;
|
||||
SDE_EVT32(DRMID(cstate->base.crtc), y_remain, y_start, y_end, *padding_y, *padding_start,
|
||||
*padding_height);
|
||||
SDE_DEBUG("crtc:%d padding_y:%d padding_start:%d padding_height:%d\n",
|
||||
DRMID(cstate->base.crtc), *padding_y, *padding_start, *padding_height);
|
||||
}
|
||||
|
@@ -432,6 +432,20 @@ enum sde_crtc_dirty_flags {
|
||||
|
||||
#define to_sde_crtc(x) container_of(x, struct sde_crtc, base)
|
||||
|
||||
/**
|
||||
* struct sde_line_insertion_param - sde line insertion parameters
|
||||
* @panel_line_insertion_enable: line insertion support status
|
||||
* @padding_height: panel height after line padding
|
||||
* @padding_active: active lines in panel stacking pattern
|
||||
* @padding_dummy: dummy lines in panel stacking pattern
|
||||
*/
|
||||
struct sde_line_insertion_param {
|
||||
bool panel_line_insertion_enable;
|
||||
u32 padding_height;
|
||||
u32 padding_active;
|
||||
u32 padding_dummy;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct sde_crtc_state - sde container for atomic crtc state
|
||||
* @base: Base drm crtc state structure
|
||||
@@ -467,6 +481,7 @@ enum sde_crtc_dirty_flags {
|
||||
* @cp_dirty_list: array tracking features that are dirty
|
||||
* @cp_range_payload: array storing state user_data passed via range props
|
||||
* @cont_splash_populated: State was populated as part of cont. splash
|
||||
* @param: sde line insertion parameters
|
||||
*/
|
||||
struct sde_crtc_state {
|
||||
struct drm_crtc_state base;
|
||||
@@ -506,6 +521,7 @@ struct sde_crtc_state {
|
||||
struct sde_cp_crtc_range_prop_payload
|
||||
cp_range_payload[SDE_CP_CRTC_MAX_FEATURES];
|
||||
bool cont_splash_populated;
|
||||
struct sde_line_insertion_param line_insertion;
|
||||
};
|
||||
|
||||
enum sde_crtc_irq_state {
|
||||
@@ -1073,4 +1089,24 @@ struct drm_encoder *sde_crtc_get_src_encoder_of_clone(struct drm_crtc *crtc);
|
||||
*/
|
||||
void _sde_crtc_vm_release_notify(struct drm_crtc *crtc);
|
||||
|
||||
/*
|
||||
* sde_crtc_is_line_insertion_supported - get lineinsertion
|
||||
* feature bit value from panel
|
||||
* @drm_crtc: Pointer to drm crtc structure
|
||||
* @Return: line insertion support status
|
||||
*/
|
||||
bool sde_crtc_is_line_insertion_supported(struct drm_crtc *crtc);
|
||||
|
||||
/**
|
||||
* sde_crtc_calc_vpadding_param - calculate vpadding parameters
|
||||
* @state: Pointer to DRM crtc state object
|
||||
* @crtc_y: Plane's CRTC_Y offset
|
||||
* @crtc_h: Plane's CRTC_H size
|
||||
* @padding_y: Padding Y offset
|
||||
* @padding_start: Padding start offset
|
||||
* @padding_height: Padding height in total
|
||||
*/
|
||||
void sde_crtc_calc_vpadding_param(struct drm_crtc_state *state, u32 crtc_y, u32 crtc_h,
|
||||
u32 *padding_y, u32 *padding_start, u32 *padding_height);
|
||||
|
||||
#endif /* _SDE_CRTC_H_ */
|
||||
|
@@ -1069,6 +1069,32 @@ static int _sde_encoder_atomic_check_reserve(struct drm_encoder *drm_enc,
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool sde_encoder_is_line_insertion_supported(struct drm_encoder *drm_enc)
|
||||
{
|
||||
struct sde_connector *sde_conn = NULL;
|
||||
struct sde_kms *sde_kms = NULL;
|
||||
struct drm_connector *conn = NULL;
|
||||
|
||||
if (!drm_enc) {
|
||||
SDE_ERROR("invalid drm encoder\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
sde_kms = sde_encoder_get_kms(drm_enc);
|
||||
if (!sde_kms)
|
||||
return false;
|
||||
|
||||
conn = sde_encoder_get_connector(sde_kms->dev, drm_enc);
|
||||
if (!conn || !conn->state)
|
||||
return false;
|
||||
|
||||
sde_conn = to_sde_connector(conn);
|
||||
if (!sde_conn)
|
||||
return false;
|
||||
|
||||
return sde_connector_is_line_insertion_supported(sde_conn);
|
||||
}
|
||||
|
||||
static void _sde_encoder_get_qsync_fps_callback(struct drm_encoder *drm_enc,
|
||||
u32 *qsync_fps, struct drm_connector_state *conn_state)
|
||||
{
|
||||
|
@@ -683,5 +683,13 @@ static inline bool sde_encoder_is_widebus_enabled(struct drm_encoder *drm_enc)
|
||||
return sde_enc->mode_info.wide_bus_en;
|
||||
}
|
||||
|
||||
/*
|
||||
* sde_encoder_is_line_insertion_supported - get line insertion
|
||||
* feature bit value from panel
|
||||
* @drm_enc: Pointer to drm encoder structure
|
||||
* @Return: line insertion support status
|
||||
*/
|
||||
bool sde_encoder_is_line_insertion_supported(struct drm_encoder *drm_enc);
|
||||
|
||||
void sde_encoder_add_data_to_minidump_va(struct drm_encoder *drm_enc);
|
||||
#endif /* __SDE_ENCODER_H__ */
|
||||
|
@@ -1820,6 +1820,8 @@ static void sde_sspp_set_features(struct sde_mdss_cfg *sde_cfg,
|
||||
|
||||
sblk->maxlinewidth = sde_cfg->max_sspp_linewidth;
|
||||
|
||||
if (sde_cfg->has_line_insertion)
|
||||
set_bit(SDE_SSPP_LINE_INSERTION, &sspp->features);
|
||||
sblk->smart_dma_priority =
|
||||
PROP_VALUE_ACCESS(props->values, SSPP_SMART_DMA, i);
|
||||
if (sblk->smart_dma_priority && sde_cfg->smart_dma_rev)
|
||||
@@ -5161,6 +5163,7 @@ static int _sde_hardware_pre_caps(struct sde_mdss_cfg *sde_cfg, uint32_t hw_rev)
|
||||
sde_cfg->demura_supported[SSPP_DMA1][1] = 1;
|
||||
sde_cfg->demura_supported[SSPP_DMA3][0] = 0;
|
||||
sde_cfg->demura_supported[SSPP_DMA3][1] = 1;
|
||||
sde_cfg->has_line_insertion = true;
|
||||
} else {
|
||||
SDE_ERROR("unsupported chipset id:%X\n", hw_rev);
|
||||
sde_cfg->perf.min_prefill_lines = 0xffff;
|
||||
|
@@ -199,6 +199,10 @@ enum {
|
||||
#define SYS_CACHE_OP_TYPE BIT(3)
|
||||
#define SYS_CACHE_NO_ALLOC BIT(4)
|
||||
|
||||
/* default line padding ratio limitation */
|
||||
#define MAX_VPADDING_RATIO_M 93
|
||||
#define MAX_VPADDING_RATIO_N 45
|
||||
|
||||
/**
|
||||
* sde_sys_cache_type: Types of system cache supported
|
||||
* SDE_SYS_CACHE_DISP: Static img system cache
|
||||
@@ -305,6 +309,7 @@ enum {
|
||||
* @SDE_SSPP_FP16_UNMULT FP16 alpha unmult color processing block support
|
||||
* @SDE_SSPP_UBWC_STATS: Support for ubwc stats
|
||||
* @SDE_SSPP_SCALER_DE_LPF_BLEND: Support for detail enhancer
|
||||
* @SDE_SSPP_LINE_INSERTION Line insertion support
|
||||
* @SDE_SSPP_MAX maximum value
|
||||
*/
|
||||
enum {
|
||||
@@ -341,6 +346,7 @@ enum {
|
||||
SDE_SSPP_FP16_UNMULT,
|
||||
SDE_SSPP_UBWC_STATS,
|
||||
SDE_SSPP_SCALER_DE_LPF_BLEND,
|
||||
SDE_SSPP_LINE_INSERTION,
|
||||
SDE_SSPP_MAX
|
||||
};
|
||||
|
||||
@@ -1826,6 +1832,7 @@ struct sde_perf_cfg {
|
||||
* @perf performance control settings
|
||||
* @uidle_cfg settings for uidle feature
|
||||
* @irq_offset_list list of sde_intr_irq_offsets to initialize irq table
|
||||
* @has_line_insertion line insertion support status
|
||||
* @features bitmap of supported SDE_FEATUREs
|
||||
* @dma_formats supported formats for dma pipe
|
||||
* @vig_formats supported formats for vig pipe
|
||||
@@ -1940,6 +1947,7 @@ struct sde_mdss_cfg {
|
||||
struct sde_uidle_cfg uidle_cfg;
|
||||
struct list_head irq_offset_list;
|
||||
DECLARE_BITMAP(features, SDE_FEATURE_MAX);
|
||||
bool has_line_insertion;
|
||||
|
||||
/* Supported Pixel Format Lists */
|
||||
struct sde_format_extended *dma_formats;
|
||||
|
@@ -44,6 +44,8 @@
|
||||
#define SSPP_SRC_CONSTANT_COLOR_REC1 0x180
|
||||
#define SSPP_EXCL_REC_SIZE_REC1 0x184
|
||||
#define SSPP_EXCL_REC_XY_REC1 0x188
|
||||
#define SSPP_LINE_INSERTION_CTRL_REC1 0x1E4
|
||||
#define SSPP_LINE_INSERTION_OUT_SIZE_REC1 0x1EC
|
||||
|
||||
#define SSPP_UIDLE_CTRL_VALUE 0x1f0
|
||||
#define SSPP_UIDLE_CTRL_VALUE_REC1 0x1f4
|
||||
@@ -116,6 +118,8 @@
|
||||
#define SSPP_TRAFFIC_SHAPER_BPC_MAX 0xFF
|
||||
#define SSPP_CLK_CTRL 0x330
|
||||
#define SSPP_CLK_STATUS 0x334
|
||||
#define SSPP_LINE_INSERTION_CTRL 0x1E0
|
||||
#define SSPP_LINE_INSERTION_OUT_SIZE 0x1E8
|
||||
|
||||
/* SSPP_QOS_CTRL */
|
||||
#define SSPP_QOS_CTRL_VBLANK_EN BIT(16)
|
||||
@@ -1442,6 +1446,37 @@ static int sde_hw_sspp_get_clk_ctrl_status(struct sde_hw_blk_reg_map *hw,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void sde_hw_sspp_setup_line_insertion(struct sde_hw_pipe *ctx,
|
||||
enum sde_sspp_multirect_index rect_index,
|
||||
struct sde_hw_pipe_line_insertion_cfg *cfg)
|
||||
{
|
||||
struct sde_hw_blk_reg_map *c;
|
||||
u32 ctl_off = 0, size_off = 0, ctl_val = 0;
|
||||
u32 idx;
|
||||
|
||||
if (_sspp_subblk_offset(ctx, SDE_SSPP_SRC, &idx) || !cfg)
|
||||
return;
|
||||
|
||||
c = &ctx->hw;
|
||||
|
||||
if (rect_index == SDE_SSPP_RECT_SOLO || rect_index == SDE_SSPP_RECT_0) {
|
||||
ctl_off = SSPP_LINE_INSERTION_CTRL;
|
||||
size_off = SSPP_LINE_INSERTION_OUT_SIZE;
|
||||
} else {
|
||||
ctl_off = SSPP_LINE_INSERTION_CTRL_REC1;
|
||||
size_off = SSPP_LINE_INSERTION_OUT_SIZE_REC1;
|
||||
}
|
||||
|
||||
if (cfg->enable)
|
||||
ctl_val = BIT(31) |
|
||||
(cfg->dummy_lines << 16) |
|
||||
(cfg->first_active_lines << 8) |
|
||||
(cfg->active_lines);
|
||||
|
||||
SDE_REG_WRITE(c, ctl_off, ctl_val);
|
||||
SDE_REG_WRITE(c, size_off, cfg->dst_h << 16);
|
||||
}
|
||||
|
||||
static void _setup_layer_ops(struct sde_hw_pipe *c,
|
||||
unsigned long features, unsigned long perf_features,
|
||||
bool is_virtual_pipe)
|
||||
@@ -1536,6 +1571,8 @@ static void _setup_layer_ops(struct sde_hw_pipe *c,
|
||||
c->ops.set_ubwc_stats_roi = sde_hw_sspp_ubwc_stats_set_roi;
|
||||
c->ops.get_ubwc_stats_data = sde_hw_sspp_ubwc_stats_get_data;
|
||||
}
|
||||
if (test_bit(SDE_SSPP_LINE_INSERTION, &features))
|
||||
c->ops.setup_line_insertion = sde_hw_sspp_setup_line_insertion;
|
||||
}
|
||||
|
||||
static struct sde_sspp_cfg *_sspp_offset(enum sde_sspp sspp,
|
||||
|
@@ -291,6 +291,22 @@ struct sde_hw_pipe_ts_cfg {
|
||||
*/
|
||||
#define SDE_PIPE_SBUF_PLANE_NUM 2
|
||||
|
||||
/**
|
||||
* struct sde_hw_pipe_line_insertion_cfg - line insertion config
|
||||
* @enable: line insertion is enabled
|
||||
* @dummy_lines: dummy lines before active lines
|
||||
* @first_active_lines: number of active lines before first dummy lines
|
||||
* @active_lines: active lines
|
||||
* @dst_h: total active lines plus dummy lines
|
||||
*/
|
||||
struct sde_hw_pipe_line_insertion_cfg {
|
||||
bool enable;
|
||||
u32 dummy_lines;
|
||||
u32 first_active_lines;
|
||||
u32 active_lines;
|
||||
u32 dst_h;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct sde_hw_sspp_ops - interface to the SSPP Hw driver functions
|
||||
* Caller must call the init function to get the pipe context for each pipe
|
||||
@@ -688,6 +704,15 @@ struct sde_hw_sspp_ops {
|
||||
*/
|
||||
void (*setup_fp16_unmult)(struct sde_hw_pipe *ctx,
|
||||
enum sde_sspp_multirect_index index, void *data);
|
||||
|
||||
/**
|
||||
* setup_line_insertion - setup line insertion
|
||||
* @ctx: Pointer to pipe context
|
||||
* @cfg: Pointer to line insertion configuration
|
||||
*/
|
||||
void (*setup_line_insertion)(struct sde_hw_pipe *ctx,
|
||||
enum sde_sspp_multirect_index index,
|
||||
struct sde_hw_pipe_line_insertion_cfg *cfg);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@@ -188,6 +188,45 @@ static struct sde_hw_ctl *_sde_plane_get_hw_ctl(const struct drm_plane *plane)
|
||||
return ctl;
|
||||
}
|
||||
|
||||
static void _sde_plane_setup_panel_stacking(struct sde_plane *psde,
|
||||
struct sde_plane_state *pstate)
|
||||
{
|
||||
struct sde_hw_pipe_line_insertion_cfg *cfg;
|
||||
struct sde_crtc_state *cstate;
|
||||
u32 h_start = 0, h_total = 0, y_start = 0;
|
||||
struct drm_plane_state *dpstate = NULL;
|
||||
struct drm_crtc *drm_crtc = NULL;
|
||||
|
||||
if (!psde || !psde->base.state || !psde->base.state->crtc) {
|
||||
SDE_ERROR("Invalid plane psde %p or drm plane state or drm crtc\n", psde);
|
||||
return;
|
||||
}
|
||||
|
||||
dpstate = psde->base.state;
|
||||
drm_crtc = dpstate->crtc;
|
||||
cstate = to_sde_crtc_state(drm_crtc->state);
|
||||
pstate->lineinsertion_feature = cstate->line_insertion.panel_line_insertion_enable;
|
||||
|
||||
if ((!test_bit(SDE_SSPP_LINE_INSERTION, (unsigned long *)&psde->features)) ||
|
||||
!cstate->line_insertion.panel_line_insertion_enable)
|
||||
return;
|
||||
|
||||
cfg = &pstate->line_insertion_cfg;
|
||||
memset(cfg, 0, sizeof(*cfg));
|
||||
if (!cstate->line_insertion.padding_height)
|
||||
return;
|
||||
|
||||
sde_crtc_calc_vpadding_param(psde->base.state->crtc->state,
|
||||
pstate->base.crtc_y, pstate->base.crtc_h,
|
||||
&y_start, &h_start, &h_total);
|
||||
cfg->enable = true;
|
||||
cfg->dummy_lines = cstate->line_insertion.padding_dummy;
|
||||
cfg->active_lines = cstate->line_insertion.padding_active;
|
||||
cfg->first_active_lines = h_start;
|
||||
cfg->dst_h = h_total;
|
||||
psde->pipe_cfg.dst_rect.y += y_start - pstate->base.crtc_y;
|
||||
}
|
||||
|
||||
static bool sde_plane_enabled(const struct drm_plane_state *state)
|
||||
{
|
||||
return state && state->fb && state->crtc;
|
||||
@@ -3094,6 +3133,8 @@ static void _sde_plane_update_roi_config(struct drm_plane *plane,
|
||||
|
||||
_sde_plane_setup_scaler(psde, pstate, fmt, false);
|
||||
|
||||
_sde_plane_setup_panel_stacking(psde, pstate);
|
||||
|
||||
/* check for color fill */
|
||||
psde->color_fill = (uint32_t)sde_plane_get_property(pstate,
|
||||
PLANE_PROP_COLOR_FILL);
|
||||
@@ -3137,6 +3178,11 @@ static void _sde_plane_update_roi_config(struct drm_plane *plane,
|
||||
true,
|
||||
pstate->multirect_index,
|
||||
pstate->multirect_mode);
|
||||
/* update line insertion */
|
||||
if (pstate->lineinsertion_feature && psde->pipe_hw->ops.setup_line_insertion)
|
||||
psde->pipe_hw->ops.setup_line_insertion(psde->pipe_hw,
|
||||
pstate->multirect_index,
|
||||
&pstate->line_insertion_cfg);
|
||||
}
|
||||
|
||||
static void _sde_plane_update_format_and_rects(struct sde_plane *psde,
|
||||
|
@@ -1,4 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) 2015-2021, The Linux Foundation. All rights reserved.
|
||||
* Copyright (C) 2013 Red Hat
|
||||
* Author: Rob Clark <robdclark@gmail.com>
|
||||
@@ -112,6 +113,8 @@ enum sde_plane_sclcheck_state {
|
||||
* @cdp_cfg: CDP configuration
|
||||
* @cont_splash_populated: State was populated as part of cont. splash
|
||||
* @ubwc_stats_roi: cached roi for ubwc stats
|
||||
* @line_insertion_cfg: line insertion configuration
|
||||
* @lineinsertion_feature: panel line insertion feature
|
||||
*/
|
||||
struct sde_plane_state {
|
||||
struct drm_plane_state base;
|
||||
@@ -147,6 +150,8 @@ struct sde_plane_state {
|
||||
bool cont_splash_populated;
|
||||
|
||||
struct sde_drm_ubwc_stats_roi ubwc_stats_roi;
|
||||
struct sde_hw_pipe_line_insertion_cfg line_insertion_cfg;
|
||||
bool lineinsertion_feature;
|
||||
};
|
||||
|
||||
/**
|
||||
|
Referência em uma nova issue
Block a user