Re: [Freedreno] [RFC 4/4] drm/msm/mdp5: writeback support
On Fri, Feb 23, 2018 at 01:15:54PM -0500, Rob Clark wrote: > On Fri, Feb 23, 2018 at 11:30 AM, Sean Paulwrote: > > On Fri, Feb 23, 2018 at 08:17:54AM -0500, Rob Clark wrote: > >> In a way, based on the original writeback patch from Jilai Wang, but a > >> lot has shifted around since then. > >> > >> Signed-off-by: Rob Clark > >> --- > >> drivers/gpu/drm/msm/Makefile | 1 + > >> drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c | 23 +- > >> drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c | 38 +++- > >> drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.h | 7 +- > >> drivers/gpu/drm/msm/disp/mdp5/mdp5_wb.c | 367 > >> ++ > >> drivers/gpu/drm/msm/dsi/dsi_host.c| 4 +- > >> 6 files changed, 431 insertions(+), 9 deletions(-) > >> create mode 100644 drivers/gpu/drm/msm/disp/mdp5/mdp5_wb.c > >> > >> diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile > >> index cd40c050b2d7..c9f50adef2db 100644 > >> --- a/drivers/gpu/drm/msm/Makefile > >> +++ b/drivers/gpu/drm/msm/Makefile > >> @@ -45,6 +45,7 @@ msm-y := \ > >> disp/mdp5/mdp5_mixer.o \ > >> disp/mdp5/mdp5_plane.o \ > >> disp/mdp5/mdp5_smp.o \ > >> + disp/mdp5/mdp5_wb.o \ > >> msm_atomic.o \ > >> msm_debugfs.o \ > >> msm_drv.o \ > >> diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c > >> b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c > >> index 9893e43ba6c5..b00ca88b741d 100644 > >> --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c > >> +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c > >> @@ -484,7 +484,11 @@ static void mdp5_crtc_atomic_enable(struct drm_crtc > >> *crtc, > >> } > >> > >> /* Restore vblank irq handling after power is enabled */ > >> - drm_crtc_vblank_on(crtc); > >> +// TODO we can't ->get_scanout_pos() for wb (since virtual intf).. > >> +// perhaps drm core should be clever enough not to > >> drm_reset_vblank_timestamp() > >> +// for virtual encoders / writeback? > >> + if (mdp5_cstate->pipeline.intf->type != INTF_WB) > >> + drm_crtc_vblank_on(crtc); > >> > >> mdp5_crtc_mode_set_nofb(crtc); > >> > >> @@ -518,7 +522,11 @@ int mdp5_crtc_setup_pipeline(struct drm_crtc *crtc, > >> u32 caps; > >> int ret; > >> > >> - caps = MDP_LM_CAP_DISPLAY; > >> + if (pipeline->intf->type == INTF_WB) > >> + caps = MDP_LM_CAP_WB; > >> + else > >> + caps = MDP_LM_CAP_DISPLAY; > >> + > >> if (need_right_mixer) > >> caps |= MDP_LM_CAP_PAIR; > >> > >> @@ -545,6 +553,7 @@ int mdp5_crtc_setup_pipeline(struct drm_crtc *crtc, > >> mdp5_cstate->err_irqmask = intf2err(intf->num); > >> mdp5_cstate->vblank_irqmask = intf2vblank(pipeline->mixer, intf); > >> > >> +// XXX should we be treating WB as cmd_mode?? > >> if ((intf->type == INTF_DSI) && > >> (intf->mode == MDP5_INTF_DSI_MODE_COMMAND)) { > >> mdp5_cstate->pp_done_irqmask = lm2ppdone(pipeline->mixer); > >> @@ -639,8 +648,12 @@ static int mdp5_crtc_atomic_check(struct drm_crtc > >> *crtc, > >> } > >> > >> /* bail out early if there aren't any planes */ > >> - if (!cnt) > >> - return 0; > >> + if (!cnt) { > >> + if (!state->active) > >> + return 0; > >> + dev_err(dev->dev, "%s has no planes!\n", crtc->name); > >> + return -EINVAL; > >> + } > > > > This seems unrelated? > > > > hmm, yeah, kinda. It was a case that I hit before working out all the > bugs in my kmscube writeback mode, but I guess isn't directly related > to wb. > > >> > >> hw_cfg = mdp5_cfg_get_hw_config(mdp5_kms->cfg); > >> > >> @@ -1160,7 +1173,7 @@ void mdp5_crtc_wait_for_commit_done(struct drm_crtc > >> *crtc) > >> > >> if (mdp5_cstate->cmd_mode) > >> mdp5_crtc_wait_for_pp_done(crtc); > >> - else > >> + else if (mdp5_cstate->pipeline.intf->type != INTF_WB) > >> mdp5_crtc_wait_for_flush_done(crtc); > >> } > >> > >> diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c > >> b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c > >> index 1f44d8f15ce1..239010905637 100644 > >> --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c > >> +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c > >> @@ -427,7 +427,8 @@ static int modeset_init(struct mdp5_kms *mdp5_kms) > >>* the MDP5 interfaces) than the number of layer mixers present in > >> HW, > >>* but let's be safe here anyway > >>*/ > >> - num_crtcs = min(priv->num_encoders, mdp5_kms->num_hwmixers); > >> + num_crtcs = min(priv->num_encoders + hw_cfg->wb.count, > >> + mdp5_kms->num_hwmixers); > >> > >> /* > >>* Construct planes equaling the number of hw pipes, and CRTCs for > >> the > >> @@ -482,6 +483,33 @@ static int modeset_init(struct mdp5_kms *mdp5_kms) > >>
Re: [Freedreno] [RFC 4/4] drm/msm/mdp5: writeback support
On Fri, Feb 23, 2018 at 11:30 AM, Sean Paulwrote: > On Fri, Feb 23, 2018 at 08:17:54AM -0500, Rob Clark wrote: >> In a way, based on the original writeback patch from Jilai Wang, but a >> lot has shifted around since then. >> >> Signed-off-by: Rob Clark >> --- >> drivers/gpu/drm/msm/Makefile | 1 + >> drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c | 23 +- >> drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c | 38 +++- >> drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.h | 7 +- >> drivers/gpu/drm/msm/disp/mdp5/mdp5_wb.c | 367 >> ++ >> drivers/gpu/drm/msm/dsi/dsi_host.c| 4 +- >> 6 files changed, 431 insertions(+), 9 deletions(-) >> create mode 100644 drivers/gpu/drm/msm/disp/mdp5/mdp5_wb.c >> >> diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile >> index cd40c050b2d7..c9f50adef2db 100644 >> --- a/drivers/gpu/drm/msm/Makefile >> +++ b/drivers/gpu/drm/msm/Makefile >> @@ -45,6 +45,7 @@ msm-y := \ >> disp/mdp5/mdp5_mixer.o \ >> disp/mdp5/mdp5_plane.o \ >> disp/mdp5/mdp5_smp.o \ >> + disp/mdp5/mdp5_wb.o \ >> msm_atomic.o \ >> msm_debugfs.o \ >> msm_drv.o \ >> diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c >> b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c >> index 9893e43ba6c5..b00ca88b741d 100644 >> --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c >> +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c >> @@ -484,7 +484,11 @@ static void mdp5_crtc_atomic_enable(struct drm_crtc >> *crtc, >> } >> >> /* Restore vblank irq handling after power is enabled */ >> - drm_crtc_vblank_on(crtc); >> +// TODO we can't ->get_scanout_pos() for wb (since virtual intf).. >> +// perhaps drm core should be clever enough not to >> drm_reset_vblank_timestamp() >> +// for virtual encoders / writeback? >> + if (mdp5_cstate->pipeline.intf->type != INTF_WB) >> + drm_crtc_vblank_on(crtc); >> >> mdp5_crtc_mode_set_nofb(crtc); >> >> @@ -518,7 +522,11 @@ int mdp5_crtc_setup_pipeline(struct drm_crtc *crtc, >> u32 caps; >> int ret; >> >> - caps = MDP_LM_CAP_DISPLAY; >> + if (pipeline->intf->type == INTF_WB) >> + caps = MDP_LM_CAP_WB; >> + else >> + caps = MDP_LM_CAP_DISPLAY; >> + >> if (need_right_mixer) >> caps |= MDP_LM_CAP_PAIR; >> >> @@ -545,6 +553,7 @@ int mdp5_crtc_setup_pipeline(struct drm_crtc *crtc, >> mdp5_cstate->err_irqmask = intf2err(intf->num); >> mdp5_cstate->vblank_irqmask = intf2vblank(pipeline->mixer, intf); >> >> +// XXX should we be treating WB as cmd_mode?? >> if ((intf->type == INTF_DSI) && >> (intf->mode == MDP5_INTF_DSI_MODE_COMMAND)) { >> mdp5_cstate->pp_done_irqmask = lm2ppdone(pipeline->mixer); >> @@ -639,8 +648,12 @@ static int mdp5_crtc_atomic_check(struct drm_crtc *crtc, >> } >> >> /* bail out early if there aren't any planes */ >> - if (!cnt) >> - return 0; >> + if (!cnt) { >> + if (!state->active) >> + return 0; >> + dev_err(dev->dev, "%s has no planes!\n", crtc->name); >> + return -EINVAL; >> + } > > This seems unrelated? > hmm, yeah, kinda. It was a case that I hit before working out all the bugs in my kmscube writeback mode, but I guess isn't directly related to wb. >> >> hw_cfg = mdp5_cfg_get_hw_config(mdp5_kms->cfg); >> >> @@ -1160,7 +1173,7 @@ void mdp5_crtc_wait_for_commit_done(struct drm_crtc >> *crtc) >> >> if (mdp5_cstate->cmd_mode) >> mdp5_crtc_wait_for_pp_done(crtc); >> - else >> + else if (mdp5_cstate->pipeline.intf->type != INTF_WB) >> mdp5_crtc_wait_for_flush_done(crtc); >> } >> >> diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c >> b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c >> index 1f44d8f15ce1..239010905637 100644 >> --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c >> +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c >> @@ -427,7 +427,8 @@ static int modeset_init(struct mdp5_kms *mdp5_kms) >>* the MDP5 interfaces) than the number of layer mixers present in HW, >>* but let's be safe here anyway >>*/ >> - num_crtcs = min(priv->num_encoders, mdp5_kms->num_hwmixers); >> + num_crtcs = min(priv->num_encoders + hw_cfg->wb.count, >> + mdp5_kms->num_hwmixers); >> >> /* >>* Construct planes equaling the number of hw pipes, and CRTCs for the >> @@ -482,6 +483,33 @@ static int modeset_init(struct mdp5_kms *mdp5_kms) >> encoder->possible_crtcs = (1 << priv->num_crtcs) - 1; >> } >> >> + /* >> + * Lastly, construct writeback connectors. >> + */ >> + for (i = 0; i < hw_cfg->wb.count; i++) { >> + struct drm_writeback_connector *wb_conn; >> + struct mdp5_ctl *ctl; >> + >> +
Re: [Freedreno] [RFC 4/4] drm/msm/mdp5: writeback support
On Fri, Feb 23, 2018 at 08:17:54AM -0500, Rob Clark wrote: > In a way, based on the original writeback patch from Jilai Wang, but a > lot has shifted around since then. > > Signed-off-by: Rob Clark> --- > drivers/gpu/drm/msm/Makefile | 1 + > drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c | 23 +- > drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c | 38 +++- > drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.h | 7 +- > drivers/gpu/drm/msm/disp/mdp5/mdp5_wb.c | 367 > ++ > drivers/gpu/drm/msm/dsi/dsi_host.c| 4 +- > 6 files changed, 431 insertions(+), 9 deletions(-) > create mode 100644 drivers/gpu/drm/msm/disp/mdp5/mdp5_wb.c > > diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile > index cd40c050b2d7..c9f50adef2db 100644 > --- a/drivers/gpu/drm/msm/Makefile > +++ b/drivers/gpu/drm/msm/Makefile > @@ -45,6 +45,7 @@ msm-y := \ > disp/mdp5/mdp5_mixer.o \ > disp/mdp5/mdp5_plane.o \ > disp/mdp5/mdp5_smp.o \ > + disp/mdp5/mdp5_wb.o \ > msm_atomic.o \ > msm_debugfs.o \ > msm_drv.o \ > diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c > b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c > index 9893e43ba6c5..b00ca88b741d 100644 > --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c > +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c > @@ -484,7 +484,11 @@ static void mdp5_crtc_atomic_enable(struct drm_crtc > *crtc, > } > > /* Restore vblank irq handling after power is enabled */ > - drm_crtc_vblank_on(crtc); > +// TODO we can't ->get_scanout_pos() for wb (since virtual intf).. > +// perhaps drm core should be clever enough not to > drm_reset_vblank_timestamp() > +// for virtual encoders / writeback? > + if (mdp5_cstate->pipeline.intf->type != INTF_WB) > + drm_crtc_vblank_on(crtc); > > mdp5_crtc_mode_set_nofb(crtc); > > @@ -518,7 +522,11 @@ int mdp5_crtc_setup_pipeline(struct drm_crtc *crtc, > u32 caps; > int ret; > > - caps = MDP_LM_CAP_DISPLAY; > + if (pipeline->intf->type == INTF_WB) > + caps = MDP_LM_CAP_WB; > + else > + caps = MDP_LM_CAP_DISPLAY; > + > if (need_right_mixer) > caps |= MDP_LM_CAP_PAIR; > > @@ -545,6 +553,7 @@ int mdp5_crtc_setup_pipeline(struct drm_crtc *crtc, > mdp5_cstate->err_irqmask = intf2err(intf->num); > mdp5_cstate->vblank_irqmask = intf2vblank(pipeline->mixer, intf); > > +// XXX should we be treating WB as cmd_mode?? > if ((intf->type == INTF_DSI) && > (intf->mode == MDP5_INTF_DSI_MODE_COMMAND)) { > mdp5_cstate->pp_done_irqmask = lm2ppdone(pipeline->mixer); > @@ -639,8 +648,12 @@ static int mdp5_crtc_atomic_check(struct drm_crtc *crtc, > } > > /* bail out early if there aren't any planes */ > - if (!cnt) > - return 0; > + if (!cnt) { > + if (!state->active) > + return 0; > + dev_err(dev->dev, "%s has no planes!\n", crtc->name); > + return -EINVAL; > + } This seems unrelated? > > hw_cfg = mdp5_cfg_get_hw_config(mdp5_kms->cfg); > > @@ -1160,7 +1173,7 @@ void mdp5_crtc_wait_for_commit_done(struct drm_crtc > *crtc) > > if (mdp5_cstate->cmd_mode) > mdp5_crtc_wait_for_pp_done(crtc); > - else > + else if (mdp5_cstate->pipeline.intf->type != INTF_WB) > mdp5_crtc_wait_for_flush_done(crtc); > } > > diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c > b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c > index 1f44d8f15ce1..239010905637 100644 > --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c > +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c > @@ -427,7 +427,8 @@ static int modeset_init(struct mdp5_kms *mdp5_kms) >* the MDP5 interfaces) than the number of layer mixers present in HW, >* but let's be safe here anyway >*/ > - num_crtcs = min(priv->num_encoders, mdp5_kms->num_hwmixers); > + num_crtcs = min(priv->num_encoders + hw_cfg->wb.count, > + mdp5_kms->num_hwmixers); > > /* >* Construct planes equaling the number of hw pipes, and CRTCs for the > @@ -482,6 +483,33 @@ static int modeset_init(struct mdp5_kms *mdp5_kms) > encoder->possible_crtcs = (1 << priv->num_crtcs) - 1; > } > > + /* > + * Lastly, construct writeback connectors. > + */ > + for (i = 0; i < hw_cfg->wb.count; i++) { > + struct drm_writeback_connector *wb_conn; > + struct mdp5_ctl *ctl; > + > + ctl = mdp5_ctlm_request(mdp5_kms->ctlm, -1); > + if (!ctl) { > + dev_err(dev->dev, > + "failed to allocate ctl for writeback %d\n", i); > + continue; > + } > + > + wb_conn = mdp5_wb_connector_init(dev, ctl,
[Freedreno] [RFC 4/4] drm/msm/mdp5: writeback support
In a way, based on the original writeback patch from Jilai Wang, but a lot has shifted around since then. Signed-off-by: Rob Clark--- drivers/gpu/drm/msm/Makefile | 1 + drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c | 23 +- drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c | 38 +++- drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.h | 7 +- drivers/gpu/drm/msm/disp/mdp5/mdp5_wb.c | 367 ++ drivers/gpu/drm/msm/dsi/dsi_host.c| 4 +- 6 files changed, 431 insertions(+), 9 deletions(-) create mode 100644 drivers/gpu/drm/msm/disp/mdp5/mdp5_wb.c diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile index cd40c050b2d7..c9f50adef2db 100644 --- a/drivers/gpu/drm/msm/Makefile +++ b/drivers/gpu/drm/msm/Makefile @@ -45,6 +45,7 @@ msm-y := \ disp/mdp5/mdp5_mixer.o \ disp/mdp5/mdp5_plane.o \ disp/mdp5/mdp5_smp.o \ + disp/mdp5/mdp5_wb.o \ msm_atomic.o \ msm_debugfs.o \ msm_drv.o \ diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c index 9893e43ba6c5..b00ca88b741d 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c @@ -484,7 +484,11 @@ static void mdp5_crtc_atomic_enable(struct drm_crtc *crtc, } /* Restore vblank irq handling after power is enabled */ - drm_crtc_vblank_on(crtc); +// TODO we can't ->get_scanout_pos() for wb (since virtual intf).. +// perhaps drm core should be clever enough not to drm_reset_vblank_timestamp() +// for virtual encoders / writeback? + if (mdp5_cstate->pipeline.intf->type != INTF_WB) + drm_crtc_vblank_on(crtc); mdp5_crtc_mode_set_nofb(crtc); @@ -518,7 +522,11 @@ int mdp5_crtc_setup_pipeline(struct drm_crtc *crtc, u32 caps; int ret; - caps = MDP_LM_CAP_DISPLAY; + if (pipeline->intf->type == INTF_WB) + caps = MDP_LM_CAP_WB; + else + caps = MDP_LM_CAP_DISPLAY; + if (need_right_mixer) caps |= MDP_LM_CAP_PAIR; @@ -545,6 +553,7 @@ int mdp5_crtc_setup_pipeline(struct drm_crtc *crtc, mdp5_cstate->err_irqmask = intf2err(intf->num); mdp5_cstate->vblank_irqmask = intf2vblank(pipeline->mixer, intf); +// XXX should we be treating WB as cmd_mode?? if ((intf->type == INTF_DSI) && (intf->mode == MDP5_INTF_DSI_MODE_COMMAND)) { mdp5_cstate->pp_done_irqmask = lm2ppdone(pipeline->mixer); @@ -639,8 +648,12 @@ static int mdp5_crtc_atomic_check(struct drm_crtc *crtc, } /* bail out early if there aren't any planes */ - if (!cnt) - return 0; + if (!cnt) { + if (!state->active) + return 0; + dev_err(dev->dev, "%s has no planes!\n", crtc->name); + return -EINVAL; + } hw_cfg = mdp5_cfg_get_hw_config(mdp5_kms->cfg); @@ -1160,7 +1173,7 @@ void mdp5_crtc_wait_for_commit_done(struct drm_crtc *crtc) if (mdp5_cstate->cmd_mode) mdp5_crtc_wait_for_pp_done(crtc); - else + else if (mdp5_cstate->pipeline.intf->type != INTF_WB) mdp5_crtc_wait_for_flush_done(crtc); } diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c index 1f44d8f15ce1..239010905637 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c @@ -427,7 +427,8 @@ static int modeset_init(struct mdp5_kms *mdp5_kms) * the MDP5 interfaces) than the number of layer mixers present in HW, * but let's be safe here anyway */ - num_crtcs = min(priv->num_encoders, mdp5_kms->num_hwmixers); + num_crtcs = min(priv->num_encoders + hw_cfg->wb.count, + mdp5_kms->num_hwmixers); /* * Construct planes equaling the number of hw pipes, and CRTCs for the @@ -482,6 +483,33 @@ static int modeset_init(struct mdp5_kms *mdp5_kms) encoder->possible_crtcs = (1 << priv->num_crtcs) - 1; } + /* +* Lastly, construct writeback connectors. +*/ + for (i = 0; i < hw_cfg->wb.count; i++) { + struct drm_writeback_connector *wb_conn; + struct mdp5_ctl *ctl; + + ctl = mdp5_ctlm_request(mdp5_kms->ctlm, -1); + if (!ctl) { + dev_err(dev->dev, + "failed to allocate ctl for writeback %d\n", i); + continue; + } + + wb_conn = mdp5_wb_connector_init(dev, ctl, + hw_cfg->wb.instances[i].id); + if (IS_ERR(wb_conn)) { + ret = PTR_ERR(wb_conn); + dev_err(dev->dev, +