diff options
| -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 | ||
