Re: [PATCH RESEND 10/17] drm/spacemit: add Saturn DPU KMS pipeline
Guodong Xu <[email protected]> Sat, 8 Aug 2026 01:03:52 -0400
| Newsgroups | org.kernel.vger.linux-clk,dev.linux.lists.spacemit,org.freedesktop.lists.dri-devel,org.infradead.lists.linux-phy,org.infradead.lists.linux-riscv,org.kernel.vger.linux-devicetree,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <wr3264hzlya6zep433nr3u2acukizilkrqpkj444kfqeyaeorj@2rc4zo2cqcer> |
On 2026-07-27 09:35, Philipp Zabel wrote: >On Sa, 2026-07-25 at 00:51 -0400, Cody Kang via B4 Relay wrote: >> From: Cody Kang <[email protected]> >> >> Add the atomic KMS implementation on top of the hardware backend: one >> CRTC and one primary plane per DPU instance. atomic_check validates >> the plane rectangle 1:1 against the mode and sizes the per-channel FBC >> line buffer; atomic commit builds the cmdlist batches, maps the >> framebuffer through the DMMU and arms the cfg-ready handshake, with >> vblank events driven from the DPU interrupt. >> >> Signed-off-by: Cody Kang <[email protected]> >> --- >> drivers/gpu/drm/spacemit/spacemit_crtc.c | 815 +++++++++++++++++++++++++++++ >> drivers/gpu/drm/spacemit/spacemit_planes.c | 376 +++++++++++++ >> 2 files changed, 1191 insertions(+) >> >> diff --git a/drivers/gpu/drm/spacemit/spacemit_crtc.c b/drivers/gpu/drm/spacemit/spacemit_crtc.c >> new file mode 100644 >> index 000000000000..b75ff6320501 >> --- /dev/null >> +++ b/drivers/gpu/drm/spacemit/spacemit_crtc.c >> @@ -0,0 +1,815 @@ >[...] >> +/* >> + * The assert and deassert orders are not mirror images: the hardware wants >> + * these. >> + */ >> +static void dpu_reset_assert(struct device *dev, const char *name, >> + struct reset_control *rstc) >> +{ >> + int ret = reset_control_assert(rstc); >> + >> + if (ret) >> + dev_warn(dev, "failed to assert %s reset: %d\n", name, ret); >> +} >> + >> +static void dpu_reset_deassert(struct device *dev, const char *name, >> + struct reset_control *rstc) >> +{ >> + int ret = reset_control_deassert(rstc); >> + >> + if (ret) >> + dev_warn(dev, "failed to deassert %s reset: %d\n", name, ret); >> +} >> + >> +static int dpu_pm_suspend(struct device *dev) >> +{ >> + struct spacemit_drm_private *priv = dev_get_drvdata(dev); >> + struct spacemit_crtc *a_crtc = priv->a_crtc; >> + >> + /* >> + * Assert before gating: a reset asserted into an already-gated block >> + * has no clock edges to propagate on and leaves the register file >> + * untouched. >> + */ >> + dpu_reset_assert(dev, "lcd", a_crtc->lcd_reset); >> + dpu_reset_assert(dev, "esc", a_crtc->esc_reset); >> + dpu_reset_assert(dev, "mclk", a_crtc->mclk_reset); > >It looks like these three are mirrored, and could be handled by >reset_control_bulk_assert/deassert(). > >> + dpu_reset_assert(dev, "aclk", a_crtc->aclk_reset); >> + dpu_reset_assert(dev, "dsc", a_crtc->dsc_reset); Is there a reason these two cannot be mirrored in order? Please double check. As I checked the vendor tree, the suspend/resume side appear to be copy/paste rather than a deliberate ordering. Please double-check. Unless I'm missing something, I suggest to bulk them. Thanks, Guodong >> + usleep_range(10000, 20000); >> + >> + if (a_crtc->core && a_crtc->core->disable_clk) >> + a_crtc->core->disable_clk(a_crtc); >> + >> + return 0; >> +} >> + >> +static int dpu_pm_resume(struct device *dev) >> +{ >> + struct spacemit_drm_private *priv = dev_get_drvdata(dev); >> + struct spacemit_crtc *a_crtc = priv->a_crtc; >> + >> + dpu_reset_deassert(dev, "mclk", a_crtc->mclk_reset); >> + dpu_reset_deassert(dev, "esc", a_crtc->esc_reset); >> + dpu_reset_deassert(dev, "lcd", a_crtc->lcd_reset); >> + dpu_reset_deassert(dev, "aclk", a_crtc->aclk_reset); >> + dpu_reset_deassert(dev, "dsc", a_crtc->dsc_reset); >> + >> + if (a_crtc->core && a_crtc->core->enable_clk) >> + a_crtc->core->enable_clk(a_crtc); >> + >> + return 0; >> +} > >regards >Philipp