Re: [PATCH 4/6] drm/msm/a7xx: Initialize a750 "software fuse"

2024-04-26 Thread Rob Clark
On Fri, Apr 26, 2024 at 8:24 AM Dmitry Baryshkov
 wrote:
>
> On Fri, 26 Apr 2024 at 18:08, Connor Abbott  wrote:
> >
> > On Fri, Apr 26, 2024 at 3:53 PM Dmitry Baryshkov
> >  wrote:
> > >
> > > On Fri, 26 Apr 2024 at 17:05, Connor Abbott  wrote:
> > > >
> > > > On Fri, Apr 26, 2024 at 2:31 PM Dmitry Baryshkov
> > > >  wrote:
> > > > >
> > > > > On Fri, 26 Apr 2024 at 15:35, Connor Abbott  
> > > > > wrote:
> > > > > >
> > > > > > On Fri, Apr 26, 2024 at 12:02 AM Dmitry Baryshkov
> > > > > >  wrote:
> > > > > > >
> > > > > > > On Thu, 25 Apr 2024 at 16:44, Connor Abbott  
> > > > > > > wrote:
> > > > > > > >
> > > > > > > > On all Qualcomm platforms with a7xx GPUs, qcom_scm provides a 
> > > > > > > > method to
> > > > > > > > initialize cx_mem. Copy this from downstream (minus BCL which we
> > > > > > > > currently don't support). On a750, this includes a new "fuse" 
> > > > > > > > register
> > > > > > > > which can be used by qcom_scm to fuse off certain features like
> > > > > > > > raytracing in software. The fuse is default off, and is 
> > > > > > > > initialized by
> > > > > > > > calling the method. Afterwards we have to read it to find out 
> > > > > > > > which
> > > > > > > > features were enabled.
> > > > > > > >
> > > > > > > > Signed-off-by: Connor Abbott 
> > > > > > > > ---
> > > > > > > >  drivers/gpu/drm/msm/adreno/a6xx_gpu.c   | 89 
> > > > > > > > -
> > > > > > > >  drivers/gpu/drm/msm/adreno/adreno_gpu.h |  2 +
> > > > > > > >  2 files changed, 90 insertions(+), 1 deletion(-)
> > > > > > > >
> > > > > > > > diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c 
> > > > > > > > b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> > > > > > > > index cf0b1de1c071..fb2722574ae5 100644
> > > > > > > > --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> > > > > > > > +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> > > > > > > > @@ -10,6 +10,7 @@
> > > > > > > >
> > > > > > > >  #include 
> > > > > > > >  #include 
> > > > > > > > +#include 
> > > > > > > >  #include 
> > > > > > > >  #include 
> > > > > > > >
> > > > > > > > @@ -1686,7 +1687,8 @@ static int a6xx_zap_shader_init(struct 
> > > > > > > > msm_gpu *gpu)
> > > > > > > >A6XX_RBBM_INT_0_MASK_RBBM_HANG_DETECT | \
> > > > > > > >A6XX_RBBM_INT_0_MASK_UCHE_OOB_ACCESS | \
> > > > > > > >A6XX_RBBM_INT_0_MASK_UCHE_TRAP_INTR | \
> > > > > > > > -  A6XX_RBBM_INT_0_MASK_TSBWRITEERROR)
> > > > > > > > +  A6XX_RBBM_INT_0_MASK_TSBWRITEERROR | \
> > > > > > > > +  A6XX_RBBM_INT_0_MASK_SWFUSEVIOLATION)
> > > > > > > >
> > > > > > > >  #define A7XX_APRIV_MASK (A6XX_CP_APRIV_CNTL_ICACHE | \
> > > > > > > >  A6XX_CP_APRIV_CNTL_RBFETCH | \
> > > > > > > > @@ -2356,6 +2358,26 @@ static void a6xx_fault_detect_irq(struct 
> > > > > > > > msm_gpu *gpu)
> > > > > > > > kthread_queue_work(gpu->worker, >recover_work);
> > > > > > > >  }
> > > > > > > >
> > > > > > > > +static void a7xx_sw_fuse_violation_irq(struct msm_gpu *gpu)
> > > > > > > > +{
> > > > > > > > +   u32 status;
> > > > > > > > +
> > > > > > > > +   status = gpu_read(gpu, 
> > > > > > > > REG_A7XX_RBBM_SW_FUSE_INT_STATUS);
> > > > > > > > +   gpu_write(gpu, REG_A7XX_RBBM_SW_FUSE_INT_MASK, 0);
> > > > > > > > +
> > > > > > > > +   dev_err_ratelimited(>pdev->dev, "SW fuse violation 
> > > > > > > > status=%8.8x\n", status);
> > > > > > > > +
> > > > > > > > +   /* Ignore FASTBLEND violations, because the HW will 
> > > > > > > > silently fall back
> > > > > > > > +* to legacy blending.
> > > > > > > > +*/
> > > > > > > > +   if (status & (A7XX_CX_MISC_SW_FUSE_VALUE_RAYTRACING |
> > > > > > > > + A7XX_CX_MISC_SW_FUSE_VALUE_LPAC)) {
> > > > > > > > +   del_timer(>hangcheck_timer);
> > > > > > > > +
> > > > > > > > +   kthread_queue_work(gpu->worker, 
> > > > > > > > >recover_work);
> > > > > > > > +   }
> > > > > > > > +}
> > > > > > > > +
> > > > > > > >  static irqreturn_t a6xx_irq(struct msm_gpu *gpu)
> > > > > > > >  {
> > > > > > > > struct msm_drm_private *priv = gpu->dev->dev_private;
> > > > > > > > @@ -2384,6 +2406,9 @@ static irqreturn_t a6xx_irq(struct 
> > > > > > > > msm_gpu *gpu)
> > > > > > > > if (status & A6XX_RBBM_INT_0_MASK_UCHE_OOB_ACCESS)
> > > > > > > > dev_err_ratelimited(>pdev->dev, "UCHE | 
> > > > > > > > Out of bounds access\n");
> > > > > > > >
> > > > > > > > +   if (status & A6XX_RBBM_INT_0_MASK_SWFUSEVIOLATION)
> > > > > > > > +   a7xx_sw_fuse_violation_irq(gpu);
> > > > > > > > +
> > > > > > > > if (status & A6XX_RBBM_INT_0_MASK_CP_CACHE_FLUSH_TS)
> > > > > > > > msm_gpu_retire(gpu);
> > > > > > > >
> > > > > > > > @@ -2525,6 +2550,60 @@ static void a6xx_llc_slices_init(struct 
> > > > > > > > platform_device *pdev,
> > > > > > > > 

Re: [PATCH 4/6] drm/msm/a7xx: Initialize a750 "software fuse"

2024-04-26 Thread Dmitry Baryshkov
On Fri, 26 Apr 2024 at 18:36, Connor Abbott  wrote:
>
> On Fri, Apr 26, 2024 at 4:24 PM Dmitry Baryshkov
>  wrote:
> >
> > On Fri, 26 Apr 2024 at 18:08, Connor Abbott  wrote:
> > >
> > > On Fri, Apr 26, 2024 at 3:53 PM Dmitry Baryshkov
> > >  wrote:
> > > >
> > > > On Fri, 26 Apr 2024 at 17:05, Connor Abbott  wrote:
> > > > >
> > > > > On Fri, Apr 26, 2024 at 2:31 PM Dmitry Baryshkov
> > > > >  wrote:
> > > > > >
> > > > > > On Fri, 26 Apr 2024 at 15:35, Connor Abbott  
> > > > > > wrote:
> > > > > > >
> > > > > > > On Fri, Apr 26, 2024 at 12:02 AM Dmitry Baryshkov
> > > > > > >  wrote:
> > > > > > > >
> > > > > > > > On Thu, 25 Apr 2024 at 16:44, Connor Abbott 
> > > > > > > >  wrote:
> > > > > > > > >
> > > > > > > > > On all Qualcomm platforms with a7xx GPUs, qcom_scm provides a 
> > > > > > > > > method to
> > > > > > > > > initialize cx_mem. Copy this from downstream (minus BCL which 
> > > > > > > > > we
> > > > > > > > > currently don't support). On a750, this includes a new "fuse" 
> > > > > > > > > register
> > > > > > > > > which can be used by qcom_scm to fuse off certain features 
> > > > > > > > > like
> > > > > > > > > raytracing in software. The fuse is default off, and is 
> > > > > > > > > initialized by
> > > > > > > > > calling the method. Afterwards we have to read it to find out 
> > > > > > > > > which
> > > > > > > > > features were enabled.
> > > > > > > > >
> > > > > > > > > Signed-off-by: Connor Abbott 
> > > > > > > > > ---
> > > > > > > > >  drivers/gpu/drm/msm/adreno/a6xx_gpu.c   | 89 
> > > > > > > > > -
> > > > > > > > >  drivers/gpu/drm/msm/adreno/adreno_gpu.h |  2 +
> > > > > > > > >  2 files changed, 90 insertions(+), 1 deletion(-)
> > > > > > > > >
> > > > > > > > > diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c 
> > > > > > > > > b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> > > > > > > > > index cf0b1de1c071..fb2722574ae5 100644
> > > > > > > > > --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> > > > > > > > > +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> > > > > > > > > @@ -10,6 +10,7 @@
> > > > > > > > >
> > > > > > > > >  #include 
> > > > > > > > >  #include 
> > > > > > > > > +#include 
> > > > > > > > >  #include 
> > > > > > > > >  #include 
> > > > > > > > >
> > > > > > > > > @@ -1686,7 +1687,8 @@ static int a6xx_zap_shader_init(struct 
> > > > > > > > > msm_gpu *gpu)
> > > > > > > > >A6XX_RBBM_INT_0_MASK_RBBM_HANG_DETECT 
> > > > > > > > > | \
> > > > > > > > >A6XX_RBBM_INT_0_MASK_UCHE_OOB_ACCESS | 
> > > > > > > > > \
> > > > > > > > >A6XX_RBBM_INT_0_MASK_UCHE_TRAP_INTR | \
> > > > > > > > > -  A6XX_RBBM_INT_0_MASK_TSBWRITEERROR)
> > > > > > > > > +  A6XX_RBBM_INT_0_MASK_TSBWRITEERROR | \
> > > > > > > > > +  A6XX_RBBM_INT_0_MASK_SWFUSEVIOLATION)
> > > > > > > > >
> > > > > > > > >  #define A7XX_APRIV_MASK (A6XX_CP_APRIV_CNTL_ICACHE | \
> > > > > > > > >  A6XX_CP_APRIV_CNTL_RBFETCH | \
> > > > > > > > > @@ -2356,6 +2358,26 @@ static void 
> > > > > > > > > a6xx_fault_detect_irq(struct msm_gpu *gpu)
> > > > > > > > > kthread_queue_work(gpu->worker, >recover_work);
> > > > > > > > >  }
> > > > > > > > >
> > > > > > > > > +static void a7xx_sw_fuse_violation_irq(struct msm_gpu *gpu)
> > > > > > > > > +{
> > > > > > > > > +   u32 status;
> > > > > > > > > +
> > > > > > > > > +   status = gpu_read(gpu, 
> > > > > > > > > REG_A7XX_RBBM_SW_FUSE_INT_STATUS);
> > > > > > > > > +   gpu_write(gpu, REG_A7XX_RBBM_SW_FUSE_INT_MASK, 0);
> > > > > > > > > +
> > > > > > > > > +   dev_err_ratelimited(>pdev->dev, "SW fuse 
> > > > > > > > > violation status=%8.8x\n", status);
> > > > > > > > > +
> > > > > > > > > +   /* Ignore FASTBLEND violations, because the HW will 
> > > > > > > > > silently fall back
> > > > > > > > > +* to legacy blending.
> > > > > > > > > +*/
> > > > > > > > > +   if (status & (A7XX_CX_MISC_SW_FUSE_VALUE_RAYTRACING |
> > > > > > > > > + A7XX_CX_MISC_SW_FUSE_VALUE_LPAC)) {
> > > > > > > > > +   del_timer(>hangcheck_timer);
> > > > > > > > > +
> > > > > > > > > +   kthread_queue_work(gpu->worker, 
> > > > > > > > > >recover_work);
> > > > > > > > > +   }
> > > > > > > > > +}
> > > > > > > > > +
> > > > > > > > >  static irqreturn_t a6xx_irq(struct msm_gpu *gpu)
> > > > > > > > >  {
> > > > > > > > > struct msm_drm_private *priv = gpu->dev->dev_private;
> > > > > > > > > @@ -2384,6 +2406,9 @@ static irqreturn_t a6xx_irq(struct 
> > > > > > > > > msm_gpu *gpu)
> > > > > > > > > if (status & A6XX_RBBM_INT_0_MASK_UCHE_OOB_ACCESS)
> > > > > > > > > dev_err_ratelimited(>pdev->dev, "UCHE | 
> > > > > > > > > Out of bounds access\n");
> > > > > > > > >
> > > > > > > > > +   if (status & A6XX_RBBM_INT_0_MASK_SWFUSEVIOLATION)
> > > > > > > > > +   

Re: [PATCH 4/6] drm/msm/a7xx: Initialize a750 "software fuse"

2024-04-26 Thread Connor Abbott
On Fri, Apr 26, 2024 at 4:24 PM Dmitry Baryshkov
 wrote:
>
> On Fri, 26 Apr 2024 at 18:08, Connor Abbott  wrote:
> >
> > On Fri, Apr 26, 2024 at 3:53 PM Dmitry Baryshkov
> >  wrote:
> > >
> > > On Fri, 26 Apr 2024 at 17:05, Connor Abbott  wrote:
> > > >
> > > > On Fri, Apr 26, 2024 at 2:31 PM Dmitry Baryshkov
> > > >  wrote:
> > > > >
> > > > > On Fri, 26 Apr 2024 at 15:35, Connor Abbott  
> > > > > wrote:
> > > > > >
> > > > > > On Fri, Apr 26, 2024 at 12:02 AM Dmitry Baryshkov
> > > > > >  wrote:
> > > > > > >
> > > > > > > On Thu, 25 Apr 2024 at 16:44, Connor Abbott  
> > > > > > > wrote:
> > > > > > > >
> > > > > > > > On all Qualcomm platforms with a7xx GPUs, qcom_scm provides a 
> > > > > > > > method to
> > > > > > > > initialize cx_mem. Copy this from downstream (minus BCL which we
> > > > > > > > currently don't support). On a750, this includes a new "fuse" 
> > > > > > > > register
> > > > > > > > which can be used by qcom_scm to fuse off certain features like
> > > > > > > > raytracing in software. The fuse is default off, and is 
> > > > > > > > initialized by
> > > > > > > > calling the method. Afterwards we have to read it to find out 
> > > > > > > > which
> > > > > > > > features were enabled.
> > > > > > > >
> > > > > > > > Signed-off-by: Connor Abbott 
> > > > > > > > ---
> > > > > > > >  drivers/gpu/drm/msm/adreno/a6xx_gpu.c   | 89 
> > > > > > > > -
> > > > > > > >  drivers/gpu/drm/msm/adreno/adreno_gpu.h |  2 +
> > > > > > > >  2 files changed, 90 insertions(+), 1 deletion(-)
> > > > > > > >
> > > > > > > > diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c 
> > > > > > > > b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> > > > > > > > index cf0b1de1c071..fb2722574ae5 100644
> > > > > > > > --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> > > > > > > > +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> > > > > > > > @@ -10,6 +10,7 @@
> > > > > > > >
> > > > > > > >  #include 
> > > > > > > >  #include 
> > > > > > > > +#include 
> > > > > > > >  #include 
> > > > > > > >  #include 
> > > > > > > >
> > > > > > > > @@ -1686,7 +1687,8 @@ static int a6xx_zap_shader_init(struct 
> > > > > > > > msm_gpu *gpu)
> > > > > > > >A6XX_RBBM_INT_0_MASK_RBBM_HANG_DETECT | \
> > > > > > > >A6XX_RBBM_INT_0_MASK_UCHE_OOB_ACCESS | \
> > > > > > > >A6XX_RBBM_INT_0_MASK_UCHE_TRAP_INTR | \
> > > > > > > > -  A6XX_RBBM_INT_0_MASK_TSBWRITEERROR)
> > > > > > > > +  A6XX_RBBM_INT_0_MASK_TSBWRITEERROR | \
> > > > > > > > +  A6XX_RBBM_INT_0_MASK_SWFUSEVIOLATION)
> > > > > > > >
> > > > > > > >  #define A7XX_APRIV_MASK (A6XX_CP_APRIV_CNTL_ICACHE | \
> > > > > > > >  A6XX_CP_APRIV_CNTL_RBFETCH | \
> > > > > > > > @@ -2356,6 +2358,26 @@ static void a6xx_fault_detect_irq(struct 
> > > > > > > > msm_gpu *gpu)
> > > > > > > > kthread_queue_work(gpu->worker, >recover_work);
> > > > > > > >  }
> > > > > > > >
> > > > > > > > +static void a7xx_sw_fuse_violation_irq(struct msm_gpu *gpu)
> > > > > > > > +{
> > > > > > > > +   u32 status;
> > > > > > > > +
> > > > > > > > +   status = gpu_read(gpu, 
> > > > > > > > REG_A7XX_RBBM_SW_FUSE_INT_STATUS);
> > > > > > > > +   gpu_write(gpu, REG_A7XX_RBBM_SW_FUSE_INT_MASK, 0);
> > > > > > > > +
> > > > > > > > +   dev_err_ratelimited(>pdev->dev, "SW fuse violation 
> > > > > > > > status=%8.8x\n", status);
> > > > > > > > +
> > > > > > > > +   /* Ignore FASTBLEND violations, because the HW will 
> > > > > > > > silently fall back
> > > > > > > > +* to legacy blending.
> > > > > > > > +*/
> > > > > > > > +   if (status & (A7XX_CX_MISC_SW_FUSE_VALUE_RAYTRACING |
> > > > > > > > + A7XX_CX_MISC_SW_FUSE_VALUE_LPAC)) {
> > > > > > > > +   del_timer(>hangcheck_timer);
> > > > > > > > +
> > > > > > > > +   kthread_queue_work(gpu->worker, 
> > > > > > > > >recover_work);
> > > > > > > > +   }
> > > > > > > > +}
> > > > > > > > +
> > > > > > > >  static irqreturn_t a6xx_irq(struct msm_gpu *gpu)
> > > > > > > >  {
> > > > > > > > struct msm_drm_private *priv = gpu->dev->dev_private;
> > > > > > > > @@ -2384,6 +2406,9 @@ static irqreturn_t a6xx_irq(struct 
> > > > > > > > msm_gpu *gpu)
> > > > > > > > if (status & A6XX_RBBM_INT_0_MASK_UCHE_OOB_ACCESS)
> > > > > > > > dev_err_ratelimited(>pdev->dev, "UCHE | 
> > > > > > > > Out of bounds access\n");
> > > > > > > >
> > > > > > > > +   if (status & A6XX_RBBM_INT_0_MASK_SWFUSEVIOLATION)
> > > > > > > > +   a7xx_sw_fuse_violation_irq(gpu);
> > > > > > > > +
> > > > > > > > if (status & A6XX_RBBM_INT_0_MASK_CP_CACHE_FLUSH_TS)
> > > > > > > > msm_gpu_retire(gpu);
> > > > > > > >
> > > > > > > > @@ -2525,6 +2550,60 @@ static void a6xx_llc_slices_init(struct 
> > > > > > > > platform_device *pdev,
> > > > > > > > 

Re: [PATCH 4/6] drm/msm/a7xx: Initialize a750 "software fuse"

2024-04-26 Thread Dmitry Baryshkov
On Fri, 26 Apr 2024 at 18:08, Connor Abbott  wrote:
>
> On Fri, Apr 26, 2024 at 3:53 PM Dmitry Baryshkov
>  wrote:
> >
> > On Fri, 26 Apr 2024 at 17:05, Connor Abbott  wrote:
> > >
> > > On Fri, Apr 26, 2024 at 2:31 PM Dmitry Baryshkov
> > >  wrote:
> > > >
> > > > On Fri, 26 Apr 2024 at 15:35, Connor Abbott  wrote:
> > > > >
> > > > > On Fri, Apr 26, 2024 at 12:02 AM Dmitry Baryshkov
> > > > >  wrote:
> > > > > >
> > > > > > On Thu, 25 Apr 2024 at 16:44, Connor Abbott  
> > > > > > wrote:
> > > > > > >
> > > > > > > On all Qualcomm platforms with a7xx GPUs, qcom_scm provides a 
> > > > > > > method to
> > > > > > > initialize cx_mem. Copy this from downstream (minus BCL which we
> > > > > > > currently don't support). On a750, this includes a new "fuse" 
> > > > > > > register
> > > > > > > which can be used by qcom_scm to fuse off certain features like
> > > > > > > raytracing in software. The fuse is default off, and is 
> > > > > > > initialized by
> > > > > > > calling the method. Afterwards we have to read it to find out 
> > > > > > > which
> > > > > > > features were enabled.
> > > > > > >
> > > > > > > Signed-off-by: Connor Abbott 
> > > > > > > ---
> > > > > > >  drivers/gpu/drm/msm/adreno/a6xx_gpu.c   | 89 
> > > > > > > -
> > > > > > >  drivers/gpu/drm/msm/adreno/adreno_gpu.h |  2 +
> > > > > > >  2 files changed, 90 insertions(+), 1 deletion(-)
> > > > > > >
> > > > > > > diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c 
> > > > > > > b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> > > > > > > index cf0b1de1c071..fb2722574ae5 100644
> > > > > > > --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> > > > > > > +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> > > > > > > @@ -10,6 +10,7 @@
> > > > > > >
> > > > > > >  #include 
> > > > > > >  #include 
> > > > > > > +#include 
> > > > > > >  #include 
> > > > > > >  #include 
> > > > > > >
> > > > > > > @@ -1686,7 +1687,8 @@ static int a6xx_zap_shader_init(struct 
> > > > > > > msm_gpu *gpu)
> > > > > > >A6XX_RBBM_INT_0_MASK_RBBM_HANG_DETECT | \
> > > > > > >A6XX_RBBM_INT_0_MASK_UCHE_OOB_ACCESS | \
> > > > > > >A6XX_RBBM_INT_0_MASK_UCHE_TRAP_INTR | \
> > > > > > > -  A6XX_RBBM_INT_0_MASK_TSBWRITEERROR)
> > > > > > > +  A6XX_RBBM_INT_0_MASK_TSBWRITEERROR | \
> > > > > > > +  A6XX_RBBM_INT_0_MASK_SWFUSEVIOLATION)
> > > > > > >
> > > > > > >  #define A7XX_APRIV_MASK (A6XX_CP_APRIV_CNTL_ICACHE | \
> > > > > > >  A6XX_CP_APRIV_CNTL_RBFETCH | \
> > > > > > > @@ -2356,6 +2358,26 @@ static void a6xx_fault_detect_irq(struct 
> > > > > > > msm_gpu *gpu)
> > > > > > > kthread_queue_work(gpu->worker, >recover_work);
> > > > > > >  }
> > > > > > >
> > > > > > > +static void a7xx_sw_fuse_violation_irq(struct msm_gpu *gpu)
> > > > > > > +{
> > > > > > > +   u32 status;
> > > > > > > +
> > > > > > > +   status = gpu_read(gpu, REG_A7XX_RBBM_SW_FUSE_INT_STATUS);
> > > > > > > +   gpu_write(gpu, REG_A7XX_RBBM_SW_FUSE_INT_MASK, 0);
> > > > > > > +
> > > > > > > +   dev_err_ratelimited(>pdev->dev, "SW fuse violation 
> > > > > > > status=%8.8x\n", status);
> > > > > > > +
> > > > > > > +   /* Ignore FASTBLEND violations, because the HW will 
> > > > > > > silently fall back
> > > > > > > +* to legacy blending.
> > > > > > > +*/
> > > > > > > +   if (status & (A7XX_CX_MISC_SW_FUSE_VALUE_RAYTRACING |
> > > > > > > + A7XX_CX_MISC_SW_FUSE_VALUE_LPAC)) {
> > > > > > > +   del_timer(>hangcheck_timer);
> > > > > > > +
> > > > > > > +   kthread_queue_work(gpu->worker, 
> > > > > > > >recover_work);
> > > > > > > +   }
> > > > > > > +}
> > > > > > > +
> > > > > > >  static irqreturn_t a6xx_irq(struct msm_gpu *gpu)
> > > > > > >  {
> > > > > > > struct msm_drm_private *priv = gpu->dev->dev_private;
> > > > > > > @@ -2384,6 +2406,9 @@ static irqreturn_t a6xx_irq(struct msm_gpu 
> > > > > > > *gpu)
> > > > > > > if (status & A6XX_RBBM_INT_0_MASK_UCHE_OOB_ACCESS)
> > > > > > > dev_err_ratelimited(>pdev->dev, "UCHE | Out 
> > > > > > > of bounds access\n");
> > > > > > >
> > > > > > > +   if (status & A6XX_RBBM_INT_0_MASK_SWFUSEVIOLATION)
> > > > > > > +   a7xx_sw_fuse_violation_irq(gpu);
> > > > > > > +
> > > > > > > if (status & A6XX_RBBM_INT_0_MASK_CP_CACHE_FLUSH_TS)
> > > > > > > msm_gpu_retire(gpu);
> > > > > > >
> > > > > > > @@ -2525,6 +2550,60 @@ static void a6xx_llc_slices_init(struct 
> > > > > > > platform_device *pdev,
> > > > > > > a6xx_gpu->llc_mmio = ERR_PTR(-EINVAL);
> > > > > > >  }
> > > > > > >
> > > > > > > +static int a7xx_cx_mem_init(struct a6xx_gpu *a6xx_gpu)
> > > > > > > +{
> > > > > > > +   struct adreno_gpu *adreno_gpu = _gpu->base;
> > > > > > > +   struct msm_gpu *gpu = _gpu->base;
> > > > > > > +   

Re: [PATCH 4/6] drm/msm/a7xx: Initialize a750 "software fuse"

2024-04-26 Thread Connor Abbott
On Fri, Apr 26, 2024 at 3:53 PM Dmitry Baryshkov
 wrote:
>
> On Fri, 26 Apr 2024 at 17:05, Connor Abbott  wrote:
> >
> > On Fri, Apr 26, 2024 at 2:31 PM Dmitry Baryshkov
> >  wrote:
> > >
> > > On Fri, 26 Apr 2024 at 15:35, Connor Abbott  wrote:
> > > >
> > > > On Fri, Apr 26, 2024 at 12:02 AM Dmitry Baryshkov
> > > >  wrote:
> > > > >
> > > > > On Thu, 25 Apr 2024 at 16:44, Connor Abbott  
> > > > > wrote:
> > > > > >
> > > > > > On all Qualcomm platforms with a7xx GPUs, qcom_scm provides a 
> > > > > > method to
> > > > > > initialize cx_mem. Copy this from downstream (minus BCL which we
> > > > > > currently don't support). On a750, this includes a new "fuse" 
> > > > > > register
> > > > > > which can be used by qcom_scm to fuse off certain features like
> > > > > > raytracing in software. The fuse is default off, and is initialized 
> > > > > > by
> > > > > > calling the method. Afterwards we have to read it to find out which
> > > > > > features were enabled.
> > > > > >
> > > > > > Signed-off-by: Connor Abbott 
> > > > > > ---
> > > > > >  drivers/gpu/drm/msm/adreno/a6xx_gpu.c   | 89 
> > > > > > -
> > > > > >  drivers/gpu/drm/msm/adreno/adreno_gpu.h |  2 +
> > > > > >  2 files changed, 90 insertions(+), 1 deletion(-)
> > > > > >
> > > > > > diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c 
> > > > > > b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> > > > > > index cf0b1de1c071..fb2722574ae5 100644
> > > > > > --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> > > > > > +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> > > > > > @@ -10,6 +10,7 @@
> > > > > >
> > > > > >  #include 
> > > > > >  #include 
> > > > > > +#include 
> > > > > >  #include 
> > > > > >  #include 
> > > > > >
> > > > > > @@ -1686,7 +1687,8 @@ static int a6xx_zap_shader_init(struct 
> > > > > > msm_gpu *gpu)
> > > > > >A6XX_RBBM_INT_0_MASK_RBBM_HANG_DETECT | \
> > > > > >A6XX_RBBM_INT_0_MASK_UCHE_OOB_ACCESS | \
> > > > > >A6XX_RBBM_INT_0_MASK_UCHE_TRAP_INTR | \
> > > > > > -  A6XX_RBBM_INT_0_MASK_TSBWRITEERROR)
> > > > > > +  A6XX_RBBM_INT_0_MASK_TSBWRITEERROR | \
> > > > > > +  A6XX_RBBM_INT_0_MASK_SWFUSEVIOLATION)
> > > > > >
> > > > > >  #define A7XX_APRIV_MASK (A6XX_CP_APRIV_CNTL_ICACHE | \
> > > > > >  A6XX_CP_APRIV_CNTL_RBFETCH | \
> > > > > > @@ -2356,6 +2358,26 @@ static void a6xx_fault_detect_irq(struct 
> > > > > > msm_gpu *gpu)
> > > > > > kthread_queue_work(gpu->worker, >recover_work);
> > > > > >  }
> > > > > >
> > > > > > +static void a7xx_sw_fuse_violation_irq(struct msm_gpu *gpu)
> > > > > > +{
> > > > > > +   u32 status;
> > > > > > +
> > > > > > +   status = gpu_read(gpu, REG_A7XX_RBBM_SW_FUSE_INT_STATUS);
> > > > > > +   gpu_write(gpu, REG_A7XX_RBBM_SW_FUSE_INT_MASK, 0);
> > > > > > +
> > > > > > +   dev_err_ratelimited(>pdev->dev, "SW fuse violation 
> > > > > > status=%8.8x\n", status);
> > > > > > +
> > > > > > +   /* Ignore FASTBLEND violations, because the HW will 
> > > > > > silently fall back
> > > > > > +* to legacy blending.
> > > > > > +*/
> > > > > > +   if (status & (A7XX_CX_MISC_SW_FUSE_VALUE_RAYTRACING |
> > > > > > + A7XX_CX_MISC_SW_FUSE_VALUE_LPAC)) {
> > > > > > +   del_timer(>hangcheck_timer);
> > > > > > +
> > > > > > +   kthread_queue_work(gpu->worker, >recover_work);
> > > > > > +   }
> > > > > > +}
> > > > > > +
> > > > > >  static irqreturn_t a6xx_irq(struct msm_gpu *gpu)
> > > > > >  {
> > > > > > struct msm_drm_private *priv = gpu->dev->dev_private;
> > > > > > @@ -2384,6 +2406,9 @@ static irqreturn_t a6xx_irq(struct msm_gpu 
> > > > > > *gpu)
> > > > > > if (status & A6XX_RBBM_INT_0_MASK_UCHE_OOB_ACCESS)
> > > > > > dev_err_ratelimited(>pdev->dev, "UCHE | Out of 
> > > > > > bounds access\n");
> > > > > >
> > > > > > +   if (status & A6XX_RBBM_INT_0_MASK_SWFUSEVIOLATION)
> > > > > > +   a7xx_sw_fuse_violation_irq(gpu);
> > > > > > +
> > > > > > if (status & A6XX_RBBM_INT_0_MASK_CP_CACHE_FLUSH_TS)
> > > > > > msm_gpu_retire(gpu);
> > > > > >
> > > > > > @@ -2525,6 +2550,60 @@ static void a6xx_llc_slices_init(struct 
> > > > > > platform_device *pdev,
> > > > > > a6xx_gpu->llc_mmio = ERR_PTR(-EINVAL);
> > > > > >  }
> > > > > >
> > > > > > +static int a7xx_cx_mem_init(struct a6xx_gpu *a6xx_gpu)
> > > > > > +{
> > > > > > +   struct adreno_gpu *adreno_gpu = _gpu->base;
> > > > > > +   struct msm_gpu *gpu = _gpu->base;
> > > > > > +   u32 gpu_req = QCOM_SCM_GPU_ALWAYS_EN_REQ;
> > > > > > +   u32 fuse_val;
> > > > > > +   int ret;
> > > > > > +
> > > > > > +   if (adreno_is_a740(adreno_gpu)) {
> > > > > > +   /* Raytracing is always enabled on a740 */
> > > > > > +   adreno_gpu->has_ray_tracing 

Re: [PATCH 4/6] drm/msm/a7xx: Initialize a750 "software fuse"

2024-04-26 Thread Dmitry Baryshkov
On Fri, 26 Apr 2024 at 17:05, Connor Abbott  wrote:
>
> On Fri, Apr 26, 2024 at 2:31 PM Dmitry Baryshkov
>  wrote:
> >
> > On Fri, 26 Apr 2024 at 15:35, Connor Abbott  wrote:
> > >
> > > On Fri, Apr 26, 2024 at 12:02 AM Dmitry Baryshkov
> > >  wrote:
> > > >
> > > > On Thu, 25 Apr 2024 at 16:44, Connor Abbott  wrote:
> > > > >
> > > > > On all Qualcomm platforms with a7xx GPUs, qcom_scm provides a method 
> > > > > to
> > > > > initialize cx_mem. Copy this from downstream (minus BCL which we
> > > > > currently don't support). On a750, this includes a new "fuse" register
> > > > > which can be used by qcom_scm to fuse off certain features like
> > > > > raytracing in software. The fuse is default off, and is initialized by
> > > > > calling the method. Afterwards we have to read it to find out which
> > > > > features were enabled.
> > > > >
> > > > > Signed-off-by: Connor Abbott 
> > > > > ---
> > > > >  drivers/gpu/drm/msm/adreno/a6xx_gpu.c   | 89 
> > > > > -
> > > > >  drivers/gpu/drm/msm/adreno/adreno_gpu.h |  2 +
> > > > >  2 files changed, 90 insertions(+), 1 deletion(-)
> > > > >
> > > > > diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c 
> > > > > b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> > > > > index cf0b1de1c071..fb2722574ae5 100644
> > > > > --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> > > > > +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> > > > > @@ -10,6 +10,7 @@
> > > > >
> > > > >  #include 
> > > > >  #include 
> > > > > +#include 
> > > > >  #include 
> > > > >  #include 
> > > > >
> > > > > @@ -1686,7 +1687,8 @@ static int a6xx_zap_shader_init(struct msm_gpu 
> > > > > *gpu)
> > > > >A6XX_RBBM_INT_0_MASK_RBBM_HANG_DETECT | \
> > > > >A6XX_RBBM_INT_0_MASK_UCHE_OOB_ACCESS | \
> > > > >A6XX_RBBM_INT_0_MASK_UCHE_TRAP_INTR | \
> > > > > -  A6XX_RBBM_INT_0_MASK_TSBWRITEERROR)
> > > > > +  A6XX_RBBM_INT_0_MASK_TSBWRITEERROR | \
> > > > > +  A6XX_RBBM_INT_0_MASK_SWFUSEVIOLATION)
> > > > >
> > > > >  #define A7XX_APRIV_MASK (A6XX_CP_APRIV_CNTL_ICACHE | \
> > > > >  A6XX_CP_APRIV_CNTL_RBFETCH | \
> > > > > @@ -2356,6 +2358,26 @@ static void a6xx_fault_detect_irq(struct 
> > > > > msm_gpu *gpu)
> > > > > kthread_queue_work(gpu->worker, >recover_work);
> > > > >  }
> > > > >
> > > > > +static void a7xx_sw_fuse_violation_irq(struct msm_gpu *gpu)
> > > > > +{
> > > > > +   u32 status;
> > > > > +
> > > > > +   status = gpu_read(gpu, REG_A7XX_RBBM_SW_FUSE_INT_STATUS);
> > > > > +   gpu_write(gpu, REG_A7XX_RBBM_SW_FUSE_INT_MASK, 0);
> > > > > +
> > > > > +   dev_err_ratelimited(>pdev->dev, "SW fuse violation 
> > > > > status=%8.8x\n", status);
> > > > > +
> > > > > +   /* Ignore FASTBLEND violations, because the HW will silently 
> > > > > fall back
> > > > > +* to legacy blending.
> > > > > +*/
> > > > > +   if (status & (A7XX_CX_MISC_SW_FUSE_VALUE_RAYTRACING |
> > > > > + A7XX_CX_MISC_SW_FUSE_VALUE_LPAC)) {
> > > > > +   del_timer(>hangcheck_timer);
> > > > > +
> > > > > +   kthread_queue_work(gpu->worker, >recover_work);
> > > > > +   }
> > > > > +}
> > > > > +
> > > > >  static irqreturn_t a6xx_irq(struct msm_gpu *gpu)
> > > > >  {
> > > > > struct msm_drm_private *priv = gpu->dev->dev_private;
> > > > > @@ -2384,6 +2406,9 @@ static irqreturn_t a6xx_irq(struct msm_gpu *gpu)
> > > > > if (status & A6XX_RBBM_INT_0_MASK_UCHE_OOB_ACCESS)
> > > > > dev_err_ratelimited(>pdev->dev, "UCHE | Out of 
> > > > > bounds access\n");
> > > > >
> > > > > +   if (status & A6XX_RBBM_INT_0_MASK_SWFUSEVIOLATION)
> > > > > +   a7xx_sw_fuse_violation_irq(gpu);
> > > > > +
> > > > > if (status & A6XX_RBBM_INT_0_MASK_CP_CACHE_FLUSH_TS)
> > > > > msm_gpu_retire(gpu);
> > > > >
> > > > > @@ -2525,6 +2550,60 @@ static void a6xx_llc_slices_init(struct 
> > > > > platform_device *pdev,
> > > > > a6xx_gpu->llc_mmio = ERR_PTR(-EINVAL);
> > > > >  }
> > > > >
> > > > > +static int a7xx_cx_mem_init(struct a6xx_gpu *a6xx_gpu)
> > > > > +{
> > > > > +   struct adreno_gpu *adreno_gpu = _gpu->base;
> > > > > +   struct msm_gpu *gpu = _gpu->base;
> > > > > +   u32 gpu_req = QCOM_SCM_GPU_ALWAYS_EN_REQ;
> > > > > +   u32 fuse_val;
> > > > > +   int ret;
> > > > > +
> > > > > +   if (adreno_is_a740(adreno_gpu)) {
> > > > > +   /* Raytracing is always enabled on a740 */
> > > > > +   adreno_gpu->has_ray_tracing = true;
> > > > > +   }
> > > > > +
> > > > > +   if (!qcom_scm_is_available()) {
> > > > > +   /* Assume that if qcom scm isn't available, that 
> > > > > whatever
> > > > > +* replacement allows writing the fuse register 
> > > > > ourselves.
> > > > > +* Users of 

Re: [PATCH 4/6] drm/msm/a7xx: Initialize a750 "software fuse"

2024-04-26 Thread Connor Abbott
On Fri, Apr 26, 2024 at 2:31 PM Dmitry Baryshkov
 wrote:
>
> On Fri, 26 Apr 2024 at 15:35, Connor Abbott  wrote:
> >
> > On Fri, Apr 26, 2024 at 12:02 AM Dmitry Baryshkov
> >  wrote:
> > >
> > > On Thu, 25 Apr 2024 at 16:44, Connor Abbott  wrote:
> > > >
> > > > On all Qualcomm platforms with a7xx GPUs, qcom_scm provides a method to
> > > > initialize cx_mem. Copy this from downstream (minus BCL which we
> > > > currently don't support). On a750, this includes a new "fuse" register
> > > > which can be used by qcom_scm to fuse off certain features like
> > > > raytracing in software. The fuse is default off, and is initialized by
> > > > calling the method. Afterwards we have to read it to find out which
> > > > features were enabled.
> > > >
> > > > Signed-off-by: Connor Abbott 
> > > > ---
> > > >  drivers/gpu/drm/msm/adreno/a6xx_gpu.c   | 89 -
> > > >  drivers/gpu/drm/msm/adreno/adreno_gpu.h |  2 +
> > > >  2 files changed, 90 insertions(+), 1 deletion(-)
> > > >
> > > > diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c 
> > > > b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> > > > index cf0b1de1c071..fb2722574ae5 100644
> > > > --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> > > > +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> > > > @@ -10,6 +10,7 @@
> > > >
> > > >  #include 
> > > >  #include 
> > > > +#include 
> > > >  #include 
> > > >  #include 
> > > >
> > > > @@ -1686,7 +1687,8 @@ static int a6xx_zap_shader_init(struct msm_gpu 
> > > > *gpu)
> > > >A6XX_RBBM_INT_0_MASK_RBBM_HANG_DETECT | \
> > > >A6XX_RBBM_INT_0_MASK_UCHE_OOB_ACCESS | \
> > > >A6XX_RBBM_INT_0_MASK_UCHE_TRAP_INTR | \
> > > > -  A6XX_RBBM_INT_0_MASK_TSBWRITEERROR)
> > > > +  A6XX_RBBM_INT_0_MASK_TSBWRITEERROR | \
> > > > +  A6XX_RBBM_INT_0_MASK_SWFUSEVIOLATION)
> > > >
> > > >  #define A7XX_APRIV_MASK (A6XX_CP_APRIV_CNTL_ICACHE | \
> > > >  A6XX_CP_APRIV_CNTL_RBFETCH | \
> > > > @@ -2356,6 +2358,26 @@ static void a6xx_fault_detect_irq(struct msm_gpu 
> > > > *gpu)
> > > > kthread_queue_work(gpu->worker, >recover_work);
> > > >  }
> > > >
> > > > +static void a7xx_sw_fuse_violation_irq(struct msm_gpu *gpu)
> > > > +{
> > > > +   u32 status;
> > > > +
> > > > +   status = gpu_read(gpu, REG_A7XX_RBBM_SW_FUSE_INT_STATUS);
> > > > +   gpu_write(gpu, REG_A7XX_RBBM_SW_FUSE_INT_MASK, 0);
> > > > +
> > > > +   dev_err_ratelimited(>pdev->dev, "SW fuse violation 
> > > > status=%8.8x\n", status);
> > > > +
> > > > +   /* Ignore FASTBLEND violations, because the HW will silently 
> > > > fall back
> > > > +* to legacy blending.
> > > > +*/
> > > > +   if (status & (A7XX_CX_MISC_SW_FUSE_VALUE_RAYTRACING |
> > > > + A7XX_CX_MISC_SW_FUSE_VALUE_LPAC)) {
> > > > +   del_timer(>hangcheck_timer);
> > > > +
> > > > +   kthread_queue_work(gpu->worker, >recover_work);
> > > > +   }
> > > > +}
> > > > +
> > > >  static irqreturn_t a6xx_irq(struct msm_gpu *gpu)
> > > >  {
> > > > struct msm_drm_private *priv = gpu->dev->dev_private;
> > > > @@ -2384,6 +2406,9 @@ static irqreturn_t a6xx_irq(struct msm_gpu *gpu)
> > > > if (status & A6XX_RBBM_INT_0_MASK_UCHE_OOB_ACCESS)
> > > > dev_err_ratelimited(>pdev->dev, "UCHE | Out of 
> > > > bounds access\n");
> > > >
> > > > +   if (status & A6XX_RBBM_INT_0_MASK_SWFUSEVIOLATION)
> > > > +   a7xx_sw_fuse_violation_irq(gpu);
> > > > +
> > > > if (status & A6XX_RBBM_INT_0_MASK_CP_CACHE_FLUSH_TS)
> > > > msm_gpu_retire(gpu);
> > > >
> > > > @@ -2525,6 +2550,60 @@ static void a6xx_llc_slices_init(struct 
> > > > platform_device *pdev,
> > > > a6xx_gpu->llc_mmio = ERR_PTR(-EINVAL);
> > > >  }
> > > >
> > > > +static int a7xx_cx_mem_init(struct a6xx_gpu *a6xx_gpu)
> > > > +{
> > > > +   struct adreno_gpu *adreno_gpu = _gpu->base;
> > > > +   struct msm_gpu *gpu = _gpu->base;
> > > > +   u32 gpu_req = QCOM_SCM_GPU_ALWAYS_EN_REQ;
> > > > +   u32 fuse_val;
> > > > +   int ret;
> > > > +
> > > > +   if (adreno_is_a740(adreno_gpu)) {
> > > > +   /* Raytracing is always enabled on a740 */
> > > > +   adreno_gpu->has_ray_tracing = true;
> > > > +   }
> > > > +
> > > > +   if (!qcom_scm_is_available()) {
> > > > +   /* Assume that if qcom scm isn't available, that 
> > > > whatever
> > > > +* replacement allows writing the fuse register 
> > > > ourselves.
> > > > +* Users of alternative firmware need to make sure this
> > > > +* register is writeable or indicate that it's not 
> > > > somehow.
> > > > +* Print a warning because if you mess this up you're 
> > > > about to
> > > > +* crash horribly.
> > > > +*/
> > > 

Re: [PATCH 4/6] drm/msm/a7xx: Initialize a750 "software fuse"

2024-04-26 Thread Dmitry Baryshkov
On Fri, 26 Apr 2024 at 15:54, Connor Abbott  wrote:
>
> On Fri, Apr 26, 2024 at 1:35 PM Connor Abbott  wrote:
> >
> > On Fri, Apr 26, 2024 at 12:02 AM Dmitry Baryshkov
> >  wrote:
> > >
> > > On Thu, 25 Apr 2024 at 16:44, Connor Abbott  wrote:
> > > >
> > > > On all Qualcomm platforms with a7xx GPUs, qcom_scm provides a method to
> > > > initialize cx_mem. Copy this from downstream (minus BCL which we
> > > > currently don't support). On a750, this includes a new "fuse" register
> > > > which can be used by qcom_scm to fuse off certain features like
> > > > raytracing in software. The fuse is default off, and is initialized by
> > > > calling the method. Afterwards we have to read it to find out which
> > > > features were enabled.
> > > >
> > > > Signed-off-by: Connor Abbott 
> > > > ---
> > > >  drivers/gpu/drm/msm/adreno/a6xx_gpu.c   | 89 -
> > > >  drivers/gpu/drm/msm/adreno/adreno_gpu.h |  2 +
> > > >  2 files changed, 90 insertions(+), 1 deletion(-)
> > > >
> > > > diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c 
> > > > b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> > > > index cf0b1de1c071..fb2722574ae5 100644
> > > > --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> > > > +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> > > > @@ -10,6 +10,7 @@
> > > >
> > > >  #include 
> > > >  #include 
> > > > +#include 
> > > >  #include 
> > > >  #include 
> > > >
> > > > @@ -1686,7 +1687,8 @@ static int a6xx_zap_shader_init(struct msm_gpu 
> > > > *gpu)
> > > >A6XX_RBBM_INT_0_MASK_RBBM_HANG_DETECT | \
> > > >A6XX_RBBM_INT_0_MASK_UCHE_OOB_ACCESS | \
> > > >A6XX_RBBM_INT_0_MASK_UCHE_TRAP_INTR | \
> > > > -  A6XX_RBBM_INT_0_MASK_TSBWRITEERROR)
> > > > +  A6XX_RBBM_INT_0_MASK_TSBWRITEERROR | \
> > > > +  A6XX_RBBM_INT_0_MASK_SWFUSEVIOLATION)
> > > >
> > > >  #define A7XX_APRIV_MASK (A6XX_CP_APRIV_CNTL_ICACHE | \
> > > >  A6XX_CP_APRIV_CNTL_RBFETCH | \
> > > > @@ -2356,6 +2358,26 @@ static void a6xx_fault_detect_irq(struct msm_gpu 
> > > > *gpu)
> > > > kthread_queue_work(gpu->worker, >recover_work);
> > > >  }
> > > >
> > > > +static void a7xx_sw_fuse_violation_irq(struct msm_gpu *gpu)
> > > > +{
> > > > +   u32 status;
> > > > +
> > > > +   status = gpu_read(gpu, REG_A7XX_RBBM_SW_FUSE_INT_STATUS);
> > > > +   gpu_write(gpu, REG_A7XX_RBBM_SW_FUSE_INT_MASK, 0);
> > > > +
> > > > +   dev_err_ratelimited(>pdev->dev, "SW fuse violation 
> > > > status=%8.8x\n", status);
> > > > +
> > > > +   /* Ignore FASTBLEND violations, because the HW will silently 
> > > > fall back
> > > > +* to legacy blending.
> > > > +*/
> > > > +   if (status & (A7XX_CX_MISC_SW_FUSE_VALUE_RAYTRACING |
> > > > + A7XX_CX_MISC_SW_FUSE_VALUE_LPAC)) {
> > > > +   del_timer(>hangcheck_timer);
> > > > +
> > > > +   kthread_queue_work(gpu->worker, >recover_work);
> > > > +   }
> > > > +}
> > > > +
> > > >  static irqreturn_t a6xx_irq(struct msm_gpu *gpu)
> > > >  {
> > > > struct msm_drm_private *priv = gpu->dev->dev_private;
> > > > @@ -2384,6 +2406,9 @@ static irqreturn_t a6xx_irq(struct msm_gpu *gpu)
> > > > if (status & A6XX_RBBM_INT_0_MASK_UCHE_OOB_ACCESS)
> > > > dev_err_ratelimited(>pdev->dev, "UCHE | Out of 
> > > > bounds access\n");
> > > >
> > > > +   if (status & A6XX_RBBM_INT_0_MASK_SWFUSEVIOLATION)
> > > > +   a7xx_sw_fuse_violation_irq(gpu);
> > > > +
> > > > if (status & A6XX_RBBM_INT_0_MASK_CP_CACHE_FLUSH_TS)
> > > > msm_gpu_retire(gpu);
> > > >
> > > > @@ -2525,6 +2550,60 @@ static void a6xx_llc_slices_init(struct 
> > > > platform_device *pdev,
> > > > a6xx_gpu->llc_mmio = ERR_PTR(-EINVAL);
> > > >  }
> > > >
> > > > +static int a7xx_cx_mem_init(struct a6xx_gpu *a6xx_gpu)
> > > > +{
> > > > +   struct adreno_gpu *adreno_gpu = _gpu->base;
> > > > +   struct msm_gpu *gpu = _gpu->base;
> > > > +   u32 gpu_req = QCOM_SCM_GPU_ALWAYS_EN_REQ;
> > > > +   u32 fuse_val;
> > > > +   int ret;
> > > > +
> > > > +   if (adreno_is_a740(adreno_gpu)) {
> > > > +   /* Raytracing is always enabled on a740 */
> > > > +   adreno_gpu->has_ray_tracing = true;
> > > > +   }
> > > > +
> > > > +   if (!qcom_scm_is_available()) {
> > > > +   /* Assume that if qcom scm isn't available, that 
> > > > whatever
> > > > +* replacement allows writing the fuse register 
> > > > ourselves.
> > > > +* Users of alternative firmware need to make sure this
> > > > +* register is writeable or indicate that it's not 
> > > > somehow.
> > > > +* Print a warning because if you mess this up you're 
> > > > about to
> > > > +* crash horribly.
> > > > +*/
> > > > 

Re: [PATCH 4/6] drm/msm/a7xx: Initialize a750 "software fuse"

2024-04-26 Thread Dmitry Baryshkov
On Fri, 26 Apr 2024 at 15:35, Connor Abbott  wrote:
>
> On Fri, Apr 26, 2024 at 12:02 AM Dmitry Baryshkov
>  wrote:
> >
> > On Thu, 25 Apr 2024 at 16:44, Connor Abbott  wrote:
> > >
> > > On all Qualcomm platforms with a7xx GPUs, qcom_scm provides a method to
> > > initialize cx_mem. Copy this from downstream (minus BCL which we
> > > currently don't support). On a750, this includes a new "fuse" register
> > > which can be used by qcom_scm to fuse off certain features like
> > > raytracing in software. The fuse is default off, and is initialized by
> > > calling the method. Afterwards we have to read it to find out which
> > > features were enabled.
> > >
> > > Signed-off-by: Connor Abbott 
> > > ---
> > >  drivers/gpu/drm/msm/adreno/a6xx_gpu.c   | 89 -
> > >  drivers/gpu/drm/msm/adreno/adreno_gpu.h |  2 +
> > >  2 files changed, 90 insertions(+), 1 deletion(-)
> > >
> > > diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c 
> > > b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> > > index cf0b1de1c071..fb2722574ae5 100644
> > > --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> > > +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> > > @@ -10,6 +10,7 @@
> > >
> > >  #include 
> > >  #include 
> > > +#include 
> > >  #include 
> > >  #include 
> > >
> > > @@ -1686,7 +1687,8 @@ static int a6xx_zap_shader_init(struct msm_gpu *gpu)
> > >A6XX_RBBM_INT_0_MASK_RBBM_HANG_DETECT | \
> > >A6XX_RBBM_INT_0_MASK_UCHE_OOB_ACCESS | \
> > >A6XX_RBBM_INT_0_MASK_UCHE_TRAP_INTR | \
> > > -  A6XX_RBBM_INT_0_MASK_TSBWRITEERROR)
> > > +  A6XX_RBBM_INT_0_MASK_TSBWRITEERROR | \
> > > +  A6XX_RBBM_INT_0_MASK_SWFUSEVIOLATION)
> > >
> > >  #define A7XX_APRIV_MASK (A6XX_CP_APRIV_CNTL_ICACHE | \
> > >  A6XX_CP_APRIV_CNTL_RBFETCH | \
> > > @@ -2356,6 +2358,26 @@ static void a6xx_fault_detect_irq(struct msm_gpu 
> > > *gpu)
> > > kthread_queue_work(gpu->worker, >recover_work);
> > >  }
> > >
> > > +static void a7xx_sw_fuse_violation_irq(struct msm_gpu *gpu)
> > > +{
> > > +   u32 status;
> > > +
> > > +   status = gpu_read(gpu, REG_A7XX_RBBM_SW_FUSE_INT_STATUS);
> > > +   gpu_write(gpu, REG_A7XX_RBBM_SW_FUSE_INT_MASK, 0);
> > > +
> > > +   dev_err_ratelimited(>pdev->dev, "SW fuse violation 
> > > status=%8.8x\n", status);
> > > +
> > > +   /* Ignore FASTBLEND violations, because the HW will silently fall 
> > > back
> > > +* to legacy blending.
> > > +*/
> > > +   if (status & (A7XX_CX_MISC_SW_FUSE_VALUE_RAYTRACING |
> > > + A7XX_CX_MISC_SW_FUSE_VALUE_LPAC)) {
> > > +   del_timer(>hangcheck_timer);
> > > +
> > > +   kthread_queue_work(gpu->worker, >recover_work);
> > > +   }
> > > +}
> > > +
> > >  static irqreturn_t a6xx_irq(struct msm_gpu *gpu)
> > >  {
> > > struct msm_drm_private *priv = gpu->dev->dev_private;
> > > @@ -2384,6 +2406,9 @@ static irqreturn_t a6xx_irq(struct msm_gpu *gpu)
> > > if (status & A6XX_RBBM_INT_0_MASK_UCHE_OOB_ACCESS)
> > > dev_err_ratelimited(>pdev->dev, "UCHE | Out of 
> > > bounds access\n");
> > >
> > > +   if (status & A6XX_RBBM_INT_0_MASK_SWFUSEVIOLATION)
> > > +   a7xx_sw_fuse_violation_irq(gpu);
> > > +
> > > if (status & A6XX_RBBM_INT_0_MASK_CP_CACHE_FLUSH_TS)
> > > msm_gpu_retire(gpu);
> > >
> > > @@ -2525,6 +2550,60 @@ static void a6xx_llc_slices_init(struct 
> > > platform_device *pdev,
> > > a6xx_gpu->llc_mmio = ERR_PTR(-EINVAL);
> > >  }
> > >
> > > +static int a7xx_cx_mem_init(struct a6xx_gpu *a6xx_gpu)
> > > +{
> > > +   struct adreno_gpu *adreno_gpu = _gpu->base;
> > > +   struct msm_gpu *gpu = _gpu->base;
> > > +   u32 gpu_req = QCOM_SCM_GPU_ALWAYS_EN_REQ;
> > > +   u32 fuse_val;
> > > +   int ret;
> > > +
> > > +   if (adreno_is_a740(adreno_gpu)) {
> > > +   /* Raytracing is always enabled on a740 */
> > > +   adreno_gpu->has_ray_tracing = true;
> > > +   }
> > > +
> > > +   if (!qcom_scm_is_available()) {
> > > +   /* Assume that if qcom scm isn't available, that whatever
> > > +* replacement allows writing the fuse register ourselves.
> > > +* Users of alternative firmware need to make sure this
> > > +* register is writeable or indicate that it's not 
> > > somehow.
> > > +* Print a warning because if you mess this up you're 
> > > about to
> > > +* crash horribly.
> > > +*/
> > > +   if (adreno_is_a750(adreno_gpu)) {
> > > +   dev_warn_once(gpu->dev->dev,
> > > +   "SCM is not available, poking fuse 
> > > register\n");
> > > +   a6xx_llc_write(a6xx_gpu, 
> > > REG_A7XX_CX_MISC_SW_FUSE_VALUE,
> > > +

Re: [PATCH 4/6] drm/msm/a7xx: Initialize a750 "software fuse"

2024-04-26 Thread Dmitry Baryshkov
On Fri, 26 Apr 2024 at 15:46, Rob Clark  wrote:
>
> On Thu, Apr 25, 2024 at 4:02 PM Dmitry Baryshkov
>  wrote:
> >
> > On Thu, 25 Apr 2024 at 16:44, Connor Abbott  wrote:
> > >
> > > On all Qualcomm platforms with a7xx GPUs, qcom_scm provides a method to
> > > initialize cx_mem. Copy this from downstream (minus BCL which we
> > > currently don't support). On a750, this includes a new "fuse" register
> > > which can be used by qcom_scm to fuse off certain features like
> > > raytracing in software. The fuse is default off, and is initialized by
> > > calling the method. Afterwards we have to read it to find out which
> > > features were enabled.
> > >
> > > Signed-off-by: Connor Abbott 
> > > ---
> > >  drivers/gpu/drm/msm/adreno/a6xx_gpu.c   | 89 -
> > >  drivers/gpu/drm/msm/adreno/adreno_gpu.h |  2 +
> > >  2 files changed, 90 insertions(+), 1 deletion(-)
> > >

[...]

> > > +   gpu_req |= QCOM_SCM_GPU_TSENSE_EN_REQ;
> > > +
> > > +   ret = qcom_scm_gpu_init_regs(gpu_req);
> > > +   if (ret)
> > > +   return ret;
> > > +
> > > +   /* On a750 raytracing may be disabled by the firmware, find out 
> > > whether
> > > +* that's the case. The scm call above sets the fuse register.
> > > +*/
> > > +   if (adreno_is_a750(adreno_gpu)) {
> > > +   fuse_val = a6xx_llc_read(a6xx_gpu, 
> > > REG_A7XX_CX_MISC_SW_FUSE_VALUE);
> >
> > This register isn't accessible with the current sm8650.dtsi. Since DT
> > and driver are going through different trees, please add safety guards
> > here, so that the driver doesn't crash if used with older dtsi
> > (not to mention that dts is considered to be an ABI and newer kernels
> > are supposed not to break with older DT files).
>
> I'd be happy if older kernels consistently worked with newer dtb, the
> other direction is too much to ask.

Well, we guarantee that newer kernels work with older dts.

>  If necessary we can ask for ack
> to land the dts fix thru msm-next somehow, but since the gpu is newly
> enabled device landing in the same merge window I think that is not
> necessary.

This might work too.

-- 
With best wishes
Dmitry


Re: [PATCH 4/6] drm/msm/a7xx: Initialize a750 "software fuse"

2024-04-26 Thread Connor Abbott
On Fri, Apr 26, 2024 at 1:35 PM Connor Abbott  wrote:
>
> On Fri, Apr 26, 2024 at 12:02 AM Dmitry Baryshkov
>  wrote:
> >
> > On Thu, 25 Apr 2024 at 16:44, Connor Abbott  wrote:
> > >
> > > On all Qualcomm platforms with a7xx GPUs, qcom_scm provides a method to
> > > initialize cx_mem. Copy this from downstream (minus BCL which we
> > > currently don't support). On a750, this includes a new "fuse" register
> > > which can be used by qcom_scm to fuse off certain features like
> > > raytracing in software. The fuse is default off, and is initialized by
> > > calling the method. Afterwards we have to read it to find out which
> > > features were enabled.
> > >
> > > Signed-off-by: Connor Abbott 
> > > ---
> > >  drivers/gpu/drm/msm/adreno/a6xx_gpu.c   | 89 -
> > >  drivers/gpu/drm/msm/adreno/adreno_gpu.h |  2 +
> > >  2 files changed, 90 insertions(+), 1 deletion(-)
> > >
> > > diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c 
> > > b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> > > index cf0b1de1c071..fb2722574ae5 100644
> > > --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> > > +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> > > @@ -10,6 +10,7 @@
> > >
> > >  #include 
> > >  #include 
> > > +#include 
> > >  #include 
> > >  #include 
> > >
> > > @@ -1686,7 +1687,8 @@ static int a6xx_zap_shader_init(struct msm_gpu *gpu)
> > >A6XX_RBBM_INT_0_MASK_RBBM_HANG_DETECT | \
> > >A6XX_RBBM_INT_0_MASK_UCHE_OOB_ACCESS | \
> > >A6XX_RBBM_INT_0_MASK_UCHE_TRAP_INTR | \
> > > -  A6XX_RBBM_INT_0_MASK_TSBWRITEERROR)
> > > +  A6XX_RBBM_INT_0_MASK_TSBWRITEERROR | \
> > > +  A6XX_RBBM_INT_0_MASK_SWFUSEVIOLATION)
> > >
> > >  #define A7XX_APRIV_MASK (A6XX_CP_APRIV_CNTL_ICACHE | \
> > >  A6XX_CP_APRIV_CNTL_RBFETCH | \
> > > @@ -2356,6 +2358,26 @@ static void a6xx_fault_detect_irq(struct msm_gpu 
> > > *gpu)
> > > kthread_queue_work(gpu->worker, >recover_work);
> > >  }
> > >
> > > +static void a7xx_sw_fuse_violation_irq(struct msm_gpu *gpu)
> > > +{
> > > +   u32 status;
> > > +
> > > +   status = gpu_read(gpu, REG_A7XX_RBBM_SW_FUSE_INT_STATUS);
> > > +   gpu_write(gpu, REG_A7XX_RBBM_SW_FUSE_INT_MASK, 0);
> > > +
> > > +   dev_err_ratelimited(>pdev->dev, "SW fuse violation 
> > > status=%8.8x\n", status);
> > > +
> > > +   /* Ignore FASTBLEND violations, because the HW will silently fall 
> > > back
> > > +* to legacy blending.
> > > +*/
> > > +   if (status & (A7XX_CX_MISC_SW_FUSE_VALUE_RAYTRACING |
> > > + A7XX_CX_MISC_SW_FUSE_VALUE_LPAC)) {
> > > +   del_timer(>hangcheck_timer);
> > > +
> > > +   kthread_queue_work(gpu->worker, >recover_work);
> > > +   }
> > > +}
> > > +
> > >  static irqreturn_t a6xx_irq(struct msm_gpu *gpu)
> > >  {
> > > struct msm_drm_private *priv = gpu->dev->dev_private;
> > > @@ -2384,6 +2406,9 @@ static irqreturn_t a6xx_irq(struct msm_gpu *gpu)
> > > if (status & A6XX_RBBM_INT_0_MASK_UCHE_OOB_ACCESS)
> > > dev_err_ratelimited(>pdev->dev, "UCHE | Out of 
> > > bounds access\n");
> > >
> > > +   if (status & A6XX_RBBM_INT_0_MASK_SWFUSEVIOLATION)
> > > +   a7xx_sw_fuse_violation_irq(gpu);
> > > +
> > > if (status & A6XX_RBBM_INT_0_MASK_CP_CACHE_FLUSH_TS)
> > > msm_gpu_retire(gpu);
> > >
> > > @@ -2525,6 +2550,60 @@ static void a6xx_llc_slices_init(struct 
> > > platform_device *pdev,
> > > a6xx_gpu->llc_mmio = ERR_PTR(-EINVAL);
> > >  }
> > >
> > > +static int a7xx_cx_mem_init(struct a6xx_gpu *a6xx_gpu)
> > > +{
> > > +   struct adreno_gpu *adreno_gpu = _gpu->base;
> > > +   struct msm_gpu *gpu = _gpu->base;
> > > +   u32 gpu_req = QCOM_SCM_GPU_ALWAYS_EN_REQ;
> > > +   u32 fuse_val;
> > > +   int ret;
> > > +
> > > +   if (adreno_is_a740(adreno_gpu)) {
> > > +   /* Raytracing is always enabled on a740 */
> > > +   adreno_gpu->has_ray_tracing = true;
> > > +   }
> > > +
> > > +   if (!qcom_scm_is_available()) {
> > > +   /* Assume that if qcom scm isn't available, that whatever
> > > +* replacement allows writing the fuse register ourselves.
> > > +* Users of alternative firmware need to make sure this
> > > +* register is writeable or indicate that it's not 
> > > somehow.
> > > +* Print a warning because if you mess this up you're 
> > > about to
> > > +* crash horribly.
> > > +*/
> > > +   if (adreno_is_a750(adreno_gpu)) {
> > > +   dev_warn_once(gpu->dev->dev,
> > > +   "SCM is not available, poking fuse 
> > > register\n");
> > > +   a6xx_llc_write(a6xx_gpu, 
> > > REG_A7XX_CX_MISC_SW_FUSE_VALUE,
> > > +  

Re: [PATCH 4/6] drm/msm/a7xx: Initialize a750 "software fuse"

2024-04-26 Thread Rob Clark
On Thu, Apr 25, 2024 at 4:02 PM Dmitry Baryshkov
 wrote:
>
> On Thu, 25 Apr 2024 at 16:44, Connor Abbott  wrote:
> >
> > On all Qualcomm platforms with a7xx GPUs, qcom_scm provides a method to
> > initialize cx_mem. Copy this from downstream (minus BCL which we
> > currently don't support). On a750, this includes a new "fuse" register
> > which can be used by qcom_scm to fuse off certain features like
> > raytracing in software. The fuse is default off, and is initialized by
> > calling the method. Afterwards we have to read it to find out which
> > features were enabled.
> >
> > Signed-off-by: Connor Abbott 
> > ---
> >  drivers/gpu/drm/msm/adreno/a6xx_gpu.c   | 89 -
> >  drivers/gpu/drm/msm/adreno/adreno_gpu.h |  2 +
> >  2 files changed, 90 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c 
> > b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> > index cf0b1de1c071..fb2722574ae5 100644
> > --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> > +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> > @@ -10,6 +10,7 @@
> >
> >  #include 
> >  #include 
> > +#include 
> >  #include 
> >  #include 
> >
> > @@ -1686,7 +1687,8 @@ static int a6xx_zap_shader_init(struct msm_gpu *gpu)
> >A6XX_RBBM_INT_0_MASK_RBBM_HANG_DETECT | \
> >A6XX_RBBM_INT_0_MASK_UCHE_OOB_ACCESS | \
> >A6XX_RBBM_INT_0_MASK_UCHE_TRAP_INTR | \
> > -  A6XX_RBBM_INT_0_MASK_TSBWRITEERROR)
> > +  A6XX_RBBM_INT_0_MASK_TSBWRITEERROR | \
> > +  A6XX_RBBM_INT_0_MASK_SWFUSEVIOLATION)
> >
> >  #define A7XX_APRIV_MASK (A6XX_CP_APRIV_CNTL_ICACHE | \
> >  A6XX_CP_APRIV_CNTL_RBFETCH | \
> > @@ -2356,6 +2358,26 @@ static void a6xx_fault_detect_irq(struct msm_gpu 
> > *gpu)
> > kthread_queue_work(gpu->worker, >recover_work);
> >  }
> >
> > +static void a7xx_sw_fuse_violation_irq(struct msm_gpu *gpu)
> > +{
> > +   u32 status;
> > +
> > +   status = gpu_read(gpu, REG_A7XX_RBBM_SW_FUSE_INT_STATUS);
> > +   gpu_write(gpu, REG_A7XX_RBBM_SW_FUSE_INT_MASK, 0);
> > +
> > +   dev_err_ratelimited(>pdev->dev, "SW fuse violation 
> > status=%8.8x\n", status);
> > +
> > +   /* Ignore FASTBLEND violations, because the HW will silently fall 
> > back
> > +* to legacy blending.
> > +*/
> > +   if (status & (A7XX_CX_MISC_SW_FUSE_VALUE_RAYTRACING |
> > + A7XX_CX_MISC_SW_FUSE_VALUE_LPAC)) {
> > +   del_timer(>hangcheck_timer);
> > +
> > +   kthread_queue_work(gpu->worker, >recover_work);
> > +   }
> > +}
> > +
> >  static irqreturn_t a6xx_irq(struct msm_gpu *gpu)
> >  {
> > struct msm_drm_private *priv = gpu->dev->dev_private;
> > @@ -2384,6 +2406,9 @@ static irqreturn_t a6xx_irq(struct msm_gpu *gpu)
> > if (status & A6XX_RBBM_INT_0_MASK_UCHE_OOB_ACCESS)
> > dev_err_ratelimited(>pdev->dev, "UCHE | Out of bounds 
> > access\n");
> >
> > +   if (status & A6XX_RBBM_INT_0_MASK_SWFUSEVIOLATION)
> > +   a7xx_sw_fuse_violation_irq(gpu);
> > +
> > if (status & A6XX_RBBM_INT_0_MASK_CP_CACHE_FLUSH_TS)
> > msm_gpu_retire(gpu);
> >
> > @@ -2525,6 +2550,60 @@ static void a6xx_llc_slices_init(struct 
> > platform_device *pdev,
> > a6xx_gpu->llc_mmio = ERR_PTR(-EINVAL);
> >  }
> >
> > +static int a7xx_cx_mem_init(struct a6xx_gpu *a6xx_gpu)
> > +{
> > +   struct adreno_gpu *adreno_gpu = _gpu->base;
> > +   struct msm_gpu *gpu = _gpu->base;
> > +   u32 gpu_req = QCOM_SCM_GPU_ALWAYS_EN_REQ;
> > +   u32 fuse_val;
> > +   int ret;
> > +
> > +   if (adreno_is_a740(adreno_gpu)) {
> > +   /* Raytracing is always enabled on a740 */
> > +   adreno_gpu->has_ray_tracing = true;
> > +   }
> > +
> > +   if (!qcom_scm_is_available()) {
> > +   /* Assume that if qcom scm isn't available, that whatever
> > +* replacement allows writing the fuse register ourselves.
> > +* Users of alternative firmware need to make sure this
> > +* register is writeable or indicate that it's not somehow.
> > +* Print a warning because if you mess this up you're about 
> > to
> > +* crash horribly.
> > +*/
> > +   if (adreno_is_a750(adreno_gpu)) {
> > +   dev_warn_once(gpu->dev->dev,
> > +   "SCM is not available, poking fuse 
> > register\n");
> > +   a6xx_llc_write(a6xx_gpu, 
> > REG_A7XX_CX_MISC_SW_FUSE_VALUE,
> > +   A7XX_CX_MISC_SW_FUSE_VALUE_RAYTRACING |
> > +   A7XX_CX_MISC_SW_FUSE_VALUE_FASTBLEND |
> > +   A7XX_CX_MISC_SW_FUSE_VALUE_LPAC);
> > +   adreno_gpu->has_ray_tracing = true;
> > +   }
> 

Re: [PATCH 4/6] drm/msm/a7xx: Initialize a750 "software fuse"

2024-04-26 Thread Connor Abbott
On Fri, Apr 26, 2024 at 12:02 AM Dmitry Baryshkov
 wrote:
>
> On Thu, 25 Apr 2024 at 16:44, Connor Abbott  wrote:
> >
> > On all Qualcomm platforms with a7xx GPUs, qcom_scm provides a method to
> > initialize cx_mem. Copy this from downstream (minus BCL which we
> > currently don't support). On a750, this includes a new "fuse" register
> > which can be used by qcom_scm to fuse off certain features like
> > raytracing in software. The fuse is default off, and is initialized by
> > calling the method. Afterwards we have to read it to find out which
> > features were enabled.
> >
> > Signed-off-by: Connor Abbott 
> > ---
> >  drivers/gpu/drm/msm/adreno/a6xx_gpu.c   | 89 -
> >  drivers/gpu/drm/msm/adreno/adreno_gpu.h |  2 +
> >  2 files changed, 90 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c 
> > b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> > index cf0b1de1c071..fb2722574ae5 100644
> > --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> > +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> > @@ -10,6 +10,7 @@
> >
> >  #include 
> >  #include 
> > +#include 
> >  #include 
> >  #include 
> >
> > @@ -1686,7 +1687,8 @@ static int a6xx_zap_shader_init(struct msm_gpu *gpu)
> >A6XX_RBBM_INT_0_MASK_RBBM_HANG_DETECT | \
> >A6XX_RBBM_INT_0_MASK_UCHE_OOB_ACCESS | \
> >A6XX_RBBM_INT_0_MASK_UCHE_TRAP_INTR | \
> > -  A6XX_RBBM_INT_0_MASK_TSBWRITEERROR)
> > +  A6XX_RBBM_INT_0_MASK_TSBWRITEERROR | \
> > +  A6XX_RBBM_INT_0_MASK_SWFUSEVIOLATION)
> >
> >  #define A7XX_APRIV_MASK (A6XX_CP_APRIV_CNTL_ICACHE | \
> >  A6XX_CP_APRIV_CNTL_RBFETCH | \
> > @@ -2356,6 +2358,26 @@ static void a6xx_fault_detect_irq(struct msm_gpu 
> > *gpu)
> > kthread_queue_work(gpu->worker, >recover_work);
> >  }
> >
> > +static void a7xx_sw_fuse_violation_irq(struct msm_gpu *gpu)
> > +{
> > +   u32 status;
> > +
> > +   status = gpu_read(gpu, REG_A7XX_RBBM_SW_FUSE_INT_STATUS);
> > +   gpu_write(gpu, REG_A7XX_RBBM_SW_FUSE_INT_MASK, 0);
> > +
> > +   dev_err_ratelimited(>pdev->dev, "SW fuse violation 
> > status=%8.8x\n", status);
> > +
> > +   /* Ignore FASTBLEND violations, because the HW will silently fall 
> > back
> > +* to legacy blending.
> > +*/
> > +   if (status & (A7XX_CX_MISC_SW_FUSE_VALUE_RAYTRACING |
> > + A7XX_CX_MISC_SW_FUSE_VALUE_LPAC)) {
> > +   del_timer(>hangcheck_timer);
> > +
> > +   kthread_queue_work(gpu->worker, >recover_work);
> > +   }
> > +}
> > +
> >  static irqreturn_t a6xx_irq(struct msm_gpu *gpu)
> >  {
> > struct msm_drm_private *priv = gpu->dev->dev_private;
> > @@ -2384,6 +2406,9 @@ static irqreturn_t a6xx_irq(struct msm_gpu *gpu)
> > if (status & A6XX_RBBM_INT_0_MASK_UCHE_OOB_ACCESS)
> > dev_err_ratelimited(>pdev->dev, "UCHE | Out of bounds 
> > access\n");
> >
> > +   if (status & A6XX_RBBM_INT_0_MASK_SWFUSEVIOLATION)
> > +   a7xx_sw_fuse_violation_irq(gpu);
> > +
> > if (status & A6XX_RBBM_INT_0_MASK_CP_CACHE_FLUSH_TS)
> > msm_gpu_retire(gpu);
> >
> > @@ -2525,6 +2550,60 @@ static void a6xx_llc_slices_init(struct 
> > platform_device *pdev,
> > a6xx_gpu->llc_mmio = ERR_PTR(-EINVAL);
> >  }
> >
> > +static int a7xx_cx_mem_init(struct a6xx_gpu *a6xx_gpu)
> > +{
> > +   struct adreno_gpu *adreno_gpu = _gpu->base;
> > +   struct msm_gpu *gpu = _gpu->base;
> > +   u32 gpu_req = QCOM_SCM_GPU_ALWAYS_EN_REQ;
> > +   u32 fuse_val;
> > +   int ret;
> > +
> > +   if (adreno_is_a740(adreno_gpu)) {
> > +   /* Raytracing is always enabled on a740 */
> > +   adreno_gpu->has_ray_tracing = true;
> > +   }
> > +
> > +   if (!qcom_scm_is_available()) {
> > +   /* Assume that if qcom scm isn't available, that whatever
> > +* replacement allows writing the fuse register ourselves.
> > +* Users of alternative firmware need to make sure this
> > +* register is writeable or indicate that it's not somehow.
> > +* Print a warning because if you mess this up you're about 
> > to
> > +* crash horribly.
> > +*/
> > +   if (adreno_is_a750(adreno_gpu)) {
> > +   dev_warn_once(gpu->dev->dev,
> > +   "SCM is not available, poking fuse 
> > register\n");
> > +   a6xx_llc_write(a6xx_gpu, 
> > REG_A7XX_CX_MISC_SW_FUSE_VALUE,
> > +   A7XX_CX_MISC_SW_FUSE_VALUE_RAYTRACING |
> > +   A7XX_CX_MISC_SW_FUSE_VALUE_FASTBLEND |
> > +   A7XX_CX_MISC_SW_FUSE_VALUE_LPAC);
> > +   adreno_gpu->has_ray_tracing = true;
> > +   }

Re: [PATCH 4/6] drm/msm/a7xx: Initialize a750 "software fuse"

2024-04-25 Thread Dmitry Baryshkov
On Thu, 25 Apr 2024 at 16:44, Connor Abbott  wrote:
>
> On all Qualcomm platforms with a7xx GPUs, qcom_scm provides a method to
> initialize cx_mem. Copy this from downstream (minus BCL which we
> currently don't support). On a750, this includes a new "fuse" register
> which can be used by qcom_scm to fuse off certain features like
> raytracing in software. The fuse is default off, and is initialized by
> calling the method. Afterwards we have to read it to find out which
> features were enabled.
>
> Signed-off-by: Connor Abbott 
> ---
>  drivers/gpu/drm/msm/adreno/a6xx_gpu.c   | 89 -
>  drivers/gpu/drm/msm/adreno/adreno_gpu.h |  2 +
>  2 files changed, 90 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c 
> b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> index cf0b1de1c071..fb2722574ae5 100644
> --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> @@ -10,6 +10,7 @@
>
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>
> @@ -1686,7 +1687,8 @@ static int a6xx_zap_shader_init(struct msm_gpu *gpu)
>A6XX_RBBM_INT_0_MASK_RBBM_HANG_DETECT | \
>A6XX_RBBM_INT_0_MASK_UCHE_OOB_ACCESS | \
>A6XX_RBBM_INT_0_MASK_UCHE_TRAP_INTR | \
> -  A6XX_RBBM_INT_0_MASK_TSBWRITEERROR)
> +  A6XX_RBBM_INT_0_MASK_TSBWRITEERROR | \
> +  A6XX_RBBM_INT_0_MASK_SWFUSEVIOLATION)
>
>  #define A7XX_APRIV_MASK (A6XX_CP_APRIV_CNTL_ICACHE | \
>  A6XX_CP_APRIV_CNTL_RBFETCH | \
> @@ -2356,6 +2358,26 @@ static void a6xx_fault_detect_irq(struct msm_gpu *gpu)
> kthread_queue_work(gpu->worker, >recover_work);
>  }
>
> +static void a7xx_sw_fuse_violation_irq(struct msm_gpu *gpu)
> +{
> +   u32 status;
> +
> +   status = gpu_read(gpu, REG_A7XX_RBBM_SW_FUSE_INT_STATUS);
> +   gpu_write(gpu, REG_A7XX_RBBM_SW_FUSE_INT_MASK, 0);
> +
> +   dev_err_ratelimited(>pdev->dev, "SW fuse violation 
> status=%8.8x\n", status);
> +
> +   /* Ignore FASTBLEND violations, because the HW will silently fall back
> +* to legacy blending.
> +*/
> +   if (status & (A7XX_CX_MISC_SW_FUSE_VALUE_RAYTRACING |
> + A7XX_CX_MISC_SW_FUSE_VALUE_LPAC)) {
> +   del_timer(>hangcheck_timer);
> +
> +   kthread_queue_work(gpu->worker, >recover_work);
> +   }
> +}
> +
>  static irqreturn_t a6xx_irq(struct msm_gpu *gpu)
>  {
> struct msm_drm_private *priv = gpu->dev->dev_private;
> @@ -2384,6 +2406,9 @@ static irqreturn_t a6xx_irq(struct msm_gpu *gpu)
> if (status & A6XX_RBBM_INT_0_MASK_UCHE_OOB_ACCESS)
> dev_err_ratelimited(>pdev->dev, "UCHE | Out of bounds 
> access\n");
>
> +   if (status & A6XX_RBBM_INT_0_MASK_SWFUSEVIOLATION)
> +   a7xx_sw_fuse_violation_irq(gpu);
> +
> if (status & A6XX_RBBM_INT_0_MASK_CP_CACHE_FLUSH_TS)
> msm_gpu_retire(gpu);
>
> @@ -2525,6 +2550,60 @@ static void a6xx_llc_slices_init(struct 
> platform_device *pdev,
> a6xx_gpu->llc_mmio = ERR_PTR(-EINVAL);
>  }
>
> +static int a7xx_cx_mem_init(struct a6xx_gpu *a6xx_gpu)
> +{
> +   struct adreno_gpu *adreno_gpu = _gpu->base;
> +   struct msm_gpu *gpu = _gpu->base;
> +   u32 gpu_req = QCOM_SCM_GPU_ALWAYS_EN_REQ;
> +   u32 fuse_val;
> +   int ret;
> +
> +   if (adreno_is_a740(adreno_gpu)) {
> +   /* Raytracing is always enabled on a740 */
> +   adreno_gpu->has_ray_tracing = true;
> +   }
> +
> +   if (!qcom_scm_is_available()) {
> +   /* Assume that if qcom scm isn't available, that whatever
> +* replacement allows writing the fuse register ourselves.
> +* Users of alternative firmware need to make sure this
> +* register is writeable or indicate that it's not somehow.
> +* Print a warning because if you mess this up you're about to
> +* crash horribly.
> +*/
> +   if (adreno_is_a750(adreno_gpu)) {
> +   dev_warn_once(gpu->dev->dev,
> +   "SCM is not available, poking fuse 
> register\n");
> +   a6xx_llc_write(a6xx_gpu, 
> REG_A7XX_CX_MISC_SW_FUSE_VALUE,
> +   A7XX_CX_MISC_SW_FUSE_VALUE_RAYTRACING |
> +   A7XX_CX_MISC_SW_FUSE_VALUE_FASTBLEND |
> +   A7XX_CX_MISC_SW_FUSE_VALUE_LPAC);
> +   adreno_gpu->has_ray_tracing = true;
> +   }
> +
> +   return 0;
> +   }
> +
> +   if (adreno_is_a750(adreno_gpu))

Most of the function is under the if (adreno_is_a750) conditions. Can
we invert the logic and add a single block of if(adreno_is_a750) and
then place all the code underneath?

> +   gpu_req |= 

[PATCH 4/6] drm/msm/a7xx: Initialize a750 "software fuse"

2024-04-25 Thread Connor Abbott
On all Qualcomm platforms with a7xx GPUs, qcom_scm provides a method to
initialize cx_mem. Copy this from downstream (minus BCL which we
currently don't support). On a750, this includes a new "fuse" register
which can be used by qcom_scm to fuse off certain features like
raytracing in software. The fuse is default off, and is initialized by
calling the method. Afterwards we have to read it to find out which
features were enabled.

Signed-off-by: Connor Abbott 
---
 drivers/gpu/drm/msm/adreno/a6xx_gpu.c   | 89 -
 drivers/gpu/drm/msm/adreno/adreno_gpu.h |  2 +
 2 files changed, 90 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c 
b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
index cf0b1de1c071..fb2722574ae5 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
@@ -10,6 +10,7 @@
 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -1686,7 +1687,8 @@ static int a6xx_zap_shader_init(struct msm_gpu *gpu)
   A6XX_RBBM_INT_0_MASK_RBBM_HANG_DETECT | \
   A6XX_RBBM_INT_0_MASK_UCHE_OOB_ACCESS | \
   A6XX_RBBM_INT_0_MASK_UCHE_TRAP_INTR | \
-  A6XX_RBBM_INT_0_MASK_TSBWRITEERROR)
+  A6XX_RBBM_INT_0_MASK_TSBWRITEERROR | \
+  A6XX_RBBM_INT_0_MASK_SWFUSEVIOLATION)
 
 #define A7XX_APRIV_MASK (A6XX_CP_APRIV_CNTL_ICACHE | \
 A6XX_CP_APRIV_CNTL_RBFETCH | \
@@ -2356,6 +2358,26 @@ static void a6xx_fault_detect_irq(struct msm_gpu *gpu)
kthread_queue_work(gpu->worker, >recover_work);
 }
 
+static void a7xx_sw_fuse_violation_irq(struct msm_gpu *gpu)
+{
+   u32 status;
+
+   status = gpu_read(gpu, REG_A7XX_RBBM_SW_FUSE_INT_STATUS);
+   gpu_write(gpu, REG_A7XX_RBBM_SW_FUSE_INT_MASK, 0);
+
+   dev_err_ratelimited(>pdev->dev, "SW fuse violation 
status=%8.8x\n", status);
+
+   /* Ignore FASTBLEND violations, because the HW will silently fall back
+* to legacy blending.
+*/
+   if (status & (A7XX_CX_MISC_SW_FUSE_VALUE_RAYTRACING |
+ A7XX_CX_MISC_SW_FUSE_VALUE_LPAC)) {
+   del_timer(>hangcheck_timer);
+
+   kthread_queue_work(gpu->worker, >recover_work);
+   }
+}
+
 static irqreturn_t a6xx_irq(struct msm_gpu *gpu)
 {
struct msm_drm_private *priv = gpu->dev->dev_private;
@@ -2384,6 +2406,9 @@ static irqreturn_t a6xx_irq(struct msm_gpu *gpu)
if (status & A6XX_RBBM_INT_0_MASK_UCHE_OOB_ACCESS)
dev_err_ratelimited(>pdev->dev, "UCHE | Out of bounds 
access\n");
 
+   if (status & A6XX_RBBM_INT_0_MASK_SWFUSEVIOLATION)
+   a7xx_sw_fuse_violation_irq(gpu);
+
if (status & A6XX_RBBM_INT_0_MASK_CP_CACHE_FLUSH_TS)
msm_gpu_retire(gpu);
 
@@ -2525,6 +2550,60 @@ static void a6xx_llc_slices_init(struct platform_device 
*pdev,
a6xx_gpu->llc_mmio = ERR_PTR(-EINVAL);
 }
 
+static int a7xx_cx_mem_init(struct a6xx_gpu *a6xx_gpu)
+{
+   struct adreno_gpu *adreno_gpu = _gpu->base;
+   struct msm_gpu *gpu = _gpu->base;
+   u32 gpu_req = QCOM_SCM_GPU_ALWAYS_EN_REQ;
+   u32 fuse_val;
+   int ret;
+
+   if (adreno_is_a740(adreno_gpu)) {
+   /* Raytracing is always enabled on a740 */
+   adreno_gpu->has_ray_tracing = true;
+   }
+
+   if (!qcom_scm_is_available()) {
+   /* Assume that if qcom scm isn't available, that whatever
+* replacement allows writing the fuse register ourselves.
+* Users of alternative firmware need to make sure this
+* register is writeable or indicate that it's not somehow.
+* Print a warning because if you mess this up you're about to
+* crash horribly.
+*/
+   if (adreno_is_a750(adreno_gpu)) {
+   dev_warn_once(gpu->dev->dev,
+   "SCM is not available, poking fuse register\n");
+   a6xx_llc_write(a6xx_gpu, REG_A7XX_CX_MISC_SW_FUSE_VALUE,
+   A7XX_CX_MISC_SW_FUSE_VALUE_RAYTRACING |
+   A7XX_CX_MISC_SW_FUSE_VALUE_FASTBLEND |
+   A7XX_CX_MISC_SW_FUSE_VALUE_LPAC);
+   adreno_gpu->has_ray_tracing = true;
+   }
+
+   return 0;
+   }
+
+   if (adreno_is_a750(adreno_gpu))
+   gpu_req |= QCOM_SCM_GPU_TSENSE_EN_REQ;
+
+   ret = qcom_scm_gpu_init_regs(gpu_req);
+   if (ret)
+   return ret;
+
+   /* On a750 raytracing may be disabled by the firmware, find out whether
+* that's the case. The scm call above sets the fuse register.
+*/
+   if (adreno_is_a750(adreno_gpu)) {
+   fuse_val = a6xx_llc_read(a6xx_gpu, 
REG_A7XX_CX_MISC_SW_FUSE_VALUE);
+   adreno_gpu->has_ray_tracing =
+