Re: [Freedreno] [v2] drm/msm/disp/dpu1: add safe lut config in dpu driver

2021-08-03 Thread kalyan_t

On 2021-08-04 01:43, Stephen Boyd wrote:

Quoting Kalyan Thota (2021-08-03 03:41:47)

Add safe lut configuration for all the targets in dpu
driver as per QOS recommendation.

Issue reported on SC7280:

With wait-for-safe feature in smmu enabled, RT client
buffer levels are checked to be safe before smmu invalidation.
Since display was always set to unsafe it was delaying the
invalidaiton process thus impacting the performance on NRT clients
such as eMMC and NVMe.

Validated this change on SC7280, With this change eMMC performance
has improved significantly.

Changes in v1:
- Add fixes tag (Sai)
- CC stable kernel (Dimtry)

Fixes: cfacf946a464d4(drm/msm/disp/dpu1: add support for display for 
SC7280 target)


This is wrong format and commit hash


My bad, i'll fix it right away
- KT


Fixes: 591e34a091d1 ("drm/msm/disp/dpu1: add support for display for
SC7280 target")


Signed-off-by: Kalyan Thota 
Tested-by: Sai Prakash Ranjan  
(sc7280, sc7180)


Re: [Freedreno] [v2] drm/msm/disp/dpu1: add safe lut config in dpu driver

2021-08-03 Thread Stephen Boyd
Quoting Kalyan Thota (2021-08-03 03:41:47)
> Add safe lut configuration for all the targets in dpu
> driver as per QOS recommendation.
>
> Issue reported on SC7280:
>
> With wait-for-safe feature in smmu enabled, RT client
> buffer levels are checked to be safe before smmu invalidation.
> Since display was always set to unsafe it was delaying the
> invalidaiton process thus impacting the performance on NRT clients
> such as eMMC and NVMe.
>
> Validated this change on SC7280, With this change eMMC performance
> has improved significantly.
>
> Changes in v1:
> - Add fixes tag (Sai)
> - CC stable kernel (Dimtry)
>
> Fixes: cfacf946a464d4(drm/msm/disp/dpu1: add support for display for SC7280 
> target)

This is wrong format and commit hash

Fixes: 591e34a091d1 ("drm/msm/disp/dpu1: add support for display for
SC7280 target")

> Signed-off-by: Kalyan Thota 
> Tested-by: Sai Prakash Ranjan  (sc7280, 
> sc7180)


Re: [Freedreno] [PATCH v3] drm/msm/dp: update is_connected status base on sink count at dp_pm_resume()

2021-08-03 Thread Stephen Boyd
Quoting Kuogee Hsieh (2021-08-03 09:25:13)
> Currently at dp_pm_resume() is_connected state is decided base on hpd 
> connection
> status only. This will put is_connected in wrongly "true" state at the 
> scenario
> that dongle attached to DUT but without hmdi cable connecting to it. Fix this
> problem by adding read sink count from dongle and decided is_connected state 
> base
> on both sink count and hpd connection status.
>
> Changes in v2:
> -- remove dp_get_sink_count() cand call drm_dp_read_sink_count()
>
> Changes in v3:
> -- delete status local variable from dp_pm_resume()
>
> Fixes: d9aa6571b28ba ("drm/msm/dp: check sink_count before update 
> is_connected status")
> Signed-off-by: Kuogee Hsieh 
> ---
>  drivers/gpu/drm/msm/dp/dp_display.c | 18 +++---
>  1 file changed, 15 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/dp/dp_display.c 
> b/drivers/gpu/drm/msm/dp/dp_display.c
> index 78c5301..0f39256 100644
> --- a/drivers/gpu/drm/msm/dp/dp_display.c
> +++ b/drivers/gpu/drm/msm/dp/dp_display.c
> @@ -1313,7 +1313,7 @@ static int dp_pm_resume(struct device *dev)
> struct platform_device *pdev = to_platform_device(dev);
> struct msm_dp *dp_display = platform_get_drvdata(pdev);
> struct dp_display_private *dp;
> -   u32 status;
> +   int sink_count = 0;
>
> dp = container_of(dp_display, struct dp_display_private, dp_display);
>
> @@ -1327,14 +1327,26 @@ static int dp_pm_resume(struct device *dev)
>
> dp_catalog_ctrl_hpd_config(dp->catalog);
>
> -   status = dp_catalog_link_is_connected(dp->catalog);
> +   /*
> +* set sink to normal operation mode -- D0
> +* before dpcd read
> +*/
> +   dp_link_psm_config(dp->link, >panel->link_info, false);
> +
> +   /* if sink conencted, do dpcd read sink count */

s/conencted/connected/

This also just says what the code is doing. Why do we only read the sink
count if the link is connected? Can we read the sink count even if the
link isn't connected and then consider sink count as 0 if trying to read
fails?

> +   if (dp_catalog_link_is_connected(dp->catalog)) {
> +   sink_count = drm_dp_read_sink_count(dp->aux);
> +   if (sink_count < 0)
> +   sink_count = 0;
> +   }
>
> +   dp->link->sink_count = sink_count;
> /*
>  * can not declared display is connected unless
>  * HDMI cable is plugged in and sink_count of
>  * dongle become 1
>  */
> -   if (status && dp->link->sink_count)
> +   if (dp->link->sink_count)
> dp->dp_display.is_connected = true;
> else
> dp->dp_display.is_connected = false;


Re: [Freedreno] [PATCH v2 07/14] drm/msm: Convert to Linux IRQ interfaces

2021-08-03 Thread abhinavk

On 2021-08-03 02:06, Thomas Zimmermann wrote:

Drop the DRM IRQ midlayer in favor of Linux IRQ interfaces. DRM's
IRQ helpers are mostly useful for UMS drivers. Modern KMS drivers
don't benefit from using it.

DRM IRQ callbacks are now being called directly or inlined.

Signed-off-by: Thomas Zimmermann 

Reviewed-by: Abhinav Kumar 

---
 drivers/gpu/drm/msm/msm_drv.c | 113 --
 drivers/gpu/drm/msm/msm_kms.h |   2 +-
 2 files changed, 69 insertions(+), 46 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_drv.c 
b/drivers/gpu/drm/msm/msm_drv.c

index 1594ae39d54f..a332b09a5a11 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -14,7 +14,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
@@ -201,6 +200,71 @@ void msm_rmw(void __iomem *addr, u32 mask, u32 or)
msm_writel(val | or, addr);
 }

+static irqreturn_t msm_irq(int irq, void *arg)
+{
+   struct drm_device *dev = arg;
+   struct msm_drm_private *priv = dev->dev_private;
+   struct msm_kms *kms = priv->kms;
+
+   BUG_ON(!kms);
+
+   return kms->funcs->irq(kms);
+}
+
+static void msm_irq_preinstall(struct drm_device *dev)
+{
+   struct msm_drm_private *priv = dev->dev_private;
+   struct msm_kms *kms = priv->kms;
+
+   BUG_ON(!kms);
+
+   kms->funcs->irq_preinstall(kms);
+}
+
+static int msm_irq_postinstall(struct drm_device *dev)
+{
+   struct msm_drm_private *priv = dev->dev_private;
+   struct msm_kms *kms = priv->kms;
+
+   BUG_ON(!kms);
+
+   if (kms->funcs->irq_postinstall)
+   return kms->funcs->irq_postinstall(kms);
+
+   return 0;
+}
+
+static int msm_irq_install(struct drm_device *dev, unsigned int irq)
+{
+   int ret;
+
+   if (irq == IRQ_NOTCONNECTED)
+   return -ENOTCONN;
+
+   msm_irq_preinstall(dev);
+
+   ret = request_irq(irq, msm_irq, 0, dev->driver->name, dev);
+   if (ret)
+   return ret;
+
+   ret = msm_irq_postinstall(dev);
+   if (ret) {
+   free_irq(irq, dev);
+   return ret;
+   }
+
+   return 0;
+}
+
+static void msm_irq_uninstall(struct drm_device *dev)
+{
+   struct msm_drm_private *priv = dev->dev_private;
+   struct msm_kms *kms = priv->kms;
+
+   kms->funcs->irq_uninstall(kms);
+   free_irq(kms->irq, dev);
+}
+
 struct msm_vblank_work {
struct work_struct work;
int crtc_id;
@@ -265,7 +329,7 @@ static int msm_drm_uninit(struct device *dev)
}

/* We must cancel and cleanup any pending vblank enable/disable
-* work before drm_irq_uninstall() to avoid work re-enabling an
+* work before msm_irq_uninstall() to avoid work re-enabling an
 * irq after uninstall has disabled it.
 */

@@ -294,7 +358,7 @@ static int msm_drm_uninit(struct device *dev)
drm_mode_config_cleanup(ddev);

pm_runtime_get_sync(dev);
-   drm_irq_uninstall(ddev);
+   msm_irq_uninstall(ddev);
pm_runtime_put_sync(dev);

if (kms && kms->funcs)
@@ -553,7 +617,7 @@ static int msm_drm_init(struct device *dev, const
struct drm_driver *drv)

if (kms) {
pm_runtime_get_sync(dev);
-   ret = drm_irq_install(ddev, kms->irq);
+   ret = msm_irq_install(ddev, kms->irq);
pm_runtime_put_sync(dev);
if (ret < 0) {
DRM_DEV_ERROR(dev, "failed to install IRQ handler\n");
@@ -662,43 +726,6 @@ static void msm_postclose(struct drm_device *dev,
struct drm_file *file)
context_close(ctx);
 }

-static irqreturn_t msm_irq(int irq, void *arg)
-{
-   struct drm_device *dev = arg;
-   struct msm_drm_private *priv = dev->dev_private;
-   struct msm_kms *kms = priv->kms;
-   BUG_ON(!kms);
-   return kms->funcs->irq(kms);
-}
-
-static void msm_irq_preinstall(struct drm_device *dev)
-{
-   struct msm_drm_private *priv = dev->dev_private;
-   struct msm_kms *kms = priv->kms;
-   BUG_ON(!kms);
-   kms->funcs->irq_preinstall(kms);
-}
-
-static int msm_irq_postinstall(struct drm_device *dev)
-{
-   struct msm_drm_private *priv = dev->dev_private;
-   struct msm_kms *kms = priv->kms;
-   BUG_ON(!kms);
-
-   if (kms->funcs->irq_postinstall)
-   return kms->funcs->irq_postinstall(kms);
-
-   return 0;
-}
-
-static void msm_irq_uninstall(struct drm_device *dev)
-{
-   struct msm_drm_private *priv = dev->dev_private;
-   struct msm_kms *kms = priv->kms;
-   BUG_ON(!kms);
-   kms->funcs->irq_uninstall(kms);
-}
-
 int msm_crtc_enable_vblank(struct drm_crtc *crtc)
 {
struct drm_device *dev = crtc->dev;
@@ -1051,10 +1078,6 @@ static const struct drm_driver msm_driver = {
.open   = msm_open,
.postclose   = msm_postclose,
.lastclose  = drm_fb_helper_lastclose,
-   .irq_handler= msm_irq,

[Freedreno] [PATCH v3] drm/msm/dp: update is_connected status base on sink count at dp_pm_resume()

2021-08-03 Thread Kuogee Hsieh
Currently at dp_pm_resume() is_connected state is decided base on hpd connection
status only. This will put is_connected in wrongly "true" state at the scenario
that dongle attached to DUT but without hmdi cable connecting to it. Fix this
problem by adding read sink count from dongle and decided is_connected state 
base
on both sink count and hpd connection status.

Changes in v2:
-- remove dp_get_sink_count() cand call drm_dp_read_sink_count()

Changes in v3:
-- delete status local variable from dp_pm_resume()

Fixes: d9aa6571b28ba ("drm/msm/dp: check sink_count before update is_connected 
status")
Signed-off-by: Kuogee Hsieh 
---
 drivers/gpu/drm/msm/dp/dp_display.c | 18 +++---
 1 file changed, 15 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_display.c 
b/drivers/gpu/drm/msm/dp/dp_display.c
index 78c5301..0f39256 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -1313,7 +1313,7 @@ static int dp_pm_resume(struct device *dev)
struct platform_device *pdev = to_platform_device(dev);
struct msm_dp *dp_display = platform_get_drvdata(pdev);
struct dp_display_private *dp;
-   u32 status;
+   int sink_count = 0;
 
dp = container_of(dp_display, struct dp_display_private, dp_display);
 
@@ -1327,14 +1327,26 @@ static int dp_pm_resume(struct device *dev)
 
dp_catalog_ctrl_hpd_config(dp->catalog);
 
-   status = dp_catalog_link_is_connected(dp->catalog);
+   /*
+* set sink to normal operation mode -- D0
+* before dpcd read
+*/
+   dp_link_psm_config(dp->link, >panel->link_info, false);
+
+   /* if sink conencted, do dpcd read sink count */
+   if (dp_catalog_link_is_connected(dp->catalog)) {
+   sink_count = drm_dp_read_sink_count(dp->aux);
+   if (sink_count < 0)
+   sink_count = 0;
+   }
 
+   dp->link->sink_count = sink_count;
/*
 * can not declared display is connected unless
 * HDMI cable is plugged in and sink_count of
 * dongle become 1
 */
-   if (status && dp->link->sink_count)
+   if (dp->link->sink_count)
dp->dp_display.is_connected = true;
else
dp->dp_display.is_connected = false;
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



Re: [Freedreno] [PATCH v2 00/14] drm: Make DRM's IRQ helpers legacy

2021-08-03 Thread Sam Ravnborg
Hi Thomas,

On Tue, Aug 03, 2021 at 11:06:50AM +0200, Thomas Zimmermann wrote:
> DRM's IRQ helpers are only helpful for old, non-KMS drivers. Move
> the code behind CONFIG_DRM_LEGACY. Convert KMS drivers to Linux
> IRQ interfaces.
> 
> DRM provides IRQ helpers for setting up, receiving and removing IRQ
> handlers. It's an abstraction over plain Linux functions. The code
> is mid-layerish with several callbacks to hook into the rsp drivers.
> Old UMS driver have their interrupts enabled via ioctl, so these
> abstractions makes some sense. Modern KMS manage all their interrupts
> internally. Using the DRM helpers adds indirection without benefits.
> 
> Most KMS drivers already use Linux IRQ functions instead of DRM's
> abstraction layer. Patches 1 to 12 convert the remaining ones.
> The patches also resolve a bug for devices without assigned interrupt
> number. DRM helpers don't test for IRQ_NOTCONNECTED, so drivers do
> not detect if the device has no interrupt assigned.
> 
> Patch 13 removes an unused function.
> 
> Patch 14 moves the DRM IRQ helpers behind CONFIG_DRM_LEGACY. Only
> the old non-KMS drivers still use the functionality.
> 
> v2:
>   * drop IRQ_NOTCONNECTED test from atmel-hlcdc (Sam)
>   * use devm_request_irq() in atmel-hlcdc (Sam)
>   * unify variable names in arm/hlcdc (Sam)
> 
> Thomas Zimmermann (14):

The following patches are all:
Acked-by: Sam Ravnborg 

>   drm/fsl-dcu: Convert to Linux IRQ interfaces
>   drm/gma500: Convert to Linux IRQ interfaces
>   drm/kmb: Convert to Linux IRQ interfaces
>   drm/msm: Convert to Linux IRQ interfaces
>   drm/mxsfb: Convert to Linux IRQ interfaces
>   drm/tidss: Convert to Linux IRQ interfaces
>   drm/vc4: Convert to Linux IRQ interfaces
>   drm: Remove unused devm_drm_irq_install()

The remaining patches I either skipped or already had a feedback from
me or I asked a question.

Sam


Re: [Freedreno] [PATCH v2 11/14] drm/tilcdc: Convert to Linux IRQ interfaces

2021-08-03 Thread Sam Ravnborg
Hi Thomas,

On Tue, Aug 03, 2021 at 11:07:01AM +0200, Thomas Zimmermann wrote:
> Drop the DRM IRQ midlayer in favor of Linux IRQ interfaces. DRM's
> IRQ helpers are mostly useful for UMS drivers. Modern KMS drivers
> don't benefit from using it.
> 
> DRM IRQ callbacks are now being called directly or inlined.
> 
> Calls to platform_get_irq() can fail with a negative errno code.
> Abort initialization in this case. The DRM IRQ midlayer does not
> handle this case correctly.

I cannot see why the irq_enabled flag is needed here, and the changelog
do not help me.
What do I miss?

Sam


> 
> Signed-off-by: Thomas Zimmermann 
> ---
>  drivers/gpu/drm/tilcdc/tilcdc_drv.c | 51 ++---
>  drivers/gpu/drm/tilcdc/tilcdc_drv.h |  3 ++
>  2 files changed, 43 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c 
> b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
> index f1d3a9f919fd..6b03f89a98d4 100644
> --- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c
> +++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
> @@ -20,7 +20,6 @@
>  #include 
>  #include 
>  #include 
> -#include 
>  #include 
>  #include 
>  #include 
> @@ -124,6 +123,39 @@ static int cpufreq_transition(struct notifier_block *nb,
>  }
>  #endif
>  
> +static irqreturn_t tilcdc_irq(int irq, void *arg)
> +{
> + struct drm_device *dev = arg;
> + struct tilcdc_drm_private *priv = dev->dev_private;
> +
> + return tilcdc_crtc_irq(priv->crtc);
> +}
> +
> +static int tilcdc_irq_install(struct drm_device *dev, unsigned int irq)
> +{
> + struct tilcdc_drm_private *priv = dev->dev_private;
> + int ret;
> +
> + ret = request_irq(irq, tilcdc_irq, 0, dev->driver->name, dev);
> + if (ret)
> + return ret;
> +
> + priv->irq_enabled = false;
> +
> + return 0;
> +}
> +
> +static void tilcdc_irq_uninstall(struct drm_device *dev)
> +{
> + struct tilcdc_drm_private *priv = dev->dev_private;
> +
> + if (!priv->irq_enabled)
> + return;
> +
> + free_irq(priv->irq, dev);
> + priv->irq_enabled = false;
> +}
> +
>  /*
>   * DRM operations:
>   */
> @@ -145,7 +177,7 @@ static void tilcdc_fini(struct drm_device *dev)
>   drm_dev_unregister(dev);
>  
>   drm_kms_helper_poll_fini(dev);
> - drm_irq_uninstall(dev);
> + tilcdc_irq_uninstall(dev);
>   drm_mode_config_cleanup(dev);
>  
>   if (priv->clk)
> @@ -336,7 +368,12 @@ static int tilcdc_init(const struct drm_driver *ddrv, 
> struct device *dev)
>   goto init_failed;
>   }
>  
> - ret = drm_irq_install(ddev, platform_get_irq(pdev, 0));
> + ret = platform_get_irq(pdev, 0);
> + if (ret < 0)
> + goto init_failed;
> + priv->irq = ret;
> +
> + ret = tilcdc_irq_install(ddev, priv->irq);
>   if (ret < 0) {
>   dev_err(dev, "failed to install IRQ handler\n");
>   goto init_failed;
> @@ -360,13 +397,6 @@ static int tilcdc_init(const struct drm_driver *ddrv, 
> struct device *dev)
>   return ret;
>  }
>  
> -static irqreturn_t tilcdc_irq(int irq, void *arg)
> -{
> - struct drm_device *dev = arg;
> - struct tilcdc_drm_private *priv = dev->dev_private;
> - return tilcdc_crtc_irq(priv->crtc);
> -}
> -
>  #if defined(CONFIG_DEBUG_FS)
>  static const struct {
>   const char *name;
> @@ -454,7 +484,6 @@ DEFINE_DRM_GEM_CMA_FOPS(fops);
>  
>  static const struct drm_driver tilcdc_driver = {
>   .driver_features= DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
> - .irq_handler= tilcdc_irq,
>   DRM_GEM_CMA_DRIVER_OPS,
>  #ifdef CONFIG_DEBUG_FS
>   .debugfs_init   = tilcdc_debugfs_init,
> diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.h 
> b/drivers/gpu/drm/tilcdc/tilcdc_drv.h
> index d29806ca8817..b818448c83f6 100644
> --- a/drivers/gpu/drm/tilcdc/tilcdc_drv.h
> +++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.h
> @@ -46,6 +46,8 @@ struct tilcdc_drm_private {
>   struct clk *clk; /* functional clock */
>   int rev; /* IP revision */
>  
> + unsigned int irq;
> +
>   /* don't attempt resolutions w/ higher W * H * Hz: */
>   uint32_t max_bandwidth;
>   /*
> @@ -82,6 +84,7 @@ struct tilcdc_drm_private {
>  
>   bool is_registered;
>   bool is_componentized;
> + bool irq_enabled;
>  };
>  
>  /* Sub-module for display.  Since we don't know at compile time what panels
> -- 
> 2.32.0


Re: [Freedreno] [PATCH v2 07/14] drm/msm: Convert to Linux IRQ interfaces

2021-08-03 Thread Rob Clark
On Tue, Aug 3, 2021 at 2:37 AM Dmitry Baryshkov
 wrote:
>
> On 03/08/2021 12:06, Thomas Zimmermann wrote:
> > Drop the DRM IRQ midlayer in favor of Linux IRQ interfaces. DRM's
> > IRQ helpers are mostly useful for UMS drivers. Modern KMS drivers
> > don't benefit from using it.
> >
> > DRM IRQ callbacks are now being called directly or inlined.
> >
> > Signed-off-by: Thomas Zimmermann 
>
> Reviewed-by: Dmitry Baryshkov 
>
> Rob should probably also give his blessing on this patch though.

It looks ok.. I can't really test it this week, but it should be
pretty obvious if it wasn't working

BR,
-R

>
> > ---
> >   drivers/gpu/drm/msm/msm_drv.c | 113 --
> >   drivers/gpu/drm/msm/msm_kms.h |   2 +-
> >   2 files changed, 69 insertions(+), 46 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
> > index 1594ae39d54f..a332b09a5a11 100644
> > --- a/drivers/gpu/drm/msm/msm_drv.c
> > +++ b/drivers/gpu/drm/msm/msm_drv.c
> > @@ -14,7 +14,6 @@
> >   #include 
> >   #include 
> >   #include 
> > -#include 
> >   #include 
> >   #include 
> >   #include 
> > @@ -201,6 +200,71 @@ void msm_rmw(void __iomem *addr, u32 mask, u32 or)
> >   msm_writel(val | or, addr);
> >   }
> >
> > +static irqreturn_t msm_irq(int irq, void *arg)
> > +{
> > + struct drm_device *dev = arg;
> > + struct msm_drm_private *priv = dev->dev_private;
> > + struct msm_kms *kms = priv->kms;
> > +
> > + BUG_ON(!kms);
> > +
> > + return kms->funcs->irq(kms);
> > +}
> > +
> > +static void msm_irq_preinstall(struct drm_device *dev)
> > +{
> > + struct msm_drm_private *priv = dev->dev_private;
> > + struct msm_kms *kms = priv->kms;
> > +
> > + BUG_ON(!kms);
> > +
> > + kms->funcs->irq_preinstall(kms);
> > +}
> > +
> > +static int msm_irq_postinstall(struct drm_device *dev)
> > +{
> > + struct msm_drm_private *priv = dev->dev_private;
> > + struct msm_kms *kms = priv->kms;
> > +
> > + BUG_ON(!kms);
> > +
> > + if (kms->funcs->irq_postinstall)
> > + return kms->funcs->irq_postinstall(kms);
> > +
> > + return 0;
> > +}
> > +
> > +static int msm_irq_install(struct drm_device *dev, unsigned int irq)
> > +{
> > + int ret;
> > +
> > + if (irq == IRQ_NOTCONNECTED)
> > + return -ENOTCONN;
> > +
> > + msm_irq_preinstall(dev);
> > +
> > + ret = request_irq(irq, msm_irq, 0, dev->driver->name, dev);
> > + if (ret)
> > + return ret;
> > +
> > + ret = msm_irq_postinstall(dev);
> > + if (ret) {
> > + free_irq(irq, dev);
> > + return ret;
> > + }
> > +
> > + return 0;
> > +}
> > +
> > +static void msm_irq_uninstall(struct drm_device *dev)
> > +{
> > + struct msm_drm_private *priv = dev->dev_private;
> > + struct msm_kms *kms = priv->kms;
> > +
> > + kms->funcs->irq_uninstall(kms);
> > + free_irq(kms->irq, dev);
> > +}
> > +
> >   struct msm_vblank_work {
> >   struct work_struct work;
> >   int crtc_id;
> > @@ -265,7 +329,7 @@ static int msm_drm_uninit(struct device *dev)
> >   }
> >
> >   /* We must cancel and cleanup any pending vblank enable/disable
> > -  * work before drm_irq_uninstall() to avoid work re-enabling an
> > +  * work before msm_irq_uninstall() to avoid work re-enabling an
> >* irq after uninstall has disabled it.
> >*/
> >
> > @@ -294,7 +358,7 @@ static int msm_drm_uninit(struct device *dev)
> >   drm_mode_config_cleanup(ddev);
> >
> >   pm_runtime_get_sync(dev);
> > - drm_irq_uninstall(ddev);
> > + msm_irq_uninstall(ddev);
> >   pm_runtime_put_sync(dev);
> >
> >   if (kms && kms->funcs)
> > @@ -553,7 +617,7 @@ static int msm_drm_init(struct device *dev, const 
> > struct drm_driver *drv)
> >
> >   if (kms) {
> >   pm_runtime_get_sync(dev);
> > - ret = drm_irq_install(ddev, kms->irq);
> > + ret = msm_irq_install(ddev, kms->irq);
> >   pm_runtime_put_sync(dev);
> >   if (ret < 0) {
> >   DRM_DEV_ERROR(dev, "failed to install IRQ handler\n");
> > @@ -662,43 +726,6 @@ static void msm_postclose(struct drm_device *dev, 
> > struct drm_file *file)
> >   context_close(ctx);
> >   }
> >
> > -static irqreturn_t msm_irq(int irq, void *arg)
> > -{
> > - struct drm_device *dev = arg;
> > - struct msm_drm_private *priv = dev->dev_private;
> > - struct msm_kms *kms = priv->kms;
> > - BUG_ON(!kms);
> > - return kms->funcs->irq(kms);
> > -}
> > -
> > -static void msm_irq_preinstall(struct drm_device *dev)
> > -{
> > - struct msm_drm_private *priv = dev->dev_private;
> > - struct msm_kms *kms = priv->kms;
> > - BUG_ON(!kms);
> > - kms->funcs->irq_preinstall(kms);
> > -}
> > -
> > -static int msm_irq_postinstall(struct drm_device *dev)
> > -{
> > - struct msm_drm_private *priv = dev->dev_private;
> > - struct msm_kms *kms = priv->kms;
> 

Re: [Freedreno] [v2] drm/msm/disp/dpu1: add safe lut config in dpu driver

2021-08-03 Thread Dmitry Baryshkov
On Tue, 3 Aug 2021 at 13:42, Kalyan Thota  wrote:
>
> Add safe lut configuration for all the targets in dpu
> driver as per QOS recommendation.
>
> Issue reported on SC7280:
>
> With wait-for-safe feature in smmu enabled, RT client
> buffer levels are checked to be safe before smmu invalidation.
> Since display was always set to unsafe it was delaying the
> invalidaiton process thus impacting the performance on NRT clients
> such as eMMC and NVMe.
>
> Validated this change on SC7280, With this change eMMC performance
> has improved significantly.
>
> Changes in v1:
> - Add fixes tag (Sai)
> - CC stable kernel (Dimtry)
>
> Fixes: cfacf946a464d4(drm/msm/disp/dpu1: add support for display for SC7280 
> target)
> Signed-off-by: Kalyan Thota 
> Tested-by: Sai Prakash Ranjan  (sc7280, 
> sc7180)

Reviewed-by: Dmitry Baryshkov 

> ---
>  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 5 +
>  1 file changed, 5 insertions(+)
>
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c 
> b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
> index d01c4c9..2e482cd 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
> @@ -974,6 +974,7 @@ static const struct dpu_perf_cfg sdm845_perf_data = {
> .amortizable_threshold = 25,
> .min_prefill_lines = 24,
> .danger_lut_tbl = {0xf, 0x, 0x0},
> +   .safe_lut_tbl = {0xfff0, 0xf000, 0x},
> .qos_lut_tbl = {
> {.nentry = ARRAY_SIZE(sdm845_qos_linear),
> .entries = sdm845_qos_linear
> @@ -1001,6 +1002,7 @@ static const struct dpu_perf_cfg sc7180_perf_data = {
> .min_dram_ib = 160,
> .min_prefill_lines = 24,
> .danger_lut_tbl = {0xff, 0x, 0x0},
> +   .safe_lut_tbl = {0xfff0, 0xff00, 0x},
> .qos_lut_tbl = {
> {.nentry = ARRAY_SIZE(sc7180_qos_linear),
> .entries = sc7180_qos_linear
> @@ -1028,6 +1030,7 @@ static const struct dpu_perf_cfg sm8150_perf_data = {
> .min_dram_ib = 80,
> .min_prefill_lines = 24,
> .danger_lut_tbl = {0xf, 0x, 0x0},
> +   .safe_lut_tbl = {0xfff8, 0xf000, 0x},
> .qos_lut_tbl = {
> {.nentry = ARRAY_SIZE(sm8150_qos_linear),
> .entries = sm8150_qos_linear
> @@ -1056,6 +1059,7 @@ static const struct dpu_perf_cfg sm8250_perf_data = {
> .min_dram_ib = 80,
> .min_prefill_lines = 35,
> .danger_lut_tbl = {0xf, 0x, 0x0},
> +   .safe_lut_tbl = {0xfff0, 0xff00, 0x},
> .qos_lut_tbl = {
> {.nentry = ARRAY_SIZE(sc7180_qos_linear),
> .entries = sc7180_qos_linear
> @@ -1084,6 +1088,7 @@ static const struct dpu_perf_cfg sc7280_perf_data = {
> .min_dram_ib = 160,
> .min_prefill_lines = 24,
> .danger_lut_tbl = {0x, 0x, 0x0},
> +   .safe_lut_tbl = {0xff00, 0xff00, 0x},
> .qos_lut_tbl = {
> {.nentry = ARRAY_SIZE(sc7180_qos_macrotile),
> .entries = sc7180_qos_macrotile
> --
> 2.7.4
>


-- 
With best wishes
Dmitry


[Freedreno] [v2] drm/msm/disp/dpu1: add safe lut config in dpu driver

2021-08-03 Thread Kalyan Thota
Add safe lut configuration for all the targets in dpu
driver as per QOS recommendation.

Issue reported on SC7280:

With wait-for-safe feature in smmu enabled, RT client
buffer levels are checked to be safe before smmu invalidation.
Since display was always set to unsafe it was delaying the
invalidaiton process thus impacting the performance on NRT clients
such as eMMC and NVMe.

Validated this change on SC7280, With this change eMMC performance
has improved significantly.

Changes in v1:
- Add fixes tag (Sai)
- CC stable kernel (Dimtry)

Fixes: cfacf946a464d4(drm/msm/disp/dpu1: add support for display for SC7280 
target)
Signed-off-by: Kalyan Thota 
Tested-by: Sai Prakash Ranjan  (sc7280, 
sc7180)
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
index d01c4c9..2e482cd 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
@@ -974,6 +974,7 @@ static const struct dpu_perf_cfg sdm845_perf_data = {
.amortizable_threshold = 25,
.min_prefill_lines = 24,
.danger_lut_tbl = {0xf, 0x, 0x0},
+   .safe_lut_tbl = {0xfff0, 0xf000, 0x},
.qos_lut_tbl = {
{.nentry = ARRAY_SIZE(sdm845_qos_linear),
.entries = sdm845_qos_linear
@@ -1001,6 +1002,7 @@ static const struct dpu_perf_cfg sc7180_perf_data = {
.min_dram_ib = 160,
.min_prefill_lines = 24,
.danger_lut_tbl = {0xff, 0x, 0x0},
+   .safe_lut_tbl = {0xfff0, 0xff00, 0x},
.qos_lut_tbl = {
{.nentry = ARRAY_SIZE(sc7180_qos_linear),
.entries = sc7180_qos_linear
@@ -1028,6 +1030,7 @@ static const struct dpu_perf_cfg sm8150_perf_data = {
.min_dram_ib = 80,
.min_prefill_lines = 24,
.danger_lut_tbl = {0xf, 0x, 0x0},
+   .safe_lut_tbl = {0xfff8, 0xf000, 0x},
.qos_lut_tbl = {
{.nentry = ARRAY_SIZE(sm8150_qos_linear),
.entries = sm8150_qos_linear
@@ -1056,6 +1059,7 @@ static const struct dpu_perf_cfg sm8250_perf_data = {
.min_dram_ib = 80,
.min_prefill_lines = 35,
.danger_lut_tbl = {0xf, 0x, 0x0},
+   .safe_lut_tbl = {0xfff0, 0xff00, 0x},
.qos_lut_tbl = {
{.nentry = ARRAY_SIZE(sc7180_qos_linear),
.entries = sc7180_qos_linear
@@ -1084,6 +1088,7 @@ static const struct dpu_perf_cfg sc7280_perf_data = {
.min_dram_ib = 160,
.min_prefill_lines = 24,
.danger_lut_tbl = {0x, 0x, 0x0},
+   .safe_lut_tbl = {0xff00, 0xff00, 0x},
.qos_lut_tbl = {
{.nentry = ARRAY_SIZE(sc7180_qos_macrotile),
.entries = sc7180_qos_macrotile
-- 
2.7.4



[Freedreno] [PATCH v3 2/2] arm64: dts: sm8250: remove bus clock from the mdss node for sm8250 target

2021-08-03 Thread Dmitry Baryshkov
Remove the bus clock from the mdss device node, in order to facilitate
bus band width scaling on sm8250 target.

The parent device MDSS will not vote for bus bw, instead the vote will
be triggered by mdp device node. Since a minimum vote is required to
turn on bus clock, and since mdp device node already has the bus clock,
remove the clock from the mdss device.

Signed-off-by: Dmitry Baryshkov 
---
 arch/arm64/boot/dts/qcom/sm8250.dtsi | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/qcom/sm8250.dtsi 
b/arch/arm64/boot/dts/qcom/sm8250.dtsi
index 4798368b02ef..1df03c809d02 100644
--- a/arch/arm64/boot/dts/qcom/sm8250.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm8250.dtsi
@@ -2470,10 +2470,9 @@ mdss: mdss@ae0 {
power-domains = < MDSS_GDSC>;
 
clocks = < DISP_CC_MDSS_AHB_CLK>,
-< GCC_DISP_HF_AXI_CLK>,
 < GCC_DISP_SF_AXI_CLK>,
 < DISP_CC_MDSS_MDP_CLK>;
-   clock-names = "iface", "bus", "nrt_bus", "core";
+   clock-names = "iface", "nrt_bus", "core";
 
assigned-clocks = < DISP_CC_MDSS_MDP_CLK>;
assigned-clock-rates = <46000>;
-- 
2.30.2



[Freedreno] [PATCH v3 0/4] drm/msm/dpu: always use mdp device to scale bandwidth

2021-08-03 Thread Dmitry Baryshkov
In 5.13 the DPU driver was changed to vote on the bus bandwidth for all
the soc families, however suggested [1] dts changes were for some reason
not merged at that time. Let's merge them now.

If the bootloader does not setup the bus vote, clock might not be
enabled before the driver votes on the MDP bus bandwidth. Originally bus
votes were static and happened in MDSS hadling code, while now they are
dynamic and are moved to the MDP handling code, thus bus clocks also
should belong to the MDP device.

[1] 
https://lore.kernel.org/linux-arm-msm/04b4612dfd3f651ead06872540921...@codeaurora.org/

Changes since v2:
 - Dropped merged patches
 - Rephrased commit message for sm8250.

Changes since v1:
 - Add dts changes as requested by Kalyan Thota


Dmitry Baryshkov (2):
  arm64: dts: sdm845: move bus clock to mdp node for sdm845 target
  arm64: dts: sm8250: remove bus clock from the mdss node for sm8250 target

 arch/arm64/boot/dts/qcom/sdm845.dtsi | 8 
 arch/arm64/boot/dts/qcom/sm8250.dtsi | 3 +--
 2 files changed, 5 insertions(+), 6 deletions(-)



[Freedreno] [PATCH v3 1/2] arm64: dts: sdm845: move bus clock to mdp node for sdm845 target

2021-08-03 Thread Dmitry Baryshkov
Move the bus clock to mdp device node,in order to facilitate bus band
width scaling on sdm845 target.

The parent device MDSS will not vote for bus bw, instead the vote will
be triggered by mdp device node. Since a minimum vote is required to
turn on bus clock, move the clock node to mdp device from where the
votes are requested.

Signed-off-by: Dmitry Baryshkov 
---
 arch/arm64/boot/dts/qcom/sdm845.dtsi | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi 
b/arch/arm64/boot/dts/qcom/sdm845.dtsi
index 1796ae8372be..9e77a323b1cd 100644
--- a/arch/arm64/boot/dts/qcom/sdm845.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi
@@ -4148,9 +4148,8 @@ mdss: mdss@ae0 {
power-domains = < MDSS_GDSC>;
 
clocks = < GCC_DISP_AHB_CLK>,
-< GCC_DISP_AXI_CLK>,
 < DISP_CC_MDSS_MDP_CLK>;
-   clock-names = "iface", "bus", "core";
+   clock-names = "iface", "core";
 
assigned-clocks = < DISP_CC_MDSS_MDP_CLK>;
assigned-clock-rates = <3>;
@@ -4178,11 +4177,12 @@ mdss_mdp: mdp@ae01000 {
  <0 0x0aeb 0 0x2008>;
reg-names = "mdp", "vbif";
 
-   clocks = < DISP_CC_MDSS_AHB_CLK>,
+   clocks = < GCC_DISP_AXI_CLK>,
+< DISP_CC_MDSS_AHB_CLK>,
 < DISP_CC_MDSS_AXI_CLK>,
 < DISP_CC_MDSS_MDP_CLK>,
 < DISP_CC_MDSS_VSYNC_CLK>;
-   clock-names = "iface", "bus", "core", "vsync";
+   clock-names = "gcc-bus", "iface", "bus", 
"core", "vsync";
 
assigned-clocks = < 
DISP_CC_MDSS_MDP_CLK>,
  < 
DISP_CC_MDSS_VSYNC_CLK>;
-- 
2.30.2



Re: [Freedreno] [PATCH v2 07/14] drm/msm: Convert to Linux IRQ interfaces

2021-08-03 Thread Dmitry Baryshkov

On 03/08/2021 12:06, Thomas Zimmermann wrote:

Drop the DRM IRQ midlayer in favor of Linux IRQ interfaces. DRM's
IRQ helpers are mostly useful for UMS drivers. Modern KMS drivers
don't benefit from using it.

DRM IRQ callbacks are now being called directly or inlined.

Signed-off-by: Thomas Zimmermann 


Reviewed-by: Dmitry Baryshkov 

Rob should probably also give his blessing on this patch though.


---
  drivers/gpu/drm/msm/msm_drv.c | 113 --
  drivers/gpu/drm/msm/msm_kms.h |   2 +-
  2 files changed, 69 insertions(+), 46 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index 1594ae39d54f..a332b09a5a11 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -14,7 +14,6 @@
  #include 
  #include 
  #include 
-#include 
  #include 
  #include 
  #include 
@@ -201,6 +200,71 @@ void msm_rmw(void __iomem *addr, u32 mask, u32 or)
msm_writel(val | or, addr);
  }
  
+static irqreturn_t msm_irq(int irq, void *arg)

+{
+   struct drm_device *dev = arg;
+   struct msm_drm_private *priv = dev->dev_private;
+   struct msm_kms *kms = priv->kms;
+
+   BUG_ON(!kms);
+
+   return kms->funcs->irq(kms);
+}
+
+static void msm_irq_preinstall(struct drm_device *dev)
+{
+   struct msm_drm_private *priv = dev->dev_private;
+   struct msm_kms *kms = priv->kms;
+
+   BUG_ON(!kms);
+
+   kms->funcs->irq_preinstall(kms);
+}
+
+static int msm_irq_postinstall(struct drm_device *dev)
+{
+   struct msm_drm_private *priv = dev->dev_private;
+   struct msm_kms *kms = priv->kms;
+
+   BUG_ON(!kms);
+
+   if (kms->funcs->irq_postinstall)
+   return kms->funcs->irq_postinstall(kms);
+
+   return 0;
+}
+
+static int msm_irq_install(struct drm_device *dev, unsigned int irq)
+{
+   int ret;
+
+   if (irq == IRQ_NOTCONNECTED)
+   return -ENOTCONN;
+
+   msm_irq_preinstall(dev);
+
+   ret = request_irq(irq, msm_irq, 0, dev->driver->name, dev);
+   if (ret)
+   return ret;
+
+   ret = msm_irq_postinstall(dev);
+   if (ret) {
+   free_irq(irq, dev);
+   return ret;
+   }
+
+   return 0;
+}
+
+static void msm_irq_uninstall(struct drm_device *dev)
+{
+   struct msm_drm_private *priv = dev->dev_private;
+   struct msm_kms *kms = priv->kms;
+
+   kms->funcs->irq_uninstall(kms);
+   free_irq(kms->irq, dev);
+}
+
  struct msm_vblank_work {
struct work_struct work;
int crtc_id;
@@ -265,7 +329,7 @@ static int msm_drm_uninit(struct device *dev)
}
  
  	/* We must cancel and cleanup any pending vblank enable/disable

-* work before drm_irq_uninstall() to avoid work re-enabling an
+* work before msm_irq_uninstall() to avoid work re-enabling an
 * irq after uninstall has disabled it.
 */
  
@@ -294,7 +358,7 @@ static int msm_drm_uninit(struct device *dev)

drm_mode_config_cleanup(ddev);
  
  	pm_runtime_get_sync(dev);

-   drm_irq_uninstall(ddev);
+   msm_irq_uninstall(ddev);
pm_runtime_put_sync(dev);
  
  	if (kms && kms->funcs)

@@ -553,7 +617,7 @@ static int msm_drm_init(struct device *dev, const struct 
drm_driver *drv)
  
  	if (kms) {

pm_runtime_get_sync(dev);
-   ret = drm_irq_install(ddev, kms->irq);
+   ret = msm_irq_install(ddev, kms->irq);
pm_runtime_put_sync(dev);
if (ret < 0) {
DRM_DEV_ERROR(dev, "failed to install IRQ handler\n");
@@ -662,43 +726,6 @@ static void msm_postclose(struct drm_device *dev, struct 
drm_file *file)
context_close(ctx);
  }
  
-static irqreturn_t msm_irq(int irq, void *arg)

-{
-   struct drm_device *dev = arg;
-   struct msm_drm_private *priv = dev->dev_private;
-   struct msm_kms *kms = priv->kms;
-   BUG_ON(!kms);
-   return kms->funcs->irq(kms);
-}
-
-static void msm_irq_preinstall(struct drm_device *dev)
-{
-   struct msm_drm_private *priv = dev->dev_private;
-   struct msm_kms *kms = priv->kms;
-   BUG_ON(!kms);
-   kms->funcs->irq_preinstall(kms);
-}
-
-static int msm_irq_postinstall(struct drm_device *dev)
-{
-   struct msm_drm_private *priv = dev->dev_private;
-   struct msm_kms *kms = priv->kms;
-   BUG_ON(!kms);
-
-   if (kms->funcs->irq_postinstall)
-   return kms->funcs->irq_postinstall(kms);
-
-   return 0;
-}
-
-static void msm_irq_uninstall(struct drm_device *dev)
-{
-   struct msm_drm_private *priv = dev->dev_private;
-   struct msm_kms *kms = priv->kms;
-   BUG_ON(!kms);
-   kms->funcs->irq_uninstall(kms);
-}
-
  int msm_crtc_enable_vblank(struct drm_crtc *crtc)
  {
struct drm_device *dev = crtc->dev;
@@ -1051,10 +1078,6 @@ static const struct drm_driver msm_driver = {
.open   = msm_open,
.postclose   = msm_postclose,

[Freedreno] [PATCH v2 11/14] drm/tilcdc: Convert to Linux IRQ interfaces

2021-08-03 Thread Thomas Zimmermann
Drop the DRM IRQ midlayer in favor of Linux IRQ interfaces. DRM's
IRQ helpers are mostly useful for UMS drivers. Modern KMS drivers
don't benefit from using it.

DRM IRQ callbacks are now being called directly or inlined.

Calls to platform_get_irq() can fail with a negative errno code.
Abort initialization in this case. The DRM IRQ midlayer does not
handle this case correctly.

Signed-off-by: Thomas Zimmermann 
---
 drivers/gpu/drm/tilcdc/tilcdc_drv.c | 51 ++---
 drivers/gpu/drm/tilcdc/tilcdc_drv.h |  3 ++
 2 files changed, 43 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c 
b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
index f1d3a9f919fd..6b03f89a98d4 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
@@ -20,7 +20,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
@@ -124,6 +123,39 @@ static int cpufreq_transition(struct notifier_block *nb,
 }
 #endif
 
+static irqreturn_t tilcdc_irq(int irq, void *arg)
+{
+   struct drm_device *dev = arg;
+   struct tilcdc_drm_private *priv = dev->dev_private;
+
+   return tilcdc_crtc_irq(priv->crtc);
+}
+
+static int tilcdc_irq_install(struct drm_device *dev, unsigned int irq)
+{
+   struct tilcdc_drm_private *priv = dev->dev_private;
+   int ret;
+
+   ret = request_irq(irq, tilcdc_irq, 0, dev->driver->name, dev);
+   if (ret)
+   return ret;
+
+   priv->irq_enabled = false;
+
+   return 0;
+}
+
+static void tilcdc_irq_uninstall(struct drm_device *dev)
+{
+   struct tilcdc_drm_private *priv = dev->dev_private;
+
+   if (!priv->irq_enabled)
+   return;
+
+   free_irq(priv->irq, dev);
+   priv->irq_enabled = false;
+}
+
 /*
  * DRM operations:
  */
@@ -145,7 +177,7 @@ static void tilcdc_fini(struct drm_device *dev)
drm_dev_unregister(dev);
 
drm_kms_helper_poll_fini(dev);
-   drm_irq_uninstall(dev);
+   tilcdc_irq_uninstall(dev);
drm_mode_config_cleanup(dev);
 
if (priv->clk)
@@ -336,7 +368,12 @@ static int tilcdc_init(const struct drm_driver *ddrv, 
struct device *dev)
goto init_failed;
}
 
-   ret = drm_irq_install(ddev, platform_get_irq(pdev, 0));
+   ret = platform_get_irq(pdev, 0);
+   if (ret < 0)
+   goto init_failed;
+   priv->irq = ret;
+
+   ret = tilcdc_irq_install(ddev, priv->irq);
if (ret < 0) {
dev_err(dev, "failed to install IRQ handler\n");
goto init_failed;
@@ -360,13 +397,6 @@ static int tilcdc_init(const struct drm_driver *ddrv, 
struct device *dev)
return ret;
 }
 
-static irqreturn_t tilcdc_irq(int irq, void *arg)
-{
-   struct drm_device *dev = arg;
-   struct tilcdc_drm_private *priv = dev->dev_private;
-   return tilcdc_crtc_irq(priv->crtc);
-}
-
 #if defined(CONFIG_DEBUG_FS)
 static const struct {
const char *name;
@@ -454,7 +484,6 @@ DEFINE_DRM_GEM_CMA_FOPS(fops);
 
 static const struct drm_driver tilcdc_driver = {
.driver_features= DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
-   .irq_handler= tilcdc_irq,
DRM_GEM_CMA_DRIVER_OPS,
 #ifdef CONFIG_DEBUG_FS
.debugfs_init   = tilcdc_debugfs_init,
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.h 
b/drivers/gpu/drm/tilcdc/tilcdc_drv.h
index d29806ca8817..b818448c83f6 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_drv.h
+++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.h
@@ -46,6 +46,8 @@ struct tilcdc_drm_private {
struct clk *clk; /* functional clock */
int rev; /* IP revision */
 
+   unsigned int irq;
+
/* don't attempt resolutions w/ higher W * H * Hz: */
uint32_t max_bandwidth;
/*
@@ -82,6 +84,7 @@ struct tilcdc_drm_private {
 
bool is_registered;
bool is_componentized;
+   bool irq_enabled;
 };
 
 /* Sub-module for display.  Since we don't know at compile time what panels
-- 
2.32.0



[Freedreno] [PATCH v2 14/14] drm: IRQ midlayer is now legacy

2021-08-03 Thread Thomas Zimmermann
Hide the DRM midlayer behind CONFIG_DRM_LEGACY, make functions use
the prefix drm_legacy_, and move declarations to drm_legacy.h.
In struct drm_device, move the fields irq and irq_enabled behind
CONFIG_DRM_LEGACY.

All callers have been updated.

Signed-off-by: Thomas Zimmermann 
Acked-by: Sam Ravnborg 
---
 drivers/gpu/drm/drm_irq.c | 63 ---
 drivers/gpu/drm/drm_legacy_misc.c |  3 +-
 drivers/gpu/drm/drm_vblank.c  |  8 ++--
 drivers/gpu/drm/i810/i810_dma.c   |  3 +-
 drivers/gpu/drm/mga/mga_dma.c |  2 +-
 drivers/gpu/drm/mga/mga_drv.h |  1 -
 drivers/gpu/drm/r128/r128_cce.c   |  3 +-
 drivers/gpu/drm/via/via_mm.c  |  3 +-
 include/drm/drm_device.h  | 18 ++---
 include/drm/drm_drv.h | 44 ++---
 include/drm/drm_irq.h | 31 ---
 include/drm/drm_legacy.h  |  3 ++
 12 files changed, 27 insertions(+), 155 deletions(-)
 delete mode 100644 include/drm/drm_irq.h

diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
index dc6e38fa8a48..13e1d5c4ec82 100644
--- a/drivers/gpu/drm/drm_irq.c
+++ b/drivers/gpu/drm/drm_irq.c
@@ -60,46 +60,14 @@
 #include 
 #include 
 #include 
-#include 
+#include 
 #include 
 #include 
 
 #include "drm_internal.h"
 
-/**
- * DOC: irq helpers
- *
- * The DRM core provides very simple support helpers to enable IRQ handling on 
a
- * device through the drm_irq_install() and drm_irq_uninstall() functions. This
- * only supports devices with a single interrupt on the main device stored in
- * _device.dev and set as the device paramter in drm_dev_alloc().
- *
- * These IRQ helpers are strictly optional. Since these helpers don't 
automatically
- * clean up the requested interrupt like e.g. devm_request_irq() they're not 
really
- * recommended.
- */
-
-/**
- * drm_irq_install - install IRQ handler
- * @dev: DRM device
- * @irq: IRQ number to install the handler for
- *
- * Initializes the IRQ related data. Installs the handler, calling the driver
- * _driver.irq_preinstall and _driver.irq_postinstall functions before
- * and after the installation.
- *
- * This is the simplified helper interface provided for drivers with no special
- * needs.
- *
- * @irq must match the interrupt number that would be passed to request_irq(),
- * if called directly instead of using this helper function.
- *
- * _driver.irq_handler is called to handle the registered interrupt.
- *
- * Returns:
- * Zero on success or a negative error code on failure.
- */
-int drm_irq_install(struct drm_device *dev, int irq)
+#if IS_ENABLED(CONFIG_DRM_LEGACY)
+static int drm_legacy_irq_install(struct drm_device *dev, int irq)
 {
int ret;
unsigned long sh_flags = 0;
@@ -144,24 +112,8 @@ int drm_irq_install(struct drm_device *dev, int irq)
 
return ret;
 }
-EXPORT_SYMBOL(drm_irq_install);
 
-/**
- * drm_irq_uninstall - uninstall the IRQ handler
- * @dev: DRM device
- *
- * Calls the driver's _driver.irq_uninstall function and unregisters the 
IRQ
- * handler.  This should only be called by drivers which used drm_irq_install()
- * to set up their interrupt handler.
- *
- * Note that for kernel modesetting drivers it is a bug if this function fails.
- * The sanity checks are only to catch buggy user modesetting drivers which 
call
- * the same function through an ioctl.
- *
- * Returns:
- * Zero on success or a negative error code on failure.
- */
-int drm_irq_uninstall(struct drm_device *dev)
+int drm_legacy_irq_uninstall(struct drm_device *dev)
 {
unsigned long irqflags;
bool irq_enabled;
@@ -207,9 +159,8 @@ int drm_irq_uninstall(struct drm_device *dev)
 
return 0;
 }
-EXPORT_SYMBOL(drm_irq_uninstall);
+EXPORT_SYMBOL(drm_legacy_irq_uninstall);
 
-#if IS_ENABLED(CONFIG_DRM_LEGACY)
 int drm_legacy_irq_control(struct drm_device *dev, void *data,
   struct drm_file *file_priv)
 {
@@ -238,13 +189,13 @@ int drm_legacy_irq_control(struct drm_device *dev, void 
*data,
ctl->irq != irq)
return -EINVAL;
mutex_lock(>struct_mutex);
-   ret = drm_irq_install(dev, irq);
+   ret = drm_legacy_irq_install(dev, irq);
mutex_unlock(>struct_mutex);
 
return ret;
case DRM_UNINST_HANDLER:
mutex_lock(>struct_mutex);
-   ret = drm_irq_uninstall(dev);
+   ret = drm_legacy_irq_uninstall(dev);
mutex_unlock(>struct_mutex);
 
return ret;
diff --git a/drivers/gpu/drm/drm_legacy_misc.c 
b/drivers/gpu/drm/drm_legacy_misc.c
index 83db43b7a25e..d4c5434062d7 100644
--- a/drivers/gpu/drm/drm_legacy_misc.c
+++ b/drivers/gpu/drm/drm_legacy_misc.c
@@ -35,7 +35,6 @@
 
 #include 
 #include 
-#include 
 #include 
 
 #include "drm_internal.h"
@@ -78,7 +77,7 @@ int drm_legacy_setup(struct drm_device * dev)
 void drm_legacy_dev_reinit(struct drm_device *dev)
 {
if 

[Freedreno] [PATCH v2 12/14] drm/vc4: Convert to Linux IRQ interfaces

2021-08-03 Thread Thomas Zimmermann
Drop the DRM IRQ midlayer in favor of Linux IRQ interfaces. DRM's
IRQ helpers are mostly useful for UMS drivers. Modern KMS drivers
don't benefit from using it.

DRM IRQ callbacks are now being called directly or inlined.

Calls to platform_get_irq() can fail with a negative errno code.
Abort initialization in this case. The DRM IRQ midlayer does not
handle this case correctly.

Signed-off-by: Thomas Zimmermann 
---
 drivers/gpu/drm/vc4/vc4_drv.c |  4 ---
 drivers/gpu/drm/vc4/vc4_drv.h |  8 +++---
 drivers/gpu/drm/vc4/vc4_irq.c | 48 +++
 drivers/gpu/drm/vc4/vc4_v3d.c | 17 -
 4 files changed, 53 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c
index 73335feb712f..f6c16c5aee68 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.c
+++ b/drivers/gpu/drm/vc4/vc4_drv.c
@@ -168,10 +168,6 @@ static struct drm_driver vc4_drm_driver = {
DRIVER_SYNCOBJ),
.open = vc4_open,
.postclose = vc4_close,
-   .irq_handler = vc4_irq,
-   .irq_preinstall = vc4_irq_preinstall,
-   .irq_postinstall = vc4_irq_postinstall,
-   .irq_uninstall = vc4_irq_uninstall,
 
 #if defined(CONFIG_DEBUG_FS)
.debugfs_init = vc4_debugfs_init,
diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
index 5dceadc61600..ef73e0aaf726 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.h
+++ b/drivers/gpu/drm/vc4/vc4_drv.h
@@ -74,6 +74,8 @@ struct vc4_perfmon {
 struct vc4_dev {
struct drm_device base;
 
+   unsigned int irq;
+
struct vc4_hvs *hvs;
struct vc4_v3d *v3d;
struct vc4_dpi *dpi;
@@ -895,9 +897,9 @@ extern struct platform_driver vc4_vec_driver;
 extern struct platform_driver vc4_txp_driver;
 
 /* vc4_irq.c */
-irqreturn_t vc4_irq(int irq, void *arg);
-void vc4_irq_preinstall(struct drm_device *dev);
-int vc4_irq_postinstall(struct drm_device *dev);
+void vc4_irq_enable(struct drm_device *dev);
+void vc4_irq_disable(struct drm_device *dev);
+int vc4_irq_install(struct drm_device *dev, int irq);
 void vc4_irq_uninstall(struct drm_device *dev);
 void vc4_irq_reset(struct drm_device *dev);
 
diff --git a/drivers/gpu/drm/vc4/vc4_irq.c b/drivers/gpu/drm/vc4/vc4_irq.c
index e226c24e543f..20fa8e34c20b 100644
--- a/drivers/gpu/drm/vc4/vc4_irq.c
+++ b/drivers/gpu/drm/vc4/vc4_irq.c
@@ -45,6 +45,10 @@
  * current job can make progress.
  */
 
+#include 
+
+#include 
+
 #include "vc4_drv.h"
 #include "vc4_regs.h"
 
@@ -192,7 +196,7 @@ vc4_irq_finish_render_job(struct drm_device *dev)
schedule_work(>job_done_work);
 }
 
-irqreturn_t
+static irqreturn_t
 vc4_irq(int irq, void *arg)
 {
struct drm_device *dev = arg;
@@ -234,8 +238,8 @@ vc4_irq(int irq, void *arg)
return status;
 }
 
-void
-vc4_irq_preinstall(struct drm_device *dev)
+static void
+vc4_irq_prepare(struct drm_device *dev)
 {
struct vc4_dev *vc4 = to_vc4_dev(dev);
 
@@ -251,24 +255,22 @@ vc4_irq_preinstall(struct drm_device *dev)
V3D_WRITE(V3D_INTCTL, V3D_DRIVER_IRQS);
 }
 
-int
-vc4_irq_postinstall(struct drm_device *dev)
+void
+vc4_irq_enable(struct drm_device *dev)
 {
struct vc4_dev *vc4 = to_vc4_dev(dev);
 
if (!vc4->v3d)
-   return 0;
+   return;
 
/* Enable the render done interrupts. The out-of-memory interrupt is
 * enabled as soon as we have a binner BO allocated.
 */
V3D_WRITE(V3D_INTENA, V3D_INT_FLDONE | V3D_INT_FRDONE);
-
-   return 0;
 }
 
 void
-vc4_irq_uninstall(struct drm_device *dev)
+vc4_irq_disable(struct drm_device *dev)
 {
struct vc4_dev *vc4 = to_vc4_dev(dev);
 
@@ -282,11 +284,37 @@ vc4_irq_uninstall(struct drm_device *dev)
V3D_WRITE(V3D_INTCTL, V3D_DRIVER_IRQS);
 
/* Finish any interrupt handler still in flight. */
-   disable_irq(dev->irq);
+   disable_irq(vc4->irq);
 
cancel_work_sync(>overflow_mem_work);
 }
 
+int vc4_irq_install(struct drm_device *dev, int irq)
+{
+   int ret;
+
+   if (irq == IRQ_NOTCONNECTED)
+   return -ENOTCONN;
+
+   vc4_irq_prepare(dev);
+
+   ret = request_irq(irq, vc4_irq, 0, dev->driver->name, dev);
+   if (ret)
+   return ret;
+
+   vc4_irq_enable(dev);
+
+   return 0;
+}
+
+void vc4_irq_uninstall(struct drm_device *dev)
+{
+   struct vc4_dev *vc4 = to_vc4_dev(dev);
+
+   vc4_irq_disable(dev);
+   free_irq(vc4->irq, dev);
+}
+
 /** Reinitializes interrupt registers when a GPU reset is performed. */
 void vc4_irq_reset(struct drm_device *dev)
 {
diff --git a/drivers/gpu/drm/vc4/vc4_v3d.c b/drivers/gpu/drm/vc4/vc4_v3d.c
index 73d63d72575b..7bb3067f8425 100644
--- a/drivers/gpu/drm/vc4/vc4_v3d.c
+++ b/drivers/gpu/drm/vc4/vc4_v3d.c
@@ -10,8 +10,6 @@
 #include 
 #include 
 
-#include 
-
 #include "vc4_drv.h"
 #include "vc4_regs.h"
 
@@ -361,7 +359,7 @@ static int vc4_v3d_runtime_suspend(struct device *dev)
struct vc4_v3d *v3d 

[Freedreno] [PATCH v2 13/14] drm: Remove unused devm_drm_irq_install()

2021-08-03 Thread Thomas Zimmermann
DRM IRQ helpers will become legacy. The function devm_drm_irq_install()
is unused and won't be required later.

Signed-off-by: Thomas Zimmermann 
---
 drivers/gpu/drm/drm_irq.c | 32 
 include/drm/drm_irq.h |  1 -
 2 files changed, 33 deletions(-)

diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
index 201eae4bba6c..dc6e38fa8a48 100644
--- a/drivers/gpu/drm/drm_irq.c
+++ b/drivers/gpu/drm/drm_irq.c
@@ -209,38 +209,6 @@ int drm_irq_uninstall(struct drm_device *dev)
 }
 EXPORT_SYMBOL(drm_irq_uninstall);
 
-static void devm_drm_irq_uninstall(void *data)
-{
-   drm_irq_uninstall(data);
-}
-
-/**
- * devm_drm_irq_install - install IRQ handler
- * @dev: DRM device
- * @irq: IRQ number to install the handler for
- *
- * devm_drm_irq_install is a  help function of drm_irq_install.
- *
- * if the driver uses devm_drm_irq_install, there is no need
- * to call drm_irq_uninstall when the drm module get unloaded,
- * as this will done automagically.
- *
- * Returns:
- * Zero on success or a negative error code on failure.
- */
-int devm_drm_irq_install(struct drm_device *dev, int irq)
-{
-   int ret;
-
-   ret = drm_irq_install(dev, irq);
-   if (ret)
-   return ret;
-
-   return devm_add_action_or_reset(dev->dev,
-   devm_drm_irq_uninstall, dev);
-}
-EXPORT_SYMBOL(devm_drm_irq_install);
-
 #if IS_ENABLED(CONFIG_DRM_LEGACY)
 int drm_legacy_irq_control(struct drm_device *dev, void *data,
   struct drm_file *file_priv)
diff --git a/include/drm/drm_irq.h b/include/drm/drm_irq.h
index 631b22f9757d..53634b988f57 100644
--- a/include/drm/drm_irq.h
+++ b/include/drm/drm_irq.h
@@ -28,5 +28,4 @@ struct drm_device;
 
 int drm_irq_install(struct drm_device *dev, int irq);
 int drm_irq_uninstall(struct drm_device *dev);
-int devm_drm_irq_install(struct drm_device *dev, int irq);
 #endif
-- 
2.32.0



[Freedreno] [PATCH v2 10/14] drm/tidss: Convert to Linux IRQ interfaces

2021-08-03 Thread Thomas Zimmermann
Drop the DRM IRQ midlayer in favor of Linux IRQ interfaces. DRM's
IRQ helpers are mostly useful for UMS drivers. Modern KMS drivers
don't benefit from using it.

DRM IRQ callbacks are now being called directly or inlined.

Signed-off-by: Thomas Zimmermann 
Reviewed-by: Tomi Valkeinen 
---
 drivers/gpu/drm/tidss/tidss_drv.c | 15 +--
 drivers/gpu/drm/tidss/tidss_drv.h |  2 ++
 drivers/gpu/drm/tidss/tidss_irq.c | 27 ---
 drivers/gpu/drm/tidss/tidss_irq.h |  4 +---
 4 files changed, 32 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/tidss/tidss_drv.c 
b/drivers/gpu/drm/tidss/tidss_drv.c
index 66e3c86eb5c7..d620f35688da 100644
--- a/drivers/gpu/drm/tidss/tidss_drv.c
+++ b/drivers/gpu/drm/tidss/tidss_drv.c
@@ -16,7 +16,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 
@@ -118,11 +117,6 @@ static const struct drm_driver tidss_driver = {
.date   = "20180215",
.major  = 1,
.minor  = 0,
-
-   .irq_preinstall = tidss_irq_preinstall,
-   .irq_postinstall= tidss_irq_postinstall,
-   .irq_handler= tidss_irq_handler,
-   .irq_uninstall  = tidss_irq_uninstall,
 };
 
 static int tidss_probe(struct platform_device *pdev)
@@ -172,10 +166,11 @@ static int tidss_probe(struct platform_device *pdev)
ret = irq;
goto err_runtime_suspend;
}
+   tidss->irq = irq;
 
-   ret = drm_irq_install(ddev, irq);
+   ret = tidss_irq_install(ddev, irq);
if (ret) {
-   dev_err(dev, "drm_irq_install failed: %d\n", ret);
+   dev_err(dev, "tidss_irq_install failed: %d\n", ret);
goto err_runtime_suspend;
}
 
@@ -196,7 +191,7 @@ static int tidss_probe(struct platform_device *pdev)
return 0;
 
 err_irq_uninstall:
-   drm_irq_uninstall(ddev);
+   tidss_irq_uninstall(ddev);
 
 err_runtime_suspend:
 #ifndef CONFIG_PM
@@ -219,7 +214,7 @@ static int tidss_remove(struct platform_device *pdev)
 
drm_atomic_helper_shutdown(ddev);
 
-   drm_irq_uninstall(ddev);
+   tidss_irq_uninstall(ddev);
 
 #ifndef CONFIG_PM
/* If we don't have PM, we need to call suspend manually */
diff --git a/drivers/gpu/drm/tidss/tidss_drv.h 
b/drivers/gpu/drm/tidss/tidss_drv.h
index 7de4bba52e6f..d7f27b0b0315 100644
--- a/drivers/gpu/drm/tidss/tidss_drv.h
+++ b/drivers/gpu/drm/tidss/tidss_drv.h
@@ -27,6 +27,8 @@ struct tidss_device {
unsigned int num_planes;
struct drm_plane *planes[TIDSS_MAX_PLANES];
 
+   unsigned int irq;
+
spinlock_t wait_lock;   /* protects the irq masks */
dispc_irq_t irq_mask;   /* enabled irqs in addition to wait_list */
 };
diff --git a/drivers/gpu/drm/tidss/tidss_irq.c 
b/drivers/gpu/drm/tidss/tidss_irq.c
index 2ed3e3296776..0c681c7600bc 100644
--- a/drivers/gpu/drm/tidss/tidss_irq.c
+++ b/drivers/gpu/drm/tidss/tidss_irq.c
@@ -4,6 +4,9 @@
  * Author: Tomi Valkeinen 
  */
 
+#include 
+
+#include 
 #include 
 
 #include "tidss_crtc.h"
@@ -50,7 +53,7 @@ void tidss_irq_disable_vblank(struct drm_crtc *crtc)
spin_unlock_irqrestore(>wait_lock, flags);
 }
 
-irqreturn_t tidss_irq_handler(int irq, void *arg)
+static irqreturn_t tidss_irq_handler(int irq, void *arg)
 {
struct drm_device *ddev = (struct drm_device *)arg;
struct tidss_device *tidss = to_tidss(ddev);
@@ -90,7 +93,7 @@ void tidss_irq_resume(struct tidss_device *tidss)
spin_unlock_irqrestore(>wait_lock, flags);
 }
 
-void tidss_irq_preinstall(struct drm_device *ddev)
+static void tidss_irq_preinstall(struct drm_device *ddev)
 {
struct tidss_device *tidss = to_tidss(ddev);
 
@@ -104,7 +107,7 @@ void tidss_irq_preinstall(struct drm_device *ddev)
tidss_runtime_put(tidss);
 }
 
-int tidss_irq_postinstall(struct drm_device *ddev)
+static void tidss_irq_postinstall(struct drm_device *ddev)
 {
struct tidss_device *tidss = to_tidss(ddev);
unsigned long flags;
@@ -129,6 +132,22 @@ int tidss_irq_postinstall(struct drm_device *ddev)
spin_unlock_irqrestore(>wait_lock, flags);
 
tidss_runtime_put(tidss);
+}
+
+int tidss_irq_install(struct drm_device *ddev, unsigned int irq)
+{
+   int ret;
+
+   if (irq == IRQ_NOTCONNECTED)
+   return -ENOTCONN;
+
+   tidss_irq_preinstall(ddev);
+
+   ret = request_irq(irq, tidss_irq_handler, 0, ddev->driver->name, ddev);
+   if (ret)
+   return ret;
+
+   tidss_irq_postinstall(ddev);
 
return 0;
 }
@@ -140,4 +159,6 @@ void tidss_irq_uninstall(struct drm_device *ddev)
tidss_runtime_get(tidss);
dispc_set_irqenable(tidss->dispc, 0);
tidss_runtime_put(tidss);
+
+   free_irq(tidss->irq, ddev);
 }
diff --git a/drivers/gpu/drm/tidss/tidss_irq.h 
b/drivers/gpu/drm/tidss/tidss_irq.h
index 4aaad5dfd7c2..b512614d5863 100644
--- 

[Freedreno] [PATCH v2 05/14] drm/gma500: Convert to Linux IRQ interfaces

2021-08-03 Thread Thomas Zimmermann
Drop the DRM IRQ midlayer in favor of Linux IRQ interfaces. DRM's
IRQ helpers are mostly useful for UMS drivers. Modern KMS drivers
don't benefit from using it. DRM IRQ callbacks are now being called
directly or inlined.

Signed-off-by: Thomas Zimmermann 
---
 drivers/gpu/drm/gma500/power.c   |  1 +
 drivers/gpu/drm/gma500/psb_drv.c |  8 ++--
 drivers/gpu/drm/gma500/psb_drv.h |  5 -
 drivers/gpu/drm/gma500/psb_irq.c | 26 --
 drivers/gpu/drm/gma500/psb_irq.h |  4 ++--
 5 files changed, 29 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/gma500/power.c b/drivers/gpu/drm/gma500/power.c
index f07641dfa5a4..20ace6010f9f 100644
--- a/drivers/gpu/drm/gma500/power.c
+++ b/drivers/gpu/drm/gma500/power.c
@@ -32,6 +32,7 @@
 #include "psb_drv.h"
 #include "psb_reg.h"
 #include "psb_intel_reg.h"
+#include "psb_irq.h"
 #include 
 #include 
 
diff --git a/drivers/gpu/drm/gma500/psb_drv.c b/drivers/gpu/drm/gma500/psb_drv.c
index 3850842d58f3..58bce1a60a4d 100644
--- a/drivers/gpu/drm/gma500/psb_drv.c
+++ b/drivers/gpu/drm/gma500/psb_drv.c
@@ -23,7 +23,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 
@@ -33,6 +32,7 @@
 #include "power.h"
 #include "psb_drv.h"
 #include "psb_intel_reg.h"
+#include "psb_irq.h"
 #include "psb_reg.h"
 
 static const struct drm_driver driver;
@@ -380,7 +380,7 @@ static int psb_driver_load(struct drm_device *dev, unsigned 
long flags)
PSB_WVDC32(0x, PSB_INT_MASK_R);
spin_unlock_irqrestore(_priv->irqmask_lock, irqflags);
 
-   drm_irq_install(dev, pdev->irq);
+   psb_irq_install(dev, pdev->irq);
 
dev->max_vblank_count = 0xff; /* only 24 bits of frame count */
 
@@ -515,10 +515,6 @@ static const struct drm_driver driver = {
.lastclose = drm_fb_helper_lastclose,
 
.num_ioctls = ARRAY_SIZE(psb_ioctls),
-   .irq_preinstall = psb_irq_preinstall,
-   .irq_postinstall = psb_irq_postinstall,
-   .irq_uninstall = psb_irq_uninstall,
-   .irq_handler = psb_irq_handler,
 
.dumb_create = psb_gem_dumb_create,
.ioctls = psb_ioctls,
diff --git a/drivers/gpu/drm/gma500/psb_drv.h b/drivers/gpu/drm/gma500/psb_drv.h
index d6e7c2c2c947..f2bae270ca7b 100644
--- a/drivers/gpu/drm/gma500/psb_drv.h
+++ b/drivers/gpu/drm/gma500/psb_drv.h
@@ -624,11 +624,6 @@ static inline struct drm_psb_private *psb_priv(struct 
drm_device *dev)
 }
 
 /* psb_irq.c */
-extern irqreturn_t psb_irq_handler(int irq, void *arg);
-extern void psb_irq_preinstall(struct drm_device *dev);
-extern int psb_irq_postinstall(struct drm_device *dev);
-extern void psb_irq_uninstall(struct drm_device *dev);
-
 extern void psb_irq_uninstall_islands(struct drm_device *dev, int hw_islands);
 extern int psb_vblank_wait2(struct drm_device *dev, unsigned int *sequence);
 extern int psb_vblank_wait(struct drm_device *dev, unsigned int *sequence);
diff --git a/drivers/gpu/drm/gma500/psb_irq.c b/drivers/gpu/drm/gma500/psb_irq.c
index 104009e78487..deb1fbc1f748 100644
--- a/drivers/gpu/drm/gma500/psb_irq.c
+++ b/drivers/gpu/drm/gma500/psb_irq.c
@@ -8,6 +8,7 @@
  *
  **/
 
+#include 
 #include 
 
 #include "power.h"
@@ -222,7 +223,7 @@ static void psb_sgx_interrupt(struct drm_device *dev, u32 
stat_1, u32 stat_2)
PSB_RSGX32(PSB_CR_EVENT_HOST_CLEAR2);
 }
 
-irqreturn_t psb_irq_handler(int irq, void *arg)
+static irqreturn_t psb_irq_handler(int irq, void *arg)
 {
struct drm_device *dev = arg;
struct drm_psb_private *dev_priv = dev->dev_private;
@@ -304,7 +305,7 @@ void psb_irq_preinstall(struct drm_device *dev)
spin_unlock_irqrestore(_priv->irqmask_lock, irqflags);
 }
 
-int psb_irq_postinstall(struct drm_device *dev)
+void psb_irq_postinstall(struct drm_device *dev)
 {
struct drm_psb_private *dev_priv = dev->dev_private;
unsigned long irqflags;
@@ -332,12 +333,31 @@ int psb_irq_postinstall(struct drm_device *dev)
dev_priv->ops->hotplug_enable(dev, true);
 
spin_unlock_irqrestore(_priv->irqmask_lock, irqflags);
+}
+
+int psb_irq_install(struct drm_device *dev, unsigned int irq)
+{
+   int ret;
+
+   if (irq == IRQ_NOTCONNECTED)
+   return -ENOTCONN;
+
+   psb_irq_preinstall(dev);
+
+   /* PCI devices require shared interrupts. */
+   ret = request_irq(irq, psb_irq_handler, IRQF_SHARED, dev->driver->name, 
dev);
+   if (ret)
+   return ret;
+
+   psb_irq_postinstall(dev);
+
return 0;
 }
 
 void psb_irq_uninstall(struct drm_device *dev)
 {
struct drm_psb_private *dev_priv = dev->dev_private;
+   struct pci_dev *pdev = to_pci_dev(dev->dev);
unsigned long irqflags;
unsigned int i;
 
@@ -366,6 +386,8 @@ void psb_irq_uninstall(struct drm_device *dev)
/* This register is safe even if display island is off */
PSB_WVDC32(PSB_RVDC32(PSB_INT_IDENTITY_R), PSB_INT_IDENTITY_R);
   

[Freedreno] [PATCH v2 08/14] drm/mxsfb: Convert to Linux IRQ interfaces

2021-08-03 Thread Thomas Zimmermann
Drop the DRM IRQ midlayer in favor of Linux IRQ interfaces. DRM's
IRQ helpers are mostly useful for UMS drivers. Modern KMS drivers
don't benefit from using it.

DRM IRQ callbacks are now being called directly or inlined.

Calls to platform_get_irq() can fail with a negative errno code.
Abort initialization in this case. The DRM IRQ midlayer does not
handle this case correctly.

Signed-off-by: Thomas Zimmermann 
---
 drivers/gpu/drm/mxsfb/mxsfb_drv.c | 81 +++
 drivers/gpu/drm/mxsfb/mxsfb_drv.h |  2 +
 2 files changed, 52 insertions(+), 31 deletions(-)

diff --git a/drivers/gpu/drm/mxsfb/mxsfb_drv.c 
b/drivers/gpu/drm/mxsfb/mxsfb_drv.c
index c277d3f61a5e..ec0432fe1bdf 100644
--- a/drivers/gpu/drm/mxsfb/mxsfb_drv.c
+++ b/drivers/gpu/drm/mxsfb/mxsfb_drv.c
@@ -24,7 +24,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
@@ -153,6 +152,49 @@ static int mxsfb_attach_bridge(struct mxsfb_drm_private 
*mxsfb)
return 0;
 }
 
+static irqreturn_t mxsfb_irq_handler(int irq, void *data)
+{
+   struct drm_device *drm = data;
+   struct mxsfb_drm_private *mxsfb = drm->dev_private;
+   u32 reg;
+
+   reg = readl(mxsfb->base + LCDC_CTRL1);
+
+   if (reg & CTRL1_CUR_FRAME_DONE_IRQ)
+   drm_crtc_handle_vblank(>crtc);
+
+   writel(CTRL1_CUR_FRAME_DONE_IRQ, mxsfb->base + LCDC_CTRL1 + REG_CLR);
+
+   return IRQ_HANDLED;
+}
+
+static void mxsfb_irq_disable(struct drm_device *drm)
+{
+   struct mxsfb_drm_private *mxsfb = drm->dev_private;
+
+   mxsfb_enable_axi_clk(mxsfb);
+   mxsfb->crtc.funcs->disable_vblank(>crtc);
+   mxsfb_disable_axi_clk(mxsfb);
+}
+
+static int mxsfb_irq_install(struct drm_device *dev, int irq)
+{
+   if (irq == IRQ_NOTCONNECTED)
+   return -ENOTCONN;
+
+   mxsfb_irq_disable(dev);
+
+   return request_irq(irq, mxsfb_irq_handler, 0,  dev->driver->name, dev);
+}
+
+static void mxsfb_irq_uninstall(struct drm_device *dev)
+{
+   struct mxsfb_drm_private *mxsfb = dev->dev_private;
+
+   mxsfb_irq_disable(dev);
+   free_irq(mxsfb->irq, dev);
+}
+
 static int mxsfb_load(struct drm_device *drm,
  const struct mxsfb_devdata *devdata)
 {
@@ -226,8 +268,13 @@ static int mxsfb_load(struct drm_device *drm,
 
drm_mode_config_reset(drm);
 
+   ret = platform_get_irq(pdev, 0);
+   if (ret < 0)
+   goto err_vblank;
+   mxsfb->irq = ret;
+
pm_runtime_get_sync(drm->dev);
-   ret = drm_irq_install(drm, platform_get_irq(pdev, 0));
+   ret = mxsfb_irq_install(drm, mxsfb->irq);
pm_runtime_put_sync(drm->dev);
 
if (ret < 0) {
@@ -255,7 +302,7 @@ static void mxsfb_unload(struct drm_device *drm)
drm_mode_config_cleanup(drm);
 
pm_runtime_get_sync(drm->dev);
-   drm_irq_uninstall(drm);
+   mxsfb_irq_uninstall(drm);
pm_runtime_put_sync(drm->dev);
 
drm->dev_private = NULL;
@@ -263,38 +310,10 @@ static void mxsfb_unload(struct drm_device *drm)
pm_runtime_disable(drm->dev);
 }
 
-static void mxsfb_irq_disable(struct drm_device *drm)
-{
-   struct mxsfb_drm_private *mxsfb = drm->dev_private;
-
-   mxsfb_enable_axi_clk(mxsfb);
-   mxsfb->crtc.funcs->disable_vblank(>crtc);
-   mxsfb_disable_axi_clk(mxsfb);
-}
-
-static irqreturn_t mxsfb_irq_handler(int irq, void *data)
-{
-   struct drm_device *drm = data;
-   struct mxsfb_drm_private *mxsfb = drm->dev_private;
-   u32 reg;
-
-   reg = readl(mxsfb->base + LCDC_CTRL1);
-
-   if (reg & CTRL1_CUR_FRAME_DONE_IRQ)
-   drm_crtc_handle_vblank(>crtc);
-
-   writel(CTRL1_CUR_FRAME_DONE_IRQ, mxsfb->base + LCDC_CTRL1 + REG_CLR);
-
-   return IRQ_HANDLED;
-}
-
 DEFINE_DRM_GEM_CMA_FOPS(fops);
 
 static const struct drm_driver mxsfb_driver = {
.driver_features= DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
-   .irq_handler= mxsfb_irq_handler,
-   .irq_preinstall = mxsfb_irq_disable,
-   .irq_uninstall  = mxsfb_irq_disable,
DRM_GEM_CMA_DRIVER_OPS,
.fops   = ,
.name   = "mxsfb-drm",
diff --git a/drivers/gpu/drm/mxsfb/mxsfb_drv.h 
b/drivers/gpu/drm/mxsfb/mxsfb_drv.h
index 7c720e226fdf..ddb5b0417a82 100644
--- a/drivers/gpu/drm/mxsfb/mxsfb_drv.h
+++ b/drivers/gpu/drm/mxsfb/mxsfb_drv.h
@@ -33,6 +33,8 @@ struct mxsfb_drm_private {
struct clk  *clk_axi;
struct clk  *clk_disp_axi;
 
+   unsigned intirq;
+
struct drm_device   *drm;
struct {
struct drm_planeprimary;
-- 
2.32.0



[Freedreno] [PATCH v2 09/14] drm/radeon: Convert to Linux IRQ interfaces

2021-08-03 Thread Thomas Zimmermann
Drop the DRM IRQ midlayer in favor of Linux IRQ interfaces. DRM's
IRQ helpers are mostly useful for UMS drivers. Modern KMS drivers
don't benefit from using it.

DRM IRQ callbacks are now being called directly or inlined.

Signed-off-by: Thomas Zimmermann 
Reviewed-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/radeon_drv.c |  4 ---
 drivers/gpu/drm/radeon/radeon_irq_kms.c | 44 +
 drivers/gpu/drm/radeon/radeon_kms.h |  4 ---
 3 files changed, 37 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon_drv.c 
b/drivers/gpu/drm/radeon/radeon_drv.c
index c8dd68152d65..b74cebca1f89 100644
--- a/drivers/gpu/drm/radeon/radeon_drv.c
+++ b/drivers/gpu/drm/radeon/radeon_drv.c
@@ -607,10 +607,6 @@ static const struct drm_driver kms_driver = {
.postclose = radeon_driver_postclose_kms,
.lastclose = radeon_driver_lastclose_kms,
.unload = radeon_driver_unload_kms,
-   .irq_preinstall = radeon_driver_irq_preinstall_kms,
-   .irq_postinstall = radeon_driver_irq_postinstall_kms,
-   .irq_uninstall = radeon_driver_irq_uninstall_kms,
-   .irq_handler = radeon_driver_irq_handler_kms,
.ioctls = radeon_ioctls_kms,
.num_ioctls = ARRAY_SIZE(radeon_ioctls_kms),
.dumb_create = radeon_mode_dumb_create,
diff --git a/drivers/gpu/drm/radeon/radeon_irq_kms.c 
b/drivers/gpu/drm/radeon/radeon_irq_kms.c
index a36ce826d0c0..3907785d0798 100644
--- a/drivers/gpu/drm/radeon/radeon_irq_kms.c
+++ b/drivers/gpu/drm/radeon/radeon_irq_kms.c
@@ -31,7 +31,7 @@
 
 #include 
 #include 
-#include 
+#include 
 #include 
 #include 
 #include 
@@ -51,7 +51,7 @@
  * radeon_irq_process is a macro that points to the per-asic
  * irq handler callback.
  */
-irqreturn_t radeon_driver_irq_handler_kms(int irq, void *arg)
+static irqreturn_t radeon_driver_irq_handler_kms(int irq, void *arg)
 {
struct drm_device *dev = (struct drm_device *) arg;
struct radeon_device *rdev = dev->dev_private;
@@ -118,7 +118,7 @@ static void radeon_dp_work_func(struct work_struct *work)
  * Gets the hw ready to enable irqs (all asics).
  * This function disables all interrupt sources on the GPU.
  */
-void radeon_driver_irq_preinstall_kms(struct drm_device *dev)
+static void radeon_driver_irq_preinstall_kms(struct drm_device *dev)
 {
struct radeon_device *rdev = dev->dev_private;
unsigned long irqflags;
@@ -150,7 +150,7 @@ void radeon_driver_irq_preinstall_kms(struct drm_device 
*dev)
  * Handles stuff to be done after enabling irqs (all asics).
  * Returns 0 on success.
  */
-int radeon_driver_irq_postinstall_kms(struct drm_device *dev)
+static int radeon_driver_irq_postinstall_kms(struct drm_device *dev)
 {
struct radeon_device *rdev = dev->dev_private;
 
@@ -169,7 +169,7 @@ int radeon_driver_irq_postinstall_kms(struct drm_device 
*dev)
  *
  * This function disables all interrupt sources on the GPU (all asics).
  */
-void radeon_driver_irq_uninstall_kms(struct drm_device *dev)
+static void radeon_driver_irq_uninstall_kms(struct drm_device *dev)
 {
struct radeon_device *rdev = dev->dev_private;
unsigned long irqflags;
@@ -194,6 +194,36 @@ void radeon_driver_irq_uninstall_kms(struct drm_device 
*dev)
spin_unlock_irqrestore(>irq.lock, irqflags);
 }
 
+static int radeon_irq_install(struct radeon_device *rdev, int irq)
+{
+   struct drm_device *dev = rdev->ddev;
+   int ret;
+
+   if (irq == IRQ_NOTCONNECTED)
+   return -ENOTCONN;
+
+   radeon_driver_irq_preinstall_kms(dev);
+
+   /* PCI devices require shared interrupts. */
+   ret = request_irq(irq, radeon_driver_irq_handler_kms,
+ IRQF_SHARED, dev->driver->name, dev);
+   if (ret)
+   return ret;
+
+   radeon_driver_irq_postinstall_kms(dev);
+
+   return 0;
+}
+
+static void radeon_irq_uninstall(struct radeon_device *rdev)
+{
+   struct drm_device *dev = rdev->ddev;
+   struct pci_dev *pdev = to_pci_dev(dev->dev);
+
+   radeon_driver_irq_uninstall_kms(dev);
+   free_irq(pdev->irq, dev);
+}
+
 /**
  * radeon_msi_ok - asic specific msi checks
  *
@@ -314,7 +344,7 @@ int radeon_irq_kms_init(struct radeon_device *rdev)
INIT_WORK(>audio_work, r600_audio_update_hdmi);
 
rdev->irq.installed = true;
-   r = drm_irq_install(rdev->ddev, rdev->pdev->irq);
+   r = radeon_irq_install(rdev, rdev->pdev->irq);
if (r) {
rdev->irq.installed = false;
flush_delayed_work(>hotplug_work);
@@ -335,7 +365,7 @@ int radeon_irq_kms_init(struct radeon_device *rdev)
 void radeon_irq_kms_fini(struct radeon_device *rdev)
 {
if (rdev->irq.installed) {
-   drm_irq_uninstall(rdev->ddev);
+   radeon_irq_uninstall(rdev);
rdev->irq.installed = false;
if (rdev->msi_enabled)
pci_disable_msi(rdev->pdev);
diff --git 

[Freedreno] [PATCH v2 07/14] drm/msm: Convert to Linux IRQ interfaces

2021-08-03 Thread Thomas Zimmermann
Drop the DRM IRQ midlayer in favor of Linux IRQ interfaces. DRM's
IRQ helpers are mostly useful for UMS drivers. Modern KMS drivers
don't benefit from using it.

DRM IRQ callbacks are now being called directly or inlined.

Signed-off-by: Thomas Zimmermann 
---
 drivers/gpu/drm/msm/msm_drv.c | 113 --
 drivers/gpu/drm/msm/msm_kms.h |   2 +-
 2 files changed, 69 insertions(+), 46 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index 1594ae39d54f..a332b09a5a11 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -14,7 +14,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
@@ -201,6 +200,71 @@ void msm_rmw(void __iomem *addr, u32 mask, u32 or)
msm_writel(val | or, addr);
 }
 
+static irqreturn_t msm_irq(int irq, void *arg)
+{
+   struct drm_device *dev = arg;
+   struct msm_drm_private *priv = dev->dev_private;
+   struct msm_kms *kms = priv->kms;
+
+   BUG_ON(!kms);
+
+   return kms->funcs->irq(kms);
+}
+
+static void msm_irq_preinstall(struct drm_device *dev)
+{
+   struct msm_drm_private *priv = dev->dev_private;
+   struct msm_kms *kms = priv->kms;
+
+   BUG_ON(!kms);
+
+   kms->funcs->irq_preinstall(kms);
+}
+
+static int msm_irq_postinstall(struct drm_device *dev)
+{
+   struct msm_drm_private *priv = dev->dev_private;
+   struct msm_kms *kms = priv->kms;
+
+   BUG_ON(!kms);
+
+   if (kms->funcs->irq_postinstall)
+   return kms->funcs->irq_postinstall(kms);
+
+   return 0;
+}
+
+static int msm_irq_install(struct drm_device *dev, unsigned int irq)
+{
+   int ret;
+
+   if (irq == IRQ_NOTCONNECTED)
+   return -ENOTCONN;
+
+   msm_irq_preinstall(dev);
+
+   ret = request_irq(irq, msm_irq, 0, dev->driver->name, dev);
+   if (ret)
+   return ret;
+
+   ret = msm_irq_postinstall(dev);
+   if (ret) {
+   free_irq(irq, dev);
+   return ret;
+   }
+
+   return 0;
+}
+
+static void msm_irq_uninstall(struct drm_device *dev)
+{
+   struct msm_drm_private *priv = dev->dev_private;
+   struct msm_kms *kms = priv->kms;
+
+   kms->funcs->irq_uninstall(kms);
+   free_irq(kms->irq, dev);
+}
+
 struct msm_vblank_work {
struct work_struct work;
int crtc_id;
@@ -265,7 +329,7 @@ static int msm_drm_uninit(struct device *dev)
}
 
/* We must cancel and cleanup any pending vblank enable/disable
-* work before drm_irq_uninstall() to avoid work re-enabling an
+* work before msm_irq_uninstall() to avoid work re-enabling an
 * irq after uninstall has disabled it.
 */
 
@@ -294,7 +358,7 @@ static int msm_drm_uninit(struct device *dev)
drm_mode_config_cleanup(ddev);
 
pm_runtime_get_sync(dev);
-   drm_irq_uninstall(ddev);
+   msm_irq_uninstall(ddev);
pm_runtime_put_sync(dev);
 
if (kms && kms->funcs)
@@ -553,7 +617,7 @@ static int msm_drm_init(struct device *dev, const struct 
drm_driver *drv)
 
if (kms) {
pm_runtime_get_sync(dev);
-   ret = drm_irq_install(ddev, kms->irq);
+   ret = msm_irq_install(ddev, kms->irq);
pm_runtime_put_sync(dev);
if (ret < 0) {
DRM_DEV_ERROR(dev, "failed to install IRQ handler\n");
@@ -662,43 +726,6 @@ static void msm_postclose(struct drm_device *dev, struct 
drm_file *file)
context_close(ctx);
 }
 
-static irqreturn_t msm_irq(int irq, void *arg)
-{
-   struct drm_device *dev = arg;
-   struct msm_drm_private *priv = dev->dev_private;
-   struct msm_kms *kms = priv->kms;
-   BUG_ON(!kms);
-   return kms->funcs->irq(kms);
-}
-
-static void msm_irq_preinstall(struct drm_device *dev)
-{
-   struct msm_drm_private *priv = dev->dev_private;
-   struct msm_kms *kms = priv->kms;
-   BUG_ON(!kms);
-   kms->funcs->irq_preinstall(kms);
-}
-
-static int msm_irq_postinstall(struct drm_device *dev)
-{
-   struct msm_drm_private *priv = dev->dev_private;
-   struct msm_kms *kms = priv->kms;
-   BUG_ON(!kms);
-
-   if (kms->funcs->irq_postinstall)
-   return kms->funcs->irq_postinstall(kms);
-
-   return 0;
-}
-
-static void msm_irq_uninstall(struct drm_device *dev)
-{
-   struct msm_drm_private *priv = dev->dev_private;
-   struct msm_kms *kms = priv->kms;
-   BUG_ON(!kms);
-   kms->funcs->irq_uninstall(kms);
-}
-
 int msm_crtc_enable_vblank(struct drm_crtc *crtc)
 {
struct drm_device *dev = crtc->dev;
@@ -1051,10 +1078,6 @@ static const struct drm_driver msm_driver = {
.open   = msm_open,
.postclose   = msm_postclose,
.lastclose  = drm_fb_helper_lastclose,
-   .irq_handler= msm_irq,
-   .irq_preinstall = msm_irq_preinstall,
-   

[Freedreno] [PATCH v2 06/14] drm/kmb: Convert to Linux IRQ interfaces

2021-08-03 Thread Thomas Zimmermann
Drop the DRM IRQ midlayer in favor of Linux IRQ interfaces. DRM's
IRQ helpers are mostly useful for UMS drivers. Modern KMS drivers
don't benefit from using it.

DRM IRQ callbacks are now being called directly or inlined.

Signed-off-by: Thomas Zimmermann 
---
 drivers/gpu/drm/kmb/kmb_drv.c | 26 --
 1 file changed, 20 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/kmb/kmb_drv.c b/drivers/gpu/drm/kmb/kmb_drv.c
index f54392ec4fab..1c2f4799f421 100644
--- a/drivers/gpu/drm/kmb/kmb_drv.c
+++ b/drivers/gpu/drm/kmb/kmb_drv.c
@@ -17,7 +17,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 
@@ -413,14 +412,29 @@ static void kmb_irq_reset(struct drm_device *drm)
kmb_write_lcd(to_kmb(drm), LCD_INT_ENABLE, 0);
 }
 
+static int kmb_irq_install(struct drm_device *drm, unsigned int irq)
+{
+   if (irq == IRQ_NOTCONNECTED)
+   return -ENOTCONN;
+
+   kmb_irq_reset(drm);
+
+   return request_irq(irq, kmb_isr, 0, drm->driver->name, drm);
+}
+
+static void kmb_irq_uninstall(struct drm_device *drm)
+{
+   struct kmb_drm_private *kmb = to_kmb(drm);
+
+   kmb_irq_reset(drm);
+   free_irq(kmb->irq_lcd, drm);
+}
+
 DEFINE_DRM_GEM_CMA_FOPS(fops);
 
 static const struct drm_driver kmb_driver = {
.driver_features = DRIVER_GEM |
DRIVER_MODESET | DRIVER_ATOMIC,
-   .irq_handler = kmb_isr,
-   .irq_preinstall = kmb_irq_reset,
-   .irq_uninstall = kmb_irq_reset,
/* GEM Operations */
.fops = ,
DRM_GEM_CMA_DRIVER_OPS_VMAP,
@@ -442,7 +456,7 @@ static int kmb_remove(struct platform_device *pdev)
of_node_put(kmb->crtc.port);
kmb->crtc.port = NULL;
pm_runtime_get_sync(drm->dev);
-   drm_irq_uninstall(drm);
+   kmb_irq_uninstall(drm);
pm_runtime_put_sync(drm->dev);
pm_runtime_disable(drm->dev);
 
@@ -532,7 +546,7 @@ static int kmb_probe(struct platform_device *pdev)
if (ret)
goto err_free;
 
-   ret = drm_irq_install(>drm, kmb->irq_lcd);
+   ret = kmb_irq_install(>drm, kmb->irq_lcd);
if (ret < 0) {
drm_err(>drm, "failed to install IRQ handler\n");
goto err_irq;
-- 
2.32.0



[Freedreno] [PATCH v2 04/14] drm/fsl-dcu: Convert to Linux IRQ interfaces

2021-08-03 Thread Thomas Zimmermann
Drop the DRM IRQ midlayer in favor of Linux IRQ interfaces. DRM's
IRQ helpers are mostly useful for UMS drivers. Modern KMS drivers
don't benefit from using it. DRM IRQ callbacks are now being called
directly or inlined.

Signed-off-by: Thomas Zimmermann 
---
 drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c | 78 +--
 1 file changed, 46 insertions(+), 32 deletions(-)

diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c 
b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
index 7528e8a2d359..660fe573db96 100644
--- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
+++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
@@ -23,7 +23,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
@@ -51,7 +50,7 @@ static const struct regmap_config fsl_dcu_regmap_config = {
.volatile_reg = fsl_dcu_drm_is_volatile_reg,
 };
 
-static void fsl_dcu_irq_uninstall(struct drm_device *dev)
+static void fsl_dcu_irq_reset(struct drm_device *dev)
 {
struct fsl_dcu_drm_device *fsl_dev = dev->dev_private;
 
@@ -59,6 +58,45 @@ static void fsl_dcu_irq_uninstall(struct drm_device *dev)
regmap_write(fsl_dev->regmap, DCU_INT_MASK, ~0);
 }
 
+static irqreturn_t fsl_dcu_drm_irq(int irq, void *arg)
+{
+   struct drm_device *dev = arg;
+   struct fsl_dcu_drm_device *fsl_dev = dev->dev_private;
+   unsigned int int_status;
+   int ret;
+
+   ret = regmap_read(fsl_dev->regmap, DCU_INT_STATUS, _status);
+   if (ret) {
+   dev_err(dev->dev, "read DCU_INT_STATUS failed\n");
+   return IRQ_NONE;
+   }
+
+   if (int_status & DCU_INT_STATUS_VBLANK)
+   drm_handle_vblank(dev, 0);
+
+   regmap_write(fsl_dev->regmap, DCU_INT_STATUS, int_status);
+
+   return IRQ_HANDLED;
+}
+
+static int fsl_dcu_irq_install(struct drm_device *dev, unsigned int irq)
+{
+   if (irq == IRQ_NOTCONNECTED)
+   return -ENOTCONN;
+
+   fsl_dcu_irq_reset(dev);
+
+   return request_irq(irq, fsl_dcu_drm_irq, 0, dev->driver->name, dev);
+}
+
+static void fsl_dcu_irq_uninstall(struct drm_device *dev)
+{
+   struct fsl_dcu_drm_device *fsl_dev = dev->dev_private;
+
+   fsl_dcu_irq_reset(dev);
+   free_irq(fsl_dev->irq, dev);
+}
+
 static int fsl_dcu_load(struct drm_device *dev, unsigned long flags)
 {
struct fsl_dcu_drm_device *fsl_dev = dev->dev_private;
@@ -73,13 +111,13 @@ static int fsl_dcu_load(struct drm_device *dev, unsigned 
long flags)
ret = drm_vblank_init(dev, dev->mode_config.num_crtc);
if (ret < 0) {
dev_err(dev->dev, "failed to initialize vblank\n");
-   goto done;
+   goto done_vblank;
}
 
-   ret = drm_irq_install(dev, fsl_dev->irq);
+   ret = fsl_dcu_irq_install(dev, fsl_dev->irq);
if (ret < 0) {
dev_err(dev->dev, "failed to install IRQ handler\n");
-   goto done;
+   goto done_irq;
}
 
if (legacyfb_depth != 16 && legacyfb_depth != 24 &&
@@ -90,11 +128,11 @@ static int fsl_dcu_load(struct drm_device *dev, unsigned 
long flags)
}
 
return 0;
-done:
+done_irq:
drm_kms_helper_poll_fini(dev);
 
drm_mode_config_cleanup(dev);
-   drm_irq_uninstall(dev);
+done_vblank:
dev->dev_private = NULL;
 
return ret;
@@ -106,41 +144,17 @@ static void fsl_dcu_unload(struct drm_device *dev)
drm_kms_helper_poll_fini(dev);
 
drm_mode_config_cleanup(dev);
-   drm_irq_uninstall(dev);
+   fsl_dcu_irq_uninstall(dev);
 
dev->dev_private = NULL;
 }
 
-static irqreturn_t fsl_dcu_drm_irq(int irq, void *arg)
-{
-   struct drm_device *dev = arg;
-   struct fsl_dcu_drm_device *fsl_dev = dev->dev_private;
-   unsigned int int_status;
-   int ret;
-
-   ret = regmap_read(fsl_dev->regmap, DCU_INT_STATUS, _status);
-   if (ret) {
-   dev_err(dev->dev, "read DCU_INT_STATUS failed\n");
-   return IRQ_NONE;
-   }
-
-   if (int_status & DCU_INT_STATUS_VBLANK)
-   drm_handle_vblank(dev, 0);
-
-   regmap_write(fsl_dev->regmap, DCU_INT_STATUS, int_status);
-
-   return IRQ_HANDLED;
-}
-
 DEFINE_DRM_GEM_CMA_FOPS(fsl_dcu_drm_fops);
 
 static const struct drm_driver fsl_dcu_drm_driver = {
.driver_features= DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
.load   = fsl_dcu_load,
.unload = fsl_dcu_unload,
-   .irq_handler= fsl_dcu_drm_irq,
-   .irq_preinstall = fsl_dcu_irq_uninstall,
-   .irq_uninstall  = fsl_dcu_irq_uninstall,
DRM_GEM_CMA_DRIVER_OPS,
.fops   = _dcu_drm_fops,
.name   = "fsl-dcu-drm",
-- 
2.32.0



[Freedreno] [PATCH v2 03/14] drm/atmel-hlcdc: Convert to Linux IRQ interfaces

2021-08-03 Thread Thomas Zimmermann
Drop the DRM IRQ midlayer in favor of Linux IRQ interfaces. DRM's
IRQ helpers are mostly useful for UMS drivers. Modern KMS drivers
don't benefit from using it. DRM IRQ callbacks are now being called
directly or inlined.

v2:
* use managed release via devm_request_irq() (Sam)
* drop extra test for irq != IRQ_NOTCONNECTED (Sam)

Signed-off-by: Thomas Zimmermann 
Reviewed-by: Sam Ravnborg 
Tested-by: Dan Sneddon 
---
 drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c | 80 
 1 file changed, 47 insertions(+), 33 deletions(-)

diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c 
b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
index f09b6dd8754c..1656d27b78b6 100644
--- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
+++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
@@ -22,7 +22,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 
@@ -557,6 +556,51 @@ static irqreturn_t atmel_hlcdc_dc_irq_handler(int irq, 
void *data)
return IRQ_HANDLED;
 }
 
+static void atmel_hlcdc_dc_irq_postinstall(struct drm_device *dev)
+{
+   struct atmel_hlcdc_dc *dc = dev->dev_private;
+   unsigned int cfg = 0;
+   int i;
+
+   /* Enable interrupts on activated layers */
+   for (i = 0; i < ATMEL_HLCDC_MAX_LAYERS; i++) {
+   if (dc->layers[i])
+   cfg |= ATMEL_HLCDC_LAYER_STATUS(i);
+   }
+
+   regmap_write(dc->hlcdc->regmap, ATMEL_HLCDC_IER, cfg);
+}
+
+static void atmel_hlcdc_dc_irq_disable(struct drm_device *dev)
+{
+   struct atmel_hlcdc_dc *dc = dev->dev_private;
+   unsigned int isr;
+
+   regmap_write(dc->hlcdc->regmap, ATMEL_HLCDC_IDR, 0x);
+   regmap_read(dc->hlcdc->regmap, ATMEL_HLCDC_ISR, );
+}
+
+static int atmel_hlcdc_dc_irq_install(struct drm_device *dev, unsigned int irq)
+{
+   int ret;
+
+   atmel_hlcdc_dc_irq_disable(dev);
+
+   ret = devm_request_irq(dev->dev, irq, atmel_hlcdc_dc_irq_handler, 0,
+  dev->driver->name, dev);
+   if (ret)
+   return ret;
+
+   atmel_hlcdc_dc_irq_postinstall(dev);
+
+   return 0;
+}
+
+static void atmel_hlcdc_dc_irq_uninstall(struct drm_device *dev)
+{
+   atmel_hlcdc_dc_irq_disable(dev);
+}
+
 static const struct drm_mode_config_funcs mode_config_funcs = {
.fb_create = drm_gem_fb_create,
.atomic_check = drm_atomic_helper_check,
@@ -647,7 +691,7 @@ static int atmel_hlcdc_dc_load(struct drm_device *dev)
drm_mode_config_reset(dev);
 
pm_runtime_get_sync(dev->dev);
-   ret = drm_irq_install(dev, dc->hlcdc->irq);
+   ret = atmel_hlcdc_dc_irq_install(dev, dc->hlcdc->irq);
pm_runtime_put_sync(dev->dev);
if (ret < 0) {
dev_err(dev->dev, "failed to install IRQ handler\n");
@@ -676,7 +720,7 @@ static void atmel_hlcdc_dc_unload(struct drm_device *dev)
drm_mode_config_cleanup(dev);
 
pm_runtime_get_sync(dev->dev);
-   drm_irq_uninstall(dev);
+   atmel_hlcdc_dc_irq_uninstall(dev);
pm_runtime_put_sync(dev->dev);
 
dev->dev_private = NULL;
@@ -685,40 +729,10 @@ static void atmel_hlcdc_dc_unload(struct drm_device *dev)
clk_disable_unprepare(dc->hlcdc->periph_clk);
 }
 
-static int atmel_hlcdc_dc_irq_postinstall(struct drm_device *dev)
-{
-   struct atmel_hlcdc_dc *dc = dev->dev_private;
-   unsigned int cfg = 0;
-   int i;
-
-   /* Enable interrupts on activated layers */
-   for (i = 0; i < ATMEL_HLCDC_MAX_LAYERS; i++) {
-   if (dc->layers[i])
-   cfg |= ATMEL_HLCDC_LAYER_STATUS(i);
-   }
-
-   regmap_write(dc->hlcdc->regmap, ATMEL_HLCDC_IER, cfg);
-
-   return 0;
-}
-
-static void atmel_hlcdc_dc_irq_uninstall(struct drm_device *dev)
-{
-   struct atmel_hlcdc_dc *dc = dev->dev_private;
-   unsigned int isr;
-
-   regmap_write(dc->hlcdc->regmap, ATMEL_HLCDC_IDR, 0x);
-   regmap_read(dc->hlcdc->regmap, ATMEL_HLCDC_ISR, );
-}
-
 DEFINE_DRM_GEM_CMA_FOPS(fops);
 
 static const struct drm_driver atmel_hlcdc_dc_driver = {
.driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
-   .irq_handler = atmel_hlcdc_dc_irq_handler,
-   .irq_preinstall = atmel_hlcdc_dc_irq_uninstall,
-   .irq_postinstall = atmel_hlcdc_dc_irq_postinstall,
-   .irq_uninstall = atmel_hlcdc_dc_irq_uninstall,
DRM_GEM_CMA_DRIVER_OPS,
.fops = ,
.name = "atmel-hlcdc",
-- 
2.32.0



[Freedreno] [PATCH v2 02/14] drm/arm/hdlcd: Convert to Linux IRQ interfaces

2021-08-03 Thread Thomas Zimmermann
Drop the DRM IRQ midlayer in favor of Linux IRQ interfaces. DRM's
IRQ helpers are mostly useful for UMS drivers. Modern KMS drivers
don't benefit from using it.

DRM IRQ callbacks are now being called directly or inlined.

Calls to platform_get_irq() can fail with a negative errno code.
Abort initialization in this case. The DRM IRQ midlayer does not
handle this case correctly.

v2:
* name struct drm_device variables 'drm' (Sam)

Signed-off-by: Thomas Zimmermann 
Acked-by: Sam Ravnborg 
---
 drivers/gpu/drm/arm/hdlcd_drv.c | 174 ++--
 drivers/gpu/drm/arm/hdlcd_drv.h |   1 +
 2 files changed, 97 insertions(+), 78 deletions(-)

diff --git a/drivers/gpu/drm/arm/hdlcd_drv.c b/drivers/gpu/drm/arm/hdlcd_drv.c
index 81ae92390736..479c2422a2e0 100644
--- a/drivers/gpu/drm/arm/hdlcd_drv.c
+++ b/drivers/gpu/drm/arm/hdlcd_drv.c
@@ -29,7 +29,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
@@ -38,6 +37,94 @@
 #include "hdlcd_drv.h"
 #include "hdlcd_regs.h"
 
+static irqreturn_t hdlcd_irq(int irq, void *arg)
+{
+   struct drm_device *drm = arg;
+   struct hdlcd_drm_private *hdlcd = drm->dev_private;
+   unsigned long irq_status;
+
+   irq_status = hdlcd_read(hdlcd, HDLCD_REG_INT_STATUS);
+
+#ifdef CONFIG_DEBUG_FS
+   if (irq_status & HDLCD_INTERRUPT_UNDERRUN)
+   atomic_inc(>buffer_underrun_count);
+
+   if (irq_status & HDLCD_INTERRUPT_DMA_END)
+   atomic_inc(>dma_end_count);
+
+   if (irq_status & HDLCD_INTERRUPT_BUS_ERROR)
+   atomic_inc(>bus_error_count);
+
+   if (irq_status & HDLCD_INTERRUPT_VSYNC)
+   atomic_inc(>vsync_count);
+
+#endif
+   if (irq_status & HDLCD_INTERRUPT_VSYNC)
+   drm_crtc_handle_vblank(>crtc);
+
+   /* acknowledge interrupt(s) */
+   hdlcd_write(hdlcd, HDLCD_REG_INT_CLEAR, irq_status);
+
+   return IRQ_HANDLED;
+}
+
+static void hdlcd_irq_preinstall(struct drm_device *drm)
+{
+   struct hdlcd_drm_private *hdlcd = drm->dev_private;
+   /* Ensure interrupts are disabled */
+   hdlcd_write(hdlcd, HDLCD_REG_INT_MASK, 0);
+   hdlcd_write(hdlcd, HDLCD_REG_INT_CLEAR, ~0);
+}
+
+static void hdlcd_irq_postinstall(struct drm_device *drm)
+{
+#ifdef CONFIG_DEBUG_FS
+   struct hdlcd_drm_private *hdlcd = drm->dev_private;
+   unsigned long irq_mask = hdlcd_read(hdlcd, HDLCD_REG_INT_MASK);
+
+   /* enable debug interrupts */
+   irq_mask |= HDLCD_DEBUG_INT_MASK;
+
+   hdlcd_write(hdlcd, HDLCD_REG_INT_MASK, irq_mask);
+#endif
+}
+
+static int hdlcd_irq_install(struct drm_device *drm, int irq)
+{
+   int ret;
+
+   if (irq == IRQ_NOTCONNECTED)
+   return -ENOTCONN;
+
+   hdlcd_irq_preinstall(drm);
+
+   ret = request_irq(irq, hdlcd_irq, 0, drm->driver->name, drm);
+   if (ret)
+   return ret;
+
+   hdlcd_irq_postinstall(drm);
+
+   return 0;
+}
+
+static void hdlcd_irq_uninstall(struct drm_device *drm)
+{
+   struct hdlcd_drm_private *hdlcd = drm->dev_private;
+   /* disable all the interrupts that we might have enabled */
+   unsigned long irq_mask = hdlcd_read(hdlcd, HDLCD_REG_INT_MASK);
+
+#ifdef CONFIG_DEBUG_FS
+   /* disable debug interrupts */
+   irq_mask &= ~HDLCD_DEBUG_INT_MASK;
+#endif
+
+   /* disable vsync interrupts */
+   irq_mask &= ~HDLCD_INTERRUPT_VSYNC;
+   hdlcd_write(hdlcd, HDLCD_REG_INT_MASK, irq_mask);
+
+   free_irq(hdlcd->irq, drm);
+}
+
 static int hdlcd_load(struct drm_device *drm, unsigned long flags)
 {
struct hdlcd_drm_private *hdlcd = drm->dev_private;
@@ -90,7 +177,12 @@ static int hdlcd_load(struct drm_device *drm, unsigned long 
flags)
goto setup_fail;
}
 
-   ret = drm_irq_install(drm, platform_get_irq(pdev, 0));
+   ret = platform_get_irq(pdev, 0);
+   if (ret < 0)
+   goto irq_fail;
+   hdlcd->irq = ret;
+
+   ret = hdlcd_irq_install(drm, hdlcd->irq);
if (ret < 0) {
DRM_ERROR("failed to install IRQ handler\n");
goto irq_fail;
@@ -122,76 +214,6 @@ static void hdlcd_setup_mode_config(struct drm_device *drm)
drm->mode_config.funcs = _mode_config_funcs;
 }
 
-static irqreturn_t hdlcd_irq(int irq, void *arg)
-{
-   struct drm_device *drm = arg;
-   struct hdlcd_drm_private *hdlcd = drm->dev_private;
-   unsigned long irq_status;
-
-   irq_status = hdlcd_read(hdlcd, HDLCD_REG_INT_STATUS);
-
-#ifdef CONFIG_DEBUG_FS
-   if (irq_status & HDLCD_INTERRUPT_UNDERRUN)
-   atomic_inc(>buffer_underrun_count);
-
-   if (irq_status & HDLCD_INTERRUPT_DMA_END)
-   atomic_inc(>dma_end_count);
-
-   if (irq_status & HDLCD_INTERRUPT_BUS_ERROR)
-   atomic_inc(>bus_error_count);
-
-   if (irq_status & HDLCD_INTERRUPT_VSYNC)
-   atomic_inc(>vsync_count);
-
-#endif
-   if (irq_status & HDLCD_INTERRUPT_VSYNC)
- 

[Freedreno] [PATCH v2 00/14] drm: Make DRM's IRQ helpers legacy

2021-08-03 Thread Thomas Zimmermann
DRM's IRQ helpers are only helpful for old, non-KMS drivers. Move
the code behind CONFIG_DRM_LEGACY. Convert KMS drivers to Linux
IRQ interfaces.

DRM provides IRQ helpers for setting up, receiving and removing IRQ
handlers. It's an abstraction over plain Linux functions. The code
is mid-layerish with several callbacks to hook into the rsp drivers.
Old UMS driver have their interrupts enabled via ioctl, so these
abstractions makes some sense. Modern KMS manage all their interrupts
internally. Using the DRM helpers adds indirection without benefits.

Most KMS drivers already use Linux IRQ functions instead of DRM's
abstraction layer. Patches 1 to 12 convert the remaining ones.
The patches also resolve a bug for devices without assigned interrupt
number. DRM helpers don't test for IRQ_NOTCONNECTED, so drivers do
not detect if the device has no interrupt assigned.

Patch 13 removes an unused function.

Patch 14 moves the DRM IRQ helpers behind CONFIG_DRM_LEGACY. Only
the old non-KMS drivers still use the functionality.

v2:
* drop IRQ_NOTCONNECTED test from atmel-hlcdc (Sam)
* use devm_request_irq() in atmel-hlcdc (Sam)
* unify variable names in arm/hlcdc (Sam)

Thomas Zimmermann (14):
  drm/amdgpu: Convert to Linux IRQ interfaces
  drm/arm/hdlcd: Convert to Linux IRQ interfaces
  drm/atmel-hlcdc: Convert to Linux IRQ interfaces
  drm/fsl-dcu: Convert to Linux IRQ interfaces
  drm/gma500: Convert to Linux IRQ interfaces
  drm/kmb: Convert to Linux IRQ interfaces
  drm/msm: Convert to Linux IRQ interfaces
  drm/mxsfb: Convert to Linux IRQ interfaces
  drm/radeon: Convert to Linux IRQ interfaces
  drm/tidss: Convert to Linux IRQ interfaces
  drm/tilcdc: Convert to Linux IRQ interfaces
  drm/vc4: Convert to Linux IRQ interfaces
  drm: Remove unused devm_drm_irq_install()
  drm: IRQ midlayer is now legacy

 drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c  |   1 -
 drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c  |  21 ++-
 drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h  |   2 +-
 drivers/gpu/drm/arm/hdlcd_drv.c  | 174 ++-
 drivers/gpu/drm/arm/hdlcd_drv.h  |   1 +
 drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c |  80 +
 drivers/gpu/drm/drm_irq.c|  95 +-
 drivers/gpu/drm/drm_legacy_misc.c|   3 +-
 drivers/gpu/drm/drm_vblank.c |   8 +-
 drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c|  78 +
 drivers/gpu/drm/gma500/power.c   |   1 +
 drivers/gpu/drm/gma500/psb_drv.c |   8 +-
 drivers/gpu/drm/gma500/psb_drv.h |   5 -
 drivers/gpu/drm/gma500/psb_irq.c |  26 ++-
 drivers/gpu/drm/gma500/psb_irq.h |   4 +-
 drivers/gpu/drm/i810/i810_dma.c  |   3 +-
 drivers/gpu/drm/kmb/kmb_drv.c|  26 ++-
 drivers/gpu/drm/mga/mga_dma.c|   2 +-
 drivers/gpu/drm/mga/mga_drv.h|   1 -
 drivers/gpu/drm/msm/msm_drv.c| 113 +++-
 drivers/gpu/drm/msm/msm_kms.h|   2 +-
 drivers/gpu/drm/mxsfb/mxsfb_drv.c|  81 +
 drivers/gpu/drm/mxsfb/mxsfb_drv.h|   2 +
 drivers/gpu/drm/r128/r128_cce.c  |   3 +-
 drivers/gpu/drm/radeon/radeon_drv.c  |   4 -
 drivers/gpu/drm/radeon/radeon_irq_kms.c  |  44 -
 drivers/gpu/drm/radeon/radeon_kms.h  |   4 -
 drivers/gpu/drm/tidss/tidss_drv.c|  15 +-
 drivers/gpu/drm/tidss/tidss_drv.h|   2 +
 drivers/gpu/drm/tidss/tidss_irq.c|  27 ++-
 drivers/gpu/drm/tidss/tidss_irq.h|   4 +-
 drivers/gpu/drm/tilcdc/tilcdc_drv.c  |  51 --
 drivers/gpu/drm/tilcdc/tilcdc_drv.h  |   3 +
 drivers/gpu/drm/vc4/vc4_drv.c|   4 -
 drivers/gpu/drm/vc4/vc4_drv.h|   8 +-
 drivers/gpu/drm/vc4/vc4_irq.c|  48 +++--
 drivers/gpu/drm/vc4/vc4_v3d.c|  17 +-
 drivers/gpu/drm/via/via_mm.c |   3 +-
 include/drm/drm_device.h |  18 +-
 include/drm/drm_drv.h|  44 +
 include/drm/drm_irq.h|  32 
 include/drm/drm_legacy.h |   3 +
 42 files changed, 567 insertions(+), 504 deletions(-)
 delete mode 100644 include/drm/drm_irq.h


base-commit: c9d6903562aa335593daf44b4a1edeaef6bf9206
prerequisite-patch-id: c2b2f08f0eccc9f5df0c0da49fa1d36267deb11d
prerequisite-patch-id: c67e5d886a47b7d0266d81100837557fda34cb24
prerequisite-patch-id: c3f32630e1d2de2eb74316c930578847d4b83fb3
prerequisite-patch-id: b32ca0abfc255601f8a5052d3b88be09527dabcb
prerequisite-patch-id: 22a3f264168bacb04ef65306b32b86be8dc982ef
prerequisite-patch-id: 095a0acb604eb02956e1a7e53da41371c64eb813
prerequisite-patch-id: 7a2417d5d8d453204bd94aa873e3faae812f26fc
--
2.32.0



[Freedreno] [PATCH v2 01/14] drm/amdgpu: Convert to Linux IRQ interfaces

2021-08-03 Thread Thomas Zimmermann
Drop the DRM IRQ midlayer in favor of Linux IRQ interfaces. DRM's
IRQ helpers are mostly useful for UMS drivers. Modern KMS drivers
don't benefit from using it.

DRM IRQ callbacks are now being called directly or inlined.

The interrupt number returned by pci_msi_vector() is now stored
in struct amdgpu_irq. Calls to pci_msi_vector() can fail and return
a negative errno code. Abort initlaizaton in thi case. The DRM IRQ
midlayer does not handle this correctly.

Signed-off-by: Thomas Zimmermann 
Reviewed-by: Alex Deucher 
Acked-by: Christian König 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c |  1 -
 drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c | 21 ++---
 drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h |  2 +-
 3 files changed, 15 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
index d637b0536f84..2b0b0e8a6acb 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
@@ -1777,7 +1777,6 @@ static const struct drm_driver amdgpu_kms_driver = {
.open = amdgpu_driver_open_kms,
.postclose = amdgpu_driver_postclose_kms,
.lastclose = amdgpu_driver_lastclose_kms,
-   .irq_handler = amdgpu_irq_handler,
.ioctls = amdgpu_ioctls_kms,
.num_ioctls = ARRAY_SIZE(amdgpu_ioctls_kms),
.dumb_create = amdgpu_mode_dumb_create,
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
index 7dfdabe1cdf9..3ac39b44a211 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
@@ -46,7 +46,6 @@
 #include 
 
 #include 
-#include 
 #include 
 #include 
 #include 
@@ -184,7 +183,7 @@ void amdgpu_irq_disable_all(struct amdgpu_device *adev)
  * Returns:
  * result of handling the IRQ, as defined by _t
  */
-irqreturn_t amdgpu_irq_handler(int irq, void *arg)
+static irqreturn_t amdgpu_irq_handler(int irq, void *arg)
 {
struct drm_device *dev = (struct drm_device *) arg;
struct amdgpu_device *adev = drm_to_adev(dev);
@@ -307,6 +306,7 @@ static void amdgpu_restore_msix(struct amdgpu_device *adev)
 int amdgpu_irq_init(struct amdgpu_device *adev)
 {
int r = 0;
+   unsigned int irq;
 
spin_lock_init(>irq.lock);
 
@@ -349,15 +349,22 @@ int amdgpu_irq_init(struct amdgpu_device *adev)
INIT_WORK(>irq.ih2_work, amdgpu_irq_handle_ih2);
INIT_WORK(>irq.ih_soft_work, amdgpu_irq_handle_ih_soft);
 
-   adev->irq.installed = true;
-   /* Use vector 0 for MSI-X */
-   r = drm_irq_install(adev_to_drm(adev), pci_irq_vector(adev->pdev, 0));
+   /* Use vector 0 for MSI-X. */
+   r = pci_irq_vector(adev->pdev, 0);
+   if (r < 0)
+   return r;
+   irq = r;
+
+   /* PCI devices require shared interrupts. */
+   r = request_irq(irq, amdgpu_irq_handler, IRQF_SHARED, 
adev_to_drm(adev)->driver->name,
+   adev_to_drm(adev));
if (r) {
-   adev->irq.installed = false;
if (!amdgpu_device_has_dc_support(adev))
flush_work(>hotplug_work);
return r;
}
+   adev->irq.installed = true;
+   adev->irq.irq = irq;
adev_to_drm(adev)->max_vblank_count = 0x00ff;
 
DRM_DEBUG("amdgpu: irq initialized.\n");
@@ -368,7 +375,7 @@ int amdgpu_irq_init(struct amdgpu_device *adev)
 void amdgpu_irq_fini_hw(struct amdgpu_device *adev)
 {
if (adev->irq.installed) {
-   drm_irq_uninstall(>ddev);
+   free_irq(adev->irq.irq, adev_to_drm(adev));
adev->irq.installed = false;
if (adev->irq.msi_enabled)
pci_free_irq_vectors(adev->pdev);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h
index 78ad4784cc74..e9f2c11ea416 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h
@@ -80,6 +80,7 @@ struct amdgpu_irq_src_funcs {
 
 struct amdgpu_irq {
boolinstalled;
+   unsigned intirq;
spinlock_t  lock;
/* interrupt sources */
struct amdgpu_irq_clientclient[AMDGPU_IRQ_CLIENTID_MAX];
@@ -100,7 +101,6 @@ struct amdgpu_irq {
 };
 
 void amdgpu_irq_disable_all(struct amdgpu_device *adev);
-irqreturn_t amdgpu_irq_handler(int irq, void *arg);
 
 int amdgpu_irq_init(struct amdgpu_device *adev);
 void amdgpu_irq_fini_sw(struct amdgpu_device *adev);
-- 
2.32.0



Re: [Freedreno] [PATCH v2] drm/msm/dp: update is_connected status base on sink count at dp_pm_resume()

2021-08-03 Thread Stephen Boyd
Quoting Kuogee Hsieh (2021-08-02 13:20:55)
> Currently at dp_pm_resume() is_connected state is decided base on hpd 
> connection
> status only. This will put is_connected in wrongly "true" state at the 
> scenario
> that dongle attached to DUT but without hmdi cable connecting to it. Fix this
> problem by adding read sink count from dongle and decided is_connected state 
> base
> on both sink count and hpd connection status.
>
> Changes in v2:
> -- remove dp_get_sink_count() cand call drm_dp_read_sink_count()
>
> Fixes: d9aa6571b28ba ("drm/msm/dp: check sink_count before update 
> is_connected status")
> Signed-off-by: Kuogee Hsieh 
> ---
>  drivers/gpu/drm/msm/dp/dp_display.c | 18 +++---
>  1 file changed, 15 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/dp/dp_display.c 
> b/drivers/gpu/drm/msm/dp/dp_display.c
> index 8b69114..6dcb78e 100644
> --- a/drivers/gpu/drm/msm/dp/dp_display.c
> +++ b/drivers/gpu/drm/msm/dp/dp_display.c
> @@ -1403,6 +1403,7 @@ static int dp_pm_resume(struct device *dev)
> struct msm_dp *dp_display = platform_get_drvdata(pdev);
> struct dp_display_private *dp;
> u32 status;

'status' is unused now, right? The compiler should be complaining about
unused local variables.

> +   int sink_count = 0;
>
> dp = container_of(dp_display, struct dp_display_private, dp_display);
>  xlog(__func__, 1,0,0, dp->core_initialized, dp_display->power_on);
> @@ -1417,15 +1418,26 @@ xlog(__func__, 1,0,0, dp->core_initialized, 
> dp_display->power_on);
>
> dp_catalog_ctrl_hpd_config(dp->catalog);
>
> -   status = dp_catalog_link_is_connected(dp->catalog);
> +   /*
> +* set sink to normal operation mode -- D0
> +* before dpcd read
> +*/
> +   dp_link_psm_config(dp->link, >panel->link_info, false);
> +
> +   /* if sink conencted, do dpcd read sink count */
> +   if ((status = dp_catalog_link_is_connected(dp->catalog))) {
> +   sink_count = drm_dp_read_sink_count(dp->aux);
> +   if (sink_count < 0)
> +   sink_count = 0;
> +   }
>
> +   dp->link->sink_count = sink_count;
> /*
>  * can not declared display is connected unless
>  * HDMI cable is plugged in and sink_count of
>  * dongle become 1
>  */
> -xlog(__func__, 0x12,0,0, 0, dp->link->sink_count);
> -   if (status && dp->link->sink_count)
> +   if (dp->link->sink_count)
> dp->dp_display.is_connected = true;
> else
> dp->dp_display.is_connected = false;