diff options
author | Rob Clark <robdclark@gmail.com> | 2013-10-08 12:57:48 -0400 |
---|---|---|
committer | Rob Clark <robdclark@gmail.com> | 2013-11-01 12:39:44 -0400 |
commit | a862391871004bf8dea2299bb712aa93a512334a (patch) | |
tree | 89f8d1d779f133bd4d271378d4d7df1a0eceeeab | |
parent | 22ba8b6b230aa584171fb06c656157e752943ed0 (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.c | 136 | ||||
-rw-r--r-- | drivers/gpu/drm/msm/mdp4/mdp4_format.c | 16 | ||||
-rw-r--r-- | drivers/gpu/drm/msm/mdp4/mdp4_kms.c | 17 | ||||
-rw-r--r-- | drivers/gpu/drm/msm/mdp4/mdp4_kms.h | 46 | ||||
-rw-r--r-- | drivers/gpu/drm/msm/mdp4/mdp4_plane.c | 20 | ||||
-rw-r--r-- | drivers/gpu/drm/msm/msm_drv.h | 3 |
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 | ||
634 | static 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 | |||
650 | void mdp4_crtc_attach(struct drm_crtc *crtc, struct drm_plane *plane) | ||
651 | { | ||
652 | set_attach(crtc, mdp4_plane_pipe(plane), plane); | ||
653 | } | ||
654 | |||
655 | void mdp4_crtc_detach(struct drm_crtc *crtc, struct drm_plane *plane) | ||
656 | { | ||
657 | set_attach(crtc, mdp4_plane_pipe(plane), NULL); | ||
658 | } | ||
659 | |||
625 | static const char *dma_names[] = { | 660 | static 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 | ||
47 | uint32_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 | |||
47 | const struct msm_format *mdp4_get_format(struct msm_kms *kms, uint32_t format) | 63 | const 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 | ||
136 | static 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 | |||
136 | int mdp4_disable(struct mdp4_kms *mdp4_kms); | 178 | int mdp4_disable(struct mdp4_kms *mdp4_kms); |
137 | int mdp4_enable(struct mdp4_kms *mdp4_kms); | 179 | int 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); | |||
146 | int mdp4_enable_vblank(struct msm_kms *kms, struct drm_crtc *crtc); | 188 | int mdp4_enable_vblank(struct msm_kms *kms, struct drm_crtc *crtc); |
147 | void mdp4_disable_vblank(struct msm_kms *kms, struct drm_crtc *crtc); | 189 | void mdp4_disable_vblank(struct msm_kms *kms, struct drm_crtc *crtc); |
148 | 190 | ||
191 | uint32_t mdp4_get_formats(enum mdp4_pipe pipe_id, uint32_t *formats, | ||
192 | uint32_t max_formats); | ||
149 | const struct msm_format *mdp4_get_format(struct msm_kms *kms, uint32_t format); | 193 | const struct msm_format *mdp4_get_format(struct msm_kms *kms, uint32_t format); |
150 | 194 | ||
151 | void mdp4_plane_install_properties(struct drm_plane *plane, | 195 | void mdp4_plane_install_properties(struct drm_plane *plane, |
@@ -166,6 +210,8 @@ uint32_t mdp4_crtc_vblank(struct drm_crtc *crtc); | |||
166 | void mdp4_crtc_cancel_pending_flip(struct drm_crtc *crtc); | 210 | void mdp4_crtc_cancel_pending_flip(struct drm_crtc *crtc); |
167 | void mdp4_crtc_set_config(struct drm_crtc *crtc, uint32_t config); | 211 | void mdp4_crtc_set_config(struct drm_crtc *crtc, uint32_t config); |
168 | void mdp4_crtc_set_intf(struct drm_crtc *crtc, enum mdp4_intf intf); | 212 | void mdp4_crtc_set_intf(struct drm_crtc *crtc, enum mdp4_intf intf); |
213 | void mdp4_crtc_attach(struct drm_crtc *crtc, struct drm_plane *plane); | ||
214 | void mdp4_crtc_detach(struct drm_crtc *crtc, struct drm_plane *plane); | ||
169 | struct drm_crtc *mdp4_crtc_init(struct drm_device *dev, | 215 | struct 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, | |||
61 | static int mdp4_plane_disable(struct drm_plane *plane) | 61 | static 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) | |||
212 | struct drm_plane *mdp4_plane_init(struct drm_device *dev, | 219 | struct 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 | ||