mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-26 22:24:09 +08:00
drm/msm/mdp5: Misc cursor plane bits
These are various changes added in preparation for cursor planes: - Add a pipe_cursor block for 8x96 in mdp5_cfg. - Add a new pipe CAP called MDP_PIPE_CAP_CURSOR. Use this to ensure we assign a cursor SSPP for a drm_plane with type DRM_PLANE_TYPE_CURSOR. - Update mdp5_ctl_blend_mask/ext_blend_mask funcs to incorporate cursor SSPPs. - In mdp5_ctl_blend, iterate through MAX_STAGES instead of stage_cnt, we need to do this because we can now have empty stages in between. - In mdp5_crtc_atomic_check, make sure that the cursor plane has the highest zorder, and stage the cursor plane to the maximum stage # present on the HW. - Create drm_crtc_funcs that doesn't try to implement cursors using the older LM cursor HW. - Pass drm_plane_type in mdp5_plane_init instead of a bool telling whether plane is primary or not. Signed-off-by: Archit Taneja <architt@codeaurora.org> Signed-off-by: Rob Clark <robdclark@gmail.com>
This commit is contained in:
parent
829200ac91
commit
5798c8e0d3
@ -421,6 +421,16 @@ const struct mdp5_cfg_hw msm8x96_config = {
|
|||||||
MDP_PIPE_CAP_SW_PIX_EXT |
|
MDP_PIPE_CAP_SW_PIX_EXT |
|
||||||
0,
|
0,
|
||||||
},
|
},
|
||||||
|
.pipe_cursor = {
|
||||||
|
.count = 2,
|
||||||
|
.base = { 0x34000, 0x36000 },
|
||||||
|
.caps = MDP_PIPE_CAP_HFLIP |
|
||||||
|
MDP_PIPE_CAP_VFLIP |
|
||||||
|
MDP_PIPE_CAP_SW_PIX_EXT |
|
||||||
|
MDP_PIPE_CAP_CURSOR |
|
||||||
|
0,
|
||||||
|
},
|
||||||
|
|
||||||
.lm = {
|
.lm = {
|
||||||
.count = 6,
|
.count = 6,
|
||||||
.base = { 0x44000, 0x45000, 0x46000, 0x47000, 0x48000, 0x49000 },
|
.base = { 0x44000, 0x45000, 0x46000, 0x47000, 0x48000, 0x49000 },
|
||||||
|
@ -400,6 +400,7 @@ static int mdp5_crtc_atomic_check(struct drm_crtc *crtc,
|
|||||||
struct plane_state pstates[STAGE_MAX + 1];
|
struct plane_state pstates[STAGE_MAX + 1];
|
||||||
const struct mdp5_cfg_hw *hw_cfg;
|
const struct mdp5_cfg_hw *hw_cfg;
|
||||||
const struct drm_plane_state *pstate;
|
const struct drm_plane_state *pstate;
|
||||||
|
bool cursor_plane = false;
|
||||||
int cnt = 0, base = 0, i;
|
int cnt = 0, base = 0, i;
|
||||||
|
|
||||||
DBG("%s: check", crtc->name);
|
DBG("%s: check", crtc->name);
|
||||||
@ -409,6 +410,9 @@ static int mdp5_crtc_atomic_check(struct drm_crtc *crtc,
|
|||||||
pstates[cnt].state = to_mdp5_plane_state(pstate);
|
pstates[cnt].state = to_mdp5_plane_state(pstate);
|
||||||
|
|
||||||
cnt++;
|
cnt++;
|
||||||
|
|
||||||
|
if (plane->type == DRM_PLANE_TYPE_CURSOR)
|
||||||
|
cursor_plane = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* assign a stage based on sorted zpos property */
|
/* assign a stage based on sorted zpos property */
|
||||||
@ -420,6 +424,10 @@ static int mdp5_crtc_atomic_check(struct drm_crtc *crtc,
|
|||||||
if ((cnt > 0) && !is_fullscreen(state, &pstates[0].state->base))
|
if ((cnt > 0) && !is_fullscreen(state, &pstates[0].state->base))
|
||||||
base++;
|
base++;
|
||||||
|
|
||||||
|
/* trigger a warning if cursor isn't the highest zorder */
|
||||||
|
WARN_ON(cursor_plane &&
|
||||||
|
(pstates[cnt - 1].plane->type != DRM_PLANE_TYPE_CURSOR));
|
||||||
|
|
||||||
/* verify that there are not too many planes attached to crtc
|
/* verify that there are not too many planes attached to crtc
|
||||||
* and that we don't have conflicting mixer stages:
|
* and that we don't have conflicting mixer stages:
|
||||||
*/
|
*/
|
||||||
@ -431,6 +439,9 @@ static int mdp5_crtc_atomic_check(struct drm_crtc *crtc,
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < cnt; i++) {
|
for (i = 0; i < cnt; i++) {
|
||||||
|
if (cursor_plane && (i == (cnt - 1)))
|
||||||
|
pstates[i].state->stage = hw_cfg->lm.nb_stages;
|
||||||
|
else
|
||||||
pstates[i].state->stage = STAGE_BASE + i + base;
|
pstates[i].state->stage = STAGE_BASE + i + base;
|
||||||
DBG("%s: assign pipe %s on stage=%d", crtc->name,
|
DBG("%s: assign pipe %s on stage=%d", crtc->name,
|
||||||
pstates[i].plane->name,
|
pstates[i].plane->name,
|
||||||
@ -642,6 +653,16 @@ static const struct drm_crtc_funcs mdp5_crtc_funcs = {
|
|||||||
.cursor_move = mdp5_crtc_cursor_move,
|
.cursor_move = mdp5_crtc_cursor_move,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct drm_crtc_funcs mdp5_crtc_no_lm_cursor_funcs = {
|
||||||
|
.set_config = drm_atomic_helper_set_config,
|
||||||
|
.destroy = mdp5_crtc_destroy,
|
||||||
|
.page_flip = drm_atomic_helper_page_flip,
|
||||||
|
.set_property = drm_atomic_helper_crtc_set_property,
|
||||||
|
.reset = drm_atomic_helper_crtc_reset,
|
||||||
|
.atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
|
||||||
|
.atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
|
||||||
|
};
|
||||||
|
|
||||||
static const struct drm_crtc_helper_funcs mdp5_crtc_helper_funcs = {
|
static const struct drm_crtc_helper_funcs mdp5_crtc_helper_funcs = {
|
||||||
.mode_set_nofb = mdp5_crtc_mode_set_nofb,
|
.mode_set_nofb = mdp5_crtc_mode_set_nofb,
|
||||||
.disable = mdp5_crtc_disable,
|
.disable = mdp5_crtc_disable,
|
||||||
@ -775,7 +796,8 @@ void mdp5_crtc_wait_for_commit_done(struct drm_crtc *crtc)
|
|||||||
|
|
||||||
/* initialize crtc */
|
/* initialize crtc */
|
||||||
struct drm_crtc *mdp5_crtc_init(struct drm_device *dev,
|
struct drm_crtc *mdp5_crtc_init(struct drm_device *dev,
|
||||||
struct drm_plane *plane, int id)
|
struct drm_plane *plane,
|
||||||
|
struct drm_plane *cursor_plane, int id)
|
||||||
{
|
{
|
||||||
struct drm_crtc *crtc = NULL;
|
struct drm_crtc *crtc = NULL;
|
||||||
struct mdp5_crtc *mdp5_crtc;
|
struct mdp5_crtc *mdp5_crtc;
|
||||||
@ -796,8 +818,12 @@ struct drm_crtc *mdp5_crtc_init(struct drm_device *dev,
|
|||||||
mdp5_crtc->vblank.irq = mdp5_crtc_vblank_irq;
|
mdp5_crtc->vblank.irq = mdp5_crtc_vblank_irq;
|
||||||
mdp5_crtc->err.irq = mdp5_crtc_err_irq;
|
mdp5_crtc->err.irq = mdp5_crtc_err_irq;
|
||||||
|
|
||||||
drm_crtc_init_with_planes(dev, crtc, plane, NULL, &mdp5_crtc_funcs,
|
if (cursor_plane)
|
||||||
NULL);
|
drm_crtc_init_with_planes(dev, crtc, plane, cursor_plane,
|
||||||
|
&mdp5_crtc_no_lm_cursor_funcs, NULL);
|
||||||
|
else
|
||||||
|
drm_crtc_init_with_planes(dev, crtc, plane, NULL,
|
||||||
|
&mdp5_crtc_funcs, NULL);
|
||||||
|
|
||||||
drm_flip_work_init(&mdp5_crtc->unref_cursor_work,
|
drm_flip_work_init(&mdp5_crtc->unref_cursor_work,
|
||||||
"unref cursor", unref_cursor_worker);
|
"unref cursor", unref_cursor_worker);
|
||||||
|
@ -326,6 +326,8 @@ static u32 mdp_ctl_blend_mask(enum mdp5_pipe pipe,
|
|||||||
case SSPP_DMA1: return MDP5_CTL_LAYER_REG_DMA1(stage);
|
case SSPP_DMA1: return MDP5_CTL_LAYER_REG_DMA1(stage);
|
||||||
case SSPP_VIG3: return MDP5_CTL_LAYER_REG_VIG3(stage);
|
case SSPP_VIG3: return MDP5_CTL_LAYER_REG_VIG3(stage);
|
||||||
case SSPP_RGB3: return MDP5_CTL_LAYER_REG_RGB3(stage);
|
case SSPP_RGB3: return MDP5_CTL_LAYER_REG_RGB3(stage);
|
||||||
|
case SSPP_CURSOR0:
|
||||||
|
case SSPP_CURSOR1:
|
||||||
default: return 0;
|
default: return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -333,7 +335,7 @@ static u32 mdp_ctl_blend_mask(enum mdp5_pipe pipe,
|
|||||||
static u32 mdp_ctl_blend_ext_mask(enum mdp5_pipe pipe,
|
static u32 mdp_ctl_blend_ext_mask(enum mdp5_pipe pipe,
|
||||||
enum mdp_mixer_stage_id stage)
|
enum mdp_mixer_stage_id stage)
|
||||||
{
|
{
|
||||||
if (stage < STAGE6)
|
if (stage < STAGE6 && (pipe != SSPP_CURSOR0 && pipe != SSPP_CURSOR1))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
switch (pipe) {
|
switch (pipe) {
|
||||||
@ -347,6 +349,8 @@ static u32 mdp_ctl_blend_ext_mask(enum mdp5_pipe pipe,
|
|||||||
case SSPP_DMA1: return MDP5_CTL_LAYER_EXT_REG_DMA1_BIT3;
|
case SSPP_DMA1: return MDP5_CTL_LAYER_EXT_REG_DMA1_BIT3;
|
||||||
case SSPP_VIG3: return MDP5_CTL_LAYER_EXT_REG_VIG3_BIT3;
|
case SSPP_VIG3: return MDP5_CTL_LAYER_EXT_REG_VIG3_BIT3;
|
||||||
case SSPP_RGB3: return MDP5_CTL_LAYER_EXT_REG_RGB3_BIT3;
|
case SSPP_RGB3: return MDP5_CTL_LAYER_EXT_REG_RGB3_BIT3;
|
||||||
|
case SSPP_CURSOR0: return MDP5_CTL_LAYER_EXT_REG_CURSOR0(stage);
|
||||||
|
case SSPP_CURSOR1: return MDP5_CTL_LAYER_EXT_REG_CURSOR1(stage);
|
||||||
default: return 0;
|
default: return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -365,7 +369,7 @@ int mdp5_ctl_blend(struct mdp5_ctl *ctl, enum mdp5_pipe *stage, u32 stage_cnt,
|
|||||||
start_stage = STAGE_BASE;
|
start_stage = STAGE_BASE;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = start_stage; i < start_stage + stage_cnt; i++) {
|
for (i = start_stage; stage_cnt && i <= STAGE_MAX; i++) {
|
||||||
blend_cfg |= mdp_ctl_blend_mask(stage[i], i);
|
blend_cfg |= mdp_ctl_blend_mask(stage[i], i);
|
||||||
blend_ext_cfg |= mdp_ctl_blend_ext_mask(stage[i], i);
|
blend_ext_cfg |= mdp_ctl_blend_ext_mask(stage[i], i);
|
||||||
}
|
}
|
||||||
@ -422,6 +426,8 @@ u32 mdp_ctl_flush_mask_pipe(enum mdp5_pipe pipe)
|
|||||||
case SSPP_DMA1: return MDP5_CTL_FLUSH_DMA1;
|
case SSPP_DMA1: return MDP5_CTL_FLUSH_DMA1;
|
||||||
case SSPP_VIG3: return MDP5_CTL_FLUSH_VIG3;
|
case SSPP_VIG3: return MDP5_CTL_FLUSH_VIG3;
|
||||||
case SSPP_RGB3: return MDP5_CTL_FLUSH_RGB3;
|
case SSPP_RGB3: return MDP5_CTL_FLUSH_RGB3;
|
||||||
|
case SSPP_CURSOR0: return MDP5_CTL_FLUSH_CURSOR_0;
|
||||||
|
case SSPP_CURSOR1: return MDP5_CTL_FLUSH_CURSOR_1;
|
||||||
default: return 0;
|
default: return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -441,8 +441,14 @@ static int modeset_init(struct mdp5_kms *mdp5_kms)
|
|||||||
bool primary = i < num_crtcs;
|
bool primary = i < num_crtcs;
|
||||||
struct drm_plane *plane;
|
struct drm_plane *plane;
|
||||||
struct drm_crtc *crtc;
|
struct drm_crtc *crtc;
|
||||||
|
enum drm_plane_type type;
|
||||||
|
|
||||||
plane = mdp5_plane_init(dev, primary);
|
if (primary)
|
||||||
|
type = DRM_PLANE_TYPE_PRIMARY;
|
||||||
|
else
|
||||||
|
type = DRM_PLANE_TYPE_OVERLAY;
|
||||||
|
|
||||||
|
plane = mdp5_plane_init(dev, type);
|
||||||
if (IS_ERR(plane)) {
|
if (IS_ERR(plane)) {
|
||||||
ret = PTR_ERR(plane);
|
ret = PTR_ERR(plane);
|
||||||
dev_err(dev->dev, "failed to construct plane %d (%d)\n", i, ret);
|
dev_err(dev->dev, "failed to construct plane %d (%d)\n", i, ret);
|
||||||
@ -453,7 +459,7 @@ static int modeset_init(struct mdp5_kms *mdp5_kms)
|
|||||||
if (!primary)
|
if (!primary)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
crtc = mdp5_crtc_init(dev, plane, i);
|
crtc = mdp5_crtc_init(dev, plane, NULL, i);
|
||||||
if (IS_ERR(crtc)) {
|
if (IS_ERR(crtc)) {
|
||||||
ret = PTR_ERR(crtc);
|
ret = PTR_ERR(crtc);
|
||||||
dev_err(dev->dev, "failed to construct crtc %d (%d)\n", i, ret);
|
dev_err(dev->dev, "failed to construct crtc %d (%d)\n", i, ret);
|
||||||
|
@ -167,6 +167,7 @@ static inline const char *pipe2name(enum mdp5_pipe pipe)
|
|||||||
NAME(RGB0), NAME(RGB1), NAME(RGB2),
|
NAME(RGB0), NAME(RGB1), NAME(RGB2),
|
||||||
NAME(DMA0), NAME(DMA1),
|
NAME(DMA0), NAME(DMA1),
|
||||||
NAME(VIG3), NAME(RGB3),
|
NAME(VIG3), NAME(RGB3),
|
||||||
|
NAME(CURSOR0), NAME(CURSOR1),
|
||||||
#undef NAME
|
#undef NAME
|
||||||
};
|
};
|
||||||
return names[pipe];
|
return names[pipe];
|
||||||
@ -242,7 +243,8 @@ void mdp5_irq_domain_fini(struct mdp5_kms *mdp5_kms);
|
|||||||
|
|
||||||
uint32_t mdp5_plane_get_flush(struct drm_plane *plane);
|
uint32_t mdp5_plane_get_flush(struct drm_plane *plane);
|
||||||
enum mdp5_pipe mdp5_plane_pipe(struct drm_plane *plane);
|
enum mdp5_pipe mdp5_plane_pipe(struct drm_plane *plane);
|
||||||
struct drm_plane *mdp5_plane_init(struct drm_device *dev, bool primary);
|
struct drm_plane *mdp5_plane_init(struct drm_device *dev,
|
||||||
|
enum drm_plane_type type);
|
||||||
|
|
||||||
uint32_t mdp5_crtc_vblank(struct drm_crtc *crtc);
|
uint32_t mdp5_crtc_vblank(struct drm_crtc *crtc);
|
||||||
|
|
||||||
@ -251,7 +253,8 @@ void mdp5_crtc_set_pipeline(struct drm_crtc *crtc,
|
|||||||
struct mdp5_interface *intf, struct mdp5_ctl *ctl);
|
struct mdp5_interface *intf, struct mdp5_ctl *ctl);
|
||||||
void mdp5_crtc_wait_for_commit_done(struct drm_crtc *crtc);
|
void mdp5_crtc_wait_for_commit_done(struct drm_crtc *crtc);
|
||||||
struct drm_crtc *mdp5_crtc_init(struct drm_device *dev,
|
struct drm_crtc *mdp5_crtc_init(struct drm_device *dev,
|
||||||
struct drm_plane *plane, int id);
|
struct drm_plane *plane,
|
||||||
|
struct drm_plane *cursor_plane, int id);
|
||||||
|
|
||||||
struct drm_encoder *mdp5_encoder_init(struct drm_device *dev,
|
struct drm_encoder *mdp5_encoder_init(struct drm_device *dev,
|
||||||
struct mdp5_interface *intf, struct mdp5_ctl *ctl);
|
struct mdp5_interface *intf, struct mdp5_ctl *ctl);
|
||||||
|
@ -53,6 +53,14 @@ struct mdp5_hw_pipe *mdp5_pipe_assign(struct drm_atomic_state *s,
|
|||||||
if (caps & ~cur->caps)
|
if (caps & ~cur->caps)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* don't assign a cursor pipe to a plane that isn't going to
|
||||||
|
* be used as a cursor
|
||||||
|
*/
|
||||||
|
if (cur->caps & MDP_PIPE_CAP_CURSOR &&
|
||||||
|
plane->type != DRM_PLANE_TYPE_CURSOR)
|
||||||
|
continue;
|
||||||
|
|
||||||
/* possible candidate, take the one with the
|
/* possible candidate, take the one with the
|
||||||
* fewest unneeded caps bits set:
|
* fewest unneeded caps bits set:
|
||||||
*/
|
*/
|
||||||
|
@ -344,6 +344,9 @@ static int mdp5_plane_atomic_check(struct drm_plane *plane,
|
|||||||
if (rotation & DRM_REFLECT_Y)
|
if (rotation & DRM_REFLECT_Y)
|
||||||
caps |= MDP_PIPE_CAP_VFLIP;
|
caps |= MDP_PIPE_CAP_VFLIP;
|
||||||
|
|
||||||
|
if (plane->type == DRM_PLANE_TYPE_CURSOR)
|
||||||
|
caps |= MDP_PIPE_CAP_CURSOR;
|
||||||
|
|
||||||
/* (re)allocate hw pipe if we don't have one or caps-mismatch: */
|
/* (re)allocate hw pipe if we don't have one or caps-mismatch: */
|
||||||
if (!mdp5_state->hwpipe || (caps & ~mdp5_state->hwpipe->caps))
|
if (!mdp5_state->hwpipe || (caps & ~mdp5_state->hwpipe->caps))
|
||||||
new_hwpipe = true;
|
new_hwpipe = true;
|
||||||
@ -870,12 +873,12 @@ uint32_t mdp5_plane_get_flush(struct drm_plane *plane)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* initialize plane */
|
/* initialize plane */
|
||||||
struct drm_plane *mdp5_plane_init(struct drm_device *dev, bool primary)
|
struct drm_plane *mdp5_plane_init(struct drm_device *dev,
|
||||||
|
enum drm_plane_type type)
|
||||||
{
|
{
|
||||||
struct drm_plane *plane = NULL;
|
struct drm_plane *plane = NULL;
|
||||||
struct mdp5_plane *mdp5_plane;
|
struct mdp5_plane *mdp5_plane;
|
||||||
int ret;
|
int ret;
|
||||||
enum drm_plane_type type;
|
|
||||||
|
|
||||||
mdp5_plane = kzalloc(sizeof(*mdp5_plane), GFP_KERNEL);
|
mdp5_plane = kzalloc(sizeof(*mdp5_plane), GFP_KERNEL);
|
||||||
if (!mdp5_plane) {
|
if (!mdp5_plane) {
|
||||||
@ -888,7 +891,6 @@ struct drm_plane *mdp5_plane_init(struct drm_device *dev, bool primary)
|
|||||||
mdp5_plane->nformats = mdp_get_formats(mdp5_plane->formats,
|
mdp5_plane->nformats = mdp_get_formats(mdp5_plane->formats,
|
||||||
ARRAY_SIZE(mdp5_plane->formats), false);
|
ARRAY_SIZE(mdp5_plane->formats), false);
|
||||||
|
|
||||||
type = primary ? DRM_PLANE_TYPE_PRIMARY : DRM_PLANE_TYPE_OVERLAY;
|
|
||||||
ret = drm_universal_plane_init(dev, plane, 0xff, &mdp5_plane_funcs,
|
ret = drm_universal_plane_init(dev, plane, 0xff, &mdp5_plane_funcs,
|
||||||
mdp5_plane->formats, mdp5_plane->nformats,
|
mdp5_plane->formats, mdp5_plane->nformats,
|
||||||
type, NULL);
|
type, NULL);
|
||||||
|
@ -112,6 +112,7 @@ const struct msm_format *mdp_get_format(struct msm_kms *kms, uint32_t format);
|
|||||||
#define MDP_PIPE_CAP_CSC BIT(3)
|
#define MDP_PIPE_CAP_CSC BIT(3)
|
||||||
#define MDP_PIPE_CAP_DECIMATION BIT(4)
|
#define MDP_PIPE_CAP_DECIMATION BIT(4)
|
||||||
#define MDP_PIPE_CAP_SW_PIX_EXT BIT(5)
|
#define MDP_PIPE_CAP_SW_PIX_EXT BIT(5)
|
||||||
|
#define MDP_PIPE_CAP_CURSOR BIT(6)
|
||||||
|
|
||||||
static inline bool pipe_supports_yuv(uint32_t pipe_caps)
|
static inline bool pipe_supports_yuv(uint32_t pipe_caps)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user