diff options
-rw-r--r-- | drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c | 21 | ||||
-rw-r--r-- | drivers/gpu/drm/msm/mdp/mdp4/mdp4_dtv_encoder.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h | 43 | ||||
-rw-r--r-- | drivers/gpu/drm/msm/msm_drv.c | 2 |
5 files changed, 46 insertions, 23 deletions
diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c index 74cebb51e8c2..f9bc0ef8b836 100644 --- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c +++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c | |||
@@ -273,14 +273,17 @@ static void blend_setup(struct drm_crtc *crtc) | |||
273 | }; | 273 | }; |
274 | bool alpha[4]= { false, false, false, false }; | 274 | bool alpha[4]= { false, false, false, false }; |
275 | 275 | ||
276 | /* Don't rely on value read back from hw, but instead use our | ||
277 | * own shadowed value. Possibly disable/reenable looses the | ||
278 | * previous value and goes back to power-on default? | ||
279 | */ | ||
280 | mixer_cfg = mdp4_kms->mixer_cfg; | ||
281 | |||
276 | mdp4_write(mdp4_kms, REG_MDP4_OVLP_TRANSP_LOW0(ovlp), 0); | 282 | mdp4_write(mdp4_kms, REG_MDP4_OVLP_TRANSP_LOW0(ovlp), 0); |
277 | mdp4_write(mdp4_kms, REG_MDP4_OVLP_TRANSP_LOW1(ovlp), 0); | 283 | mdp4_write(mdp4_kms, REG_MDP4_OVLP_TRANSP_LOW1(ovlp), 0); |
278 | mdp4_write(mdp4_kms, REG_MDP4_OVLP_TRANSP_HIGH0(ovlp), 0); | 284 | mdp4_write(mdp4_kms, REG_MDP4_OVLP_TRANSP_HIGH0(ovlp), 0); |
279 | mdp4_write(mdp4_kms, REG_MDP4_OVLP_TRANSP_HIGH1(ovlp), 0); | 285 | mdp4_write(mdp4_kms, REG_MDP4_OVLP_TRANSP_HIGH1(ovlp), 0); |
280 | 286 | ||
281 | /* TODO single register for all CRTCs, so this won't work properly | ||
282 | * when multiple CRTCs are active.. | ||
283 | */ | ||
284 | for (i = 0; i < ARRAY_SIZE(mdp4_crtc->planes); i++) { | 287 | for (i = 0; i < ARRAY_SIZE(mdp4_crtc->planes); i++) { |
285 | struct drm_plane *plane = mdp4_crtc->planes[i]; | 288 | struct drm_plane *plane = mdp4_crtc->planes[i]; |
286 | if (plane) { | 289 | if (plane) { |
@@ -291,7 +294,8 @@ static void blend_setup(struct drm_crtc *crtc) | |||
291 | to_mdp_format(msm_framebuffer_format(plane->fb)); | 294 | to_mdp_format(msm_framebuffer_format(plane->fb)); |
292 | alpha[idx-1] = format->alpha_enable; | 295 | alpha[idx-1] = format->alpha_enable; |
293 | } | 296 | } |
294 | mixer_cfg |= mixercfg(mdp4_crtc->mixer, pipe_id, stages[idx]); | 297 | mixer_cfg = mixercfg(mixer_cfg, mdp4_crtc->mixer, |
298 | pipe_id, stages[idx]); | ||
295 | } | 299 | } |
296 | } | 300 | } |
297 | 301 | ||
@@ -320,6 +324,7 @@ static void blend_setup(struct drm_crtc *crtc) | |||
320 | mdp4_write(mdp4_kms, REG_MDP4_OVLP_STAGE_TRANSP_HIGH1(ovlp, i), 0); | 324 | mdp4_write(mdp4_kms, REG_MDP4_OVLP_STAGE_TRANSP_HIGH1(ovlp, i), 0); |
321 | } | 325 | } |
322 | 326 | ||
327 | mdp4_kms->mixer_cfg = mixer_cfg; | ||
323 | mdp4_write(mdp4_kms, REG_MDP4_LAYERMIXER_IN_CFG, mixer_cfg); | 328 | mdp4_write(mdp4_kms, REG_MDP4_LAYERMIXER_IN_CFG, mixer_cfg); |
324 | } | 329 | } |
325 | 330 | ||
@@ -670,7 +675,7 @@ void mdp4_crtc_set_config(struct drm_crtc *crtc, uint32_t config) | |||
670 | } | 675 | } |
671 | 676 | ||
672 | /* set interface for routing crtc->encoder: */ | 677 | /* set interface for routing crtc->encoder: */ |
673 | void mdp4_crtc_set_intf(struct drm_crtc *crtc, enum mdp4_intf intf) | 678 | void mdp4_crtc_set_intf(struct drm_crtc *crtc, enum mdp4_intf intf, int mixer) |
674 | { | 679 | { |
675 | struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc); | 680 | struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc); |
676 | struct mdp4_kms *mdp4_kms = get_kms(crtc); | 681 | struct mdp4_kms *mdp4_kms = get_kms(crtc); |
@@ -696,15 +701,13 @@ void mdp4_crtc_set_intf(struct drm_crtc *crtc, enum mdp4_intf intf) | |||
696 | if (intf == INTF_DSI_VIDEO) { | 701 | if (intf == INTF_DSI_VIDEO) { |
697 | intf_sel &= ~MDP4_DISP_INTF_SEL_DSI_CMD; | 702 | intf_sel &= ~MDP4_DISP_INTF_SEL_DSI_CMD; |
698 | intf_sel |= MDP4_DISP_INTF_SEL_DSI_VIDEO; | 703 | intf_sel |= MDP4_DISP_INTF_SEL_DSI_VIDEO; |
699 | mdp4_crtc->mixer = 0; | ||
700 | } else if (intf == INTF_DSI_CMD) { | 704 | } else if (intf == INTF_DSI_CMD) { |
701 | intf_sel &= ~MDP4_DISP_INTF_SEL_DSI_VIDEO; | 705 | intf_sel &= ~MDP4_DISP_INTF_SEL_DSI_VIDEO; |
702 | intf_sel |= MDP4_DISP_INTF_SEL_DSI_CMD; | 706 | intf_sel |= MDP4_DISP_INTF_SEL_DSI_CMD; |
703 | mdp4_crtc->mixer = 0; | ||
704 | } else if (intf == INTF_LCDC_DTV){ | ||
705 | mdp4_crtc->mixer = 1; | ||
706 | } | 707 | } |
707 | 708 | ||
709 | mdp4_crtc->mixer = mixer; | ||
710 | |||
708 | blend_setup(crtc); | 711 | blend_setup(crtc); |
709 | 712 | ||
710 | DBG("%s: intf_sel=%08x", mdp4_crtc->name, intf_sel); | 713 | DBG("%s: intf_sel=%08x", mdp4_crtc->name, intf_sel); |
diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_dtv_encoder.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_dtv_encoder.c index 067ed03b35fe..c3878420180b 100644 --- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_dtv_encoder.c +++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_dtv_encoder.c | |||
@@ -233,7 +233,7 @@ static void mdp4_dtv_encoder_commit(struct drm_encoder *encoder) | |||
233 | MDP4_DMA_CONFIG_G_BPC(BPC8) | | 233 | MDP4_DMA_CONFIG_G_BPC(BPC8) | |
234 | MDP4_DMA_CONFIG_B_BPC(BPC8) | | 234 | MDP4_DMA_CONFIG_B_BPC(BPC8) | |
235 | MDP4_DMA_CONFIG_PACK(0x21)); | 235 | MDP4_DMA_CONFIG_PACK(0x21)); |
236 | mdp4_crtc_set_intf(encoder->crtc, INTF_LCDC_DTV); | 236 | mdp4_crtc_set_intf(encoder->crtc, INTF_LCDC_DTV, 1); |
237 | mdp4_dtv_encoder_dpms(encoder, DRM_MODE_DPMS_ON); | 237 | mdp4_dtv_encoder_dpms(encoder, DRM_MODE_DPMS_ON); |
238 | } | 238 | } |
239 | 239 | ||
diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c index 733646c0d3f8..af69079082f7 100644 --- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c +++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c | |||
@@ -106,6 +106,7 @@ static int mdp4_hw_init(struct msm_kms *kms) | |||
106 | 106 | ||
107 | if (mdp4_kms->rev >= 2) | 107 | if (mdp4_kms->rev >= 2) |
108 | mdp4_write(mdp4_kms, REG_MDP4_LAYERMIXER_IN_CFG_UPDATE_METHOD, 1); | 108 | mdp4_write(mdp4_kms, REG_MDP4_LAYERMIXER_IN_CFG_UPDATE_METHOD, 1); |
109 | mdp4_write(mdp4_kms, REG_MDP4_LAYERMIXER_IN_CFG, 0); | ||
109 | 110 | ||
110 | /* disable CSC matrix / YUV by default: */ | 111 | /* disable CSC matrix / YUV by default: */ |
111 | mdp4_write(mdp4_kms, REG_MDP4_PIPE_OP_MODE(VG1), 0); | 112 | mdp4_write(mdp4_kms, REG_MDP4_PIPE_OP_MODE(VG1), 0); |
diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h index 6a8a94f0cb96..e74146fe2ae6 100644 --- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h +++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h | |||
@@ -30,6 +30,13 @@ struct mdp4_kms { | |||
30 | 30 | ||
31 | int rev; | 31 | int rev; |
32 | 32 | ||
33 | /* Shadow value for MDP4_LAYERMIXER_IN_CFG.. since setup for all | ||
34 | * crtcs/encoders is in one shared register, we need to update it | ||
35 | * via read/modify/write. But to avoid getting confused by power- | ||
36 | * on-default values after resume, use this shadow value instead: | ||
37 | */ | ||
38 | uint32_t mixer_cfg; | ||
39 | |||
33 | /* mapper-id used to request GEM buffer mapped for scanout: */ | 40 | /* mapper-id used to request GEM buffer mapped for scanout: */ |
34 | int id; | 41 | int id; |
35 | 42 | ||
@@ -108,38 +115,50 @@ static inline uint32_t dma2err(enum mdp4_dma dma) | |||
108 | } | 115 | } |
109 | } | 116 | } |
110 | 117 | ||
111 | static inline uint32_t mixercfg(int mixer, enum mdp4_pipe pipe, | 118 | static inline uint32_t mixercfg(uint32_t mixer_cfg, int mixer, |
112 | enum mdp_mixer_stage_id stage) | 119 | enum mdp4_pipe pipe, enum mdp_mixer_stage_id stage) |
113 | { | 120 | { |
114 | uint32_t mixer_cfg = 0; | ||
115 | |||
116 | switch (pipe) { | 121 | switch (pipe) { |
117 | case VG1: | 122 | case VG1: |
118 | mixer_cfg = MDP4_LAYERMIXER_IN_CFG_PIPE0(stage) | | 123 | mixer_cfg &= ~(MDP4_LAYERMIXER_IN_CFG_PIPE0__MASK | |
124 | MDP4_LAYERMIXER_IN_CFG_PIPE0_MIXER1); | ||
125 | mixer_cfg |= MDP4_LAYERMIXER_IN_CFG_PIPE0(stage) | | ||
119 | COND(mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE0_MIXER1); | 126 | COND(mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE0_MIXER1); |
120 | break; | 127 | break; |
121 | case VG2: | 128 | case VG2: |
122 | mixer_cfg = MDP4_LAYERMIXER_IN_CFG_PIPE1(stage) | | 129 | mixer_cfg &= ~(MDP4_LAYERMIXER_IN_CFG_PIPE1__MASK | |
130 | MDP4_LAYERMIXER_IN_CFG_PIPE1_MIXER1); | ||
131 | mixer_cfg |= MDP4_LAYERMIXER_IN_CFG_PIPE1(stage) | | ||
123 | COND(mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE1_MIXER1); | 132 | COND(mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE1_MIXER1); |
124 | break; | 133 | break; |
125 | case RGB1: | 134 | case RGB1: |
126 | mixer_cfg = MDP4_LAYERMIXER_IN_CFG_PIPE2(stage) | | 135 | mixer_cfg &= ~(MDP4_LAYERMIXER_IN_CFG_PIPE2__MASK | |
136 | MDP4_LAYERMIXER_IN_CFG_PIPE2_MIXER1); | ||
137 | mixer_cfg |= MDP4_LAYERMIXER_IN_CFG_PIPE2(stage) | | ||
127 | COND(mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE2_MIXER1); | 138 | COND(mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE2_MIXER1); |
128 | break; | 139 | break; |
129 | case RGB2: | 140 | case RGB2: |
130 | mixer_cfg = MDP4_LAYERMIXER_IN_CFG_PIPE3(stage) | | 141 | mixer_cfg &= ~(MDP4_LAYERMIXER_IN_CFG_PIPE3__MASK | |
142 | MDP4_LAYERMIXER_IN_CFG_PIPE3_MIXER1); | ||
143 | mixer_cfg |= MDP4_LAYERMIXER_IN_CFG_PIPE3(stage) | | ||
131 | COND(mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE3_MIXER1); | 144 | COND(mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE3_MIXER1); |
132 | break; | 145 | break; |
133 | case RGB3: | 146 | case RGB3: |
134 | mixer_cfg = MDP4_LAYERMIXER_IN_CFG_PIPE4(stage) | | 147 | mixer_cfg &= ~(MDP4_LAYERMIXER_IN_CFG_PIPE4__MASK | |
148 | MDP4_LAYERMIXER_IN_CFG_PIPE4_MIXER1); | ||
149 | mixer_cfg |= MDP4_LAYERMIXER_IN_CFG_PIPE4(stage) | | ||
135 | COND(mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE4_MIXER1); | 150 | COND(mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE4_MIXER1); |
136 | break; | 151 | break; |
137 | case VG3: | 152 | case VG3: |
138 | mixer_cfg = MDP4_LAYERMIXER_IN_CFG_PIPE5(stage) | | 153 | mixer_cfg &= ~(MDP4_LAYERMIXER_IN_CFG_PIPE5__MASK | |
154 | MDP4_LAYERMIXER_IN_CFG_PIPE5_MIXER1); | ||
155 | mixer_cfg |= MDP4_LAYERMIXER_IN_CFG_PIPE5(stage) | | ||
139 | COND(mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE5_MIXER1); | 156 | COND(mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE5_MIXER1); |
140 | break; | 157 | break; |
141 | case VG4: | 158 | case VG4: |
142 | mixer_cfg = MDP4_LAYERMIXER_IN_CFG_PIPE6(stage) | | 159 | mixer_cfg &= ~(MDP4_LAYERMIXER_IN_CFG_PIPE6__MASK | |
160 | MDP4_LAYERMIXER_IN_CFG_PIPE6_MIXER1); | ||
161 | mixer_cfg |= MDP4_LAYERMIXER_IN_CFG_PIPE6(stage) | | ||
143 | COND(mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE6_MIXER1); | 162 | COND(mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE6_MIXER1); |
144 | break; | 163 | break; |
145 | default: | 164 | default: |
@@ -188,7 +207,7 @@ struct drm_plane *mdp4_plane_init(struct drm_device *dev, | |||
188 | uint32_t mdp4_crtc_vblank(struct drm_crtc *crtc); | 207 | uint32_t mdp4_crtc_vblank(struct drm_crtc *crtc); |
189 | void mdp4_crtc_cancel_pending_flip(struct drm_crtc *crtc, struct drm_file *file); | 208 | void mdp4_crtc_cancel_pending_flip(struct drm_crtc *crtc, struct drm_file *file); |
190 | void mdp4_crtc_set_config(struct drm_crtc *crtc, uint32_t config); | 209 | void mdp4_crtc_set_config(struct drm_crtc *crtc, uint32_t config); |
191 | void mdp4_crtc_set_intf(struct drm_crtc *crtc, enum mdp4_intf intf); | 210 | void mdp4_crtc_set_intf(struct drm_crtc *crtc, enum mdp4_intf intf, int mixer); |
192 | void mdp4_crtc_attach(struct drm_crtc *crtc, struct drm_plane *plane); | 211 | void mdp4_crtc_attach(struct drm_crtc *crtc, struct drm_plane *plane); |
193 | void mdp4_crtc_detach(struct drm_crtc *crtc, struct drm_plane *plane); | 212 | void mdp4_crtc_detach(struct drm_crtc *crtc, struct drm_plane *plane); |
194 | struct drm_crtc *mdp4_crtc_init(struct drm_device *dev, | 213 | struct drm_crtc *mdp4_crtc_init(struct drm_device *dev, |
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index 47ccdbf49fa1..3b05fb4e3d66 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c | |||
@@ -280,7 +280,7 @@ static int msm_load(struct drm_device *dev, unsigned long flags) | |||
280 | dev->mode_config.max_height = 2048; | 280 | dev->mode_config.max_height = 2048; |
281 | dev->mode_config.funcs = &mode_config_funcs; | 281 | dev->mode_config.funcs = &mode_config_funcs; |
282 | 282 | ||
283 | ret = drm_vblank_init(dev, 1); | 283 | ret = drm_vblank_init(dev, priv->num_crtcs); |
284 | if (ret < 0) { | 284 | if (ret < 0) { |
285 | dev_err(dev->dev, "failed to initialize vblank\n"); | 285 | dev_err(dev->dev, "failed to initialize vblank\n"); |
286 | goto fail; | 286 | goto fail; |