diff options
Diffstat (limited to 'drivers/gpu')
| -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; |
