Merge branch 'msm-next-lumag-dpu' into msm-next-lumag
Merge DPU changes, resolving conflicts between branches. Full changelog will be present in the final merge commit. DPU: - DSPP sub-block flush on sc7280 - support AR30 in addition to XR30 format - Allow using REC_0 and REC_1 to handle wide (4k) RGB planes Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
This commit is contained in:
commit
2470e93289
@ -0,0 +1,133 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only or BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/msm/qcom,sm8550-dpu.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm SM8550 Display DPU
|
||||
|
||||
maintainers:
|
||||
- Neil Armstrong <neil.armstrong@linaro.org>
|
||||
|
||||
$ref: /schemas/display/msm/dpu-common.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,sm8550-dpu
|
||||
|
||||
reg:
|
||||
items:
|
||||
- description: Address offset and size for mdp register set
|
||||
- description: Address offset and size for vbif register set
|
||||
|
||||
reg-names:
|
||||
items:
|
||||
- const: mdp
|
||||
- const: vbif
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: Display AHB
|
||||
- description: Display hf axi
|
||||
- description: Display MDSS ahb
|
||||
- description: Display lut
|
||||
- description: Display core
|
||||
- description: Display vsync
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: bus
|
||||
- const: nrt_bus
|
||||
- const: iface
|
||||
- const: lut
|
||||
- const: core
|
||||
- const: vsync
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- reg-names
|
||||
- clocks
|
||||
- clock-names
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/qcom,sm8550-dispcc.h>
|
||||
#include <dt-bindings/clock/qcom,sm8550-gcc.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/power/qcom-rpmpd.h>
|
||||
|
||||
display-controller@ae01000 {
|
||||
compatible = "qcom,sm8550-dpu";
|
||||
reg = <0x0ae01000 0x8f000>,
|
||||
<0x0aeb0000 0x2008>;
|
||||
reg-names = "mdp", "vbif";
|
||||
|
||||
clocks = <&gcc GCC_DISP_AHB_CLK>,
|
||||
<&gcc GCC_DISP_HF_AXI_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_AHB_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_MDP_LUT_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_MDP_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_VSYNC_CLK>;
|
||||
clock-names = "bus",
|
||||
"nrt_bus",
|
||||
"iface",
|
||||
"lut",
|
||||
"core",
|
||||
"vsync";
|
||||
|
||||
assigned-clocks = <&dispcc DISP_CC_MDSS_VSYNC_CLK>;
|
||||
assigned-clock-rates = <19200000>;
|
||||
|
||||
operating-points-v2 = <&mdp_opp_table>;
|
||||
power-domains = <&rpmhpd SM8550_MMCX>;
|
||||
|
||||
interrupt-parent = <&mdss>;
|
||||
interrupts = <0>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
dpu_intf1_out: endpoint {
|
||||
remote-endpoint = <&dsi0_in>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
dpu_intf2_out: endpoint {
|
||||
remote-endpoint = <&dsi1_in>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
mdp_opp_table: opp-table {
|
||||
compatible = "operating-points-v2";
|
||||
|
||||
opp-200000000 {
|
||||
opp-hz = /bits/ 64 <200000000>;
|
||||
required-opps = <&rpmhpd_opp_low_svs>;
|
||||
};
|
||||
|
||||
opp-325000000 {
|
||||
opp-hz = /bits/ 64 <325000000>;
|
||||
required-opps = <&rpmhpd_opp_svs>;
|
||||
};
|
||||
|
||||
opp-375000000 {
|
||||
opp-hz = /bits/ 64 <375000000>;
|
||||
required-opps = <&rpmhpd_opp_svs_l1>;
|
||||
};
|
||||
|
||||
opp-514000000 {
|
||||
opp-hz = /bits/ 64 <514000000>;
|
||||
required-opps = <&rpmhpd_opp_nom>;
|
||||
};
|
||||
};
|
||||
};
|
||||
...
|
@ -401,6 +401,47 @@ static void _dpu_crtc_program_lm_output_roi(struct drm_crtc *crtc)
|
||||
}
|
||||
}
|
||||
|
||||
static void _dpu_crtc_blend_setup_pipe(struct drm_crtc *crtc,
|
||||
struct drm_plane *plane,
|
||||
struct dpu_crtc_mixer *mixer,
|
||||
u32 num_mixers,
|
||||
enum dpu_stage stage,
|
||||
struct dpu_format *format,
|
||||
uint64_t modifier,
|
||||
struct dpu_sw_pipe *pipe,
|
||||
unsigned int stage_idx,
|
||||
struct dpu_hw_stage_cfg *stage_cfg
|
||||
)
|
||||
{
|
||||
uint32_t lm_idx;
|
||||
enum dpu_sspp sspp_idx;
|
||||
struct drm_plane_state *state;
|
||||
|
||||
sspp_idx = pipe->sspp->idx;
|
||||
|
||||
state = plane->state;
|
||||
|
||||
trace_dpu_crtc_setup_mixer(DRMID(crtc), DRMID(plane),
|
||||
state, to_dpu_plane_state(state), stage_idx,
|
||||
format->base.pixel_format,
|
||||
modifier);
|
||||
|
||||
DRM_DEBUG_ATOMIC("crtc %d stage:%d - plane %d sspp %d fb %d multirect_idx %d\n",
|
||||
crtc->base.id,
|
||||
stage,
|
||||
plane->base.id,
|
||||
sspp_idx - SSPP_NONE,
|
||||
state->fb ? state->fb->base.id : -1,
|
||||
pipe->multirect_index);
|
||||
|
||||
stage_cfg->stage[stage][stage_idx] = sspp_idx;
|
||||
stage_cfg->multirect_index[stage][stage_idx] = pipe->multirect_index;
|
||||
|
||||
/* blend config update */
|
||||
for (lm_idx = 0; lm_idx < num_mixers; lm_idx++)
|
||||
mixer[lm_idx].lm_ctl->ops.update_pending_flush_sspp(mixer[lm_idx].lm_ctl, sspp_idx);
|
||||
}
|
||||
|
||||
static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
|
||||
struct dpu_crtc *dpu_crtc, struct dpu_crtc_mixer *mixer,
|
||||
struct dpu_hw_stage_cfg *stage_cfg)
|
||||
@ -413,15 +454,12 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
|
||||
struct dpu_format *format;
|
||||
struct dpu_hw_ctl *ctl = mixer->lm_ctl;
|
||||
|
||||
uint32_t stage_idx, lm_idx;
|
||||
int zpos_cnt[DPU_STAGE_MAX + 1] = { 0 };
|
||||
uint32_t lm_idx;
|
||||
bool bg_alpha_enable = false;
|
||||
DECLARE_BITMAP(fetch_active, SSPP_MAX);
|
||||
|
||||
memset(fetch_active, 0, sizeof(fetch_active));
|
||||
drm_atomic_crtc_for_each_plane(plane, crtc) {
|
||||
enum dpu_sspp sspp_idx;
|
||||
|
||||
state = plane->state;
|
||||
if (!state)
|
||||
continue;
|
||||
@ -432,40 +470,30 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
|
||||
pstate = to_dpu_plane_state(state);
|
||||
fb = state->fb;
|
||||
|
||||
sspp_idx = dpu_plane_pipe(plane);
|
||||
set_bit(sspp_idx, fetch_active);
|
||||
|
||||
DRM_DEBUG_ATOMIC("crtc %d stage:%d - plane %d sspp %d fb %d\n",
|
||||
crtc->base.id,
|
||||
pstate->stage,
|
||||
plane->base.id,
|
||||
sspp_idx - SSPP_VIG0,
|
||||
state->fb ? state->fb->base.id : -1);
|
||||
|
||||
format = to_dpu_format(msm_framebuffer_format(pstate->base.fb));
|
||||
|
||||
if (pstate->stage == DPU_STAGE_BASE && format->alpha_enable)
|
||||
bg_alpha_enable = true;
|
||||
|
||||
stage_idx = zpos_cnt[pstate->stage]++;
|
||||
stage_cfg->stage[pstate->stage][stage_idx] =
|
||||
sspp_idx;
|
||||
stage_cfg->multirect_index[pstate->stage][stage_idx] =
|
||||
pstate->multirect_index;
|
||||
set_bit(pstate->pipe.sspp->idx, fetch_active);
|
||||
_dpu_crtc_blend_setup_pipe(crtc, plane,
|
||||
mixer, cstate->num_mixers,
|
||||
pstate->stage,
|
||||
format, fb ? fb->modifier : 0,
|
||||
&pstate->pipe, 0, stage_cfg);
|
||||
|
||||
trace_dpu_crtc_setup_mixer(DRMID(crtc), DRMID(plane),
|
||||
state, pstate, stage_idx,
|
||||
sspp_idx - SSPP_VIG0,
|
||||
format->base.pixel_format,
|
||||
fb ? fb->modifier : 0);
|
||||
if (pstate->r_pipe.sspp) {
|
||||
set_bit(pstate->r_pipe.sspp->idx, fetch_active);
|
||||
_dpu_crtc_blend_setup_pipe(crtc, plane,
|
||||
mixer, cstate->num_mixers,
|
||||
pstate->stage,
|
||||
format, fb ? fb->modifier : 0,
|
||||
&pstate->r_pipe, 1, stage_cfg);
|
||||
}
|
||||
|
||||
/* blend config update */
|
||||
for (lm_idx = 0; lm_idx < cstate->num_mixers; lm_idx++) {
|
||||
_dpu_crtc_setup_blend_cfg(mixer + lm_idx,
|
||||
pstate, format);
|
||||
|
||||
mixer[lm_idx].lm_ctl->ops.update_pending_flush_sspp(mixer[lm_idx].lm_ctl,
|
||||
sspp_idx);
|
||||
_dpu_crtc_setup_blend_cfg(mixer + lm_idx, pstate, format);
|
||||
|
||||
if (bg_alpha_enable && !format->alpha_enable)
|
||||
mixer[lm_idx].mixer_op_mode = 0;
|
||||
@ -768,7 +796,7 @@ static void _dpu_crtc_setup_cp_blocks(struct drm_crtc *crtc)
|
||||
|
||||
/* stage config flush mask */
|
||||
ctl->ops.update_pending_flush_dspp(ctl,
|
||||
mixer[i].hw_dspp->idx);
|
||||
mixer[i].hw_dspp->idx, DPU_DSPP_PCC);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1134,18 +1162,14 @@ static void dpu_crtc_enable(struct drm_crtc *crtc,
|
||||
drm_crtc_vblank_on(crtc);
|
||||
}
|
||||
|
||||
struct plane_state {
|
||||
struct dpu_plane_state *dpu_pstate;
|
||||
const struct drm_plane_state *drm_pstate;
|
||||
int stage;
|
||||
u32 pipe_id;
|
||||
};
|
||||
|
||||
static bool dpu_crtc_needs_dirtyfb(struct drm_crtc_state *cstate)
|
||||
{
|
||||
struct drm_crtc *crtc = cstate->crtc;
|
||||
struct drm_encoder *encoder;
|
||||
|
||||
if (cstate->self_refresh_active)
|
||||
return true;
|
||||
|
||||
drm_for_each_encoder_mask (encoder, crtc->dev, cstate->encoder_mask) {
|
||||
if (dpu_encoder_get_intf_mode(encoder) == INTF_MODE_CMD) {
|
||||
return true;
|
||||
@ -1162,151 +1186,46 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
|
||||
crtc);
|
||||
struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc);
|
||||
struct dpu_crtc_state *cstate = to_dpu_crtc_state(crtc_state);
|
||||
struct plane_state *pstates;
|
||||
|
||||
const struct drm_plane_state *pstate;
|
||||
struct drm_plane *plane;
|
||||
struct drm_display_mode *mode;
|
||||
|
||||
int cnt = 0, rc = 0, mixer_width = 0, i, z_pos;
|
||||
int rc = 0;
|
||||
|
||||
struct dpu_multirect_plane_states multirect_plane[DPU_STAGE_MAX * 2];
|
||||
int multirect_count = 0;
|
||||
const struct drm_plane_state *pipe_staged[SSPP_MAX];
|
||||
int left_zpos_cnt = 0, right_zpos_cnt = 0;
|
||||
struct drm_rect crtc_rect = { 0 };
|
||||
bool needs_dirtyfb = dpu_crtc_needs_dirtyfb(crtc_state);
|
||||
|
||||
pstates = kzalloc(sizeof(*pstates) * DPU_STAGE_MAX * 4, GFP_KERNEL);
|
||||
if (!pstates)
|
||||
return -ENOMEM;
|
||||
|
||||
if (!crtc_state->enable || !crtc_state->active) {
|
||||
if (!crtc_state->enable || !drm_atomic_crtc_effectively_active(crtc_state)) {
|
||||
DRM_DEBUG_ATOMIC("crtc%d -> enable %d, active %d, skip atomic_check\n",
|
||||
crtc->base.id, crtc_state->enable,
|
||||
crtc_state->active);
|
||||
memset(&cstate->new_perf, 0, sizeof(cstate->new_perf));
|
||||
goto end;
|
||||
return 0;
|
||||
}
|
||||
|
||||
mode = &crtc_state->adjusted_mode;
|
||||
DRM_DEBUG_ATOMIC("%s: check\n", dpu_crtc->name);
|
||||
|
||||
/* force a full mode set if active state changed */
|
||||
if (crtc_state->active_changed)
|
||||
crtc_state->mode_changed = true;
|
||||
|
||||
memset(pipe_staged, 0, sizeof(pipe_staged));
|
||||
|
||||
if (cstate->num_mixers) {
|
||||
mixer_width = mode->hdisplay / cstate->num_mixers;
|
||||
|
||||
if (cstate->num_mixers)
|
||||
_dpu_crtc_setup_lm_bounds(crtc, crtc_state);
|
||||
}
|
||||
|
||||
crtc_rect.x2 = mode->hdisplay;
|
||||
crtc_rect.y2 = mode->vdisplay;
|
||||
|
||||
/* get plane state for all drm planes associated with crtc state */
|
||||
/* FIXME: move this to dpu_plane_atomic_check? */
|
||||
drm_atomic_crtc_state_for_each_plane_state(plane, pstate, crtc_state) {
|
||||
struct dpu_plane_state *dpu_pstate = to_dpu_plane_state(pstate);
|
||||
struct drm_rect dst, clip = crtc_rect;
|
||||
|
||||
if (IS_ERR_OR_NULL(pstate)) {
|
||||
rc = PTR_ERR(pstate);
|
||||
DPU_ERROR("%s: failed to get plane%d state, %d\n",
|
||||
dpu_crtc->name, plane->base.id, rc);
|
||||
goto end;
|
||||
return rc;
|
||||
}
|
||||
if (cnt >= DPU_STAGE_MAX * 4)
|
||||
continue;
|
||||
|
||||
if (!pstate->visible)
|
||||
continue;
|
||||
|
||||
pstates[cnt].dpu_pstate = dpu_pstate;
|
||||
pstates[cnt].drm_pstate = pstate;
|
||||
pstates[cnt].stage = pstate->normalized_zpos;
|
||||
pstates[cnt].pipe_id = dpu_plane_pipe(plane);
|
||||
|
||||
dpu_pstate->needs_dirtyfb = needs_dirtyfb;
|
||||
|
||||
if (pipe_staged[pstates[cnt].pipe_id]) {
|
||||
multirect_plane[multirect_count].r0 =
|
||||
pipe_staged[pstates[cnt].pipe_id];
|
||||
multirect_plane[multirect_count].r1 = pstate;
|
||||
multirect_count++;
|
||||
|
||||
pipe_staged[pstates[cnt].pipe_id] = NULL;
|
||||
} else {
|
||||
pipe_staged[pstates[cnt].pipe_id] = pstate;
|
||||
}
|
||||
|
||||
cnt++;
|
||||
|
||||
dst = drm_plane_state_dest(pstate);
|
||||
if (!drm_rect_intersect(&clip, &dst)) {
|
||||
DPU_ERROR("invalid vertical/horizontal destination\n");
|
||||
DPU_ERROR("display: " DRM_RECT_FMT " plane: "
|
||||
DRM_RECT_FMT "\n", DRM_RECT_ARG(&crtc_rect),
|
||||
DRM_RECT_ARG(&dst));
|
||||
rc = -E2BIG;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 1; i < SSPP_MAX; i++) {
|
||||
if (pipe_staged[i])
|
||||
dpu_plane_clear_multirect(pipe_staged[i]);
|
||||
}
|
||||
|
||||
z_pos = -1;
|
||||
for (i = 0; i < cnt; i++) {
|
||||
/* reset counts at every new blend stage */
|
||||
if (pstates[i].stage != z_pos) {
|
||||
left_zpos_cnt = 0;
|
||||
right_zpos_cnt = 0;
|
||||
z_pos = pstates[i].stage;
|
||||
}
|
||||
|
||||
/* verify z_pos setting before using it */
|
||||
if (z_pos >= DPU_STAGE_MAX - DPU_STAGE_0) {
|
||||
DPU_ERROR("> %d plane stages assigned\n",
|
||||
DPU_STAGE_MAX - DPU_STAGE_0);
|
||||
rc = -EINVAL;
|
||||
goto end;
|
||||
} else if (pstates[i].drm_pstate->crtc_x < mixer_width) {
|
||||
if (left_zpos_cnt == 2) {
|
||||
DPU_ERROR("> 2 planes @ stage %d on left\n",
|
||||
z_pos);
|
||||
rc = -EINVAL;
|
||||
goto end;
|
||||
}
|
||||
left_zpos_cnt++;
|
||||
|
||||
} else {
|
||||
if (right_zpos_cnt == 2) {
|
||||
DPU_ERROR("> 2 planes @ stage %d on right\n",
|
||||
z_pos);
|
||||
rc = -EINVAL;
|
||||
goto end;
|
||||
}
|
||||
right_zpos_cnt++;
|
||||
}
|
||||
|
||||
pstates[i].dpu_pstate->stage = z_pos + DPU_STAGE_0;
|
||||
DRM_DEBUG_ATOMIC("%s: zpos %d\n", dpu_crtc->name, z_pos);
|
||||
}
|
||||
|
||||
for (i = 0; i < multirect_count; i++) {
|
||||
if (dpu_plane_validate_multirect_v2(&multirect_plane[i])) {
|
||||
DPU_ERROR(
|
||||
"multirect validation failed for planes (%d - %d)\n",
|
||||
multirect_plane[i].r0->plane->base.id,
|
||||
multirect_plane[i].r1->plane->base.id);
|
||||
rc = -EINVAL;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
atomic_inc(&_dpu_crtc_get_kms(crtc)->bandwidth_ref);
|
||||
@ -1315,74 +1234,10 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
|
||||
if (rc) {
|
||||
DPU_ERROR("crtc%d failed performance check %d\n",
|
||||
crtc->base.id, rc);
|
||||
goto end;
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* validate source split:
|
||||
* use pstates sorted by stage to check planes on same stage
|
||||
* we assume that all pipes are in source split so its valid to compare
|
||||
* without taking into account left/right mixer placement
|
||||
*/
|
||||
for (i = 1; i < cnt; i++) {
|
||||
struct plane_state *prv_pstate, *cur_pstate;
|
||||
struct drm_rect left_rect, right_rect;
|
||||
int32_t left_pid, right_pid;
|
||||
int32_t stage;
|
||||
|
||||
prv_pstate = &pstates[i - 1];
|
||||
cur_pstate = &pstates[i];
|
||||
if (prv_pstate->stage != cur_pstate->stage)
|
||||
continue;
|
||||
|
||||
stage = cur_pstate->stage;
|
||||
|
||||
left_pid = prv_pstate->dpu_pstate->base.plane->base.id;
|
||||
left_rect = drm_plane_state_dest(prv_pstate->drm_pstate);
|
||||
|
||||
right_pid = cur_pstate->dpu_pstate->base.plane->base.id;
|
||||
right_rect = drm_plane_state_dest(cur_pstate->drm_pstate);
|
||||
|
||||
if (right_rect.x1 < left_rect.x1) {
|
||||
swap(left_pid, right_pid);
|
||||
swap(left_rect, right_rect);
|
||||
}
|
||||
|
||||
/**
|
||||
* - planes are enumerated in pipe-priority order such that
|
||||
* planes with lower drm_id must be left-most in a shared
|
||||
* blend-stage when using source split.
|
||||
* - planes in source split must be contiguous in width
|
||||
* - planes in source split must have same dest yoff and height
|
||||
*/
|
||||
if (right_pid < left_pid) {
|
||||
DPU_ERROR(
|
||||
"invalid src split cfg. priority mismatch. stage: %d left: %d right: %d\n",
|
||||
stage, left_pid, right_pid);
|
||||
rc = -EINVAL;
|
||||
goto end;
|
||||
} else if (right_rect.x1 != drm_rect_width(&left_rect)) {
|
||||
DPU_ERROR("non-contiguous coordinates for src split. "
|
||||
"stage: %d left: " DRM_RECT_FMT " right: "
|
||||
DRM_RECT_FMT "\n", stage,
|
||||
DRM_RECT_ARG(&left_rect),
|
||||
DRM_RECT_ARG(&right_rect));
|
||||
rc = -EINVAL;
|
||||
goto end;
|
||||
} else if (left_rect.y1 != right_rect.y1 ||
|
||||
drm_rect_height(&left_rect) != drm_rect_height(&right_rect)) {
|
||||
DPU_ERROR("source split at stage: %d. invalid "
|
||||
"yoff/height: left: " DRM_RECT_FMT " right: "
|
||||
DRM_RECT_FMT "\n", stage,
|
||||
DRM_RECT_ARG(&left_rect),
|
||||
DRM_RECT_ARG(&right_rect));
|
||||
rc = -EINVAL;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
end:
|
||||
kfree(pstates);
|
||||
return rc;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dpu_crtc_vblank(struct drm_crtc *crtc, bool en)
|
||||
@ -1499,8 +1354,16 @@ static int _dpu_debugfs_status_show(struct seq_file *s, void *data)
|
||||
seq_printf(s, "\tdst x:%4d dst_y:%4d dst_w:%4d dst_h:%4d\n",
|
||||
state->crtc_x, state->crtc_y, state->crtc_w,
|
||||
state->crtc_h);
|
||||
seq_printf(s, "\tmultirect: mode: %d index: %d\n",
|
||||
pstate->multirect_mode, pstate->multirect_index);
|
||||
seq_printf(s, "\tsspp[0]:%s\n",
|
||||
pstate->pipe.sspp->cap->name);
|
||||
seq_printf(s, "\tmultirect[0]: mode: %d index: %d\n",
|
||||
pstate->pipe.multirect_mode, pstate->pipe.multirect_index);
|
||||
if (pstate->r_pipe.sspp) {
|
||||
seq_printf(s, "\tsspp[1]:%s\n",
|
||||
pstate->r_pipe.sspp->cap->name);
|
||||
seq_printf(s, "\tmultirect[1]: mode: %d index: %d\n",
|
||||
pstate->r_pipe.multirect_mode, pstate->r_pipe.multirect_index);
|
||||
}
|
||||
|
||||
seq_puts(s, "\n");
|
||||
}
|
||||
|
@ -545,7 +545,8 @@ bool dpu_encoder_use_dsc_merge(struct drm_encoder *drm_enc)
|
||||
static struct msm_display_topology dpu_encoder_get_topology(
|
||||
struct dpu_encoder_virt *dpu_enc,
|
||||
struct dpu_kms *dpu_kms,
|
||||
struct drm_display_mode *mode)
|
||||
struct drm_display_mode *mode,
|
||||
struct drm_crtc_state *crtc_state)
|
||||
{
|
||||
struct msm_display_topology topology = {0};
|
||||
int i, intf_count = 0;
|
||||
@ -563,8 +564,7 @@ static struct msm_display_topology dpu_encoder_get_topology(
|
||||
* 1 LM, 1 INTF
|
||||
* 2 LM, 1 INTF (stream merge to support high resolution interfaces)
|
||||
*
|
||||
* Adding color blocks only to primary interface if available in
|
||||
* sufficient number
|
||||
* Add dspps to the reservation requirements if ctm is requested
|
||||
*/
|
||||
if (intf_count == 2)
|
||||
topology.num_lm = 2;
|
||||
@ -573,11 +573,8 @@ static struct msm_display_topology dpu_encoder_get_topology(
|
||||
else
|
||||
topology.num_lm = (mode->hdisplay > MAX_HDISPLAY_SPLIT) ? 2 : 1;
|
||||
|
||||
if (dpu_enc->disp_info.intf_type == DRM_MODE_ENCODER_DSI) {
|
||||
if (dpu_kms->catalog->dspp &&
|
||||
(dpu_kms->catalog->dspp_count >= topology.num_lm))
|
||||
topology.num_dspp = topology.num_lm;
|
||||
}
|
||||
if (crtc_state->ctm)
|
||||
topology.num_dspp = topology.num_lm;
|
||||
|
||||
topology.num_intf = intf_count;
|
||||
|
||||
@ -638,25 +635,22 @@ static int dpu_encoder_virt_atomic_check(
|
||||
if (ret) {
|
||||
DPU_ERROR_ENC(dpu_enc,
|
||||
"mode unsupported, phys idx %d\n", i);
|
||||
break;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
topology = dpu_encoder_get_topology(dpu_enc, dpu_kms, adj_mode);
|
||||
topology = dpu_encoder_get_topology(dpu_enc, dpu_kms, adj_mode, crtc_state);
|
||||
|
||||
/* Reserve dynamic resources now. */
|
||||
if (!ret) {
|
||||
/*
|
||||
* Release and Allocate resources on every modeset
|
||||
* Dont allocate when active is false.
|
||||
*/
|
||||
if (drm_atomic_crtc_needs_modeset(crtc_state)) {
|
||||
dpu_rm_release(global_state, drm_enc);
|
||||
/*
|
||||
* Release and Allocate resources on every modeset
|
||||
* Dont allocate when active is false.
|
||||
*/
|
||||
if (drm_atomic_crtc_needs_modeset(crtc_state)) {
|
||||
dpu_rm_release(global_state, drm_enc);
|
||||
|
||||
if (!crtc_state->active_changed || crtc_state->enable)
|
||||
ret = dpu_rm_reserve(&dpu_kms->rm, global_state,
|
||||
drm_enc, crtc_state, topology);
|
||||
}
|
||||
if (!crtc_state->active_changed || crtc_state->enable)
|
||||
ret = dpu_rm_reserve(&dpu_kms->rm, global_state,
|
||||
drm_enc, crtc_state, topology);
|
||||
}
|
||||
|
||||
trace_dpu_enc_atomic_check_flags(DRMID(drm_enc), adj_mode->flags);
|
||||
@ -2094,25 +2088,6 @@ void dpu_encoder_helper_phys_cleanup(struct dpu_encoder_phys *phys_enc)
|
||||
ctl->ops.clear_pending_flush(ctl);
|
||||
}
|
||||
|
||||
void dpu_encoder_prepare_commit(struct drm_encoder *drm_enc)
|
||||
{
|
||||
struct dpu_encoder_virt *dpu_enc;
|
||||
struct dpu_encoder_phys *phys;
|
||||
int i;
|
||||
|
||||
if (!drm_enc) {
|
||||
DPU_ERROR("invalid encoder\n");
|
||||
return;
|
||||
}
|
||||
dpu_enc = to_dpu_encoder_virt(drm_enc);
|
||||
|
||||
for (i = 0; i < dpu_enc->num_phys_encs; i++) {
|
||||
phys = dpu_enc->phys_encs[i];
|
||||
if (phys->ops.prepare_commit)
|
||||
phys->ops.prepare_commit(phys);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
static int _dpu_encoder_status_show(struct seq_file *s, void *data)
|
||||
{
|
||||
|
@ -146,13 +146,6 @@ struct drm_encoder *dpu_encoder_init(
|
||||
int dpu_encoder_setup(struct drm_device *dev, struct drm_encoder *enc,
|
||||
struct msm_display_info *disp_info);
|
||||
|
||||
/**
|
||||
* dpu_encoder_prepare_commit - prepare encoder at the very beginning of an
|
||||
* atomic commit, before any registers are written
|
||||
* @drm_enc: Pointer to previously created drm encoder structure
|
||||
*/
|
||||
void dpu_encoder_prepare_commit(struct drm_encoder *drm_enc);
|
||||
|
||||
/**
|
||||
* dpu_encoder_set_idle_timeout - set the idle timeout for video
|
||||
* and command mode encoders.
|
||||
|
@ -40,6 +40,8 @@
|
||||
|
||||
#define DPU_ENC_MAX_POLL_TIMEOUT_US 2000
|
||||
|
||||
static void dpu_encoder_phys_cmd_enable_te(struct dpu_encoder_phys *phys_enc);
|
||||
|
||||
static bool dpu_encoder_phys_cmd_is_master(struct dpu_encoder_phys *phys_enc)
|
||||
{
|
||||
return (phys_enc->split_role != ENC_ROLE_SLAVE);
|
||||
@ -565,6 +567,8 @@ static void dpu_encoder_phys_cmd_prepare_for_kickoff(
|
||||
phys_enc->hw_pp->idx - PINGPONG_0);
|
||||
}
|
||||
|
||||
dpu_encoder_phys_cmd_enable_te(phys_enc);
|
||||
|
||||
DPU_DEBUG_CMDENC(cmd_enc, "pp:%d pending_cnt %d\n",
|
||||
phys_enc->hw_pp->idx - PINGPONG_0,
|
||||
atomic_read(&phys_enc->pending_kickoff_cnt));
|
||||
@ -586,8 +590,7 @@ static bool dpu_encoder_phys_cmd_is_ongoing_pptx(
|
||||
return false;
|
||||
}
|
||||
|
||||
static void dpu_encoder_phys_cmd_prepare_commit(
|
||||
struct dpu_encoder_phys *phys_enc)
|
||||
static void dpu_encoder_phys_cmd_enable_te(struct dpu_encoder_phys *phys_enc)
|
||||
{
|
||||
struct dpu_encoder_phys_cmd *cmd_enc =
|
||||
to_dpu_encoder_phys_cmd(phys_enc);
|
||||
@ -732,7 +735,6 @@ static void dpu_encoder_phys_cmd_trigger_start(
|
||||
static void dpu_encoder_phys_cmd_init_ops(
|
||||
struct dpu_encoder_phys_ops *ops)
|
||||
{
|
||||
ops->prepare_commit = dpu_encoder_phys_cmd_prepare_commit;
|
||||
ops->is_master = dpu_encoder_phys_cmd_is_master;
|
||||
ops->atomic_mode_set = dpu_encoder_phys_cmd_atomic_mode_set;
|
||||
ops->enable = dpu_encoder_phys_cmd_enable;
|
||||
|
@ -536,6 +536,16 @@ static const struct dpu_format dpu_format_map_ubwc[] = {
|
||||
true, 4, DPU_FORMAT_FLAG_DX | DPU_FORMAT_FLAG_COMPRESSED,
|
||||
DPU_FETCH_UBWC, 2, DPU_TILE_HEIGHT_UBWC),
|
||||
|
||||
/* XRGB2101010 and ARGB2101010 purposely have the same color
|
||||
* ordering. The hardware only supports ARGB2101010 UBWC
|
||||
* natively.
|
||||
*/
|
||||
INTERLEAVED_RGB_FMT_TILED(ARGB2101010,
|
||||
COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
|
||||
C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
|
||||
true, 4, DPU_FORMAT_FLAG_DX | DPU_FORMAT_FLAG_COMPRESSED,
|
||||
DPU_FETCH_UBWC, 2, DPU_TILE_HEIGHT_UBWC),
|
||||
|
||||
PSEUDO_YUV_FMT_TILED(NV12,
|
||||
0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
|
||||
C1_B_Cb, C2_R_Cr,
|
||||
@ -591,6 +601,7 @@ static int _dpu_format_get_media_color_ubwc(const struct dpu_format *fmt)
|
||||
{DRM_FORMAT_XBGR8888, COLOR_FMT_RGBA8888_UBWC},
|
||||
{DRM_FORMAT_XRGB8888, COLOR_FMT_RGBA8888_UBWC},
|
||||
{DRM_FORMAT_ABGR2101010, COLOR_FMT_RGBA1010102_UBWC},
|
||||
{DRM_FORMAT_ARGB2101010, COLOR_FMT_RGBA1010102_UBWC},
|
||||
{DRM_FORMAT_XRGB2101010, COLOR_FMT_RGBA1010102_UBWC},
|
||||
{DRM_FORMAT_XBGR2101010, COLOR_FMT_RGBA1010102_UBWC},
|
||||
{DRM_FORMAT_BGR565, COLOR_FMT_RGB565_UBWC},
|
||||
@ -918,8 +929,7 @@ int dpu_format_populate_layout(
|
||||
struct drm_framebuffer *fb,
|
||||
struct dpu_hw_fmt_layout *layout)
|
||||
{
|
||||
uint32_t plane_addr[DPU_MAX_PLANES];
|
||||
int i, ret;
|
||||
int ret;
|
||||
|
||||
if (!fb || !layout) {
|
||||
DRM_ERROR("invalid arguments\n");
|
||||
@ -940,9 +950,6 @@ int dpu_format_populate_layout(
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
for (i = 0; i < DPU_MAX_PLANES; ++i)
|
||||
plane_addr[i] = layout->plane_addr[i];
|
||||
|
||||
/* Populate the addresses given the fb */
|
||||
if (DPU_FORMAT_IS_UBWC(layout->format) ||
|
||||
DPU_FORMAT_IS_TILE(layout->format))
|
||||
@ -950,10 +957,6 @@ int dpu_format_populate_layout(
|
||||
else
|
||||
ret = _dpu_format_populate_addrs_linear(aspace, fb, layout);
|
||||
|
||||
/* check if anything changed */
|
||||
if (!ret && !memcmp(plane_addr, layout->plane_addr, sizeof(plane_addr)))
|
||||
ret = -EAGAIN;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -27,9 +27,15 @@
|
||||
#define VIG_SDM845_MASK \
|
||||
(VIG_MASK | BIT(DPU_SSPP_QOS_8LVL) | BIT(DPU_SSPP_SCALER_QSEED3))
|
||||
|
||||
#define VIG_SDM845_MASK_SDMA \
|
||||
(VIG_SDM845_MASK | BIT(DPU_SSPP_SMART_DMA_V2))
|
||||
|
||||
#define VIG_SC7180_MASK \
|
||||
(VIG_MASK | BIT(DPU_SSPP_QOS_8LVL) | BIT(DPU_SSPP_SCALER_QSEED4))
|
||||
|
||||
#define VIG_SC7180_MASK_SDMA \
|
||||
(VIG_SC7180_MASK | BIT(DPU_SSPP_SMART_DMA_V2))
|
||||
|
||||
#define VIG_QCM2290_MASK (VIG_BASE_MASK | BIT(DPU_SSPP_QOS_8LVL))
|
||||
|
||||
#define DMA_MSM8998_MASK \
|
||||
@ -40,6 +46,9 @@
|
||||
#define VIG_SC7280_MASK \
|
||||
(VIG_SC7180_MASK | BIT(DPU_SSPP_INLINE_ROTATION))
|
||||
|
||||
#define VIG_SC7280_MASK_SDMA \
|
||||
(VIG_SC7280_MASK | BIT(DPU_SSPP_SMART_DMA_V2))
|
||||
|
||||
#define DMA_SDM845_MASK \
|
||||
(BIT(DPU_SSPP_SRC) | BIT(DPU_SSPP_QOS) | BIT(DPU_SSPP_QOS_8LVL) |\
|
||||
BIT(DPU_SSPP_TS_PREFILL) | BIT(DPU_SSPP_TS_PREFILL_REC1) |\
|
||||
@ -48,6 +57,12 @@
|
||||
#define DMA_CURSOR_SDM845_MASK \
|
||||
(DMA_SDM845_MASK | BIT(DPU_SSPP_CURSOR))
|
||||
|
||||
#define DMA_SDM845_MASK_SDMA \
|
||||
(DMA_SDM845_MASK | BIT(DPU_SSPP_SMART_DMA_V2))
|
||||
|
||||
#define DMA_CURSOR_SDM845_MASK_SDMA \
|
||||
(DMA_CURSOR_SDM845_MASK | BIT(DPU_SSPP_SMART_DMA_V2))
|
||||
|
||||
#define DMA_CURSOR_MSM8998_MASK \
|
||||
(DMA_MSM8998_MASK | BIT(DPU_SSPP_CURSOR))
|
||||
|
||||
@ -66,7 +81,10 @@
|
||||
(PINGPONG_SDM845_MASK | BIT(DPU_PINGPONG_TE2))
|
||||
|
||||
#define CTL_SC7280_MASK \
|
||||
(BIT(DPU_CTL_ACTIVE_CFG) | BIT(DPU_CTL_FETCH_ACTIVE) | BIT(DPU_CTL_VM_CFG))
|
||||
(BIT(DPU_CTL_ACTIVE_CFG) | \
|
||||
BIT(DPU_CTL_FETCH_ACTIVE) | \
|
||||
BIT(DPU_CTL_VM_CFG) | \
|
||||
BIT(DPU_CTL_DSPP_SUB_BLOCK_FLUSH))
|
||||
|
||||
#define CTL_SM8550_MASK \
|
||||
(CTL_SC7280_MASK | BIT(DPU_CTL_HAS_LAYER_EXT4))
|
||||
@ -189,6 +207,7 @@ static const uint32_t plane_formats[] = {
|
||||
DRM_FORMAT_RGBX8888,
|
||||
DRM_FORMAT_BGRX8888,
|
||||
DRM_FORMAT_XBGR8888,
|
||||
DRM_FORMAT_ARGB2101010,
|
||||
DRM_FORMAT_XRGB2101010,
|
||||
DRM_FORMAT_RGB888,
|
||||
DRM_FORMAT_BGR888,
|
||||
@ -218,6 +237,7 @@ static const uint32_t plane_formats_yuv[] = {
|
||||
DRM_FORMAT_RGBA8888,
|
||||
DRM_FORMAT_BGRX8888,
|
||||
DRM_FORMAT_BGRA8888,
|
||||
DRM_FORMAT_ARGB2101010,
|
||||
DRM_FORMAT_XRGB2101010,
|
||||
DRM_FORMAT_XRGB8888,
|
||||
DRM_FORMAT_XBGR8888,
|
||||
@ -303,7 +323,6 @@ static const struct dpu_caps msm8998_dpu_caps = {
|
||||
.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
|
||||
.max_mixer_blendstages = 0x7,
|
||||
.qseed_type = DPU_SSPP_SCALER_QSEED3,
|
||||
.smart_dma_rev = DPU_SSPP_SMART_DMA_V1,
|
||||
.ubwc_version = DPU_HW_UBWC_VER_10,
|
||||
.has_src_split = true,
|
||||
.has_dim_layer = true,
|
||||
@ -318,7 +337,6 @@ static const struct dpu_caps msm8998_dpu_caps = {
|
||||
static const struct dpu_caps qcm2290_dpu_caps = {
|
||||
.max_mixer_width = DEFAULT_DPU_LINE_WIDTH,
|
||||
.max_mixer_blendstages = 0x4,
|
||||
.smart_dma_rev = DPU_SSPP_SMART_DMA_V2,
|
||||
.has_dim_layer = true,
|
||||
.has_idle_pc = true,
|
||||
.max_linewidth = 2160,
|
||||
@ -329,7 +347,6 @@ static const struct dpu_caps sdm845_dpu_caps = {
|
||||
.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
|
||||
.max_mixer_blendstages = 0xb,
|
||||
.qseed_type = DPU_SSPP_SCALER_QSEED3,
|
||||
.smart_dma_rev = DPU_SSPP_SMART_DMA_V2,
|
||||
.ubwc_version = DPU_HW_UBWC_VER_20,
|
||||
.has_src_split = true,
|
||||
.has_dim_layer = true,
|
||||
@ -345,7 +362,6 @@ static const struct dpu_caps sc7180_dpu_caps = {
|
||||
.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
|
||||
.max_mixer_blendstages = 0x9,
|
||||
.qseed_type = DPU_SSPP_SCALER_QSEED4,
|
||||
.smart_dma_rev = DPU_SSPP_SMART_DMA_V2,
|
||||
.ubwc_version = DPU_HW_UBWC_VER_20,
|
||||
.has_dim_layer = true,
|
||||
.has_idle_pc = true,
|
||||
@ -357,7 +373,6 @@ static const struct dpu_caps sm6115_dpu_caps = {
|
||||
.max_mixer_width = DEFAULT_DPU_LINE_WIDTH,
|
||||
.max_mixer_blendstages = 0x4,
|
||||
.qseed_type = DPU_SSPP_SCALER_QSEED4,
|
||||
.smart_dma_rev = DPU_SSPP_SMART_DMA_V2, /* TODO: v2.5 */
|
||||
.ubwc_version = DPU_HW_UBWC_VER_10,
|
||||
.has_dim_layer = true,
|
||||
.has_idle_pc = true,
|
||||
@ -369,7 +384,6 @@ static const struct dpu_caps sm8150_dpu_caps = {
|
||||
.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
|
||||
.max_mixer_blendstages = 0xb,
|
||||
.qseed_type = DPU_SSPP_SCALER_QSEED3,
|
||||
.smart_dma_rev = DPU_SSPP_SMART_DMA_V2, /* TODO: v2.5 */
|
||||
.ubwc_version = DPU_HW_UBWC_VER_30,
|
||||
.has_src_split = true,
|
||||
.has_dim_layer = true,
|
||||
@ -385,7 +399,6 @@ static const struct dpu_caps sc8180x_dpu_caps = {
|
||||
.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
|
||||
.max_mixer_blendstages = 0xb,
|
||||
.qseed_type = DPU_SSPP_SCALER_QSEED3,
|
||||
.smart_dma_rev = DPU_SSPP_SMART_DMA_V2, /* TODO: v2.5 */
|
||||
.ubwc_version = DPU_HW_UBWC_VER_30,
|
||||
.has_src_split = true,
|
||||
.has_dim_layer = true,
|
||||
@ -401,7 +414,6 @@ static const struct dpu_caps sc8280xp_dpu_caps = {
|
||||
.max_mixer_width = 2560,
|
||||
.max_mixer_blendstages = 11,
|
||||
.qseed_type = DPU_SSPP_SCALER_QSEED4,
|
||||
.smart_dma_rev = DPU_SSPP_SMART_DMA_V2, /* TODO: v2.5 */
|
||||
.ubwc_version = DPU_HW_UBWC_VER_40,
|
||||
.has_src_split = true,
|
||||
.has_dim_layer = true,
|
||||
@ -415,7 +427,6 @@ static const struct dpu_caps sm8250_dpu_caps = {
|
||||
.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
|
||||
.max_mixer_blendstages = 0xb,
|
||||
.qseed_type = DPU_SSPP_SCALER_QSEED4,
|
||||
.smart_dma_rev = DPU_SSPP_SMART_DMA_V2, /* TODO: v2.5 */
|
||||
.ubwc_version = DPU_HW_UBWC_VER_40,
|
||||
.has_src_split = true,
|
||||
.has_dim_layer = true,
|
||||
@ -429,7 +440,6 @@ static const struct dpu_caps sm8350_dpu_caps = {
|
||||
.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
|
||||
.max_mixer_blendstages = 0xb,
|
||||
.qseed_type = DPU_SSPP_SCALER_QSEED4,
|
||||
.smart_dma_rev = DPU_SSPP_SMART_DMA_V2, /* TODO: v2.5 */
|
||||
.ubwc_version = DPU_HW_UBWC_VER_40,
|
||||
.has_src_split = true,
|
||||
.has_dim_layer = true,
|
||||
@ -443,7 +453,6 @@ static const struct dpu_caps sm8450_dpu_caps = {
|
||||
.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
|
||||
.max_mixer_blendstages = 0xb,
|
||||
.qseed_type = DPU_SSPP_SCALER_QSEED4,
|
||||
.smart_dma_rev = DPU_SSPP_SMART_DMA_V2, /* TODO: v2.5 */
|
||||
.ubwc_version = DPU_HW_UBWC_VER_40,
|
||||
.has_src_split = true,
|
||||
.has_dim_layer = true,
|
||||
@ -457,7 +466,6 @@ static const struct dpu_caps sm8550_dpu_caps = {
|
||||
.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
|
||||
.max_mixer_blendstages = 0xb,
|
||||
.qseed_type = DPU_SSPP_SCALER_QSEED4,
|
||||
.smart_dma_rev = DPU_SSPP_SMART_DMA_V2, /* TODO: v2.5 */
|
||||
.ubwc_version = DPU_HW_UBWC_VER_40,
|
||||
.has_src_split = true,
|
||||
.has_dim_layer = true,
|
||||
@ -471,7 +479,6 @@ static const struct dpu_caps sc7280_dpu_caps = {
|
||||
.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
|
||||
.max_mixer_blendstages = 0x7,
|
||||
.qseed_type = DPU_SSPP_SCALER_QSEED4,
|
||||
.smart_dma_rev = DPU_SSPP_SMART_DMA_V2,
|
||||
.ubwc_version = DPU_HW_UBWC_VER_30,
|
||||
.has_dim_layer = true,
|
||||
.has_idle_pc = true,
|
||||
@ -1197,21 +1204,21 @@ static const struct dpu_sspp_cfg msm8998_sspp[] = {
|
||||
};
|
||||
|
||||
static const struct dpu_sspp_cfg sdm845_sspp[] = {
|
||||
SSPP_BLK("sspp_0", SSPP_VIG0, 0x4000, VIG_SDM845_MASK,
|
||||
SSPP_BLK("sspp_0", SSPP_VIG0, 0x4000, VIG_SDM845_MASK_SDMA,
|
||||
sdm845_vig_sblk_0, 0, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG0),
|
||||
SSPP_BLK("sspp_1", SSPP_VIG1, 0x6000, VIG_SDM845_MASK,
|
||||
SSPP_BLK("sspp_1", SSPP_VIG1, 0x6000, VIG_SDM845_MASK_SDMA,
|
||||
sdm845_vig_sblk_1, 4, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG1),
|
||||
SSPP_BLK("sspp_2", SSPP_VIG2, 0x8000, VIG_SDM845_MASK,
|
||||
SSPP_BLK("sspp_2", SSPP_VIG2, 0x8000, VIG_SDM845_MASK_SDMA,
|
||||
sdm845_vig_sblk_2, 8, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG2),
|
||||
SSPP_BLK("sspp_3", SSPP_VIG3, 0xa000, VIG_SDM845_MASK,
|
||||
SSPP_BLK("sspp_3", SSPP_VIG3, 0xa000, VIG_SDM845_MASK_SDMA,
|
||||
sdm845_vig_sblk_3, 12, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG3),
|
||||
SSPP_BLK("sspp_8", SSPP_DMA0, 0x24000, DMA_SDM845_MASK,
|
||||
SSPP_BLK("sspp_8", SSPP_DMA0, 0x24000, DMA_SDM845_MASK_SDMA,
|
||||
sdm845_dma_sblk_0, 1, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA0),
|
||||
SSPP_BLK("sspp_9", SSPP_DMA1, 0x26000, DMA_SDM845_MASK,
|
||||
SSPP_BLK("sspp_9", SSPP_DMA1, 0x26000, DMA_SDM845_MASK_SDMA,
|
||||
sdm845_dma_sblk_1, 5, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA1),
|
||||
SSPP_BLK("sspp_10", SSPP_DMA2, 0x28000, DMA_CURSOR_SDM845_MASK,
|
||||
SSPP_BLK("sspp_10", SSPP_DMA2, 0x28000, DMA_CURSOR_SDM845_MASK_SDMA,
|
||||
sdm845_dma_sblk_2, 9, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA2),
|
||||
SSPP_BLK("sspp_11", SSPP_DMA3, 0x2a000, DMA_CURSOR_SDM845_MASK,
|
||||
SSPP_BLK("sspp_11", SSPP_DMA3, 0x2a000, DMA_CURSOR_SDM845_MASK_SDMA,
|
||||
sdm845_dma_sblk_3, 13, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA3),
|
||||
};
|
||||
|
||||
@ -1252,21 +1259,21 @@ static const struct dpu_sspp_sub_blks sm8250_vig_sblk_3 =
|
||||
_VIG_SBLK("3", 8, DPU_SSPP_SCALER_QSEED4);
|
||||
|
||||
static const struct dpu_sspp_cfg sm8250_sspp[] = {
|
||||
SSPP_BLK("sspp_0", SSPP_VIG0, 0x4000, VIG_SC7180_MASK,
|
||||
SSPP_BLK("sspp_0", SSPP_VIG0, 0x4000, VIG_SC7180_MASK_SDMA,
|
||||
sm8250_vig_sblk_0, 0, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG0),
|
||||
SSPP_BLK("sspp_1", SSPP_VIG1, 0x6000, VIG_SC7180_MASK,
|
||||
SSPP_BLK("sspp_1", SSPP_VIG1, 0x6000, VIG_SC7180_MASK_SDMA,
|
||||
sm8250_vig_sblk_1, 4, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG1),
|
||||
SSPP_BLK("sspp_2", SSPP_VIG2, 0x8000, VIG_SC7180_MASK,
|
||||
SSPP_BLK("sspp_2", SSPP_VIG2, 0x8000, VIG_SC7180_MASK_SDMA,
|
||||
sm8250_vig_sblk_2, 8, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG2),
|
||||
SSPP_BLK("sspp_3", SSPP_VIG3, 0xa000, VIG_SC7180_MASK,
|
||||
SSPP_BLK("sspp_3", SSPP_VIG3, 0xa000, VIG_SC7180_MASK_SDMA,
|
||||
sm8250_vig_sblk_3, 12, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG3),
|
||||
SSPP_BLK("sspp_8", SSPP_DMA0, 0x24000, DMA_SDM845_MASK,
|
||||
SSPP_BLK("sspp_8", SSPP_DMA0, 0x24000, DMA_SDM845_MASK_SDMA,
|
||||
sdm845_dma_sblk_0, 1, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA0),
|
||||
SSPP_BLK("sspp_9", SSPP_DMA1, 0x26000, DMA_SDM845_MASK,
|
||||
SSPP_BLK("sspp_9", SSPP_DMA1, 0x26000, DMA_SDM845_MASK_SDMA,
|
||||
sdm845_dma_sblk_1, 5, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA1),
|
||||
SSPP_BLK("sspp_10", SSPP_DMA2, 0x28000, DMA_CURSOR_SDM845_MASK,
|
||||
SSPP_BLK("sspp_10", SSPP_DMA2, 0x28000, DMA_CURSOR_SDM845_MASK_SDMA,
|
||||
sdm845_dma_sblk_2, 9, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA2),
|
||||
SSPP_BLK("sspp_11", SSPP_DMA3, 0x2a000, DMA_CURSOR_SDM845_MASK,
|
||||
SSPP_BLK("sspp_11", SSPP_DMA3, 0x2a000, DMA_CURSOR_SDM845_MASK_SDMA,
|
||||
sdm845_dma_sblk_3, 13, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA3),
|
||||
};
|
||||
|
||||
@ -1333,13 +1340,13 @@ static const struct dpu_sspp_cfg sm8550_sspp[] = {
|
||||
};
|
||||
|
||||
static const struct dpu_sspp_cfg sc7280_sspp[] = {
|
||||
SSPP_BLK("sspp_0", SSPP_VIG0, 0x4000, VIG_SC7280_MASK,
|
||||
SSPP_BLK("sspp_0", SSPP_VIG0, 0x4000, VIG_SC7280_MASK_SDMA,
|
||||
sc7280_vig_sblk_0, 0, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG0),
|
||||
SSPP_BLK("sspp_8", SSPP_DMA0, 0x24000, DMA_SDM845_MASK,
|
||||
SSPP_BLK("sspp_8", SSPP_DMA0, 0x24000, DMA_SDM845_MASK_SDMA,
|
||||
sdm845_dma_sblk_0, 1, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA0),
|
||||
SSPP_BLK("sspp_9", SSPP_DMA1, 0x26000, DMA_CURSOR_SDM845_MASK,
|
||||
SSPP_BLK("sspp_9", SSPP_DMA1, 0x26000, DMA_CURSOR_SDM845_MASK_SDMA,
|
||||
sdm845_dma_sblk_1, 5, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA1),
|
||||
SSPP_BLK("sspp_10", SSPP_DMA2, 0x28000, DMA_CURSOR_SDM845_MASK,
|
||||
SSPP_BLK("sspp_10", SSPP_DMA2, 0x28000, DMA_CURSOR_SDM845_MASK_SDMA,
|
||||
sdm845_dma_sblk_2, 9, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA2),
|
||||
};
|
||||
|
||||
|
@ -19,8 +19,9 @@
|
||||
*/
|
||||
#define MAX_BLOCKS 12
|
||||
|
||||
#define DPU_HW_VER(MAJOR, MINOR, STEP) (((MAJOR & 0xF) << 28) |\
|
||||
((MINOR & 0xFFF) << 16) |\
|
||||
#define DPU_HW_VER(MAJOR, MINOR, STEP) \
|
||||
((((unsigned int)MAJOR & 0xF) << 28) | \
|
||||
((MINOR & 0xFFF) << 16) | \
|
||||
(STEP & 0xFFFF))
|
||||
|
||||
#define DPU_HW_MAJOR(rev) ((rev) >> 28)
|
||||
@ -169,10 +170,12 @@ enum {
|
||||
* DSPP sub-blocks
|
||||
* @DPU_DSPP_PCC Panel color correction block
|
||||
* @DPU_DSPP_GC Gamma correction block
|
||||
* @DPU_DSPP_IGC Inverse gamma correction block
|
||||
*/
|
||||
enum {
|
||||
DPU_DSPP_PCC = 0x1,
|
||||
DPU_DSPP_GC,
|
||||
DPU_DSPP_IGC,
|
||||
DPU_DSPP_MAX
|
||||
};
|
||||
|
||||
@ -200,6 +203,7 @@ enum {
|
||||
* @DPU_CTL_FETCH_ACTIVE: Active CTL for fetch HW (SSPPs)
|
||||
* @DPU_CTL_VM_CFG: CTL config to support multiple VMs
|
||||
* @DPU_CTL_HAS_LAYER_EXT4: CTL has the CTL_LAYER_EXT4 register
|
||||
* @DPU_CTL_DSPP_BLOCK_FLUSH: CTL config to support dspp sub-block flush
|
||||
* @DPU_CTL_MAX
|
||||
*/
|
||||
enum {
|
||||
@ -208,6 +212,7 @@ enum {
|
||||
DPU_CTL_FETCH_ACTIVE,
|
||||
DPU_CTL_VM_CFG,
|
||||
DPU_CTL_HAS_LAYER_EXT4,
|
||||
DPU_CTL_DSPP_SUB_BLOCK_FLUSH,
|
||||
DPU_CTL_MAX
|
||||
};
|
||||
|
||||
@ -395,7 +400,6 @@ struct dpu_rotation_cfg {
|
||||
* @max_mixer_blendstages max layer mixer blend stages or
|
||||
* supported z order
|
||||
* @qseed_type qseed2 or qseed3 support.
|
||||
* @smart_dma_rev Supported version of SmartDMA feature.
|
||||
* @ubwc_version UBWC feature version (0x0 for not supported)
|
||||
* @has_src_split source split feature status
|
||||
* @has_dim_layer dim layer feature status
|
||||
@ -410,7 +414,6 @@ struct dpu_caps {
|
||||
u32 max_mixer_width;
|
||||
u32 max_mixer_blendstages;
|
||||
u32 qseed_type;
|
||||
u32 smart_dma_rev;
|
||||
u32 ubwc_version;
|
||||
bool has_src_split;
|
||||
bool has_dim_layer;
|
||||
|
@ -26,15 +26,16 @@
|
||||
#define CTL_SW_RESET 0x030
|
||||
#define CTL_LAYER_EXTN_OFFSET 0x40
|
||||
#define CTL_MERGE_3D_ACTIVE 0x0E4
|
||||
#define CTL_DSC_ACTIVE 0x0E8
|
||||
#define CTL_WB_ACTIVE 0x0EC
|
||||
#define CTL_INTF_ACTIVE 0x0F4
|
||||
#define CTL_FETCH_PIPE_ACTIVE 0x0FC
|
||||
#define CTL_MERGE_3D_FLUSH 0x100
|
||||
#define CTL_DSC_ACTIVE 0x0E8
|
||||
#define CTL_DSC_FLUSH 0x104
|
||||
#define CTL_WB_FLUSH 0x108
|
||||
#define CTL_INTF_FLUSH 0x110
|
||||
#define CTL_INTF_MASTER 0x134
|
||||
#define CTL_FETCH_PIPE_ACTIVE 0x0FC
|
||||
#define CTL_DSPP_n_FLUSH(n) ((0x13C) + ((n) * 4))
|
||||
|
||||
#define CTL_MIXER_BORDER_OUT BIT(24)
|
||||
#define CTL_FLUSH_MASK_CTL BIT(17)
|
||||
@ -44,6 +45,7 @@
|
||||
#define DSC_IDX 22
|
||||
#define INTF_IDX 31
|
||||
#define WB_IDX 16
|
||||
#define DSPP_IDX 29 /* From DPU hw rev 7.x.x */
|
||||
#define CTL_INVALID_BIT 0xffff
|
||||
#define CTL_DEFAULT_GROUP_ID 0xf
|
||||
|
||||
@ -115,6 +117,9 @@ static inline void dpu_hw_ctl_clear_pending_flush(struct dpu_hw_ctl *ctx)
|
||||
trace_dpu_hw_ctl_clear_pending_flush(ctx->pending_flush_mask,
|
||||
dpu_hw_ctl_get_flush_register(ctx));
|
||||
ctx->pending_flush_mask = 0x0;
|
||||
|
||||
memset(ctx->pending_dspp_flush_mask, 0,
|
||||
sizeof(ctx->pending_dspp_flush_mask));
|
||||
}
|
||||
|
||||
static inline void dpu_hw_ctl_update_pending_flush(struct dpu_hw_ctl *ctx,
|
||||
@ -132,6 +137,8 @@ static u32 dpu_hw_ctl_get_pending_flush(struct dpu_hw_ctl *ctx)
|
||||
|
||||
static inline void dpu_hw_ctl_trigger_flush_v1(struct dpu_hw_ctl *ctx)
|
||||
{
|
||||
int dspp;
|
||||
|
||||
if (ctx->pending_flush_mask & BIT(MERGE_3D_IDX))
|
||||
DPU_REG_WRITE(&ctx->hw, CTL_MERGE_3D_FLUSH,
|
||||
ctx->pending_merge_3d_flush_mask);
|
||||
@ -142,6 +149,13 @@ static inline void dpu_hw_ctl_trigger_flush_v1(struct dpu_hw_ctl *ctx)
|
||||
DPU_REG_WRITE(&ctx->hw, CTL_WB_FLUSH,
|
||||
ctx->pending_wb_flush_mask);
|
||||
|
||||
if (ctx->pending_flush_mask & BIT(DSPP_IDX))
|
||||
for (dspp = DSPP_0; dspp < DSPP_MAX; dspp++) {
|
||||
if (ctx->pending_dspp_flush_mask[dspp - DSPP_0])
|
||||
DPU_REG_WRITE(&ctx->hw,
|
||||
CTL_DSPP_n_FLUSH(dspp - DSPP_0),
|
||||
ctx->pending_dspp_flush_mask[dspp - DSPP_0]);
|
||||
}
|
||||
DPU_REG_WRITE(&ctx->hw, CTL_FLUSH, ctx->pending_flush_mask);
|
||||
}
|
||||
|
||||
@ -289,7 +303,7 @@ static void dpu_hw_ctl_update_pending_flush_merge_3d_v1(struct dpu_hw_ctl *ctx,
|
||||
}
|
||||
|
||||
static void dpu_hw_ctl_update_pending_flush_dspp(struct dpu_hw_ctl *ctx,
|
||||
enum dpu_dspp dspp)
|
||||
enum dpu_dspp dspp, u32 dspp_sub_blk)
|
||||
{
|
||||
switch (dspp) {
|
||||
case DSPP_0:
|
||||
@ -309,6 +323,29 @@ static void dpu_hw_ctl_update_pending_flush_dspp(struct dpu_hw_ctl *ctx,
|
||||
}
|
||||
}
|
||||
|
||||
static void dpu_hw_ctl_update_pending_flush_dspp_sub_blocks(
|
||||
struct dpu_hw_ctl *ctx, enum dpu_dspp dspp, u32 dspp_sub_blk)
|
||||
{
|
||||
if (dspp >= DSPP_MAX)
|
||||
return;
|
||||
|
||||
switch (dspp_sub_blk) {
|
||||
case DPU_DSPP_IGC:
|
||||
ctx->pending_dspp_flush_mask[dspp - DSPP_0] |= BIT(2);
|
||||
break;
|
||||
case DPU_DSPP_PCC:
|
||||
ctx->pending_dspp_flush_mask[dspp - DSPP_0] |= BIT(4);
|
||||
break;
|
||||
case DPU_DSPP_GC:
|
||||
ctx->pending_dspp_flush_mask[dspp - DSPP_0] |= BIT(5);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
ctx->pending_flush_mask |= BIT(DSPP_IDX);
|
||||
}
|
||||
|
||||
static u32 dpu_hw_ctl_poll_reset_status(struct dpu_hw_ctl *ctx, u32 timeout_us)
|
||||
{
|
||||
struct dpu_hw_blk_reg_map *c = &ctx->hw;
|
||||
@ -630,7 +667,11 @@ static void _setup_ctl_ops(struct dpu_hw_ctl_ops *ops,
|
||||
ops->setup_blendstage = dpu_hw_ctl_setup_blendstage;
|
||||
ops->update_pending_flush_sspp = dpu_hw_ctl_update_pending_flush_sspp;
|
||||
ops->update_pending_flush_mixer = dpu_hw_ctl_update_pending_flush_mixer;
|
||||
ops->update_pending_flush_dspp = dpu_hw_ctl_update_pending_flush_dspp;
|
||||
if (cap & BIT(DPU_CTL_DSPP_SUB_BLOCK_FLUSH))
|
||||
ops->update_pending_flush_dspp = dpu_hw_ctl_update_pending_flush_dspp_sub_blocks;
|
||||
else
|
||||
ops->update_pending_flush_dspp = dpu_hw_ctl_update_pending_flush_dspp;
|
||||
|
||||
if (cap & BIT(DPU_CTL_FETCH_ACTIVE))
|
||||
ops->set_active_pipes = dpu_hw_ctl_set_fetch_pipe_active;
|
||||
};
|
||||
|
@ -152,9 +152,11 @@ struct dpu_hw_ctl_ops {
|
||||
* No effect on hardware
|
||||
* @ctx : ctl path ctx pointer
|
||||
* @blk : DSPP block index
|
||||
* @dspp_sub_blk : DSPP sub-block index
|
||||
*/
|
||||
void (*update_pending_flush_dspp)(struct dpu_hw_ctl *ctx,
|
||||
enum dpu_dspp blk);
|
||||
enum dpu_dspp blk, u32 dspp_sub_blk);
|
||||
|
||||
/**
|
||||
* Write the value of the pending_flush_mask to hardware
|
||||
* @ctx : ctl path ctx pointer
|
||||
@ -242,6 +244,7 @@ struct dpu_hw_ctl {
|
||||
u32 pending_intf_flush_mask;
|
||||
u32 pending_wb_flush_mask;
|
||||
u32 pending_merge_3d_flush_mask;
|
||||
u32 pending_dspp_flush_mask[DSPP_MAX - DSPP_0];
|
||||
|
||||
/* ops */
|
||||
struct dpu_hw_ctl_ops ops;
|
||||
|
@ -136,7 +136,7 @@
|
||||
#define TS_CLK 19200000
|
||||
|
||||
|
||||
static int _sspp_subblk_offset(struct dpu_hw_pipe *ctx,
|
||||
static int _sspp_subblk_offset(struct dpu_hw_sspp *ctx,
|
||||
int s_id,
|
||||
u32 *idx)
|
||||
{
|
||||
@ -168,17 +168,16 @@ static int _sspp_subblk_offset(struct dpu_hw_pipe *ctx,
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void dpu_hw_sspp_setup_multirect(struct dpu_hw_pipe *ctx,
|
||||
enum dpu_sspp_multirect_index index,
|
||||
enum dpu_sspp_multirect_mode mode)
|
||||
static void dpu_hw_sspp_setup_multirect(struct dpu_sw_pipe *pipe)
|
||||
{
|
||||
struct dpu_hw_sspp *ctx = pipe->sspp;
|
||||
u32 mode_mask;
|
||||
u32 idx;
|
||||
|
||||
if (_sspp_subblk_offset(ctx, DPU_SSPP_SRC, &idx))
|
||||
return;
|
||||
|
||||
if (index == DPU_SSPP_RECT_SOLO) {
|
||||
if (pipe->multirect_index == DPU_SSPP_RECT_SOLO) {
|
||||
/**
|
||||
* if rect index is RECT_SOLO, we cannot expect a
|
||||
* virtual plane sharing the same SSPP id. So we go
|
||||
@ -187,8 +186,8 @@ static void dpu_hw_sspp_setup_multirect(struct dpu_hw_pipe *ctx,
|
||||
mode_mask = 0;
|
||||
} else {
|
||||
mode_mask = DPU_REG_READ(&ctx->hw, SSPP_MULTIRECT_OPMODE + idx);
|
||||
mode_mask |= index;
|
||||
if (mode == DPU_SSPP_MULTIRECT_TIME_MX)
|
||||
mode_mask |= pipe->multirect_index;
|
||||
if (pipe->multirect_mode == DPU_SSPP_MULTIRECT_TIME_MX)
|
||||
mode_mask |= BIT(2);
|
||||
else
|
||||
mode_mask &= ~BIT(2);
|
||||
@ -197,7 +196,7 @@ static void dpu_hw_sspp_setup_multirect(struct dpu_hw_pipe *ctx,
|
||||
DPU_REG_WRITE(&ctx->hw, SSPP_MULTIRECT_OPMODE + idx, mode_mask);
|
||||
}
|
||||
|
||||
static void _sspp_setup_opmode(struct dpu_hw_pipe *ctx,
|
||||
static void _sspp_setup_opmode(struct dpu_hw_sspp *ctx,
|
||||
u32 mask, u8 en)
|
||||
{
|
||||
u32 idx;
|
||||
@ -218,7 +217,7 @@ static void _sspp_setup_opmode(struct dpu_hw_pipe *ctx,
|
||||
DPU_REG_WRITE(&ctx->hw, SSPP_VIG_OP_MODE + idx, opmode);
|
||||
}
|
||||
|
||||
static void _sspp_setup_csc10_opmode(struct dpu_hw_pipe *ctx,
|
||||
static void _sspp_setup_csc10_opmode(struct dpu_hw_sspp *ctx,
|
||||
u32 mask, u8 en)
|
||||
{
|
||||
u32 idx;
|
||||
@ -239,10 +238,10 @@ static void _sspp_setup_csc10_opmode(struct dpu_hw_pipe *ctx,
|
||||
/*
|
||||
* Setup source pixel format, flip,
|
||||
*/
|
||||
static void dpu_hw_sspp_setup_format(struct dpu_hw_pipe *ctx,
|
||||
const struct dpu_format *fmt, u32 flags,
|
||||
enum dpu_sspp_multirect_index rect_mode)
|
||||
static void dpu_hw_sspp_setup_format(struct dpu_sw_pipe *pipe,
|
||||
const struct dpu_format *fmt, u32 flags)
|
||||
{
|
||||
struct dpu_hw_sspp *ctx = pipe->sspp;
|
||||
struct dpu_hw_blk_reg_map *c;
|
||||
u32 chroma_samp, unpack, src_format;
|
||||
u32 opmode = 0;
|
||||
@ -253,7 +252,8 @@ static void dpu_hw_sspp_setup_format(struct dpu_hw_pipe *ctx,
|
||||
if (_sspp_subblk_offset(ctx, DPU_SSPP_SRC, &idx) || !fmt)
|
||||
return;
|
||||
|
||||
if (rect_mode == DPU_SSPP_RECT_SOLO || rect_mode == DPU_SSPP_RECT_0) {
|
||||
if (pipe->multirect_index == DPU_SSPP_RECT_SOLO ||
|
||||
pipe->multirect_index == DPU_SSPP_RECT_0) {
|
||||
op_mode_off = SSPP_SRC_OP_MODE;
|
||||
unpack_pat_off = SSPP_SRC_UNPACK_PATTERN;
|
||||
format_off = SSPP_SRC_FORMAT;
|
||||
@ -360,7 +360,7 @@ static void dpu_hw_sspp_setup_format(struct dpu_hw_pipe *ctx,
|
||||
DPU_REG_WRITE(c, SSPP_UBWC_ERROR_STATUS + idx, BIT(31));
|
||||
}
|
||||
|
||||
static void dpu_hw_sspp_setup_pe_config(struct dpu_hw_pipe *ctx,
|
||||
static void dpu_hw_sspp_setup_pe_config(struct dpu_hw_sspp *ctx,
|
||||
struct dpu_hw_pixel_ext *pe_ext)
|
||||
{
|
||||
struct dpu_hw_blk_reg_map *c;
|
||||
@ -418,23 +418,22 @@ static void dpu_hw_sspp_setup_pe_config(struct dpu_hw_pipe *ctx,
|
||||
tot_req_pixels[3]);
|
||||
}
|
||||
|
||||
static void _dpu_hw_sspp_setup_scaler3(struct dpu_hw_pipe *ctx,
|
||||
struct dpu_hw_pipe_cfg *sspp,
|
||||
void *scaler_cfg)
|
||||
static void _dpu_hw_sspp_setup_scaler3(struct dpu_hw_sspp *ctx,
|
||||
struct dpu_hw_scaler3_cfg *scaler3_cfg,
|
||||
const struct dpu_format *format)
|
||||
{
|
||||
u32 idx;
|
||||
struct dpu_hw_scaler3_cfg *scaler3_cfg = scaler_cfg;
|
||||
|
||||
if (_sspp_subblk_offset(ctx, DPU_SSPP_SCALER_QSEED3, &idx) || !sspp
|
||||
if (_sspp_subblk_offset(ctx, DPU_SSPP_SCALER_QSEED3, &idx)
|
||||
|| !scaler3_cfg)
|
||||
return;
|
||||
|
||||
dpu_hw_setup_scaler3(&ctx->hw, scaler3_cfg, idx,
|
||||
ctx->cap->sblk->scaler_blk.version,
|
||||
sspp->layout.format);
|
||||
format);
|
||||
}
|
||||
|
||||
static u32 _dpu_hw_sspp_get_scaler3_ver(struct dpu_hw_pipe *ctx)
|
||||
static u32 _dpu_hw_sspp_get_scaler3_ver(struct dpu_hw_sspp *ctx)
|
||||
{
|
||||
u32 idx;
|
||||
|
||||
@ -447,12 +446,12 @@ static u32 _dpu_hw_sspp_get_scaler3_ver(struct dpu_hw_pipe *ctx)
|
||||
/*
|
||||
* dpu_hw_sspp_setup_rects()
|
||||
*/
|
||||
static void dpu_hw_sspp_setup_rects(struct dpu_hw_pipe *ctx,
|
||||
struct dpu_hw_pipe_cfg *cfg,
|
||||
enum dpu_sspp_multirect_index rect_index)
|
||||
static void dpu_hw_sspp_setup_rects(struct dpu_sw_pipe *pipe,
|
||||
struct dpu_sw_pipe_cfg *cfg)
|
||||
{
|
||||
struct dpu_hw_sspp *ctx = pipe->sspp;
|
||||
struct dpu_hw_blk_reg_map *c;
|
||||
u32 src_size, src_xy, dst_size, dst_xy, ystride0, ystride1;
|
||||
u32 src_size, src_xy, dst_size, dst_xy;
|
||||
u32 src_size_off, src_xy_off, out_size_off, out_xy_off;
|
||||
u32 idx;
|
||||
|
||||
@ -461,7 +460,8 @@ static void dpu_hw_sspp_setup_rects(struct dpu_hw_pipe *ctx,
|
||||
|
||||
c = &ctx->hw;
|
||||
|
||||
if (rect_index == DPU_SSPP_RECT_SOLO || rect_index == DPU_SSPP_RECT_0) {
|
||||
if (pipe->multirect_index == DPU_SSPP_RECT_SOLO ||
|
||||
pipe->multirect_index == DPU_SSPP_RECT_0) {
|
||||
src_size_off = SSPP_SRC_SIZE;
|
||||
src_xy_off = SSPP_SRC_XY;
|
||||
out_size_off = SSPP_OUT_SIZE;
|
||||
@ -482,68 +482,69 @@ static void dpu_hw_sspp_setup_rects(struct dpu_hw_pipe *ctx,
|
||||
dst_size = (drm_rect_height(&cfg->dst_rect) << 16) |
|
||||
drm_rect_width(&cfg->dst_rect);
|
||||
|
||||
if (rect_index == DPU_SSPP_RECT_SOLO) {
|
||||
ystride0 = (cfg->layout.plane_pitch[0]) |
|
||||
(cfg->layout.plane_pitch[1] << 16);
|
||||
ystride1 = (cfg->layout.plane_pitch[2]) |
|
||||
(cfg->layout.plane_pitch[3] << 16);
|
||||
} else {
|
||||
ystride0 = DPU_REG_READ(c, SSPP_SRC_YSTRIDE0 + idx);
|
||||
ystride1 = DPU_REG_READ(c, SSPP_SRC_YSTRIDE1 + idx);
|
||||
|
||||
if (rect_index == DPU_SSPP_RECT_0) {
|
||||
ystride0 = (ystride0 & 0xFFFF0000) |
|
||||
(cfg->layout.plane_pitch[0] & 0x0000FFFF);
|
||||
ystride1 = (ystride1 & 0xFFFF0000)|
|
||||
(cfg->layout.plane_pitch[2] & 0x0000FFFF);
|
||||
} else {
|
||||
ystride0 = (ystride0 & 0x0000FFFF) |
|
||||
((cfg->layout.plane_pitch[0] << 16) &
|
||||
0xFFFF0000);
|
||||
ystride1 = (ystride1 & 0x0000FFFF) |
|
||||
((cfg->layout.plane_pitch[2] << 16) &
|
||||
0xFFFF0000);
|
||||
}
|
||||
}
|
||||
|
||||
/* rectangle register programming */
|
||||
DPU_REG_WRITE(c, src_size_off + idx, src_size);
|
||||
DPU_REG_WRITE(c, src_xy_off + idx, src_xy);
|
||||
DPU_REG_WRITE(c, out_size_off + idx, dst_size);
|
||||
DPU_REG_WRITE(c, out_xy_off + idx, dst_xy);
|
||||
|
||||
DPU_REG_WRITE(c, SSPP_SRC_YSTRIDE0 + idx, ystride0);
|
||||
DPU_REG_WRITE(c, SSPP_SRC_YSTRIDE1 + idx, ystride1);
|
||||
}
|
||||
|
||||
static void dpu_hw_sspp_setup_sourceaddress(struct dpu_hw_pipe *ctx,
|
||||
struct dpu_hw_pipe_cfg *cfg,
|
||||
enum dpu_sspp_multirect_index rect_mode)
|
||||
static void dpu_hw_sspp_setup_sourceaddress(struct dpu_sw_pipe *pipe,
|
||||
struct dpu_hw_fmt_layout *layout)
|
||||
{
|
||||
struct dpu_hw_sspp *ctx = pipe->sspp;
|
||||
u32 ystride0, ystride1;
|
||||
int i;
|
||||
u32 idx;
|
||||
|
||||
if (_sspp_subblk_offset(ctx, DPU_SSPP_SRC, &idx))
|
||||
return;
|
||||
|
||||
if (rect_mode == DPU_SSPP_RECT_SOLO) {
|
||||
for (i = 0; i < ARRAY_SIZE(cfg->layout.plane_addr); i++)
|
||||
if (pipe->multirect_index == DPU_SSPP_RECT_SOLO) {
|
||||
for (i = 0; i < ARRAY_SIZE(layout->plane_addr); i++)
|
||||
DPU_REG_WRITE(&ctx->hw, SSPP_SRC0_ADDR + idx + i * 0x4,
|
||||
cfg->layout.plane_addr[i]);
|
||||
} else if (rect_mode == DPU_SSPP_RECT_0) {
|
||||
layout->plane_addr[i]);
|
||||
} else if (pipe->multirect_index == DPU_SSPP_RECT_0) {
|
||||
DPU_REG_WRITE(&ctx->hw, SSPP_SRC0_ADDR + idx,
|
||||
cfg->layout.plane_addr[0]);
|
||||
layout->plane_addr[0]);
|
||||
DPU_REG_WRITE(&ctx->hw, SSPP_SRC2_ADDR + idx,
|
||||
cfg->layout.plane_addr[2]);
|
||||
layout->plane_addr[2]);
|
||||
} else {
|
||||
DPU_REG_WRITE(&ctx->hw, SSPP_SRC1_ADDR + idx,
|
||||
cfg->layout.plane_addr[0]);
|
||||
layout->plane_addr[0]);
|
||||
DPU_REG_WRITE(&ctx->hw, SSPP_SRC3_ADDR + idx,
|
||||
cfg->layout.plane_addr[2]);
|
||||
layout->plane_addr[2]);
|
||||
}
|
||||
|
||||
if (pipe->multirect_index == DPU_SSPP_RECT_SOLO) {
|
||||
ystride0 = (layout->plane_pitch[0]) |
|
||||
(layout->plane_pitch[1] << 16);
|
||||
ystride1 = (layout->plane_pitch[2]) |
|
||||
(layout->plane_pitch[3] << 16);
|
||||
} else {
|
||||
ystride0 = DPU_REG_READ(&ctx->hw, SSPP_SRC_YSTRIDE0 + idx);
|
||||
ystride1 = DPU_REG_READ(&ctx->hw, SSPP_SRC_YSTRIDE1 + idx);
|
||||
|
||||
if (pipe->multirect_index == DPU_SSPP_RECT_0) {
|
||||
ystride0 = (ystride0 & 0xFFFF0000) |
|
||||
(layout->plane_pitch[0] & 0x0000FFFF);
|
||||
ystride1 = (ystride1 & 0xFFFF0000)|
|
||||
(layout->plane_pitch[2] & 0x0000FFFF);
|
||||
} else {
|
||||
ystride0 = (ystride0 & 0x0000FFFF) |
|
||||
((layout->plane_pitch[0] << 16) &
|
||||
0xFFFF0000);
|
||||
ystride1 = (ystride1 & 0x0000FFFF) |
|
||||
((layout->plane_pitch[2] << 16) &
|
||||
0xFFFF0000);
|
||||
}
|
||||
}
|
||||
|
||||
DPU_REG_WRITE(&ctx->hw, SSPP_SRC_YSTRIDE0 + idx, ystride0);
|
||||
DPU_REG_WRITE(&ctx->hw, SSPP_SRC_YSTRIDE1 + idx, ystride1);
|
||||
}
|
||||
|
||||
static void dpu_hw_sspp_setup_csc(struct dpu_hw_pipe *ctx,
|
||||
static void dpu_hw_sspp_setup_csc(struct dpu_hw_sspp *ctx,
|
||||
const struct dpu_csc_cfg *data)
|
||||
{
|
||||
u32 idx;
|
||||
@ -560,22 +561,28 @@ static void dpu_hw_sspp_setup_csc(struct dpu_hw_pipe *ctx,
|
||||
dpu_hw_csc_setup(&ctx->hw, idx, data, csc10);
|
||||
}
|
||||
|
||||
static void dpu_hw_sspp_setup_solidfill(struct dpu_hw_pipe *ctx, u32 color, enum
|
||||
dpu_sspp_multirect_index rect_index)
|
||||
static void dpu_hw_sspp_setup_solidfill(struct dpu_sw_pipe *pipe, u32 color)
|
||||
{
|
||||
struct dpu_hw_sspp *ctx = pipe->sspp;
|
||||
struct dpu_hw_fmt_layout cfg;
|
||||
u32 idx;
|
||||
|
||||
if (_sspp_subblk_offset(ctx, DPU_SSPP_SRC, &idx))
|
||||
return;
|
||||
|
||||
if (rect_index == DPU_SSPP_RECT_SOLO || rect_index == DPU_SSPP_RECT_0)
|
||||
/* cleanup source addresses */
|
||||
memset(&cfg, 0, sizeof(cfg));
|
||||
ctx->ops.setup_sourceaddress(pipe, &cfg);
|
||||
|
||||
if (pipe->multirect_index == DPU_SSPP_RECT_SOLO ||
|
||||
pipe->multirect_index == DPU_SSPP_RECT_0)
|
||||
DPU_REG_WRITE(&ctx->hw, SSPP_SRC_CONSTANT_COLOR + idx, color);
|
||||
else
|
||||
DPU_REG_WRITE(&ctx->hw, SSPP_SRC_CONSTANT_COLOR_REC1 + idx,
|
||||
color);
|
||||
}
|
||||
|
||||
static void dpu_hw_sspp_setup_danger_safe_lut(struct dpu_hw_pipe *ctx,
|
||||
static void dpu_hw_sspp_setup_danger_safe_lut(struct dpu_hw_sspp *ctx,
|
||||
u32 danger_lut,
|
||||
u32 safe_lut)
|
||||
{
|
||||
@ -588,7 +595,7 @@ static void dpu_hw_sspp_setup_danger_safe_lut(struct dpu_hw_pipe *ctx,
|
||||
DPU_REG_WRITE(&ctx->hw, SSPP_SAFE_LUT + idx, safe_lut);
|
||||
}
|
||||
|
||||
static void dpu_hw_sspp_setup_creq_lut(struct dpu_hw_pipe *ctx,
|
||||
static void dpu_hw_sspp_setup_creq_lut(struct dpu_hw_sspp *ctx,
|
||||
u64 creq_lut)
|
||||
{
|
||||
u32 idx;
|
||||
@ -605,7 +612,7 @@ static void dpu_hw_sspp_setup_creq_lut(struct dpu_hw_pipe *ctx,
|
||||
}
|
||||
}
|
||||
|
||||
static void dpu_hw_sspp_setup_qos_ctrl(struct dpu_hw_pipe *ctx,
|
||||
static void dpu_hw_sspp_setup_qos_ctrl(struct dpu_hw_sspp *ctx,
|
||||
struct dpu_hw_pipe_qos_cfg *cfg)
|
||||
{
|
||||
u32 idx;
|
||||
@ -630,10 +637,10 @@ static void dpu_hw_sspp_setup_qos_ctrl(struct dpu_hw_pipe *ctx,
|
||||
DPU_REG_WRITE(&ctx->hw, SSPP_QOS_CTRL + idx, qos_ctrl);
|
||||
}
|
||||
|
||||
static void dpu_hw_sspp_setup_cdp(struct dpu_hw_pipe *ctx,
|
||||
struct dpu_hw_cdp_cfg *cfg,
|
||||
enum dpu_sspp_multirect_index index)
|
||||
static void dpu_hw_sspp_setup_cdp(struct dpu_sw_pipe *pipe,
|
||||
struct dpu_hw_cdp_cfg *cfg)
|
||||
{
|
||||
struct dpu_hw_sspp *ctx = pipe->sspp;
|
||||
u32 idx;
|
||||
u32 cdp_cntl = 0;
|
||||
u32 cdp_cntl_offset = 0;
|
||||
@ -644,7 +651,8 @@ static void dpu_hw_sspp_setup_cdp(struct dpu_hw_pipe *ctx,
|
||||
if (_sspp_subblk_offset(ctx, DPU_SSPP_SRC, &idx))
|
||||
return;
|
||||
|
||||
if (index == DPU_SSPP_RECT_SOLO || index == DPU_SSPP_RECT_0)
|
||||
if (pipe->multirect_index == DPU_SSPP_RECT_SOLO ||
|
||||
pipe->multirect_index == DPU_SSPP_RECT_0)
|
||||
cdp_cntl_offset = SSPP_CDP_CNTL;
|
||||
else
|
||||
cdp_cntl_offset = SSPP_CDP_CNTL_REC1;
|
||||
@ -661,7 +669,7 @@ static void dpu_hw_sspp_setup_cdp(struct dpu_hw_pipe *ctx,
|
||||
DPU_REG_WRITE(&ctx->hw, cdp_cntl_offset, cdp_cntl);
|
||||
}
|
||||
|
||||
static void _setup_layer_ops(struct dpu_hw_pipe *c,
|
||||
static void _setup_layer_ops(struct dpu_hw_sspp *c,
|
||||
unsigned long features)
|
||||
{
|
||||
if (test_bit(DPU_SSPP_SRC, &features)) {
|
||||
@ -699,7 +707,8 @@ static void _setup_layer_ops(struct dpu_hw_pipe *c,
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
int _dpu_hw_sspp_init_debugfs(struct dpu_hw_pipe *hw_pipe, struct dpu_kms *kms, struct dentry *entry)
|
||||
int _dpu_hw_sspp_init_debugfs(struct dpu_hw_sspp *hw_pipe, struct dpu_kms *kms,
|
||||
struct dentry *entry)
|
||||
{
|
||||
const struct dpu_sspp_cfg *cfg = hw_pipe->cap;
|
||||
const struct dpu_sspp_sub_blks *sblk = cfg->sblk;
|
||||
@ -783,10 +792,10 @@ static const struct dpu_sspp_cfg *_sspp_offset(enum dpu_sspp sspp,
|
||||
return ERR_PTR(-ENOMEM);
|
||||
}
|
||||
|
||||
struct dpu_hw_pipe *dpu_hw_sspp_init(enum dpu_sspp idx,
|
||||
struct dpu_hw_sspp *dpu_hw_sspp_init(enum dpu_sspp idx,
|
||||
void __iomem *addr, const struct dpu_mdss_cfg *catalog)
|
||||
{
|
||||
struct dpu_hw_pipe *hw_pipe;
|
||||
struct dpu_hw_sspp *hw_pipe;
|
||||
const struct dpu_sspp_cfg *cfg;
|
||||
|
||||
if (!addr || !catalog)
|
||||
@ -812,7 +821,7 @@ struct dpu_hw_pipe *dpu_hw_sspp_init(enum dpu_sspp idx,
|
||||
return hw_pipe;
|
||||
}
|
||||
|
||||
void dpu_hw_sspp_destroy(struct dpu_hw_pipe *ctx)
|
||||
void dpu_hw_sspp_destroy(struct dpu_hw_sspp *ctx)
|
||||
{
|
||||
kfree(ctx);
|
||||
}
|
||||
|
@ -10,7 +10,7 @@
|
||||
#include "dpu_hw_util.h"
|
||||
#include "dpu_formats.h"
|
||||
|
||||
struct dpu_hw_pipe;
|
||||
struct dpu_hw_sspp;
|
||||
|
||||
/**
|
||||
* Flags
|
||||
@ -153,20 +153,14 @@ struct dpu_hw_pixel_ext {
|
||||
};
|
||||
|
||||
/**
|
||||
* struct dpu_hw_pipe_cfg : Pipe description
|
||||
* @layout: format layout information for programming buffer to hardware
|
||||
* struct dpu_sw_pipe_cfg : software pipe configuration
|
||||
* @src_rect: src ROI, caller takes into account the different operations
|
||||
* such as decimation, flip etc to program this field
|
||||
* @dest_rect: destination ROI.
|
||||
* @index: index of the rectangle of SSPP
|
||||
* @mode: parallel or time multiplex multirect mode
|
||||
*/
|
||||
struct dpu_hw_pipe_cfg {
|
||||
struct dpu_hw_fmt_layout layout;
|
||||
struct dpu_sw_pipe_cfg {
|
||||
struct drm_rect src_rect;
|
||||
struct drm_rect dst_rect;
|
||||
enum dpu_sspp_multirect_index index;
|
||||
enum dpu_sspp_multirect_mode mode;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -201,6 +195,18 @@ struct dpu_hw_pipe_ts_cfg {
|
||||
u64 time;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct dpu_sw_pipe - software pipe description
|
||||
* @sspp: backing SSPP pipe
|
||||
* @index: index of the rectangle of SSPP
|
||||
* @mode: parallel or time multiplex multirect mode
|
||||
*/
|
||||
struct dpu_sw_pipe {
|
||||
struct dpu_hw_sspp *sspp;
|
||||
enum dpu_sspp_multirect_index multirect_index;
|
||||
enum dpu_sspp_multirect_mode multirect_mode;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct dpu_hw_sspp_ops - interface to the SSPP Hw driver functions
|
||||
* Caller must call the init function to get the pipe context for each pipe
|
||||
@ -209,77 +215,65 @@ struct dpu_hw_pipe_ts_cfg {
|
||||
struct dpu_hw_sspp_ops {
|
||||
/**
|
||||
* setup_format - setup pixel format cropping rectangle, flip
|
||||
* @ctx: Pointer to pipe context
|
||||
* @pipe: Pointer to software pipe context
|
||||
* @cfg: Pointer to pipe config structure
|
||||
* @flags: Extra flags for format config
|
||||
* @index: rectangle index in multirect
|
||||
*/
|
||||
void (*setup_format)(struct dpu_hw_pipe *ctx,
|
||||
const struct dpu_format *fmt, u32 flags,
|
||||
enum dpu_sspp_multirect_index index);
|
||||
void (*setup_format)(struct dpu_sw_pipe *pipe,
|
||||
const struct dpu_format *fmt, u32 flags);
|
||||
|
||||
/**
|
||||
* setup_rects - setup pipe ROI rectangles
|
||||
* @ctx: Pointer to pipe context
|
||||
* @pipe: Pointer to software pipe context
|
||||
* @cfg: Pointer to pipe config structure
|
||||
* @index: rectangle index in multirect
|
||||
*/
|
||||
void (*setup_rects)(struct dpu_hw_pipe *ctx,
|
||||
struct dpu_hw_pipe_cfg *cfg,
|
||||
enum dpu_sspp_multirect_index index);
|
||||
void (*setup_rects)(struct dpu_sw_pipe *pipe,
|
||||
struct dpu_sw_pipe_cfg *cfg);
|
||||
|
||||
/**
|
||||
* setup_pe - setup pipe pixel extension
|
||||
* @ctx: Pointer to pipe context
|
||||
* @pe_ext: Pointer to pixel ext settings
|
||||
*/
|
||||
void (*setup_pe)(struct dpu_hw_pipe *ctx,
|
||||
void (*setup_pe)(struct dpu_hw_sspp *ctx,
|
||||
struct dpu_hw_pixel_ext *pe_ext);
|
||||
|
||||
/**
|
||||
* setup_sourceaddress - setup pipe source addresses
|
||||
* @ctx: Pointer to pipe context
|
||||
* @cfg: Pointer to pipe config structure
|
||||
* @index: rectangle index in multirect
|
||||
* @pipe: Pointer to software pipe context
|
||||
* @layout: format layout information for programming buffer to hardware
|
||||
*/
|
||||
void (*setup_sourceaddress)(struct dpu_hw_pipe *ctx,
|
||||
struct dpu_hw_pipe_cfg *cfg,
|
||||
enum dpu_sspp_multirect_index index);
|
||||
void (*setup_sourceaddress)(struct dpu_sw_pipe *ctx,
|
||||
struct dpu_hw_fmt_layout *layout);
|
||||
|
||||
/**
|
||||
* setup_csc - setup color space coversion
|
||||
* @ctx: Pointer to pipe context
|
||||
* @data: Pointer to config structure
|
||||
*/
|
||||
void (*setup_csc)(struct dpu_hw_pipe *ctx, const struct dpu_csc_cfg *data);
|
||||
void (*setup_csc)(struct dpu_hw_sspp *ctx, const struct dpu_csc_cfg *data);
|
||||
|
||||
/**
|
||||
* setup_solidfill - enable/disable colorfill
|
||||
* @ctx: Pointer to pipe context
|
||||
* @pipe: Pointer to software pipe context
|
||||
* @const_color: Fill color value
|
||||
* @flags: Pipe flags
|
||||
* @index: rectangle index in multirect
|
||||
*/
|
||||
void (*setup_solidfill)(struct dpu_hw_pipe *ctx, u32 color,
|
||||
enum dpu_sspp_multirect_index index);
|
||||
void (*setup_solidfill)(struct dpu_sw_pipe *pipe, u32 color);
|
||||
|
||||
/**
|
||||
* setup_multirect - setup multirect configuration
|
||||
* @ctx: Pointer to pipe context
|
||||
* @index: rectangle index in multirect
|
||||
* @mode: parallel fetch / time multiplex multirect mode
|
||||
* @pipe: Pointer to software pipe context
|
||||
*/
|
||||
|
||||
void (*setup_multirect)(struct dpu_hw_pipe *ctx,
|
||||
enum dpu_sspp_multirect_index index,
|
||||
enum dpu_sspp_multirect_mode mode);
|
||||
void (*setup_multirect)(struct dpu_sw_pipe *pipe);
|
||||
|
||||
/**
|
||||
* setup_sharpening - setup sharpening
|
||||
* @ctx: Pointer to pipe context
|
||||
* @cfg: Pointer to config structure
|
||||
*/
|
||||
void (*setup_sharpening)(struct dpu_hw_pipe *ctx,
|
||||
void (*setup_sharpening)(struct dpu_hw_sspp *ctx,
|
||||
struct dpu_hw_sharp_cfg *cfg);
|
||||
|
||||
/**
|
||||
@ -289,7 +283,7 @@ struct dpu_hw_sspp_ops {
|
||||
* @safe_lut: LUT for generate safe level based on fill level
|
||||
*
|
||||
*/
|
||||
void (*setup_danger_safe_lut)(struct dpu_hw_pipe *ctx,
|
||||
void (*setup_danger_safe_lut)(struct dpu_hw_sspp *ctx,
|
||||
u32 danger_lut,
|
||||
u32 safe_lut);
|
||||
|
||||
@ -299,7 +293,7 @@ struct dpu_hw_sspp_ops {
|
||||
* @creq_lut: LUT for generate creq level based on fill level
|
||||
*
|
||||
*/
|
||||
void (*setup_creq_lut)(struct dpu_hw_pipe *ctx,
|
||||
void (*setup_creq_lut)(struct dpu_hw_sspp *ctx,
|
||||
u64 creq_lut);
|
||||
|
||||
/**
|
||||
@ -308,7 +302,7 @@ struct dpu_hw_sspp_ops {
|
||||
* @cfg: Pointer to pipe QoS configuration
|
||||
*
|
||||
*/
|
||||
void (*setup_qos_ctrl)(struct dpu_hw_pipe *ctx,
|
||||
void (*setup_qos_ctrl)(struct dpu_hw_sspp *ctx,
|
||||
struct dpu_hw_pipe_qos_cfg *cfg);
|
||||
|
||||
/**
|
||||
@ -316,38 +310,35 @@ struct dpu_hw_sspp_ops {
|
||||
* @ctx: Pointer to pipe context
|
||||
* @cfg: Pointer to histogram configuration
|
||||
*/
|
||||
void (*setup_histogram)(struct dpu_hw_pipe *ctx,
|
||||
void (*setup_histogram)(struct dpu_hw_sspp *ctx,
|
||||
void *cfg);
|
||||
|
||||
/**
|
||||
* setup_scaler - setup scaler
|
||||
* @ctx: Pointer to pipe context
|
||||
* @pipe_cfg: Pointer to pipe configuration
|
||||
* @scaler_cfg: Pointer to scaler configuration
|
||||
* @scaler3_cfg: Pointer to scaler configuration
|
||||
* @format: pixel format parameters
|
||||
*/
|
||||
void (*setup_scaler)(struct dpu_hw_pipe *ctx,
|
||||
struct dpu_hw_pipe_cfg *pipe_cfg,
|
||||
void *scaler_cfg);
|
||||
void (*setup_scaler)(struct dpu_hw_sspp *ctx,
|
||||
struct dpu_hw_scaler3_cfg *scaler3_cfg,
|
||||
const struct dpu_format *format);
|
||||
|
||||
/**
|
||||
* get_scaler_ver - get scaler h/w version
|
||||
* @ctx: Pointer to pipe context
|
||||
*/
|
||||
u32 (*get_scaler_ver)(struct dpu_hw_pipe *ctx);
|
||||
u32 (*get_scaler_ver)(struct dpu_hw_sspp *ctx);
|
||||
|
||||
/**
|
||||
* setup_cdp - setup client driven prefetch
|
||||
* @ctx: Pointer to pipe context
|
||||
* @pipe: Pointer to software pipe context
|
||||
* @cfg: Pointer to cdp configuration
|
||||
* @index: rectangle index in multirect
|
||||
*/
|
||||
void (*setup_cdp)(struct dpu_hw_pipe *ctx,
|
||||
struct dpu_hw_cdp_cfg *cfg,
|
||||
enum dpu_sspp_multirect_index index);
|
||||
void (*setup_cdp)(struct dpu_sw_pipe *pipe,
|
||||
struct dpu_hw_cdp_cfg *cfg);
|
||||
};
|
||||
|
||||
/**
|
||||
* struct dpu_hw_pipe - pipe description
|
||||
* struct dpu_hw_sspp - pipe description
|
||||
* @base: hardware block base structure
|
||||
* @hw: block hardware details
|
||||
* @catalog: back pointer to catalog
|
||||
@ -356,7 +347,7 @@ struct dpu_hw_sspp_ops {
|
||||
* @cap: pointer to layer_cfg
|
||||
* @ops: pointer to operations possible for this pipe
|
||||
*/
|
||||
struct dpu_hw_pipe {
|
||||
struct dpu_hw_sspp {
|
||||
struct dpu_hw_blk base;
|
||||
struct dpu_hw_blk_reg_map hw;
|
||||
const struct dpu_mdss_cfg *catalog;
|
||||
@ -378,7 +369,7 @@ struct dpu_kms;
|
||||
* @addr: Mapped register io address of MDP
|
||||
* @catalog : Pointer to mdss catalog data
|
||||
*/
|
||||
struct dpu_hw_pipe *dpu_hw_sspp_init(enum dpu_sspp idx,
|
||||
struct dpu_hw_sspp *dpu_hw_sspp_init(enum dpu_sspp idx,
|
||||
void __iomem *addr, const struct dpu_mdss_cfg *catalog);
|
||||
|
||||
/**
|
||||
@ -386,10 +377,10 @@ struct dpu_hw_pipe *dpu_hw_sspp_init(enum dpu_sspp idx,
|
||||
* should be called during Hw pipe cleanup.
|
||||
* @ctx: Pointer to SSPP driver context returned by dpu_hw_sspp_init
|
||||
*/
|
||||
void dpu_hw_sspp_destroy(struct dpu_hw_pipe *ctx);
|
||||
void dpu_hw_sspp_destroy(struct dpu_hw_sspp *ctx);
|
||||
|
||||
void dpu_debugfs_sspp_init(struct dpu_kms *dpu_kms, struct dentry *debugfs_root);
|
||||
int _dpu_hw_sspp_init_debugfs(struct dpu_hw_pipe *hw_pipe, struct dpu_kms *kms, struct dentry *entry);
|
||||
int _dpu_hw_sspp_init_debugfs(struct dpu_hw_sspp *hw_pipe, struct dpu_kms *kms,
|
||||
struct dentry *entry);
|
||||
|
||||
#endif /*_DPU_HW_SSPP_H */
|
||||
|
||||
|
@ -250,6 +250,24 @@ void dpu_debugfs_create_regset32(const char *name, umode_t mode,
|
||||
debugfs_create_file(name, mode, parent, regset, &dpu_regset32_fops);
|
||||
}
|
||||
|
||||
static void dpu_debugfs_sspp_init(struct dpu_kms *dpu_kms, struct dentry *debugfs_root)
|
||||
{
|
||||
struct dentry *entry = debugfs_create_dir("sspp", debugfs_root);
|
||||
int i;
|
||||
|
||||
if (IS_ERR(entry))
|
||||
return;
|
||||
|
||||
for (i = SSPP_NONE; i < SSPP_MAX; i++) {
|
||||
struct dpu_hw_sspp *hw = dpu_rm_get_sspp(&dpu_kms->rm, i);
|
||||
|
||||
if (!hw)
|
||||
continue;
|
||||
|
||||
_dpu_hw_sspp_init_debugfs(hw, dpu_kms, entry);
|
||||
}
|
||||
}
|
||||
|
||||
static int dpu_kms_debugfs_init(struct msm_kms *kms, struct drm_minor *minor)
|
||||
{
|
||||
struct dpu_kms *dpu_kms = to_dpu_kms(kms);
|
||||
@ -411,26 +429,6 @@ static void dpu_kms_disable_commit(struct msm_kms *kms)
|
||||
pm_runtime_put_sync(&dpu_kms->pdev->dev);
|
||||
}
|
||||
|
||||
static void dpu_kms_prepare_commit(struct msm_kms *kms,
|
||||
struct drm_atomic_state *state)
|
||||
{
|
||||
struct drm_crtc *crtc;
|
||||
struct drm_crtc_state *crtc_state;
|
||||
struct drm_encoder *encoder;
|
||||
int i;
|
||||
|
||||
if (!kms)
|
||||
return;
|
||||
|
||||
/* Call prepare_commit for all affected encoders */
|
||||
for_each_new_crtc_in_state(state, crtc, crtc_state, i) {
|
||||
drm_for_each_encoder_mask(encoder, crtc->dev,
|
||||
crtc_state->encoder_mask) {
|
||||
dpu_encoder_prepare_commit(encoder);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void dpu_kms_flush_commit(struct msm_kms *kms, unsigned crtc_mask)
|
||||
{
|
||||
struct dpu_kms *dpu_kms = to_dpu_kms(kms);
|
||||
@ -939,7 +937,6 @@ static const struct msm_kms_funcs kms_funcs = {
|
||||
.irq = dpu_core_irq,
|
||||
.enable_commit = dpu_kms_enable_commit,
|
||||
.disable_commit = dpu_kms_disable_commit,
|
||||
.prepare_commit = dpu_kms_prepare_commit,
|
||||
.flush_commit = dpu_kms_flush_commit,
|
||||
.wait_flush = dpu_kms_wait_flush,
|
||||
.complete_commit = dpu_kms_complete_commit,
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -18,6 +18,10 @@
|
||||
* struct dpu_plane_state: Define dpu extension of drm plane state object
|
||||
* @base: base drm plane state object
|
||||
* @aspace: pointer to address space for input/output buffers
|
||||
* @pipe: software pipe description
|
||||
* @r_pipe: software pipe description of the second pipe
|
||||
* @pipe_cfg: software pipe configuration
|
||||
* @r_pipe_cfg: software pipe configuration for the second pipe
|
||||
* @stage: assigned by crtc blender
|
||||
* @needs_qos_remap: qos remap settings need to be updated
|
||||
* @multirect_index: index of the rectangle of SSPP
|
||||
@ -31,10 +35,12 @@
|
||||
struct dpu_plane_state {
|
||||
struct drm_plane_state base;
|
||||
struct msm_gem_address_space *aspace;
|
||||
struct dpu_sw_pipe pipe;
|
||||
struct dpu_sw_pipe r_pipe;
|
||||
struct dpu_sw_pipe_cfg pipe_cfg;
|
||||
struct dpu_sw_pipe_cfg r_pipe_cfg;
|
||||
enum dpu_stage stage;
|
||||
bool needs_qos_remap;
|
||||
uint32_t multirect_index;
|
||||
uint32_t multirect_mode;
|
||||
bool pending;
|
||||
|
||||
u64 plane_fetch_bw;
|
||||
@ -44,26 +50,9 @@ struct dpu_plane_state {
|
||||
unsigned int rotation;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct dpu_multirect_plane_states: Defines multirect pair of drm plane states
|
||||
* @r0: drm plane configured on rect 0
|
||||
* @r1: drm plane configured on rect 1
|
||||
*/
|
||||
struct dpu_multirect_plane_states {
|
||||
const struct drm_plane_state *r0;
|
||||
const struct drm_plane_state *r1;
|
||||
};
|
||||
|
||||
#define to_dpu_plane_state(x) \
|
||||
container_of(x, struct dpu_plane_state, base)
|
||||
|
||||
/**
|
||||
* dpu_plane_pipe - return sspp identifier for the given plane
|
||||
* @plane: Pointer to DRM plane object
|
||||
* Returns: sspp identifier of the given plane
|
||||
*/
|
||||
enum dpu_sspp dpu_plane_pipe(struct drm_plane *plane);
|
||||
|
||||
/**
|
||||
* dpu_plane_flush - final plane operations before commit flush
|
||||
* @plane: Pointer to drm plane structure
|
||||
@ -88,19 +77,6 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev,
|
||||
uint32_t pipe, enum drm_plane_type type,
|
||||
unsigned long possible_crtcs);
|
||||
|
||||
/**
|
||||
* dpu_plane_validate_multirecti_v2 - validate the multirect planes
|
||||
* against hw limitations
|
||||
* @plane: drm plate states of the multirect pair
|
||||
*/
|
||||
int dpu_plane_validate_multirect_v2(struct dpu_multirect_plane_states *plane);
|
||||
|
||||
/**
|
||||
* dpu_plane_clear_multirect - clear multirect bits for the given pipe
|
||||
* @drm_state: Pointer to DRM plane state
|
||||
*/
|
||||
void dpu_plane_clear_multirect(const struct drm_plane_state *drm_state);
|
||||
|
||||
/**
|
||||
* dpu_plane_color_fill - enables color fill on plane
|
||||
* @plane: Pointer to DRM plane object
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "dpu_hw_lm.h"
|
||||
#include "dpu_hw_ctl.h"
|
||||
#include "dpu_hw_pingpong.h"
|
||||
#include "dpu_hw_sspp.h"
|
||||
#include "dpu_hw_intf.h"
|
||||
#include "dpu_hw_wb.h"
|
||||
#include "dpu_hw_dspp.h"
|
||||
@ -91,6 +92,9 @@ int dpu_rm_destroy(struct dpu_rm *rm)
|
||||
for (i = 0; i < ARRAY_SIZE(rm->hw_wb); i++)
|
||||
dpu_hw_wb_destroy(rm->hw_wb[i]);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(rm->hw_sspp); i++)
|
||||
dpu_hw_sspp_destroy(rm->hw_sspp[i]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -255,6 +259,24 @@ int dpu_rm_init(struct dpu_rm *rm,
|
||||
rm->dsc_blks[dsc->id - DSC_0] = &hw->base;
|
||||
}
|
||||
|
||||
for (i = 0; i < cat->sspp_count; i++) {
|
||||
struct dpu_hw_sspp *hw;
|
||||
const struct dpu_sspp_cfg *sspp = &cat->sspp[i];
|
||||
|
||||
if (sspp->id < SSPP_NONE || sspp->id >= SSPP_MAX) {
|
||||
DPU_ERROR("skip intf %d with invalid id\n", sspp->id);
|
||||
continue;
|
||||
}
|
||||
|
||||
hw = dpu_hw_sspp_init(sspp->id, mmio, cat);
|
||||
if (IS_ERR(hw)) {
|
||||
rc = PTR_ERR(hw);
|
||||
DPU_ERROR("failed sspp object creation: err %d\n", rc);
|
||||
goto fail;
|
||||
}
|
||||
rm->hw_sspp[sspp->id - SSPP_NONE] = hw;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
|
@ -21,6 +21,7 @@ struct dpu_global_state;
|
||||
* @hw_intf: array of intf hardware resources
|
||||
* @hw_wb: array of wb hardware resources
|
||||
* @dspp_blks: array of dspp hardware resources
|
||||
* @hw_sspp: array of sspp hardware resources
|
||||
*/
|
||||
struct dpu_rm {
|
||||
struct dpu_hw_blk *pingpong_blks[PINGPONG_MAX - PINGPONG_0];
|
||||
@ -31,6 +32,7 @@ struct dpu_rm {
|
||||
struct dpu_hw_blk *dspp_blks[DSPP_MAX - DSPP_0];
|
||||
struct dpu_hw_blk *merge_3d_blks[MERGE_3D_MAX - MERGE_3D_0];
|
||||
struct dpu_hw_blk *dsc_blks[DSC_MAX - DSC_0];
|
||||
struct dpu_hw_sspp *hw_sspp[SSPP_MAX - SSPP_NONE];
|
||||
};
|
||||
|
||||
/**
|
||||
@ -108,5 +110,15 @@ static inline struct dpu_hw_wb *dpu_rm_get_wb(struct dpu_rm *rm, enum dpu_wb wb_
|
||||
return rm->hw_wb[wb_idx - WB_0];
|
||||
}
|
||||
|
||||
/**
|
||||
* dpu_rm_get_sspp - Return a struct dpu_hw_sspp instance given it's index.
|
||||
* @rm: DPU Resource Manager handle
|
||||
* @sspp_idx: SSPP index
|
||||
*/
|
||||
static inline struct dpu_hw_sspp *dpu_rm_get_sspp(struct dpu_rm *rm, enum dpu_sspp sspp_idx)
|
||||
{
|
||||
return rm->hw_sspp[sspp_idx - SSPP_NONE];
|
||||
}
|
||||
|
||||
#endif /* __DPU_RM_H__ */
|
||||
|
||||
|
@ -633,9 +633,9 @@ TRACE_EVENT(dpu_enc_phys_vid_irq_ctrl,
|
||||
TRACE_EVENT(dpu_crtc_setup_mixer,
|
||||
TP_PROTO(uint32_t crtc_id, uint32_t plane_id,
|
||||
struct drm_plane_state *state, struct dpu_plane_state *pstate,
|
||||
uint32_t stage_idx, enum dpu_sspp sspp, uint32_t pixel_format,
|
||||
uint32_t stage_idx, uint32_t pixel_format,
|
||||
uint64_t modifier),
|
||||
TP_ARGS(crtc_id, plane_id, state, pstate, stage_idx, sspp,
|
||||
TP_ARGS(crtc_id, plane_id, state, pstate, stage_idx,
|
||||
pixel_format, modifier),
|
||||
TP_STRUCT__entry(
|
||||
__field( uint32_t, crtc_id )
|
||||
@ -659,9 +659,9 @@ TRACE_EVENT(dpu_crtc_setup_mixer,
|
||||
__entry->dst_rect = drm_plane_state_dest(state);
|
||||
__entry->stage_idx = stage_idx;
|
||||
__entry->stage = pstate->stage;
|
||||
__entry->sspp = sspp;
|
||||
__entry->multirect_idx = pstate->multirect_index;
|
||||
__entry->multirect_mode = pstate->multirect_mode;
|
||||
__entry->sspp = pstate->pipe.sspp->idx;
|
||||
__entry->multirect_idx = pstate->pipe.multirect_index;
|
||||
__entry->multirect_mode = pstate->pipe.multirect_mode;
|
||||
__entry->pixel_format = pixel_format;
|
||||
__entry->modifier = modifier;
|
||||
),
|
||||
@ -762,18 +762,17 @@ TRACE_EVENT(dpu_crtc_disable_frame_pending,
|
||||
);
|
||||
|
||||
TRACE_EVENT(dpu_plane_set_scanout,
|
||||
TP_PROTO(enum dpu_sspp index, struct dpu_hw_fmt_layout *layout,
|
||||
enum dpu_sspp_multirect_index multirect_index),
|
||||
TP_ARGS(index, layout, multirect_index),
|
||||
TP_PROTO(struct dpu_sw_pipe *pipe, struct dpu_hw_fmt_layout *layout),
|
||||
TP_ARGS(pipe, layout),
|
||||
TP_STRUCT__entry(
|
||||
__field( enum dpu_sspp, index )
|
||||
__field_struct( struct dpu_hw_fmt_layout, layout )
|
||||
__field( enum dpu_sspp_multirect_index, multirect_index)
|
||||
),
|
||||
TP_fast_assign(
|
||||
__entry->index = index;
|
||||
__entry->index = pipe->sspp->idx;
|
||||
__entry->layout = *layout;
|
||||
__entry->multirect_index = multirect_index;
|
||||
__entry->multirect_index = pipe->multirect_index;
|
||||
),
|
||||
TP_printk("index:%d layout:{%ux%u @ [%u/%u, %u/%u, %u/%u, %u/%u]} "
|
||||
"multirect_index:%d", __entry->index, __entry->layout.width,
|
||||
|
@ -179,6 +179,24 @@ static unsigned get_crtc_mask(struct drm_atomic_state *state)
|
||||
return mask;
|
||||
}
|
||||
|
||||
int msm_atomic_check(struct drm_device *dev, struct drm_atomic_state *state)
|
||||
{
|
||||
struct drm_crtc_state *old_crtc_state, *new_crtc_state;
|
||||
struct drm_crtc *crtc;
|
||||
int i;
|
||||
|
||||
for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state,
|
||||
new_crtc_state, i) {
|
||||
if ((old_crtc_state->ctm && !new_crtc_state->ctm) ||
|
||||
(!old_crtc_state->ctm && new_crtc_state->ctm)) {
|
||||
new_crtc_state->mode_changed = true;
|
||||
state->allow_modeset = true;
|
||||
}
|
||||
}
|
||||
|
||||
return drm_atomic_helper_check(dev, state);
|
||||
}
|
||||
|
||||
void msm_atomic_commit_tail(struct drm_atomic_state *state)
|
||||
{
|
||||
struct drm_device *dev = state->dev;
|
||||
|
@ -58,7 +58,7 @@ static void msm_deinit_vram(struct drm_device *ddev);
|
||||
|
||||
static const struct drm_mode_config_funcs mode_config_funcs = {
|
||||
.fb_create = msm_framebuffer_create,
|
||||
.atomic_check = drm_atomic_helper_check,
|
||||
.atomic_check = msm_atomic_check,
|
||||
.atomic_commit = drm_atomic_helper_commit,
|
||||
};
|
||||
|
||||
|
@ -258,6 +258,7 @@ int msm_atomic_init_pending_timer(struct msm_pending_timer *timer,
|
||||
struct msm_kms *kms, int crtc_idx);
|
||||
void msm_atomic_destroy_pending_timer(struct msm_pending_timer *timer);
|
||||
void msm_atomic_commit_tail(struct drm_atomic_state *state);
|
||||
int msm_atomic_check(struct drm_device *dev, struct drm_atomic_state *state);
|
||||
struct drm_atomic_state *msm_atomic_state_alloc(struct drm_device *dev);
|
||||
void msm_atomic_state_clear(struct drm_atomic_state *state);
|
||||
void msm_atomic_state_free(struct drm_atomic_state *state);
|
||||
|
Loading…
x
Reference in New Issue
Block a user