aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c21
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp4/mdp4_dtv_encoder.c2
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c1
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h43
-rw-r--r--drivers/gpu/drm/msm/msm_drv.c2
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: */
673void mdp4_crtc_set_intf(struct drm_crtc *crtc, enum mdp4_intf intf) 678void 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
111static inline uint32_t mixercfg(int mixer, enum mdp4_pipe pipe, 118static 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,
188uint32_t mdp4_crtc_vblank(struct drm_crtc *crtc); 207uint32_t mdp4_crtc_vblank(struct drm_crtc *crtc);
189void mdp4_crtc_cancel_pending_flip(struct drm_crtc *crtc, struct drm_file *file); 208void mdp4_crtc_cancel_pending_flip(struct drm_crtc *crtc, struct drm_file *file);
190void mdp4_crtc_set_config(struct drm_crtc *crtc, uint32_t config); 209void mdp4_crtc_set_config(struct drm_crtc *crtc, uint32_t config);
191void mdp4_crtc_set_intf(struct drm_crtc *crtc, enum mdp4_intf intf); 210void mdp4_crtc_set_intf(struct drm_crtc *crtc, enum mdp4_intf intf, int mixer);
192void mdp4_crtc_attach(struct drm_crtc *crtc, struct drm_plane *plane); 211void mdp4_crtc_attach(struct drm_crtc *crtc, struct drm_plane *plane);
193void mdp4_crtc_detach(struct drm_crtc *crtc, struct drm_plane *plane); 212void mdp4_crtc_detach(struct drm_crtc *crtc, struct drm_plane *plane);
194struct drm_crtc *mdp4_crtc_init(struct drm_device *dev, 213struct 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;