summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLiu Ying <victor.liu@nxp.com>2019-11-11 16:57:57 +0800
committerDong Aisheng <aisheng.dong@nxp.com>2019-11-25 15:58:12 +0800
commited071c82ec98ea6c06b327aded6915d8680c9173 (patch)
tree6c7e677c51d8081b11e06556ce2a6120a20aa100
parent95dea9fe254d55da8ff75ab2edadfd93adc4f0c3 (diff)
drm/imx: dpu: kms: Support full screen CRTC background
The CRTC background should be full screen instead of partial screen, because the DRM core is likely to add configurable background color support in the future. We may cover the full screen with ConstFrame0/1, upon which builds planes. With this, it is easier to compute each plane's layer offset vs CRTC start point and all ConstFrame units can be controlled by CRTC. Signed-off-by: Liu Ying <victor.liu@nxp.com>
-rw-r--r--drivers/gpu/drm/imx/dpu/dpu-crtc.c23
-rw-r--r--drivers/gpu/drm/imx/dpu/dpu-crtc.h3
-rw-r--r--drivers/gpu/drm/imx/dpu/dpu-kms.c42
-rw-r--r--drivers/gpu/drm/imx/dpu/dpu-plane.c37
-rw-r--r--drivers/gpu/imx/dpu/dpu-common.c9
-rw-r--r--drivers/gpu/imx/dpu/dpu-framegen.c9
-rw-r--r--include/video/dpu.h2
7 files changed, 23 insertions, 102 deletions
diff --git a/drivers/gpu/drm/imx/dpu/dpu-crtc.c b/drivers/gpu/drm/imx/dpu/dpu-crtc.c
index 8d8878ff44ac..db423af5cd11 100644
--- a/drivers/gpu/drm/imx/dpu/dpu-crtc.c
+++ b/drivers/gpu/drm/imx/dpu/dpu-crtc.c
@@ -528,8 +528,11 @@ static void dpu_crtc_mode_set_nofb(struct drm_crtc *crtc)
tcon_cfg_videomode(dpu_crtc->tcon, mode);
tcon_set_fmt(dpu_crtc->tcon, imx_crtc_state->bus_format);
- constframe_framedimensions(dpu_crtc->cf,
+ constframe_framedimensions(dpu_crtc->pa_cf,
mode->crtc_hdisplay, mode->crtc_vdisplay);
+ constframe_framedimensions(dpu_crtc->sa_cf,
+ mode->crtc_hdisplay, mode->crtc_vdisplay);
+ constframe_constantcolor(dpu_crtc->sa_cf, 0, 0, 0, 0);
ed_src = dpu_crtc->stream_id ? ED_SRC_CONSTFRAME5 : ED_SRC_CONSTFRAME4;
extdst_pixengcfg_src_sel(dpu_crtc->ed, ed_src);
@@ -550,8 +553,10 @@ static const struct drm_crtc_helper_funcs dpu_helper_funcs = {
static void dpu_crtc_put_resources(struct dpu_crtc *dpu_crtc)
{
- if (!IS_ERR_OR_NULL(dpu_crtc->cf))
- dpu_cf_put(dpu_crtc->cf);
+ if (!IS_ERR_OR_NULL(dpu_crtc->pa_cf))
+ dpu_cf_put(dpu_crtc->pa_cf);
+ if (!IS_ERR_OR_NULL(dpu_crtc->sa_cf))
+ dpu_cf_put(dpu_crtc->sa_cf);
if (!IS_ERR_OR_NULL(dpu_crtc->dec))
dpu_dec_put(dpu_crtc->dec);
if (!IS_ERR_OR_NULL(dpu_crtc->ed))
@@ -568,9 +573,15 @@ static int dpu_crtc_get_resources(struct dpu_crtc *dpu_crtc)
unsigned int stream_id = dpu_crtc->stream_id;
int ret;
- dpu_crtc->cf = dpu_cf_get(dpu, stream_id + 4);
- if (IS_ERR(dpu_crtc->cf)) {
- ret = PTR_ERR(dpu_crtc->cf);
+ dpu_crtc->pa_cf = dpu_cf_get(dpu, stream_id + 4);
+ if (IS_ERR(dpu_crtc->pa_cf)) {
+ ret = PTR_ERR(dpu_crtc->pa_cf);
+ goto err_out;
+ }
+
+ dpu_crtc->sa_cf = dpu_cf_get(dpu, stream_id);
+ if (IS_ERR(dpu_crtc->sa_cf)) {
+ ret = PTR_ERR(dpu_crtc->sa_cf);
goto err_out;
}
diff --git a/drivers/gpu/drm/imx/dpu/dpu-crtc.h b/drivers/gpu/drm/imx/dpu/dpu-crtc.h
index 5b7ca7fccdb2..05c170069421 100644
--- a/drivers/gpu/drm/imx/dpu/dpu-crtc.h
+++ b/drivers/gpu/drm/imx/dpu/dpu-crtc.h
@@ -24,7 +24,8 @@ struct dpu_crtc {
struct device *dev;
struct drm_crtc base;
struct imx_drm_crtc *imx_crtc;
- struct dpu_constframe *cf;
+ struct dpu_constframe *pa_cf;
+ struct dpu_constframe *sa_cf;
struct dpu_disengcfg *dec;
struct dpu_extdst *ed;
struct dpu_framegen *fg;
diff --git a/drivers/gpu/drm/imx/dpu/dpu-kms.c b/drivers/gpu/drm/imx/dpu/dpu-kms.c
index 35997c6b7feb..0667ffec573b 100644
--- a/drivers/gpu/drm/imx/dpu/dpu-kms.c
+++ b/drivers/gpu/drm/imx/dpu/dpu-kms.c
@@ -65,44 +65,6 @@ static int dpu_atomic_sort_planes_per_crtc(struct drm_crtc_state *crtc_state,
}
static void
-dpu_atomic_compute_plane_base_per_crtc(struct drm_plane_state **states, int n)
-{
- struct dpu_plane_state *dpstate;
- int i, left, right, top, bottom, tmp;
-
- /* compute the plane base */
- left = states[0]->crtc_x;
- top = states[0]->crtc_y;
- right = states[0]->crtc_x + states[0]->crtc_w;
- bottom = states[0]->crtc_y + states[0]->crtc_h;
-
- for (i = 1; i < n; i++) {
- left = min(states[i]->crtc_x, left);
- top = min(states[i]->crtc_y, top);
-
- tmp = states[i]->crtc_x + states[i]->crtc_w;
- right = max(tmp, right);
-
- tmp = states[i]->crtc_y + states[i]->crtc_h;
- bottom = max(tmp, bottom);
- }
-
- /* BTW, be smart to compute the layer offset */
- for (i = 0; i < n; i++) {
- dpstate = to_dpu_plane_state(states[i]);
- dpstate->layer_x = states[i]->crtc_x - left;
- dpstate->layer_y = states[i]->crtc_y - top;
- }
-
- /* finally, store the base in plane state */
- dpstate = to_dpu_plane_state(states[0]);
- dpstate->base_x = left;
- dpstate->base_y = top;
- dpstate->base_w = right - left;
- dpstate->base_h = bottom - top;
-}
-
-static void
dpu_atomic_set_top_plane_per_crtc(struct drm_plane_state **states, int n)
{
struct dpu_plane_state *dpstate;
@@ -370,8 +332,7 @@ dpu_atomic_put_possible_states_per_crtc(struct drm_crtc_state *crtc_state)
/*
* Should be enough to check the below real HW plane
* resources only.
- * Vproc resources and things like layer_x/y should
- * be fine.
+ * Things like vproc resources should be fine.
*/
if (old_dpstate->stage != new_dpstate->stage ||
old_dpstate->source != new_dpstate->source ||
@@ -541,7 +502,6 @@ static int dpu_drm_atomic_check(struct drm_device *dev,
return -EINVAL;
}
- dpu_atomic_compute_plane_base_per_crtc(states, n);
dpu_atomic_set_top_plane_per_crtc(states, n);
ret = dpu_atomic_assign_plane_source_per_crtc(states, n);
diff --git a/drivers/gpu/drm/imx/dpu/dpu-plane.c b/drivers/gpu/drm/imx/dpu/dpu-plane.c
index 520354ffc5be..b75c194d0ba4 100644
--- a/drivers/gpu/drm/imx/dpu/dpu-plane.c
+++ b/drivers/gpu/drm/imx/dpu/dpu-plane.c
@@ -115,12 +115,6 @@ dpu_drm_atomic_plane_duplicate_state(struct drm_plane *plane)
copy->stage = state->stage;
copy->source = state->source;
copy->blend = state->blend;
- copy->layer_x = state->layer_x;
- copy->layer_y = state->layer_y;
- copy->base_x = state->base_x;
- copy->base_y = state->base_y;
- copy->base_w = state->base_w;
- copy->base_h = state->base_h;
copy->is_top = state->is_top;
copy->use_prefetch = state->use_prefetch;
@@ -226,7 +220,6 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
{
struct dpu_plane *dplane = to_dpu_plane(plane);
struct dpu_plane_state *dpstate = to_dpu_plane_state(state);
- struct dpu_plane_state *old_dpstate = to_dpu_plane_state(plane->state);
struct dpu_plane_res *res = &dplane->grp->res;
struct drm_crtc_state *crtc_state;
struct drm_framebuffer *fb = state->fb;
@@ -237,23 +230,11 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
int min_scale, bpp, ret;
bool fb_is_interlaced;
- /* pure software check */
- if (plane->type != DRM_PLANE_TYPE_PRIMARY)
- if (WARN_ON(dpstate->base_x || dpstate->base_y ||
- dpstate->base_w || dpstate->base_h))
- return -EINVAL;
-
/* ok to disable */
if (!fb) {
dpstate->stage = LB_PRIM_SEL__DISABLE;
dpstate->source = LB_SEC_SEL__DISABLE;
dpstate->blend = ID_NONE;
- dpstate->layer_x = 0;
- dpstate->layer_y = 0;
- dpstate->base_x = 0;
- dpstate->base_y = 0;
- dpstate->base_w = 0;
- dpstate->base_h = 0;
dpstate->is_top = false;
dpstate->use_prefetch = false;
return 0;
@@ -299,12 +280,6 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
return ret;
}
- /* mode set is needed when base x/y is changed */
- if (plane->type == DRM_PLANE_TYPE_PRIMARY)
- if ((dpstate->base_x != old_dpstate->base_x) ||
- (dpstate->base_y != old_dpstate->base_y))
- crtc_state->mode_changed = true;
-
/* no off screen */
if (state->dst.x1 < 0 || state->dst.y1 < 0 ||
(state->dst.x2 > crtc_state->adjusted_mode.hdisplay) ||
@@ -513,7 +488,6 @@ static void dpu_plane_atomic_update(struct drm_plane *plane,
struct dpu_hscaler *hs = NULL;
struct dpu_vscaler *vs = NULL;
struct dpu_layerblend *lb;
- struct dpu_constframe *cf;
struct dpu_extdst *ed;
struct dpu_framegen *fg;
dma_addr_t baseaddr, uv_baseaddr = 0;
@@ -764,16 +738,7 @@ static void dpu_plane_atomic_update(struct drm_plane *plane,
layerblend_control(lb, LB_BLEND);
layerblend_blendcontrol(lb, need_hscaler || need_vscaler);
layerblend_pixengcfg_clken(lb, CLKEN__AUTOMATIC);
- layerblend_position(lb, dpstate->layer_x, dpstate->layer_y);
-
- if (plane->type == DRM_PLANE_TYPE_PRIMARY) {
- cf = res->cf[dplane->stream_id];
- constframe_framedimensions(cf,
- dpstate->base_w, dpstate->base_h);
- constframe_constantcolor(cf, 0, 0, 0, 0);
-
- framegen_sacfg(fg, dpstate->base_x, dpstate->base_y);
- }
+ layerblend_position(lb, state->crtc_x, state->crtc_y);
if (dpstate->is_top) {
ed = res->ed[dplane->stream_id];
diff --git a/drivers/gpu/imx/dpu/dpu-common.c b/drivers/gpu/imx/dpu/dpu-common.c
index aeba0fb24364..dc51af5265d4 100644
--- a/drivers/gpu/imx/dpu/dpu-common.c
+++ b/drivers/gpu/imx/dpu/dpu-common.c
@@ -816,11 +816,6 @@ static int dpu_get_plane_resource(struct dpu_soc *dpu,
struct dpu_plane_grp *grp = plane_res_to_grp(res);
int i;
- for (i = 0; i < ARRAY_SIZE(res->cf); i++) {
- res->cf[i] = dpu_cf_get(dpu, i);
- if (IS_ERR(res->cf[i]))
- return PTR_ERR(res->cf[i]);
- }
for (i = 0; i < ARRAY_SIZE(res->ed); i++) {
res->ed[i] = dpu_ed_get(dpu, i);
if (IS_ERR(res->ed[i]))
@@ -881,10 +876,6 @@ static void dpu_put_plane_resource(struct dpu_plane_res *res)
struct dpu_plane_grp *grp = plane_res_to_grp(res);
int i;
- for (i = 0; i < ARRAY_SIZE(res->cf); i++) {
- if (!IS_ERR_OR_NULL(res->cf[i]))
- dpu_cf_put(res->cf[i]);
- }
for (i = 0; i < ARRAY_SIZE(res->ed); i++) {
if (!IS_ERR_OR_NULL(res->ed[i]))
dpu_ed_put(res->ed[i]);
diff --git a/drivers/gpu/imx/dpu/dpu-framegen.c b/drivers/gpu/imx/dpu/dpu-framegen.c
index ad88c3885e41..de2a7e427b60 100644
--- a/drivers/gpu/imx/dpu/dpu-framegen.c
+++ b/drivers/gpu/imx/dpu/dpu-framegen.c
@@ -193,8 +193,9 @@ void framegen_cfg_videomode(struct dpu_framegen *fg, struct drm_display_mode *m,
/* skikconfig */
dpu_fg_write(fg, SKICKCONFIG, COL(kick_col) | ROW(kick_row) | EN);
- /* primary position config */
+ /* primary and secondary area position config */
dpu_fg_write(fg, PACFG, STARTX(0) | STARTY(0));
+ dpu_fg_write(fg, SACFG, STARTX(0) | STARTY(0));
/* alpha */
val = dpu_fg_read(fg, FGINCTRL);
@@ -248,12 +249,6 @@ void framegen_pkickconfig(struct dpu_framegen *fg, bool enable)
}
EXPORT_SYMBOL_GPL(framegen_pkickconfig);
-void framegen_sacfg(struct dpu_framegen *fg, unsigned int x, unsigned int y)
-{
- dpu_fg_write(fg, SACFG, STARTX(x) | STARTY(y));
-}
-EXPORT_SYMBOL_GPL(framegen_sacfg);
-
void framegen_displaymode(struct dpu_framegen *fg, fgdm_t mode)
{
u32 val;
diff --git a/include/video/dpu.h b/include/video/dpu.h
index 174985cde429..2ab8186e2040 100644
--- a/include/video/dpu.h
+++ b/include/video/dpu.h
@@ -492,7 +492,6 @@ void framegen_syncmode(struct dpu_framegen *fg, fgsyncmode_t mode);
void framegen_cfg_videomode(struct dpu_framegen *fg, struct drm_display_mode *m,
unsigned int encoder_type);
void framegen_pkickconfig(struct dpu_framegen *fg, bool enable);
-void framegen_sacfg(struct dpu_framegen *fg, unsigned int x, unsigned int y);
void framegen_displaymode(struct dpu_framegen *fg, fgdm_t mode);
void framegen_panic_displaymode(struct dpu_framegen *fg, fgdm_t mode);
void framegen_wait_done(struct dpu_framegen *fg, struct drm_display_mode *m);
@@ -627,7 +626,6 @@ bool fetchunit_is_fetchwarp(struct dpu_fetchunit *fu);
#define DPU_PLANE_SRC_DISABLED 0
struct dpu_plane_res {
- struct dpu_constframe *cf[2];
struct dpu_extdst *ed[2];
struct dpu_fetchunit *fd[2];
struct dpu_fetchunit *fe[2];