aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRob Clark <robdclark@gmail.com>2013-10-08 12:57:48 -0400
committerRob Clark <robdclark@gmail.com>2013-11-01 12:39:44 -0400
commita862391871004bf8dea2299bb712aa93a512334a (patch)
tree89f8d1d779f133bd4d271378d4d7df1a0eceeeab
parent22ba8b6b230aa584171fb06c656157e752943ed0 (diff)
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>
-rw-r--r--drivers/gpu/drm/msm/mdp4/mdp4_crtc.c136
-rw-r--r--drivers/gpu/drm/msm/mdp4/mdp4_format.c16
-rw-r--r--drivers/gpu/drm/msm/mdp4/mdp4_kms.c17
-rw-r--r--drivers/gpu/drm/msm/mdp4/mdp4_kms.h46
-rw-r--r--drivers/gpu/drm/msm/mdp4/mdp4_plane.c20
-rw-r--r--drivers/gpu/drm/msm/msm_drv.h3
6 files changed, 182 insertions, 56 deletions
diff --git a/drivers/gpu/drm/msm/mdp4/mdp4_crtc.c b/drivers/gpu/drm/msm/mdp4/mdp4_crtc.c
index de6bea297cda..5a68aab66fa2 100644
--- a/drivers/gpu/drm/msm/mdp4/mdp4_crtc.c
+++ b/drivers/gpu/drm/msm/mdp4/mdp4_crtc.c
@@ -26,6 +26,7 @@ struct mdp4_crtc {
26 struct drm_crtc base; 26 struct drm_crtc base;
27 char name[8]; 27 char name[8];
28 struct drm_plane *plane; 28 struct drm_plane *plane;
29 struct drm_plane *planes[8];
29 int id; 30 int id;
30 int ovlp; 31 int ovlp;
31 enum mdp4_dma dma; 32 enum mdp4_dma dma;
@@ -115,9 +116,15 @@ static void crtc_flush(struct drm_crtc *crtc)
115{ 116{
116 struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc); 117 struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);
117 struct mdp4_kms *mdp4_kms = get_kms(crtc); 118 struct mdp4_kms *mdp4_kms = get_kms(crtc);
118 uint32_t flush = 0; 119 uint32_t i, flush = 0;
119 120
120 flush |= pipe2flush(mdp4_plane_pipe(mdp4_crtc->plane)); 121 for (i = 0; i < ARRAY_SIZE(mdp4_crtc->planes); i++) {
122 struct drm_plane *plane = mdp4_crtc->planes[i];
123 if (plane) {
124 enum mdp4_pipe pipe_id = mdp4_plane_pipe(plane);
125 flush |= pipe2flush(pipe_id);
126 }
127 }
121 flush |= ovlp2flush(mdp4_crtc->ovlp); 128 flush |= ovlp2flush(mdp4_crtc->ovlp);
122 129
123 DBG("%s: flush=%08x", mdp4_crtc->name, flush); 130 DBG("%s: flush=%08x", mdp4_crtc->name, flush);
@@ -205,67 +212,69 @@ static void blend_setup(struct drm_crtc *crtc)
205 struct mdp4_kms *mdp4_kms = get_kms(crtc); 212 struct mdp4_kms *mdp4_kms = get_kms(crtc);
206 int i, ovlp = mdp4_crtc->ovlp; 213 int i, ovlp = mdp4_crtc->ovlp;
207 uint32_t mixer_cfg = 0; 214 uint32_t mixer_cfg = 0;
208 215 static const enum mdp4_mixer_stage_id stages[] = {
209 /* 216 STAGE_BASE, STAGE0, STAGE1, STAGE2, STAGE3,
210 * This probably would also need to be triggered by any attached 217 };
211 * plane when it changes.. for now since we are only using a single 218 /* statically (for now) map planes to mixer stage (z-order): */
212 * private plane, the configuration is hard-coded: 219 static const int idxs[] = {
213 */ 220 [VG1] = 1,
221 [VG2] = 2,
222 [RGB1] = 0,
223 [RGB2] = 0,
224 [RGB3] = 0,
225 [VG3] = 3,
226 [VG4] = 4,
227
228 };
229 bool alpha[4]= { false, false, false, false };
214 230
215 mdp4_write(mdp4_kms, REG_MDP4_OVLP_TRANSP_LOW0(ovlp), 0); 231 mdp4_write(mdp4_kms, REG_MDP4_OVLP_TRANSP_LOW0(ovlp), 0);
216 mdp4_write(mdp4_kms, REG_MDP4_OVLP_TRANSP_LOW1(ovlp), 0); 232 mdp4_write(mdp4_kms, REG_MDP4_OVLP_TRANSP_LOW1(ovlp), 0);
217 mdp4_write(mdp4_kms, REG_MDP4_OVLP_TRANSP_HIGH0(ovlp), 0); 233 mdp4_write(mdp4_kms, REG_MDP4_OVLP_TRANSP_HIGH0(ovlp), 0);
218 mdp4_write(mdp4_kms, REG_MDP4_OVLP_TRANSP_HIGH1(ovlp), 0); 234 mdp4_write(mdp4_kms, REG_MDP4_OVLP_TRANSP_HIGH1(ovlp), 0);
219 235
236 /* TODO single register for all CRTCs, so this won't work properly
237 * when multiple CRTCs are active..
238 */
239 for (i = 0; i < ARRAY_SIZE(mdp4_crtc->planes); i++) {
240 struct drm_plane *plane = mdp4_crtc->planes[i];
241 if (plane) {
242 enum mdp4_pipe pipe_id = mdp4_plane_pipe(plane);
243 int idx = idxs[pipe_id];
244 if (idx > 0) {
245 const struct mdp4_format *format =
246 to_mdp4_format(msm_framebuffer_format(plane->fb));
247 alpha[idx-1] = format->alpha_enable;
248 }
249 mixer_cfg |= mixercfg(mdp4_crtc->mixer, pipe_id, stages[idx]);
250 }
251 }
252
253 /* this shouldn't happen.. and seems to cause underflow: */
254 WARN_ON(!mixer_cfg);
255
220 for (i = 0; i < 4; i++) { 256 for (i = 0; i < 4; i++) {
221 mdp4_write(mdp4_kms, REG_MDP4_OVLP_STAGE_FG_ALPHA(ovlp, i), 0); 257 uint32_t op;
222 mdp4_write(mdp4_kms, REG_MDP4_OVLP_STAGE_BG_ALPHA(ovlp, i), 0); 258
223 mdp4_write(mdp4_kms, REG_MDP4_OVLP_STAGE_OP(ovlp, i), 259 if (alpha[i]) {
224 MDP4_OVLP_STAGE_OP_FG_ALPHA(FG_CONST) | 260 op = MDP4_OVLP_STAGE_OP_FG_ALPHA(FG_PIXEL) |
225 MDP4_OVLP_STAGE_OP_BG_ALPHA(BG_CONST)); 261 MDP4_OVLP_STAGE_OP_BG_ALPHA(FG_PIXEL) |
226 mdp4_write(mdp4_kms, REG_MDP4_OVLP_STAGE_CO3(ovlp, i), 0); 262 MDP4_OVLP_STAGE_OP_BG_INV_ALPHA;
263 } else {
264 op = MDP4_OVLP_STAGE_OP_FG_ALPHA(FG_CONST) |
265 MDP4_OVLP_STAGE_OP_BG_ALPHA(BG_CONST);
266 }
267
268 mdp4_write(mdp4_kms, REG_MDP4_OVLP_STAGE_FG_ALPHA(ovlp, i), 0xff);
269 mdp4_write(mdp4_kms, REG_MDP4_OVLP_STAGE_BG_ALPHA(ovlp, i), 0x00);
270 mdp4_write(mdp4_kms, REG_MDP4_OVLP_STAGE_OP(ovlp, i), op);
271 mdp4_write(mdp4_kms, REG_MDP4_OVLP_STAGE_CO3(ovlp, i), 1);
227 mdp4_write(mdp4_kms, REG_MDP4_OVLP_STAGE_TRANSP_LOW0(ovlp, i), 0); 272 mdp4_write(mdp4_kms, REG_MDP4_OVLP_STAGE_TRANSP_LOW0(ovlp, i), 0);
228 mdp4_write(mdp4_kms, REG_MDP4_OVLP_STAGE_TRANSP_LOW1(ovlp, i), 0); 273 mdp4_write(mdp4_kms, REG_MDP4_OVLP_STAGE_TRANSP_LOW1(ovlp, i), 0);
229 mdp4_write(mdp4_kms, REG_MDP4_OVLP_STAGE_TRANSP_HIGH0(ovlp, i), 0); 274 mdp4_write(mdp4_kms, REG_MDP4_OVLP_STAGE_TRANSP_HIGH0(ovlp, i), 0);
230 mdp4_write(mdp4_kms, REG_MDP4_OVLP_STAGE_TRANSP_HIGH1(ovlp, i), 0); 275 mdp4_write(mdp4_kms, REG_MDP4_OVLP_STAGE_TRANSP_HIGH1(ovlp, i), 0);
231 } 276 }
232 277
233 /* TODO single register for all CRTCs, so this won't work properly
234 * when multiple CRTCs are active..
235 */
236 switch (mdp4_plane_pipe(mdp4_crtc->plane)) {
237 case VG1:
238 mixer_cfg = MDP4_LAYERMIXER_IN_CFG_PIPE0(STAGE_BASE) |
239 COND(mdp4_crtc->mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE0_MIXER1);
240 break;
241 case VG2:
242 mixer_cfg = MDP4_LAYERMIXER_IN_CFG_PIPE1(STAGE_BASE) |
243 COND(mdp4_crtc->mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE1_MIXER1);
244 break;
245 case RGB1:
246 mixer_cfg = MDP4_LAYERMIXER_IN_CFG_PIPE2(STAGE_BASE) |
247 COND(mdp4_crtc->mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE2_MIXER1);
248 break;
249 case RGB2:
250 mixer_cfg = MDP4_LAYERMIXER_IN_CFG_PIPE3(STAGE_BASE) |
251 COND(mdp4_crtc->mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE3_MIXER1);
252 break;
253 case RGB3:
254 mixer_cfg = MDP4_LAYERMIXER_IN_CFG_PIPE4(STAGE_BASE) |
255 COND(mdp4_crtc->mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE4_MIXER1);
256 break;
257 case VG3:
258 mixer_cfg = MDP4_LAYERMIXER_IN_CFG_PIPE5(STAGE_BASE) |
259 COND(mdp4_crtc->mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE5_MIXER1);
260 break;
261 case VG4:
262 mixer_cfg = MDP4_LAYERMIXER_IN_CFG_PIPE6(STAGE_BASE) |
263 COND(mdp4_crtc->mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE6_MIXER1);
264 break;
265 default:
266 WARN_ON("invalid pipe");
267 break;
268 }
269 mdp4_write(mdp4_kms, REG_MDP4_LAYERMIXER_IN_CFG, mixer_cfg); 278 mdp4_write(mdp4_kms, REG_MDP4_LAYERMIXER_IN_CFG, mixer_cfg);
270} 279}
271 280
@@ -622,6 +631,32 @@ void mdp4_crtc_set_intf(struct drm_crtc *crtc, enum mdp4_intf intf)
622 mdp4_write(mdp4_kms, REG_MDP4_DISP_INTF_SEL, intf_sel); 631 mdp4_write(mdp4_kms, REG_MDP4_DISP_INTF_SEL, intf_sel);
623} 632}
624 633
634static void set_attach(struct drm_crtc *crtc, enum mdp4_pipe pipe_id,
635 struct drm_plane *plane)
636{
637 struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);
638
639 BUG_ON(pipe_id >= ARRAY_SIZE(mdp4_crtc->planes));
640
641 if (mdp4_crtc->planes[pipe_id] == plane)
642 return;
643
644 mdp4_crtc->planes[pipe_id] = plane;
645 blend_setup(crtc);
646 if (mdp4_crtc->enabled && (plane != mdp4_crtc->plane))
647 crtc_flush(crtc);
648}
649
650void mdp4_crtc_attach(struct drm_crtc *crtc, struct drm_plane *plane)
651{
652 set_attach(crtc, mdp4_plane_pipe(plane), plane);
653}
654
655void mdp4_crtc_detach(struct drm_crtc *crtc, struct drm_plane *plane)
656{
657 set_attach(crtc, mdp4_plane_pipe(plane), NULL);
658}
659
625static const char *dma_names[] = { 660static const char *dma_names[] = {
626 "DMA_P", "DMA_S", "DMA_E", 661 "DMA_P", "DMA_S", "DMA_E",
627}; 662};
@@ -644,7 +679,6 @@ struct drm_crtc *mdp4_crtc_init(struct drm_device *dev,
644 crtc = &mdp4_crtc->base; 679 crtc = &mdp4_crtc->base;
645 680
646 mdp4_crtc->plane = plane; 681 mdp4_crtc->plane = plane;
647 mdp4_crtc->plane->crtc = crtc;
648 682
649 mdp4_crtc->ovlp = ovlp_id; 683 mdp4_crtc->ovlp = ovlp_id;
650 mdp4_crtc->dma = dma_id; 684 mdp4_crtc->dma = dma_id;
diff --git a/drivers/gpu/drm/msm/mdp4/mdp4_format.c b/drivers/gpu/drm/msm/mdp4/mdp4_format.c
index 7b645f2e837a..17330b0927b2 100644
--- a/drivers/gpu/drm/msm/mdp4/mdp4_format.c
+++ b/drivers/gpu/drm/msm/mdp4/mdp4_format.c
@@ -44,6 +44,22 @@ static const struct mdp4_format formats[] = {
44 FMT(BGR565, 0, 5, 6, 5, 2, 0, 1, 0, false, true, 2, 3), 44 FMT(BGR565, 0, 5, 6, 5, 2, 0, 1, 0, false, true, 2, 3),
45}; 45};
46 46
47uint32_t mdp4_get_formats(enum mdp4_pipe pipe_id, uint32_t *pixel_formats,
48 uint32_t max_formats)
49{
50 uint32_t i;
51 for (i = 0; i < ARRAY_SIZE(formats); i++) {
52 const struct mdp4_format *f = &formats[i];
53
54 if (i == max_formats)
55 break;
56
57 pixel_formats[i] = f->base.pixel_format;
58 }
59
60 return i;
61}
62
47const struct msm_format *mdp4_get_format(struct msm_kms *kms, uint32_t format) 63const struct msm_format *mdp4_get_format(struct msm_kms *kms, uint32_t format)
48{ 64{
49 int i; 65 int i;
diff --git a/drivers/gpu/drm/msm/mdp4/mdp4_kms.c b/drivers/gpu/drm/msm/mdp4/mdp4_kms.c
index bc7fd11ad8be..c2485a71faa8 100644
--- a/drivers/gpu/drm/msm/mdp4/mdp4_kms.c
+++ b/drivers/gpu/drm/msm/mdp4/mdp4_kms.c
@@ -196,6 +196,23 @@ static int modeset_init(struct mdp4_kms *mdp4_kms)
196 * for more than just RGB1->DMA_E->DTV->HDMI 196 * for more than just RGB1->DMA_E->DTV->HDMI
197 */ 197 */
198 198
199 /* construct non-private planes: */
200 plane = mdp4_plane_init(dev, VG1, false);
201 if (IS_ERR(plane)) {
202 dev_err(dev->dev, "failed to construct plane for VG1\n");
203 ret = PTR_ERR(plane);
204 goto fail;
205 }
206 priv->planes[priv->num_planes++] = plane;
207
208 plane = mdp4_plane_init(dev, VG2, false);
209 if (IS_ERR(plane)) {
210 dev_err(dev->dev, "failed to construct plane for VG2\n");
211 ret = PTR_ERR(plane);
212 goto fail;
213 }
214 priv->planes[priv->num_planes++] = plane;
215
199 /* the CRTCs get constructed with a private plane: */ 216 /* the CRTCs get constructed with a private plane: */
200 plane = mdp4_plane_init(dev, RGB1, true); 217 plane = mdp4_plane_init(dev, RGB1, true);
201 if (IS_ERR(plane)) { 218 if (IS_ERR(plane)) {
diff --git a/drivers/gpu/drm/msm/mdp4/mdp4_kms.h b/drivers/gpu/drm/msm/mdp4/mdp4_kms.h
index 35ed3ab7da10..11c34387aeb6 100644
--- a/drivers/gpu/drm/msm/mdp4/mdp4_kms.h
+++ b/drivers/gpu/drm/msm/mdp4/mdp4_kms.h
@@ -133,6 +133,48 @@ static inline uint32_t dma2err(enum mdp4_dma dma)
133 } 133 }
134} 134}
135 135
136static inline uint32_t mixercfg(int mixer, enum mdp4_pipe pipe,
137 enum mdp4_mixer_stage_id stage)
138{
139 uint32_t mixer_cfg = 0;
140
141 switch (pipe) {
142 case VG1:
143 mixer_cfg = MDP4_LAYERMIXER_IN_CFG_PIPE0(stage) |
144 COND(mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE0_MIXER1);
145 break;
146 case VG2:
147 mixer_cfg = MDP4_LAYERMIXER_IN_CFG_PIPE1(stage) |
148 COND(mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE1_MIXER1);
149 break;
150 case RGB1:
151 mixer_cfg = MDP4_LAYERMIXER_IN_CFG_PIPE2(stage) |
152 COND(mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE2_MIXER1);
153 break;
154 case RGB2:
155 mixer_cfg = MDP4_LAYERMIXER_IN_CFG_PIPE3(stage) |
156 COND(mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE3_MIXER1);
157 break;
158 case RGB3:
159 mixer_cfg = MDP4_LAYERMIXER_IN_CFG_PIPE4(stage) |
160 COND(mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE4_MIXER1);
161 break;
162 case VG3:
163 mixer_cfg = MDP4_LAYERMIXER_IN_CFG_PIPE5(stage) |
164 COND(mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE5_MIXER1);
165 break;
166 case VG4:
167 mixer_cfg = MDP4_LAYERMIXER_IN_CFG_PIPE6(stage) |
168 COND(mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE6_MIXER1);
169 break;
170 default:
171 WARN_ON("invalid pipe");
172 break;
173 }
174
175 return mixer_cfg;
176}
177
136int mdp4_disable(struct mdp4_kms *mdp4_kms); 178int mdp4_disable(struct mdp4_kms *mdp4_kms);
137int mdp4_enable(struct mdp4_kms *mdp4_kms); 179int mdp4_enable(struct mdp4_kms *mdp4_kms);
138 180
@@ -146,6 +188,8 @@ void mdp4_irq_unregister(struct mdp4_kms *mdp4_kms, struct mdp4_irq *irq);
146int mdp4_enable_vblank(struct msm_kms *kms, struct drm_crtc *crtc); 188int mdp4_enable_vblank(struct msm_kms *kms, struct drm_crtc *crtc);
147void mdp4_disable_vblank(struct msm_kms *kms, struct drm_crtc *crtc); 189void mdp4_disable_vblank(struct msm_kms *kms, struct drm_crtc *crtc);
148 190
191uint32_t mdp4_get_formats(enum mdp4_pipe pipe_id, uint32_t *formats,
192 uint32_t max_formats);
149const struct msm_format *mdp4_get_format(struct msm_kms *kms, uint32_t format); 193const struct msm_format *mdp4_get_format(struct msm_kms *kms, uint32_t format);
150 194
151void mdp4_plane_install_properties(struct drm_plane *plane, 195void mdp4_plane_install_properties(struct drm_plane *plane,
@@ -166,6 +210,8 @@ uint32_t mdp4_crtc_vblank(struct drm_crtc *crtc);
166void mdp4_crtc_cancel_pending_flip(struct drm_crtc *crtc); 210void mdp4_crtc_cancel_pending_flip(struct drm_crtc *crtc);
167void mdp4_crtc_set_config(struct drm_crtc *crtc, uint32_t config); 211void mdp4_crtc_set_config(struct drm_crtc *crtc, uint32_t config);
168void mdp4_crtc_set_intf(struct drm_crtc *crtc, enum mdp4_intf intf); 212void mdp4_crtc_set_intf(struct drm_crtc *crtc, enum mdp4_intf intf);
213void mdp4_crtc_attach(struct drm_crtc *crtc, struct drm_plane *plane);
214void mdp4_crtc_detach(struct drm_crtc *crtc, struct drm_plane *plane);
169struct drm_crtc *mdp4_crtc_init(struct drm_device *dev, 215struct drm_crtc *mdp4_crtc_init(struct drm_device *dev,
170 struct drm_plane *plane, int id, int ovlp_id, 216 struct drm_plane *plane, int id, int ovlp_id,
171 enum mdp4_dma dma_id); 217 enum mdp4_dma dma_id);
diff --git a/drivers/gpu/drm/msm/mdp4/mdp4_plane.c b/drivers/gpu/drm/msm/mdp4/mdp4_plane.c
index a5eddf5d5f98..0f0af243f6fc 100644
--- a/drivers/gpu/drm/msm/mdp4/mdp4_plane.c
+++ b/drivers/gpu/drm/msm/mdp4/mdp4_plane.c
@@ -61,7 +61,9 @@ static int mdp4_plane_update(struct drm_plane *plane,
61static int mdp4_plane_disable(struct drm_plane *plane) 61static int mdp4_plane_disable(struct drm_plane *plane)
62{ 62{
63 struct mdp4_plane *mdp4_plane = to_mdp4_plane(plane); 63 struct mdp4_plane *mdp4_plane = to_mdp4_plane(plane);
64 DBG("%s: TODO", mdp4_plane->name); // XXX 64 DBG("%s: disable", mdp4_plane->name);
65 if (plane->crtc)
66 mdp4_crtc_detach(plane->crtc, plane);
65 return 0; 67 return 0;
66} 68}
67 69
@@ -141,6 +143,10 @@ int mdp4_plane_mode_set(struct drm_plane *plane,
141 src_w = src_w >> 16; 143 src_w = src_w >> 16;
142 src_h = src_h >> 16; 144 src_h = src_h >> 16;
143 145
146 DBG("%s: FB[%u] %u,%u,%u,%u -> CRTC[%u] %d,%d,%u,%u", mdp4_plane->name,
147 fb->base.id, src_x, src_y, src_w, src_h,
148 crtc->base.id, crtc_x, crtc_y, crtc_w, crtc_h);
149
144 if (src_w != crtc_w) { 150 if (src_w != crtc_w) {
145 op_mode |= MDP4_PIPE_OP_MODE_SCALEX_EN; 151 op_mode |= MDP4_PIPE_OP_MODE_SCALEX_EN;
146 /* TODO calc phasex_step */ 152 /* TODO calc phasex_step */
@@ -191,7 +197,8 @@ int mdp4_plane_mode_set(struct drm_plane *plane,
191 mdp4_write(mdp4_kms, REG_MDP4_PIPE_PHASEX_STEP(pipe), phasex_step); 197 mdp4_write(mdp4_kms, REG_MDP4_PIPE_PHASEX_STEP(pipe), phasex_step);
192 mdp4_write(mdp4_kms, REG_MDP4_PIPE_PHASEY_STEP(pipe), phasey_step); 198 mdp4_write(mdp4_kms, REG_MDP4_PIPE_PHASEY_STEP(pipe), phasey_step);
193 199
194 plane->crtc = crtc; 200 /* TODO detach from old crtc (if we had more than one) */
201 mdp4_crtc_attach(crtc, plane);
195 202
196 return 0; 203 return 0;
197} 204}
@@ -212,7 +219,6 @@ enum mdp4_pipe mdp4_plane_pipe(struct drm_plane *plane)
212struct drm_plane *mdp4_plane_init(struct drm_device *dev, 219struct drm_plane *mdp4_plane_init(struct drm_device *dev,
213 enum mdp4_pipe pipe_id, bool private_plane) 220 enum mdp4_pipe pipe_id, bool private_plane)
214{ 221{
215 struct msm_drm_private *priv = dev->dev_private;
216 struct drm_plane *plane = NULL; 222 struct drm_plane *plane = NULL;
217 struct mdp4_plane *mdp4_plane; 223 struct mdp4_plane *mdp4_plane;
218 int ret; 224 int ret;
@@ -228,8 +234,12 @@ struct drm_plane *mdp4_plane_init(struct drm_device *dev,
228 mdp4_plane->pipe = pipe_id; 234 mdp4_plane->pipe = pipe_id;
229 mdp4_plane->name = pipe_names[pipe_id]; 235 mdp4_plane->name = pipe_names[pipe_id];
230 236
231 drm_plane_init(dev, plane, (1 << priv->num_crtcs) - 1, &mdp4_plane_funcs, 237 mdp4_plane->nformats = mdp4_get_formats(pipe_id, mdp4_plane->formats,
232 mdp4_plane->formats, mdp4_plane->nformats, private_plane); 238 ARRAY_SIZE(mdp4_plane->formats));
239
240 drm_plane_init(dev, plane, 0xff, &mdp4_plane_funcs,
241 mdp4_plane->formats, mdp4_plane->nformats,
242 private_plane);
233 243
234 mdp4_plane_install_properties(plane, &plane->base); 244 mdp4_plane_install_properties(plane, &plane->base);
235 245
diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h
index 9ce90c267ef8..2c6bad5905e8 100644
--- a/drivers/gpu/drm/msm/msm_drv.h
+++ b/drivers/gpu/drm/msm/msm_drv.h
@@ -77,6 +77,9 @@ struct msm_drm_private {
77 unsigned int num_iommus; 77 unsigned int num_iommus;
78 struct iommu_domain *iommus[NUM_DOMAINS]; 78 struct iommu_domain *iommus[NUM_DOMAINS];
79 79
80 unsigned int num_planes;
81 struct drm_plane *planes[8];
82
80 unsigned int num_crtcs; 83 unsigned int num_crtcs;
81 struct drm_crtc *crtcs[8]; 84 struct drm_crtc *crtcs[8];
82 85