···2626 struct drm_crtc base;2727 char name[8];2828 struct drm_plane *plane;2929+ struct drm_plane *planes[8];2930 int id;3031 int ovlp;3132 enum mdp4_dma dma;···116115{117116 struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);118117 struct mdp4_kms *mdp4_kms = get_kms(crtc);119119- uint32_t flush = 0;118118+ uint32_t i, flush = 0;120119121121- flush |= pipe2flush(mdp4_plane_pipe(mdp4_crtc->plane));120120+ for (i = 0; i < ARRAY_SIZE(mdp4_crtc->planes); i++) {121121+ struct drm_plane *plane = mdp4_crtc->planes[i];122122+ if (plane) {123123+ enum mdp4_pipe pipe_id = mdp4_plane_pipe(plane);124124+ flush |= pipe2flush(pipe_id);125125+ }126126+ }122127 flush |= ovlp2flush(mdp4_crtc->ovlp);123128124129 DBG("%s: flush=%08x", mdp4_crtc->name, flush);···212205 struct mdp4_kms *mdp4_kms = get_kms(crtc);213206 int i, ovlp = mdp4_crtc->ovlp;214207 uint32_t mixer_cfg = 0;208208+ static const enum mdp4_mixer_stage_id stages[] = {209209+ STAGE_BASE, STAGE0, STAGE1, STAGE2, STAGE3,210210+ };211211+ /* statically (for now) map planes to mixer stage (z-order): */212212+ static const int idxs[] = {213213+ [VG1] = 1,214214+ [VG2] = 2,215215+ [RGB1] = 0,216216+ [RGB2] = 0,217217+ [RGB3] = 0,218218+ [VG3] = 3,219219+ [VG4] = 4,215220216216- /*217217- * This probably would also need to be triggered by any attached218218- * plane when it changes.. for now since we are only using a single219219- * private plane, the configuration is hard-coded:220220- */221221+ };222222+ bool alpha[4]= { false, false, false, false };221223222224 mdp4_write(mdp4_kms, REG_MDP4_OVLP_TRANSP_LOW0(ovlp), 0);223225 mdp4_write(mdp4_kms, REG_MDP4_OVLP_TRANSP_LOW1(ovlp), 0);224226 mdp4_write(mdp4_kms, REG_MDP4_OVLP_TRANSP_HIGH0(ovlp), 0);225227 mdp4_write(mdp4_kms, REG_MDP4_OVLP_TRANSP_HIGH1(ovlp), 0);226228229229+ /* TODO single register for all CRTCs, so this won't work properly230230+ * when multiple CRTCs are active..231231+ */232232+ for (i = 0; i < ARRAY_SIZE(mdp4_crtc->planes); i++) {233233+ struct drm_plane *plane = mdp4_crtc->planes[i];234234+ if (plane) {235235+ enum mdp4_pipe pipe_id = mdp4_plane_pipe(plane);236236+ int idx = idxs[pipe_id];237237+ if (idx > 0) {238238+ const struct mdp4_format *format =239239+ to_mdp4_format(msm_framebuffer_format(plane->fb));240240+ alpha[idx-1] = format->alpha_enable;241241+ }242242+ mixer_cfg |= mixercfg(mdp4_crtc->mixer, pipe_id, stages[idx]);243243+ }244244+ }245245+246246+ /* this shouldn't happen.. and seems to cause underflow: */247247+ WARN_ON(!mixer_cfg);248248+227249 for (i = 0; i < 4; i++) {228228- mdp4_write(mdp4_kms, REG_MDP4_OVLP_STAGE_FG_ALPHA(ovlp, i), 0);229229- mdp4_write(mdp4_kms, REG_MDP4_OVLP_STAGE_BG_ALPHA(ovlp, i), 0);230230- mdp4_write(mdp4_kms, REG_MDP4_OVLP_STAGE_OP(ovlp, i),231231- MDP4_OVLP_STAGE_OP_FG_ALPHA(FG_CONST) |232232- MDP4_OVLP_STAGE_OP_BG_ALPHA(BG_CONST));233233- mdp4_write(mdp4_kms, REG_MDP4_OVLP_STAGE_CO3(ovlp, i), 0);250250+ uint32_t op;251251+252252+ if (alpha[i]) {253253+ op = MDP4_OVLP_STAGE_OP_FG_ALPHA(FG_PIXEL) |254254+ MDP4_OVLP_STAGE_OP_BG_ALPHA(FG_PIXEL) |255255+ MDP4_OVLP_STAGE_OP_BG_INV_ALPHA;256256+ } else {257257+ op = MDP4_OVLP_STAGE_OP_FG_ALPHA(FG_CONST) |258258+ MDP4_OVLP_STAGE_OP_BG_ALPHA(BG_CONST);259259+ }260260+261261+ mdp4_write(mdp4_kms, REG_MDP4_OVLP_STAGE_FG_ALPHA(ovlp, i), 0xff);262262+ mdp4_write(mdp4_kms, REG_MDP4_OVLP_STAGE_BG_ALPHA(ovlp, i), 0x00);263263+ mdp4_write(mdp4_kms, REG_MDP4_OVLP_STAGE_OP(ovlp, i), op);264264+ mdp4_write(mdp4_kms, REG_MDP4_OVLP_STAGE_CO3(ovlp, i), 1);234265 mdp4_write(mdp4_kms, REG_MDP4_OVLP_STAGE_TRANSP_LOW0(ovlp, i), 0);235266 mdp4_write(mdp4_kms, REG_MDP4_OVLP_STAGE_TRANSP_LOW1(ovlp, i), 0);236267 mdp4_write(mdp4_kms, REG_MDP4_OVLP_STAGE_TRANSP_HIGH0(ovlp, i), 0);237268 mdp4_write(mdp4_kms, REG_MDP4_OVLP_STAGE_TRANSP_HIGH1(ovlp, i), 0);238269 }239270240240- /* TODO single register for all CRTCs, so this won't work properly241241- * when multiple CRTCs are active..242242- */243243- switch (mdp4_plane_pipe(mdp4_crtc->plane)) {244244- case VG1:245245- mixer_cfg = MDP4_LAYERMIXER_IN_CFG_PIPE0(STAGE_BASE) |246246- COND(mdp4_crtc->mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE0_MIXER1);247247- break;248248- case VG2:249249- mixer_cfg = MDP4_LAYERMIXER_IN_CFG_PIPE1(STAGE_BASE) |250250- COND(mdp4_crtc->mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE1_MIXER1);251251- break;252252- case RGB1:253253- mixer_cfg = MDP4_LAYERMIXER_IN_CFG_PIPE2(STAGE_BASE) |254254- COND(mdp4_crtc->mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE2_MIXER1);255255- break;256256- case RGB2:257257- mixer_cfg = MDP4_LAYERMIXER_IN_CFG_PIPE3(STAGE_BASE) |258258- COND(mdp4_crtc->mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE3_MIXER1);259259- break;260260- case RGB3:261261- mixer_cfg = MDP4_LAYERMIXER_IN_CFG_PIPE4(STAGE_BASE) |262262- COND(mdp4_crtc->mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE4_MIXER1);263263- break;264264- case VG3:265265- mixer_cfg = MDP4_LAYERMIXER_IN_CFG_PIPE5(STAGE_BASE) |266266- COND(mdp4_crtc->mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE5_MIXER1);267267- break;268268- case VG4:269269- mixer_cfg = MDP4_LAYERMIXER_IN_CFG_PIPE6(STAGE_BASE) |270270- COND(mdp4_crtc->mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE6_MIXER1);271271- break;272272- default:273273- WARN_ON("invalid pipe");274274- break;275275- }276271 mdp4_write(mdp4_kms, REG_MDP4_LAYERMIXER_IN_CFG, mixer_cfg);277272}278273···631622 mdp4_write(mdp4_kms, REG_MDP4_DISP_INTF_SEL, intf_sel);632623}633624625625+static void set_attach(struct drm_crtc *crtc, enum mdp4_pipe pipe_id,626626+ struct drm_plane *plane)627627+{628628+ struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);629629+630630+ BUG_ON(pipe_id >= ARRAY_SIZE(mdp4_crtc->planes));631631+632632+ if (mdp4_crtc->planes[pipe_id] == plane)633633+ return;634634+635635+ mdp4_crtc->planes[pipe_id] = plane;636636+ blend_setup(crtc);637637+ if (mdp4_crtc->enabled && (plane != mdp4_crtc->plane))638638+ crtc_flush(crtc);639639+}640640+641641+void mdp4_crtc_attach(struct drm_crtc *crtc, struct drm_plane *plane)642642+{643643+ set_attach(crtc, mdp4_plane_pipe(plane), plane);644644+}645645+646646+void mdp4_crtc_detach(struct drm_crtc *crtc, struct drm_plane *plane)647647+{648648+ set_attach(crtc, mdp4_plane_pipe(plane), NULL);649649+}650650+634651static const char *dma_names[] = {635652 "DMA_P", "DMA_S", "DMA_E",636653};···679644 crtc = &mdp4_crtc->base;680645681646 mdp4_crtc->plane = plane;682682- mdp4_crtc->plane->crtc = crtc;683647684648 mdp4_crtc->ovlp = ovlp_id;685649 mdp4_crtc->dma = dma_id;
+16
drivers/gpu/drm/msm/mdp4/mdp4_format.c
···4444 FMT(BGR565, 0, 5, 6, 5, 2, 0, 1, 0, false, true, 2, 3),4545};46464747+uint32_t mdp4_get_formats(enum mdp4_pipe pipe_id, uint32_t *pixel_formats,4848+ uint32_t max_formats)4949+{5050+ uint32_t i;5151+ for (i = 0; i < ARRAY_SIZE(formats); i++) {5252+ const struct mdp4_format *f = &formats[i];5353+5454+ if (i == max_formats)5555+ break;5656+5757+ pixel_formats[i] = f->base.pixel_format;5858+ }5959+6060+ return i;6161+}6262+4763const struct msm_format *mdp4_get_format(struct msm_kms *kms, uint32_t format)4864{4965 int i;
+17
drivers/gpu/drm/msm/mdp4/mdp4_kms.c
···196196 * for more than just RGB1->DMA_E->DTV->HDMI197197 */198198199199+ /* construct non-private planes: */200200+ plane = mdp4_plane_init(dev, VG1, false);201201+ if (IS_ERR(plane)) {202202+ dev_err(dev->dev, "failed to construct plane for VG1\n");203203+ ret = PTR_ERR(plane);204204+ goto fail;205205+ }206206+ priv->planes[priv->num_planes++] = plane;207207+208208+ plane = mdp4_plane_init(dev, VG2, false);209209+ if (IS_ERR(plane)) {210210+ dev_err(dev->dev, "failed to construct plane for VG2\n");211211+ ret = PTR_ERR(plane);212212+ goto fail;213213+ }214214+ priv->planes[priv->num_planes++] = plane;215215+199216 /* the CRTCs get constructed with a private plane: */200217 plane = mdp4_plane_init(dev, RGB1, true);201218 if (IS_ERR(plane)) {