struct drm_encoder *encoder;
struct dpu_plane *dplane = to_dpu_plane(crtc->primary);
struct dpu_plane_res *res = &dplane->grp->res;
- struct dpu_constframe *cf;
+ struct dpu_constframe *pa_cf, *sa_cf;
struct dpu_disengcfg *dec;
struct dpu_extdst *ed, *plane_ed;
struct dpu_framegen *fg;
again:
if (cfg_aux_pipe) {
- cf = dpu_crtc->aux_cf;
+ pa_cf = dpu_crtc->aux_pa_cf;
+ sa_cf = dpu_crtc->aux_sa_cf;
dec = dpu_crtc->aux_dec;
ed = dpu_crtc->aux_ed;
fg = dpu_crtc->aux_fg;
st = aux_dpu_crtc->st;
stream_id = dpu_crtc->stream_id ^ 1;
} else {
- cf = dpu_crtc->cf;
+ pa_cf = dpu_crtc->pa_cf;
+ sa_cf = dpu_crtc->sa_cf;
dec = dpu_crtc->dec;
ed = dpu_crtc->ed;
fg = dpu_crtc->fg;
disengcfg_polarity_ctrl(dec, mode->flags);
- constframe_framedimensions(cf, crtc_hdisplay, mode->crtc_vdisplay);
+ constframe_framedimensions(pa_cf, crtc_hdisplay, mode->crtc_vdisplay);
+ constframe_framedimensions(sa_cf, crtc_hdisplay, mode->crtc_vdisplay);
+ constframe_constantcolor(sa_cf, 0, 0, 0, 0);
ed_src = stream_id ? ED_SRC_CONSTFRAME5 : ED_SRC_CONSTFRAME4;
extdst_pixengcfg_src_sel(ed, ed_src);
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))
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->aux_cf = dpu_aux_cf_peek(dpu_crtc->cf);
+ dpu_crtc->aux_pa_cf = dpu_aux_cf_peek(dpu_crtc->pa_cf);
+
+ 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;
+ }
+ dpu_crtc->aux_sa_cf = dpu_aux_cf_peek(dpu_crtc->sa_cf);
dpu_crtc->dec = dpu_dec_get(dpu, stream_id);
if (IS_ERR(dpu_crtc->dec)) {
dpu_crtc->aux_tcon = dpu_aux_tcon_peek(dpu_crtc->tcon);
if (dpu_crtc->aux_is_master) {
- dpu_crtc->m_cf = dpu_crtc->aux_cf;
+ dpu_crtc->m_pa_cf = dpu_crtc->aux_pa_cf;
+ dpu_crtc->m_sa_cf = dpu_crtc->aux_sa_cf;
dpu_crtc->m_dec = dpu_crtc->aux_dec;
dpu_crtc->m_ed = dpu_crtc->aux_ed;
dpu_crtc->m_fg = dpu_crtc->aux_fg;
dpu_crtc->m_tcon = dpu_crtc->aux_tcon;
- dpu_crtc->s_cf = dpu_crtc->cf;
+ dpu_crtc->s_pa_cf = dpu_crtc->pa_cf;
+ dpu_crtc->s_sa_cf = dpu_crtc->sa_cf;
dpu_crtc->s_dec = dpu_crtc->dec;
dpu_crtc->s_ed = dpu_crtc->ed;
dpu_crtc->s_fg = dpu_crtc->fg;
dpu_crtc->s_tcon = dpu_crtc->tcon;
} else {
- dpu_crtc->m_cf = dpu_crtc->cf;
+ dpu_crtc->m_pa_cf = dpu_crtc->pa_cf;
+ dpu_crtc->m_sa_cf = dpu_crtc->sa_cf;
dpu_crtc->m_dec = dpu_crtc->dec;
dpu_crtc->m_ed = dpu_crtc->ed;
dpu_crtc->m_fg = dpu_crtc->fg;
dpu_crtc->m_tcon = dpu_crtc->tcon;
- dpu_crtc->s_cf = dpu_crtc->aux_cf;
+ dpu_crtc->s_pa_cf = dpu_crtc->aux_pa_cf;
+ dpu_crtc->s_sa_cf = dpu_crtc->aux_sa_cf;
dpu_crtc->s_dec = dpu_crtc->aux_dec;
dpu_crtc->s_ed = dpu_crtc->aux_ed;
dpu_crtc->s_fg = dpu_crtc->aux_fg;
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;
struct dpu_signature *sig;
struct dpu_tcon *tcon;
struct dpu_store *st;
- struct dpu_constframe *aux_cf;
+ struct dpu_constframe *aux_pa_cf;
+ struct dpu_constframe *aux_sa_cf;
struct dpu_disengcfg *aux_dec;
struct dpu_extdst *aux_ed;
struct dpu_framegen *aux_fg;
struct dpu_signature *aux_sig;
struct dpu_tcon *aux_tcon;
/* master */
- struct dpu_constframe *m_cf;
+ struct dpu_constframe *m_pa_cf;
+ struct dpu_constframe *m_sa_cf;
struct dpu_disengcfg *m_dec;
struct dpu_extdst *m_ed;
struct dpu_framegen *m_fg;
struct dpu_tcon *m_tcon;
/* slave */
- struct dpu_constframe *s_cf;
+ struct dpu_constframe *s_pa_cf;
+ struct dpu_constframe *s_sa_cf;
struct dpu_disengcfg *s_dec;
struct dpu_extdst *s_ed;
struct dpu_framegen *s_fg;
return n;
}
-static int
-dpu_atomic_compute_plane_base_per_crtc(struct drm_crtc_state *crtc_state,
- struct drm_plane_state **states, int n,
- bool use_pc)
+static void
+dpu_atomic_compute_plane_lrx_per_crtc(struct drm_crtc_state *crtc_state,
+ struct drm_plane_state **states, int n)
{
struct dpu_plane_state *dpstate;
- int i, left, right, top, bottom, tmp;
- int base_x, base_y, base_w, base_h;
+ struct drm_plane_state *plane_state;
+ int i;
int half_hdisplay = crtc_state->adjusted_mode.hdisplay >> 1;
bool lo, ro, bo;
- /* 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;
- }
-
- /* store the base in plane state */
- dpstate = to_dpu_plane_state(states[0]);
- base_x = left;
- base_y = top;
- base_w = right - left;
- base_h = bottom - top;
- dpstate->base_x = base_x;
- dpstate->base_y = base_y;
- dpstate->base_w = base_w;
- dpstate->base_h = base_h;
-
- if (!use_pc)
- return 0;
-
- /* compute left/right_layer/base_x/w if pixel combiner is needed */
+ /* compute left/right_crtc_x if pixel combiner is needed */
for (i = 0; i < n; i++) {
- dpstate = to_dpu_plane_state(states[i]);
+ plane_state = states[i];
+ dpstate = to_dpu_plane_state(plane_state);
lo = dpstate->left_src_w && !dpstate->right_src_w;
ro = !dpstate->left_src_w && dpstate->right_src_w;
bo = dpstate->left_src_w && dpstate->right_src_w;
if (lo || bo) {
- dpstate->left_layer_x = dpstate->layer_x;
- dpstate->right_layer_x = 0;
+ dpstate->left_crtc_x = plane_state->crtc_x;
+ dpstate->right_crtc_x = 0;
} else if (ro) {
- dpstate->left_layer_x = 0;
- dpstate->right_layer_x =
- states[i]->crtc_x - half_hdisplay;
- }
-
- if (i)
- continue;
-
- if (base_x < half_hdisplay) {
- dpstate->left_base_x = base_x;
- dpstate->right_base_x = 0;
-
- if ((base_x + base_w) < half_hdisplay) {
- dpstate->left_base_w = base_w;
- dpstate->right_base_w = 0;
- } else {
- dpstate->left_base_w = half_hdisplay - base_x;
- dpstate->right_base_w =
- base_x + base_w - half_hdisplay;
- }
- } else {
- dpstate->left_base_x = 0;
- dpstate->right_base_x = base_x - half_hdisplay;
-
- dpstate->left_base_w = 0;
- dpstate->right_base_w = base_w;
+ dpstate->left_crtc_x = 0;
+ dpstate->right_crtc_x =
+ plane_state->crtc_x - half_hdisplay;
}
}
-
- return 0;
}
static void
/*
* 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 ||
return -EINVAL;
}
- ret = dpu_atomic_compute_plane_base_per_crtc(crtc_state, states,
- n, use_pc[dpu_crtc->crtc_grp_id]);
- if (ret) {
- kfree(states);
- return ret;
- }
+ if (use_pc[dpu_crtc->crtc_grp_id])
+ dpu_atomic_compute_plane_lrx_per_crtc(crtc_state,
+ states, n);
dpu_atomic_set_top_plane_per_crtc(states, n,
use_pc[dpu_crtc->crtc_grp_id]);
copy->aux_stage = state->aux_stage;
copy->aux_source = state->aux_source;
copy->aux_blend = state->aux_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;
copy->use_aux_prefetch = state->use_aux_prefetch;
copy->need_aux_source = state->need_aux_source;
- copy->left_layer_x = state->left_layer_x;
- copy->left_base_x = state->left_base_x;
- copy->left_base_w = state->left_base_w;
copy->left_src_w = state->left_src_w;
copy->left_crtc_w = state->left_crtc_w;
- copy->right_layer_x = state->right_layer_x;
- copy->right_base_x = state->right_base_x;
- copy->right_base_w = state->right_base_w;
+ copy->left_crtc_x = state->left_crtc_x;
copy->right_src_w = state->right_src_w;
copy->right_crtc_w = state->right_crtc_w;
+ copy->right_crtc_x = state->right_crtc_x;
copy->is_left_top = state->is_left_top;
copy->is_right_top = state->is_right_top;
{
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;
bool fb_is_interlaced;
bool check_aux_source = false;
- /* 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->aux_stage = LB_PRIM_SEL__DISABLE;
dpstate->aux_source = LB_SEC_SEL__DISABLE;
dpstate->aux_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;
dpstate->use_aux_prefetch = false;
dpstate->need_aux_source = false;
- dpstate->left_layer_x = 0;
- dpstate->left_base_x = 0;
- dpstate->left_base_w = 0;
dpstate->left_src_w = 0;
dpstate->left_crtc_w = 0;
- dpstate->right_layer_x = 0;
- dpstate->right_base_x = 0;
- dpstate->right_base_w = 0;
+ dpstate->left_crtc_x = 0;
dpstate->right_src_w = 0;
dpstate->right_crtc_w = 0;
+ dpstate->right_crtc_x = 0;
dpstate->is_left_top = false;
dpstate->is_right_top = false;
return 0;
if (WARN_ON(!crtc_state))
return -EINVAL;
- /* 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;
-
if (state->crtc_x + state->crtc_w >
crtc_state->adjusted_mode.hdisplay)
return -EINVAL;
struct dpu_hscaler *hs = NULL;
struct dpu_vscaler *vs = NULL;
struct dpu_layerblend *lb;
- struct dpu_constframe *cf, *aux_cf;
struct dpu_extdst *ed;
- struct dpu_framegen *fg, *aux_fg;
+ struct dpu_framegen *fg;
struct device *dev = plane->dev->dev;
dma_addr_t baseaddr, uv_baseaddr = 0;
dpu_block_id_t blend, fe_id, vs_id = ID_NONE, hs_id;
lb_prim_sel_t stage;
unsigned int stream_id;
unsigned int src_w, src_h, src_x, src_y;
- unsigned int layer_x;
+ unsigned int crtc_x;
unsigned int mt_w = 0, mt_h = 0; /* w/h in a micro-tile */
int bpp, lb_id;
bool need_fetcheco, need_hscaler = false, need_vscaler = false;
if (crtc_use_pc) {
if (update_aux_source) {
stream_id = 1;
- layer_x = dpstate->right_layer_x;
+ crtc_x = dpstate->right_crtc_x;
} else {
stream_id = dpstate->left_src_w ? 0 : 1;
- layer_x = dpstate->left_src_w ?
- dpstate->left_layer_x : dpstate->right_layer_x;
+ crtc_x = dpstate->left_src_w ?
+ dpstate->left_crtc_x : dpstate->right_crtc_x;
}
} else {
stream_id = dplane->stream_id;
- layer_x = dpstate->layer_x;
+ crtc_x = state->crtc_x;
}
fg = res->fg[stream_id];
layerblend_control(lb, LB_BLEND);
layerblend_blendcontrol(lb, need_hscaler || need_vscaler);
layerblend_pixengcfg_clken(lb, CLKEN__AUTOMATIC);
- layerblend_position(lb, layer_x, dpstate->layer_y);
-
- if (plane->type == DRM_PLANE_TYPE_PRIMARY) {
- unsigned int base_w, base_x;
-
- cf = res->cf[stream_id];
-
- if (crtc_use_pc) {
- if (update_aux_source || !dpstate->left_crtc_w) {
- base_w = dpstate->right_base_w;
- base_x = dpstate->right_base_x;
- } else {
- base_w = dpstate->left_base_w;
- base_x = dpstate->left_base_x;
- }
-
- if (!dpstate->left_crtc_w || !dpstate->right_crtc_w) {
- aux_cf = dpu_aux_cf_peek(cf);
- aux_fg = dpu_aux_fg_peek(fg);
-
- constframe_framedimensions_copy_prim(aux_cf);
- constframe_constantcolor(aux_cf, 0, 0, 0, 0);
-
- framegen_sacfg(aux_fg, 0, 0);
- }
- } else {
- base_w = dpstate->base_w;
- base_x = dpstate->base_x;
- }
-
- constframe_framedimensions(cf, base_w, dpstate->base_h);
- constframe_constantcolor(cf, 0, 0, 0, 0);
-
- framegen_sacfg(fg, base_x, dpstate->base_y);
- }
+ layerblend_position(lb, crtc_x, state->crtc_y);
if (crtc_use_pc) {
if ((!stream_id && dpstate->is_left_top) ||
lb_prim_sel_t aux_stage;
lb_sec_sel_t aux_source;
dpu_block_id_t aux_blend;
- unsigned int layer_x;
- unsigned int layer_y;
- unsigned int base_x;
- unsigned int base_y;
- unsigned int base_w;
- unsigned int base_h;
bool is_top;
bool use_prefetch;
bool need_aux_source;
/* used when pixel combiner is needed */
- unsigned int left_layer_x;
- unsigned int left_base_x;
- unsigned int left_base_w;
unsigned int left_src_w;
unsigned int left_crtc_w;
- unsigned int right_layer_x;
- unsigned int right_base_x;
- unsigned int right_base_w;
+ unsigned int left_crtc_x;
unsigned int right_src_w;
unsigned int right_crtc_w;
+ unsigned int right_crtc_x;
bool is_left_top;
bool is_right_top;
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]))
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]);
}
EXPORT_SYMBOL_GPL(constframe_framedimensions);
-void constframe_framedimensions_copy_prim(struct dpu_constframe *cf)
-{
- struct dpu_constframe *prim_cf = NULL;
- unsigned int prim_id;
- int i;
- u32 val;
-
- if (cf->id != 0 && cf->id != 1) {
- dev_warn(cf->dpu->dev, "ConstFrame%d is not a secondary one\n",
- cf->id);
- return;
- }
-
- prim_id = cf->id + 4;
-
- for (i = 0; i < ARRAY_SIZE(cf_ids); i++)
- if (cf_ids[i] == prim_id)
- prim_cf = cf->dpu->cf_priv[i];
-
- if (!prim_cf) {
- dev_warn(cf->dpu->dev, "cannot find ConstFrame%d's primary peer\n",
- cf->id);
- return;
- }
-
- mutex_lock(&cf->mutex);
- val = dpu_cf_read(prim_cf, FRAMEDIMENSIONS);
- dpu_cf_write(cf, val, FRAMEDIMENSIONS);
- mutex_unlock(&cf->mutex);
-}
-EXPORT_SYMBOL_GPL(constframe_framedimensions_copy_prim);
-
void constframe_constantcolor(struct dpu_constframe *cf, unsigned int r,
unsigned int g, unsigned int b, unsigned int a)
{
/* skikconfig */
dpu_fg_write(fg, COL(kick_col) | ROW(kick_row) | EN, SKICKCONFIG);
- /* primary position config */
+ /* primary and secondary area position config */
dpu_fg_write(fg, STARTX(0) | STARTY(0), PACFG);
+ dpu_fg_write(fg, STARTX(0) | STARTY(0), SACFG);
/* alpha */
val = dpu_fg_read(fg, FGINCTRL);
}
EXPORT_SYMBOL_GPL(framegen_syncmode_fixup);
-void framegen_sacfg(struct dpu_framegen *fg, unsigned int x, unsigned int y)
-{
- dpu_fg_write(fg, STARTX(x) | STARTY(y), SACFG);
-}
-EXPORT_SYMBOL_GPL(framegen_sacfg);
-
void framegen_displaymode(struct dpu_framegen *fg, fgdm_t mode)
{
u32 val;
void constframe_shden(struct dpu_constframe *cf, bool enable);
void constframe_framedimensions(struct dpu_constframe *cf, unsigned int w,
unsigned int h);
-void constframe_framedimensions_copy_prim(struct dpu_constframe *cf);
void constframe_constantcolor(struct dpu_constframe *cf, unsigned int r,
unsigned int g, unsigned int b, unsigned int a);
void constframe_controltrigger(struct dpu_constframe *cf, bool trigger);
bool encoder_type_has_tmds, bool encoder_type_has_lvds);
void framegen_pkickconfig(struct dpu_framegen *fg, bool enable);
void framegen_syncmode_fixup(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);
#define MAX_FW_NUM 1
#define MAX_LB_NUM 7
struct dpu_plane_res {
- struct dpu_constframe *cf[2];
struct dpu_extdst *ed[2];
struct dpu_fetchunit *fd[MAX_FD_NUM];
struct dpu_fetchunit *fe[2];