Received: by 2002:a25:ab43:0:0:0:0:0 with SMTP id u61csp150369ybi; Fri, 7 Jun 2019 05:50:49 -0700 (PDT) X-Google-Smtp-Source: APXvYqzK6goSZCTPJStZsxiGhP0L2GnC+GiQhrNTApHfiP57DcfHcy/5UWHxsOuzPFX1PVvlane2 X-Received: by 2002:a17:902:b611:: with SMTP id b17mr1868163pls.261.1559911849530; Fri, 07 Jun 2019 05:50:49 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1559911849; cv=none; d=google.com; s=arc-20160816; b=Mfh3WhiGns6m/xAVXsJcxMuirMriVxeflyZ1terav3SMl0boBDsDusZIx0xUiEHzst pSF+rxOJf+natTjVlfD5raZrHVwh5XT353Zi9DWZeGO82BukjDl4Uei8tjSRndGx6WxZ DH97wIXEjmSJlep4pSHij6U4/vCLBPufK3CY0vTSyuqXPoSJR8jYZj1j66B9JKuX5Xnj InVtPAMLGm1y1yrkRe2iy1IMusUesQv2qsTfETqrtSVKt86iHvTBSpztuo9VrZduZ3PJ qCYQtvmkXH5UZEOtPcbrNDRhMw8EIjCDgdwS14WvLOM0igPjX3vMTMCzIRx7dhqUT1tH MYag== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:cc:to:subject :message-id:date:from:in-reply-to:references:mime-version :dkim-signature; bh=dYAnPJ618ZNlHVYVCO5fYAE+fci+l9fnhn/c36/XLCw=; b=0ft51EiuKwAWjgj9O3Rqu65LAXlk1d7Rzpy//ElFJljRWKd5piLqKfWvNIKEWuF/tu sCslAw5hnFuTZuEmDorOEYDsmEqEVEGgvLveYeIznmHtnPmYwB8q5ve9sHoAQkcAmwoP uiQGO5zlWKz5hWzAq5uzsiVxZLW9TL2H7niel8G5K5F4I1GpUuMSw3p/u2NCKEv7aYfZ tdNq1MaMKqa4SgvCREJV9gmWy/HygaMWpToZ5hf97RtRvRsQf2Um/G7mtW78XA5tKHw9 COJNaGHwk3f59ufnHyrw0eTsPLdglLWCBen0Lz9SqqyXMCYlb23P7ab1/VDyfQn+3N0A 3Fsg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=WacQlm3b; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id g17si1650396pgi.569.2019.06.07.05.50.33; Fri, 07 Jun 2019 05:50:49 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=WacQlm3b; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728771AbfFGMs4 (ORCPT + 99 others); Fri, 7 Jun 2019 08:48:56 -0400 Received: from mail-qk1-f193.google.com ([209.85.222.193]:38912 "EHLO mail-qk1-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728529AbfFGMs4 (ORCPT ); Fri, 7 Jun 2019 08:48:56 -0400 Received: by mail-qk1-f193.google.com with SMTP id i125so1128566qkd.6 for ; Fri, 07 Jun 2019 05:48:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc:content-transfer-encoding; bh=dYAnPJ618ZNlHVYVCO5fYAE+fci+l9fnhn/c36/XLCw=; b=WacQlm3bQvBfM+EIlriRzhlehMTLBuyeNLsvmJ6snBuBT+LX5MF6nplisZwdZtEF7p rI5auG7ZYVYFKtZ3EqwsgZWjsrXBx1fHIMbHLvPpS5FXyTs1VCWPwqakhL326+9tzZfM tCqrAHPKlGDuclNDBWyMwdCnOq7bqltjGLZaSwhQVGZl5fXERNBRY0EhQPBs3E/HmH7B hzLYkO2OhrLcpjnG9FZ2mBcdm1LeQ1aGL5mzc3S3GI7mgIo1xFh1B3PV112Fz2eS5O4E TanAEJ/XFSBb2dSlrOxBQRWMmsDXuXiJ34JK2P/go/jFEBopvnshj0OTd0od1pW1u0aN tDMQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc:content-transfer-encoding; bh=dYAnPJ618ZNlHVYVCO5fYAE+fci+l9fnhn/c36/XLCw=; b=AKIa5Otxwpz34hC+0nhgZPs/zAYqr0Qdv8jaFsmsrpevNhE8NfxCWrSZQ55hyMhUC+ wymWlwwKihJZG2o4tFRehncjLVIRf7pG7V2oycBQiEKISlev4QP89MOpfxuNAu7FUxI6 VagnTpVteJX4kv7/knjCXvSL1IpMnOcSwqVCvipu9TLXj6aqLa3fnoH0Zy5khpA9bpBK 3ag+7u6HZuCPblIuuPhRUTDPc8POpzwE/rhXn9D6ONLgXN9/X9WRPegROvhsuFi2ANCc vHFvaUvz0R9OMxsnT+dku77ioOMZGFmD6ggkwF3FStqzC0JNK5l9fxlwTn4/IdDAWCqc +0gg== X-Gm-Message-State: APjAAAXhroCFErcHFrHHl4KzYLSHdeJpMBY4LUNRq2SMVDJJPziagIxe SF/ZVbCQJQI4eXIwJ8e2NbSAfTWr4UIkhP0QYZUL5A== X-Received: by 2002:ae9:e40f:: with SMTP id q15mr14992240qkc.241.1559911735396; Fri, 07 Jun 2019 05:48:55 -0700 (PDT) MIME-Version: 1.0 References: <1559550722-14091-1-git-send-email-yannick.fertre@st.com> In-Reply-To: From: Benjamin Gaignard Date: Fri, 7 Jun 2019 14:48:44 +0200 Message-ID: Subject: Re: [PATCH] drm/stm: support runtime power management To: Philippe CORNU Cc: Yannick FERTRE , Benjamin GAIGNARD , Vincent ABRIOU , David Airlie , Daniel Vetter , Maxime Coquelin , Alexandre TORGUE , "dri-devel@lists.freedesktop.org" , "linux-stm32@st-md-mailman.stormreply.com" , "linux-arm-kernel@lists.infradead.org" , "linux-kernel@vger.kernel.org" Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Le ven. 7 juin 2019 =C3=A0 13:19, Philippe CORNU a = =C3=A9crit : > > Hi Yannick, > > Thank you for your patch > > Acked-by: Philippe Cornu Applied on drm-misc-next Thanks, Benjamin > > Philippe :-) > > On 6/3/19 10:32 AM, Yannick Fertr=C3=A9 wrote: > > This patch enables runtime power management (runtime PM) support for > > the display controller. pm_runtime_enable() and pm_runtime_disable() > > are added during ltdc load and unload respectively. > > pm_runtime_get_sync() and pm_runtime_put_sync() are added for ltdc > > register access. > > > > Signed-off-by: Yannick Fertr=C3=A9 > > --- > > drivers/gpu/drm/stm/drv.c | 43 +++++++++++++++++++++++------ > > drivers/gpu/drm/stm/ltdc.c | 67 +++++++++++++++++++++++++++++++++++--= --------- > > 2 files changed, 86 insertions(+), 24 deletions(-) > > > > diff --git a/drivers/gpu/drm/stm/drv.c b/drivers/gpu/drm/stm/drv.c > > index 5834ef5..5659572 100644 > > --- a/drivers/gpu/drm/stm/drv.c > > +++ b/drivers/gpu/drm/stm/drv.c > > @@ -12,6 +12,7 @@ > > #include > > #include > > #include > > +#include > > > > #include > > #include > > @@ -135,14 +136,15 @@ static __maybe_unused int drv_suspend(struct devi= ce *dev) > > struct ltdc_device *ldev =3D ddev->dev_private; > > struct drm_atomic_state *state; > > > > - drm_kms_helper_poll_disable(ddev); > > + if (WARN_ON(!ldev->suspend_state)) > > + return -ENOENT; > > + > > state =3D drm_atomic_helper_suspend(ddev); > > - if (IS_ERR(state)) { > > - drm_kms_helper_poll_enable(ddev); > > + if (IS_ERR(state)) > > return PTR_ERR(state); > > - } > > + > > ldev->suspend_state =3D state; > > - ltdc_suspend(ddev); > > + pm_runtime_force_suspend(dev); > > > > return 0; > > } > > @@ -151,16 +153,41 @@ static __maybe_unused int drv_resume(struct devic= e *dev) > > { > > struct drm_device *ddev =3D dev_get_drvdata(dev); > > struct ltdc_device *ldev =3D ddev->dev_private; > > + int ret; > > > > - ltdc_resume(ddev); > > - drm_atomic_helper_resume(ddev, ldev->suspend_state); > > - drm_kms_helper_poll_enable(ddev); > > + pm_runtime_force_resume(dev); > > + ret =3D drm_atomic_helper_resume(ddev, ldev->suspend_state); > > + if (ret) { > > + pm_runtime_force_suspend(dev); > > + ldev->suspend_state =3D NULL; > > + return ret; > > + } > > > > return 0; > > } > > > > +static __maybe_unused int drv_runtime_suspend(struct device *dev) > > +{ > > + struct drm_device *ddev =3D dev_get_drvdata(dev); > > + > > + DRM_DEBUG_DRIVER("\n"); > > + ltdc_suspend(ddev); > > + > > + return 0; > > +} > > + > > +static __maybe_unused int drv_runtime_resume(struct device *dev) > > +{ > > + struct drm_device *ddev =3D dev_get_drvdata(dev); > > + > > + DRM_DEBUG_DRIVER("\n"); > > + return ltdc_resume(ddev); > > +} > > + > > static const struct dev_pm_ops drv_pm_ops =3D { > > SET_SYSTEM_SLEEP_PM_OPS(drv_suspend, drv_resume) > > + SET_RUNTIME_PM_OPS(drv_runtime_suspend, > > + drv_runtime_resume, NULL) > > }; > > > > static int stm_drm_platform_probe(struct platform_device *pdev) > > diff --git a/drivers/gpu/drm/stm/ltdc.c b/drivers/gpu/drm/stm/ltdc.c > > index ac29890..a40870b 100644 > > --- a/drivers/gpu/drm/stm/ltdc.c > > +++ b/drivers/gpu/drm/stm/ltdc.c > > @@ -16,6 +16,7 @@ > > #include > > #include > > #include > > +#include > > #include > > > > #include > > @@ -444,6 +445,7 @@ static void ltdc_crtc_atomic_disable(struct drm_crt= c *crtc, > > struct drm_crtc_state *old_state) > > { > > struct ltdc_device *ldev =3D crtc_to_ltdc(crtc); > > + struct drm_device *ddev =3D crtc->dev; > > > > DRM_DEBUG_DRIVER("\n"); > > > > @@ -457,6 +459,8 @@ static void ltdc_crtc_atomic_disable(struct drm_crt= c *crtc, > > > > /* immediately commit disable of layers before switching off LTDC= */ > > reg_set(ldev->regs, LTDC_SRCR, SRCR_IMR); > > + > > + pm_runtime_put_sync(ddev->dev); > > } > > > > #define CLK_TOLERANCE_HZ 50 > > @@ -505,17 +509,31 @@ static bool ltdc_crtc_mode_fixup(struct drm_crtc = *crtc, > > struct drm_display_mode *adjusted_mode) > > { > > struct ltdc_device *ldev =3D crtc_to_ltdc(crtc); > > + struct drm_device *ddev =3D crtc->dev; > > int rate =3D mode->clock * 1000; > > + bool runtime_active; > > + int ret; > > + > > + runtime_active =3D pm_runtime_active(ddev->dev); > > + > > + if (runtime_active) > > + pm_runtime_put_sync(ddev->dev); > > > > - clk_disable(ldev->pixel_clk); > > if (clk_set_rate(ldev->pixel_clk, rate) < 0) { > > DRM_ERROR("Cannot set rate (%dHz) for pixel clk\n", rate)= ; > > return false; > > } > > - clk_enable(ldev->pixel_clk); > > > > adjusted_mode->clock =3D clk_get_rate(ldev->pixel_clk) / 1000; > > > > + if (runtime_active) { > > + ret =3D pm_runtime_get_sync(ddev->dev); > > + if (ret) { > > + DRM_ERROR("Failed to fixup mode, cannot get sync\= n"); > > + return false; > > + } > > + } > > + > > DRM_DEBUG_DRIVER("requested clock %dkHz, adjusted clock %dkHz\n", > > mode->clock, adjusted_mode->clock); > > > > @@ -525,11 +543,21 @@ static bool ltdc_crtc_mode_fixup(struct drm_crtc = *crtc, > > static void ltdc_crtc_mode_set_nofb(struct drm_crtc *crtc) > > { > > struct ltdc_device *ldev =3D crtc_to_ltdc(crtc); > > + struct drm_device *ddev =3D crtc->dev; > > struct drm_display_mode *mode =3D &crtc->state->adjusted_mode; > > struct videomode vm; > > u32 hsync, vsync, accum_hbp, accum_vbp, accum_act_w, accum_act_h; > > u32 total_width, total_height; > > u32 val; > > + int ret; > > + > > + if (!pm_runtime_active(ddev->dev)) { > > + ret =3D pm_runtime_get_sync(ddev->dev); > > + if (ret) { > > + DRM_ERROR("Failed to set mode, cannot get sync\n"= ); > > + return; > > + } > > + } > > > > drm_display_mode_to_videomode(mode, &vm); > > > > @@ -590,6 +618,7 @@ static void ltdc_crtc_atomic_flush(struct drm_crtc = *crtc, > > struct drm_crtc_state *old_crtc_state) > > { > > struct ltdc_device *ldev =3D crtc_to_ltdc(crtc); > > + struct drm_device *ddev =3D crtc->dev; > > struct drm_pending_vblank_event *event =3D crtc->state->event; > > > > DRM_DEBUG_ATOMIC("\n"); > > @@ -602,12 +631,12 @@ static void ltdc_crtc_atomic_flush(struct drm_crt= c *crtc, > > if (event) { > > crtc->state->event =3D NULL; > > > > - spin_lock_irq(&crtc->dev->event_lock); > > + spin_lock_irq(&ddev->event_lock); > > if (drm_crtc_vblank_get(crtc) =3D=3D 0) > > drm_crtc_arm_vblank_event(crtc, event); > > else > > drm_crtc_send_vblank_event(crtc, event); > > - spin_unlock_irq(&crtc->dev->event_lock); > > + spin_unlock_irq(&ddev->event_lock); > > } > > } > > > > @@ -663,15 +692,19 @@ bool ltdc_crtc_scanoutpos(struct drm_device *ddev= , unsigned int pipe, > > * Computation for the two first cases are identical so we can > > * simplify the code and only test if line > vactive_end > > */ > > - line =3D reg_read(ldev->regs, LTDC_CPSR) & CPSR_CYPOS; > > - vactive_start =3D reg_read(ldev->regs, LTDC_BPCR) & BPCR_AVBP; > > - vactive_end =3D reg_read(ldev->regs, LTDC_AWCR) & AWCR_AAH; > > - vtotal =3D reg_read(ldev->regs, LTDC_TWCR) & TWCR_TOTALH; > > - > > - if (line > vactive_end) > > - *vpos =3D line - vtotal - vactive_start; > > - else > > - *vpos =3D line - vactive_start; > > + if (pm_runtime_active(ddev->dev)) { > > + line =3D reg_read(ldev->regs, LTDC_CPSR) & CPSR_CYPOS; > > + vactive_start =3D reg_read(ldev->regs, LTDC_BPCR) & BPCR_= AVBP; > > + vactive_end =3D reg_read(ldev->regs, LTDC_AWCR) & AWCR_AA= H; > > + vtotal =3D reg_read(ldev->regs, LTDC_TWCR) & TWCR_TOTALH; > > + > > + if (line > vactive_end) > > + *vpos =3D line - vtotal - vactive_start; > > + else > > + *vpos =3D line - vactive_start; > > + } else { > > + *vpos =3D 0; > > + } > > > > *hpos =3D 0; > > > > @@ -1243,8 +1276,11 @@ int ltdc_load(struct drm_device *ddev) > > /* Allow usage of vblank without having to call drm_irq_install *= / > > ddev->irq_enabled =3D 1; > > > > - return 0; > > + clk_disable_unprepare(ldev->pixel_clk); > > + > > + pm_runtime_enable(ddev->dev); > > > > + return 0; > > err: > > for (i =3D 0; i < MAX_ENDPOINTS; i++) > > drm_panel_bridge_remove(bridge[i]); > > @@ -1256,7 +1292,6 @@ int ltdc_load(struct drm_device *ddev) > > > > void ltdc_unload(struct drm_device *ddev) > > { > > - struct ltdc_device *ldev =3D ddev->dev_private; > > int i; > > > > DRM_DEBUG_DRIVER("\n"); > > @@ -1264,7 +1299,7 @@ void ltdc_unload(struct drm_device *ddev) > > for (i =3D 0; i < MAX_ENDPOINTS; i++) > > drm_of_panel_bridge_remove(ddev->dev->of_node, 0, i); > > > > - clk_disable_unprepare(ldev->pixel_clk); > > + pm_runtime_disable(ddev->dev); > > } > > > > MODULE_AUTHOR("Philippe Cornu "); > > > _______________________________________________ > dri-devel mailing list > dri-devel@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/dri-devel