drm/msm: add plane support
Enable using VG1 and VG2 for planes. Currently YUV/CSC or scaling is not enabled, but ARGB and xRGB blending is. Signed-off-by: Rob Clark <robdclark@gmail.com> Acked-by: David Brown <davidb@codeaurora.org>
This commit is contained in:
parent
22ba8b6b23
commit
a862391871
|
@ -26,6 +26,7 @@ struct mdp4_crtc {
|
||||||
struct drm_crtc base;
|
struct drm_crtc base;
|
||||||
char name[8];
|
char name[8];
|
||||||
struct drm_plane *plane;
|
struct drm_plane *plane;
|
||||||
|
struct drm_plane *planes[8];
|
||||||
int id;
|
int id;
|
||||||
int ovlp;
|
int ovlp;
|
||||||
enum mdp4_dma dma;
|
enum mdp4_dma dma;
|
||||||
|
@ -115,9 +116,15 @@ static void crtc_flush(struct drm_crtc *crtc)
|
||||||
{
|
{
|
||||||
struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);
|
struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);
|
||||||
struct mdp4_kms *mdp4_kms = get_kms(crtc);
|
struct mdp4_kms *mdp4_kms = get_kms(crtc);
|
||||||
uint32_t flush = 0;
|
uint32_t i, flush = 0;
|
||||||
|
|
||||||
flush |= pipe2flush(mdp4_plane_pipe(mdp4_crtc->plane));
|
for (i = 0; i < ARRAY_SIZE(mdp4_crtc->planes); i++) {
|
||||||
|
struct drm_plane *plane = mdp4_crtc->planes[i];
|
||||||
|
if (plane) {
|
||||||
|
enum mdp4_pipe pipe_id = mdp4_plane_pipe(plane);
|
||||||
|
flush |= pipe2flush(pipe_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
flush |= ovlp2flush(mdp4_crtc->ovlp);
|
flush |= ovlp2flush(mdp4_crtc->ovlp);
|
||||||
|
|
||||||
DBG("%s: flush=%08x", mdp4_crtc->name, flush);
|
DBG("%s: flush=%08x", mdp4_crtc->name, flush);
|
||||||
|
@ -205,67 +212,69 @@ static void blend_setup(struct drm_crtc *crtc)
|
||||||
struct mdp4_kms *mdp4_kms = get_kms(crtc);
|
struct mdp4_kms *mdp4_kms = get_kms(crtc);
|
||||||
int i, ovlp = mdp4_crtc->ovlp;
|
int i, ovlp = mdp4_crtc->ovlp;
|
||||||
uint32_t mixer_cfg = 0;
|
uint32_t mixer_cfg = 0;
|
||||||
|
static const enum mdp4_mixer_stage_id stages[] = {
|
||||||
|
STAGE_BASE, STAGE0, STAGE1, STAGE2, STAGE3,
|
||||||
|
};
|
||||||
|
/* statically (for now) map planes to mixer stage (z-order): */
|
||||||
|
static const int idxs[] = {
|
||||||
|
[VG1] = 1,
|
||||||
|
[VG2] = 2,
|
||||||
|
[RGB1] = 0,
|
||||||
|
[RGB2] = 0,
|
||||||
|
[RGB3] = 0,
|
||||||
|
[VG3] = 3,
|
||||||
|
[VG4] = 4,
|
||||||
|
|
||||||
/*
|
};
|
||||||
* This probably would also need to be triggered by any attached
|
bool alpha[4]= { false, false, false, false };
|
||||||
* plane when it changes.. for now since we are only using a single
|
|
||||||
* private plane, the configuration is hard-coded:
|
|
||||||
*/
|
|
||||||
|
|
||||||
mdp4_write(mdp4_kms, REG_MDP4_OVLP_TRANSP_LOW0(ovlp), 0);
|
mdp4_write(mdp4_kms, REG_MDP4_OVLP_TRANSP_LOW0(ovlp), 0);
|
||||||
mdp4_write(mdp4_kms, REG_MDP4_OVLP_TRANSP_LOW1(ovlp), 0);
|
mdp4_write(mdp4_kms, REG_MDP4_OVLP_TRANSP_LOW1(ovlp), 0);
|
||||||
mdp4_write(mdp4_kms, REG_MDP4_OVLP_TRANSP_HIGH0(ovlp), 0);
|
mdp4_write(mdp4_kms, REG_MDP4_OVLP_TRANSP_HIGH0(ovlp), 0);
|
||||||
mdp4_write(mdp4_kms, REG_MDP4_OVLP_TRANSP_HIGH1(ovlp), 0);
|
mdp4_write(mdp4_kms, REG_MDP4_OVLP_TRANSP_HIGH1(ovlp), 0);
|
||||||
|
|
||||||
|
/* TODO single register for all CRTCs, so this won't work properly
|
||||||
|
* when multiple CRTCs are active..
|
||||||
|
*/
|
||||||
|
for (i = 0; i < ARRAY_SIZE(mdp4_crtc->planes); i++) {
|
||||||
|
struct drm_plane *plane = mdp4_crtc->planes[i];
|
||||||
|
if (plane) {
|
||||||
|
enum mdp4_pipe pipe_id = mdp4_plane_pipe(plane);
|
||||||
|
int idx = idxs[pipe_id];
|
||||||
|
if (idx > 0) {
|
||||||
|
const struct mdp4_format *format =
|
||||||
|
to_mdp4_format(msm_framebuffer_format(plane->fb));
|
||||||
|
alpha[idx-1] = format->alpha_enable;
|
||||||
|
}
|
||||||
|
mixer_cfg |= mixercfg(mdp4_crtc->mixer, pipe_id, stages[idx]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* this shouldn't happen.. and seems to cause underflow: */
|
||||||
|
WARN_ON(!mixer_cfg);
|
||||||
|
|
||||||
for (i = 0; i < 4; i++) {
|
for (i = 0; i < 4; i++) {
|
||||||
mdp4_write(mdp4_kms, REG_MDP4_OVLP_STAGE_FG_ALPHA(ovlp, i), 0);
|
uint32_t op;
|
||||||
mdp4_write(mdp4_kms, REG_MDP4_OVLP_STAGE_BG_ALPHA(ovlp, i), 0);
|
|
||||||
mdp4_write(mdp4_kms, REG_MDP4_OVLP_STAGE_OP(ovlp, i),
|
if (alpha[i]) {
|
||||||
MDP4_OVLP_STAGE_OP_FG_ALPHA(FG_CONST) |
|
op = MDP4_OVLP_STAGE_OP_FG_ALPHA(FG_PIXEL) |
|
||||||
MDP4_OVLP_STAGE_OP_BG_ALPHA(BG_CONST));
|
MDP4_OVLP_STAGE_OP_BG_ALPHA(FG_PIXEL) |
|
||||||
mdp4_write(mdp4_kms, REG_MDP4_OVLP_STAGE_CO3(ovlp, i), 0);
|
MDP4_OVLP_STAGE_OP_BG_INV_ALPHA;
|
||||||
|
} else {
|
||||||
|
op = MDP4_OVLP_STAGE_OP_FG_ALPHA(FG_CONST) |
|
||||||
|
MDP4_OVLP_STAGE_OP_BG_ALPHA(BG_CONST);
|
||||||
|
}
|
||||||
|
|
||||||
|
mdp4_write(mdp4_kms, REG_MDP4_OVLP_STAGE_FG_ALPHA(ovlp, i), 0xff);
|
||||||
|
mdp4_write(mdp4_kms, REG_MDP4_OVLP_STAGE_BG_ALPHA(ovlp, i), 0x00);
|
||||||
|
mdp4_write(mdp4_kms, REG_MDP4_OVLP_STAGE_OP(ovlp, i), op);
|
||||||
|
mdp4_write(mdp4_kms, REG_MDP4_OVLP_STAGE_CO3(ovlp, i), 1);
|
||||||
mdp4_write(mdp4_kms, REG_MDP4_OVLP_STAGE_TRANSP_LOW0(ovlp, i), 0);
|
mdp4_write(mdp4_kms, REG_MDP4_OVLP_STAGE_TRANSP_LOW0(ovlp, i), 0);
|
||||||
mdp4_write(mdp4_kms, REG_MDP4_OVLP_STAGE_TRANSP_LOW1(ovlp, i), 0);
|
mdp4_write(mdp4_kms, REG_MDP4_OVLP_STAGE_TRANSP_LOW1(ovlp, i), 0);
|
||||||
mdp4_write(mdp4_kms, REG_MDP4_OVLP_STAGE_TRANSP_HIGH0(ovlp, i), 0);
|
mdp4_write(mdp4_kms, REG_MDP4_OVLP_STAGE_TRANSP_HIGH0(ovlp, i), 0);
|
||||||
mdp4_write(mdp4_kms, REG_MDP4_OVLP_STAGE_TRANSP_HIGH1(ovlp, i), 0);
|
mdp4_write(mdp4_kms, REG_MDP4_OVLP_STAGE_TRANSP_HIGH1(ovlp, i), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO single register for all CRTCs, so this won't work properly
|
|
||||||
* when multiple CRTCs are active..
|
|
||||||
*/
|
|
||||||
switch (mdp4_plane_pipe(mdp4_crtc->plane)) {
|
|
||||||
case VG1:
|
|
||||||
mixer_cfg = MDP4_LAYERMIXER_IN_CFG_PIPE0(STAGE_BASE) |
|
|
||||||
COND(mdp4_crtc->mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE0_MIXER1);
|
|
||||||
break;
|
|
||||||
case VG2:
|
|
||||||
mixer_cfg = MDP4_LAYERMIXER_IN_CFG_PIPE1(STAGE_BASE) |
|
|
||||||
COND(mdp4_crtc->mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE1_MIXER1);
|
|
||||||
break;
|
|
||||||
case RGB1:
|
|
||||||
mixer_cfg = MDP4_LAYERMIXER_IN_CFG_PIPE2(STAGE_BASE) |
|
|
||||||
COND(mdp4_crtc->mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE2_MIXER1);
|
|
||||||
break;
|
|
||||||
case RGB2:
|
|
||||||
mixer_cfg = MDP4_LAYERMIXER_IN_CFG_PIPE3(STAGE_BASE) |
|
|
||||||
COND(mdp4_crtc->mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE3_MIXER1);
|
|
||||||
break;
|
|
||||||
case RGB3:
|
|
||||||
mixer_cfg = MDP4_LAYERMIXER_IN_CFG_PIPE4(STAGE_BASE) |
|
|
||||||
COND(mdp4_crtc->mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE4_MIXER1);
|
|
||||||
break;
|
|
||||||
case VG3:
|
|
||||||
mixer_cfg = MDP4_LAYERMIXER_IN_CFG_PIPE5(STAGE_BASE) |
|
|
||||||
COND(mdp4_crtc->mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE5_MIXER1);
|
|
||||||
break;
|
|
||||||
case VG4:
|
|
||||||
mixer_cfg = MDP4_LAYERMIXER_IN_CFG_PIPE6(STAGE_BASE) |
|
|
||||||
COND(mdp4_crtc->mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE6_MIXER1);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
WARN_ON("invalid pipe");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
mdp4_write(mdp4_kms, REG_MDP4_LAYERMIXER_IN_CFG, mixer_cfg);
|
mdp4_write(mdp4_kms, REG_MDP4_LAYERMIXER_IN_CFG, mixer_cfg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -622,6 +631,32 @@ void mdp4_crtc_set_intf(struct drm_crtc *crtc, enum mdp4_intf intf)
|
||||||
mdp4_write(mdp4_kms, REG_MDP4_DISP_INTF_SEL, intf_sel);
|
mdp4_write(mdp4_kms, REG_MDP4_DISP_INTF_SEL, intf_sel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void set_attach(struct drm_crtc *crtc, enum mdp4_pipe pipe_id,
|
||||||
|
struct drm_plane *plane)
|
||||||
|
{
|
||||||
|
struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);
|
||||||
|
|
||||||
|
BUG_ON(pipe_id >= ARRAY_SIZE(mdp4_crtc->planes));
|
||||||
|
|
||||||
|
if (mdp4_crtc->planes[pipe_id] == plane)
|
||||||
|
return;
|
||||||
|
|
||||||
|
mdp4_crtc->planes[pipe_id] = plane;
|
||||||
|
blend_setup(crtc);
|
||||||
|
if (mdp4_crtc->enabled && (plane != mdp4_crtc->plane))
|
||||||
|
crtc_flush(crtc);
|
||||||
|
}
|
||||||
|
|
||||||
|
void mdp4_crtc_attach(struct drm_crtc *crtc, struct drm_plane *plane)
|
||||||
|
{
|
||||||
|
set_attach(crtc, mdp4_plane_pipe(plane), plane);
|
||||||
|
}
|
||||||
|
|
||||||
|
void mdp4_crtc_detach(struct drm_crtc *crtc, struct drm_plane *plane)
|
||||||
|
{
|
||||||
|
set_attach(crtc, mdp4_plane_pipe(plane), NULL);
|
||||||
|
}
|
||||||
|
|
||||||
static const char *dma_names[] = {
|
static const char *dma_names[] = {
|
||||||
"DMA_P", "DMA_S", "DMA_E",
|
"DMA_P", "DMA_S", "DMA_E",
|
||||||
};
|
};
|
||||||
|
@ -644,7 +679,6 @@ struct drm_crtc *mdp4_crtc_init(struct drm_device *dev,
|
||||||
crtc = &mdp4_crtc->base;
|
crtc = &mdp4_crtc->base;
|
||||||
|
|
||||||
mdp4_crtc->plane = plane;
|
mdp4_crtc->plane = plane;
|
||||||
mdp4_crtc->plane->crtc = crtc;
|
|
||||||
|
|
||||||
mdp4_crtc->ovlp = ovlp_id;
|
mdp4_crtc->ovlp = ovlp_id;
|
||||||
mdp4_crtc->dma = dma_id;
|
mdp4_crtc->dma = dma_id;
|
||||||
|
|
|
@ -44,6 +44,22 @@ static const struct mdp4_format formats[] = {
|
||||||
FMT(BGR565, 0, 5, 6, 5, 2, 0, 1, 0, false, true, 2, 3),
|
FMT(BGR565, 0, 5, 6, 5, 2, 0, 1, 0, false, true, 2, 3),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
uint32_t mdp4_get_formats(enum mdp4_pipe pipe_id, uint32_t *pixel_formats,
|
||||||
|
uint32_t max_formats)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
for (i = 0; i < ARRAY_SIZE(formats); i++) {
|
||||||
|
const struct mdp4_format *f = &formats[i];
|
||||||
|
|
||||||
|
if (i == max_formats)
|
||||||
|
break;
|
||||||
|
|
||||||
|
pixel_formats[i] = f->base.pixel_format;
|
||||||
|
}
|
||||||
|
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
const struct msm_format *mdp4_get_format(struct msm_kms *kms, uint32_t format)
|
const struct msm_format *mdp4_get_format(struct msm_kms *kms, uint32_t format)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
|
@ -196,6 +196,23 @@ static int modeset_init(struct mdp4_kms *mdp4_kms)
|
||||||
* for more than just RGB1->DMA_E->DTV->HDMI
|
* for more than just RGB1->DMA_E->DTV->HDMI
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* construct non-private planes: */
|
||||||
|
plane = mdp4_plane_init(dev, VG1, false);
|
||||||
|
if (IS_ERR(plane)) {
|
||||||
|
dev_err(dev->dev, "failed to construct plane for VG1\n");
|
||||||
|
ret = PTR_ERR(plane);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
priv->planes[priv->num_planes++] = plane;
|
||||||
|
|
||||||
|
plane = mdp4_plane_init(dev, VG2, false);
|
||||||
|
if (IS_ERR(plane)) {
|
||||||
|
dev_err(dev->dev, "failed to construct plane for VG2\n");
|
||||||
|
ret = PTR_ERR(plane);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
priv->planes[priv->num_planes++] = plane;
|
||||||
|
|
||||||
/* the CRTCs get constructed with a private plane: */
|
/* the CRTCs get constructed with a private plane: */
|
||||||
plane = mdp4_plane_init(dev, RGB1, true);
|
plane = mdp4_plane_init(dev, RGB1, true);
|
||||||
if (IS_ERR(plane)) {
|
if (IS_ERR(plane)) {
|
||||||
|
|
|
@ -133,6 +133,48 @@ static inline uint32_t dma2err(enum mdp4_dma dma)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline uint32_t mixercfg(int mixer, enum mdp4_pipe pipe,
|
||||||
|
enum mdp4_mixer_stage_id stage)
|
||||||
|
{
|
||||||
|
uint32_t mixer_cfg = 0;
|
||||||
|
|
||||||
|
switch (pipe) {
|
||||||
|
case VG1:
|
||||||
|
mixer_cfg = MDP4_LAYERMIXER_IN_CFG_PIPE0(stage) |
|
||||||
|
COND(mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE0_MIXER1);
|
||||||
|
break;
|
||||||
|
case VG2:
|
||||||
|
mixer_cfg = MDP4_LAYERMIXER_IN_CFG_PIPE1(stage) |
|
||||||
|
COND(mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE1_MIXER1);
|
||||||
|
break;
|
||||||
|
case RGB1:
|
||||||
|
mixer_cfg = MDP4_LAYERMIXER_IN_CFG_PIPE2(stage) |
|
||||||
|
COND(mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE2_MIXER1);
|
||||||
|
break;
|
||||||
|
case RGB2:
|
||||||
|
mixer_cfg = MDP4_LAYERMIXER_IN_CFG_PIPE3(stage) |
|
||||||
|
COND(mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE3_MIXER1);
|
||||||
|
break;
|
||||||
|
case RGB3:
|
||||||
|
mixer_cfg = MDP4_LAYERMIXER_IN_CFG_PIPE4(stage) |
|
||||||
|
COND(mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE4_MIXER1);
|
||||||
|
break;
|
||||||
|
case VG3:
|
||||||
|
mixer_cfg = MDP4_LAYERMIXER_IN_CFG_PIPE5(stage) |
|
||||||
|
COND(mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE5_MIXER1);
|
||||||
|
break;
|
||||||
|
case VG4:
|
||||||
|
mixer_cfg = MDP4_LAYERMIXER_IN_CFG_PIPE6(stage) |
|
||||||
|
COND(mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE6_MIXER1);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
WARN_ON("invalid pipe");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mixer_cfg;
|
||||||
|
}
|
||||||
|
|
||||||
int mdp4_disable(struct mdp4_kms *mdp4_kms);
|
int mdp4_disable(struct mdp4_kms *mdp4_kms);
|
||||||
int mdp4_enable(struct mdp4_kms *mdp4_kms);
|
int mdp4_enable(struct mdp4_kms *mdp4_kms);
|
||||||
|
|
||||||
|
@ -146,6 +188,8 @@ void mdp4_irq_unregister(struct mdp4_kms *mdp4_kms, struct mdp4_irq *irq);
|
||||||
int mdp4_enable_vblank(struct msm_kms *kms, struct drm_crtc *crtc);
|
int mdp4_enable_vblank(struct msm_kms *kms, struct drm_crtc *crtc);
|
||||||
void mdp4_disable_vblank(struct msm_kms *kms, struct drm_crtc *crtc);
|
void mdp4_disable_vblank(struct msm_kms *kms, struct drm_crtc *crtc);
|
||||||
|
|
||||||
|
uint32_t mdp4_get_formats(enum mdp4_pipe pipe_id, uint32_t *formats,
|
||||||
|
uint32_t max_formats);
|
||||||
const struct msm_format *mdp4_get_format(struct msm_kms *kms, uint32_t format);
|
const struct msm_format *mdp4_get_format(struct msm_kms *kms, uint32_t format);
|
||||||
|
|
||||||
void mdp4_plane_install_properties(struct drm_plane *plane,
|
void mdp4_plane_install_properties(struct drm_plane *plane,
|
||||||
|
@ -166,6 +210,8 @@ uint32_t mdp4_crtc_vblank(struct drm_crtc *crtc);
|
||||||
void mdp4_crtc_cancel_pending_flip(struct drm_crtc *crtc);
|
void mdp4_crtc_cancel_pending_flip(struct drm_crtc *crtc);
|
||||||
void mdp4_crtc_set_config(struct drm_crtc *crtc, uint32_t config);
|
void mdp4_crtc_set_config(struct drm_crtc *crtc, uint32_t config);
|
||||||
void mdp4_crtc_set_intf(struct drm_crtc *crtc, enum mdp4_intf intf);
|
void mdp4_crtc_set_intf(struct drm_crtc *crtc, enum mdp4_intf intf);
|
||||||
|
void mdp4_crtc_attach(struct drm_crtc *crtc, struct drm_plane *plane);
|
||||||
|
void mdp4_crtc_detach(struct drm_crtc *crtc, struct drm_plane *plane);
|
||||||
struct drm_crtc *mdp4_crtc_init(struct drm_device *dev,
|
struct drm_crtc *mdp4_crtc_init(struct drm_device *dev,
|
||||||
struct drm_plane *plane, int id, int ovlp_id,
|
struct drm_plane *plane, int id, int ovlp_id,
|
||||||
enum mdp4_dma dma_id);
|
enum mdp4_dma dma_id);
|
||||||
|
|
|
@ -61,7 +61,9 @@ static int mdp4_plane_update(struct drm_plane *plane,
|
||||||
static int mdp4_plane_disable(struct drm_plane *plane)
|
static int mdp4_plane_disable(struct drm_plane *plane)
|
||||||
{
|
{
|
||||||
struct mdp4_plane *mdp4_plane = to_mdp4_plane(plane);
|
struct mdp4_plane *mdp4_plane = to_mdp4_plane(plane);
|
||||||
DBG("%s: TODO", mdp4_plane->name); // XXX
|
DBG("%s: disable", mdp4_plane->name);
|
||||||
|
if (plane->crtc)
|
||||||
|
mdp4_crtc_detach(plane->crtc, plane);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,6 +143,10 @@ int mdp4_plane_mode_set(struct drm_plane *plane,
|
||||||
src_w = src_w >> 16;
|
src_w = src_w >> 16;
|
||||||
src_h = src_h >> 16;
|
src_h = src_h >> 16;
|
||||||
|
|
||||||
|
DBG("%s: FB[%u] %u,%u,%u,%u -> CRTC[%u] %d,%d,%u,%u", mdp4_plane->name,
|
||||||
|
fb->base.id, src_x, src_y, src_w, src_h,
|
||||||
|
crtc->base.id, crtc_x, crtc_y, crtc_w, crtc_h);
|
||||||
|
|
||||||
if (src_w != crtc_w) {
|
if (src_w != crtc_w) {
|
||||||
op_mode |= MDP4_PIPE_OP_MODE_SCALEX_EN;
|
op_mode |= MDP4_PIPE_OP_MODE_SCALEX_EN;
|
||||||
/* TODO calc phasex_step */
|
/* TODO calc phasex_step */
|
||||||
|
@ -191,7 +197,8 @@ int mdp4_plane_mode_set(struct drm_plane *plane,
|
||||||
mdp4_write(mdp4_kms, REG_MDP4_PIPE_PHASEX_STEP(pipe), phasex_step);
|
mdp4_write(mdp4_kms, REG_MDP4_PIPE_PHASEX_STEP(pipe), phasex_step);
|
||||||
mdp4_write(mdp4_kms, REG_MDP4_PIPE_PHASEY_STEP(pipe), phasey_step);
|
mdp4_write(mdp4_kms, REG_MDP4_PIPE_PHASEY_STEP(pipe), phasey_step);
|
||||||
|
|
||||||
plane->crtc = crtc;
|
/* TODO detach from old crtc (if we had more than one) */
|
||||||
|
mdp4_crtc_attach(crtc, plane);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -212,7 +219,6 @@ enum mdp4_pipe mdp4_plane_pipe(struct drm_plane *plane)
|
||||||
struct drm_plane *mdp4_plane_init(struct drm_device *dev,
|
struct drm_plane *mdp4_plane_init(struct drm_device *dev,
|
||||||
enum mdp4_pipe pipe_id, bool private_plane)
|
enum mdp4_pipe pipe_id, bool private_plane)
|
||||||
{
|
{
|
||||||
struct msm_drm_private *priv = dev->dev_private;
|
|
||||||
struct drm_plane *plane = NULL;
|
struct drm_plane *plane = NULL;
|
||||||
struct mdp4_plane *mdp4_plane;
|
struct mdp4_plane *mdp4_plane;
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -228,8 +234,12 @@ struct drm_plane *mdp4_plane_init(struct drm_device *dev,
|
||||||
mdp4_plane->pipe = pipe_id;
|
mdp4_plane->pipe = pipe_id;
|
||||||
mdp4_plane->name = pipe_names[pipe_id];
|
mdp4_plane->name = pipe_names[pipe_id];
|
||||||
|
|
||||||
drm_plane_init(dev, plane, (1 << priv->num_crtcs) - 1, &mdp4_plane_funcs,
|
mdp4_plane->nformats = mdp4_get_formats(pipe_id, mdp4_plane->formats,
|
||||||
mdp4_plane->formats, mdp4_plane->nformats, private_plane);
|
ARRAY_SIZE(mdp4_plane->formats));
|
||||||
|
|
||||||
|
drm_plane_init(dev, plane, 0xff, &mdp4_plane_funcs,
|
||||||
|
mdp4_plane->formats, mdp4_plane->nformats,
|
||||||
|
private_plane);
|
||||||
|
|
||||||
mdp4_plane_install_properties(plane, &plane->base);
|
mdp4_plane_install_properties(plane, &plane->base);
|
||||||
|
|
||||||
|
|
|
@ -77,6 +77,9 @@ struct msm_drm_private {
|
||||||
unsigned int num_iommus;
|
unsigned int num_iommus;
|
||||||
struct iommu_domain *iommus[NUM_DOMAINS];
|
struct iommu_domain *iommus[NUM_DOMAINS];
|
||||||
|
|
||||||
|
unsigned int num_planes;
|
||||||
|
struct drm_plane *planes[8];
|
||||||
|
|
||||||
unsigned int num_crtcs;
|
unsigned int num_crtcs;
|
||||||
struct drm_crtc *crtcs[8];
|
struct drm_crtc *crtcs[8];
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue