Re: [PATCH v2 1/6] arm64: dts: qcom: sm8650: Fix GPU cx_mem size

2024-04-27 Thread Konrad Dybcio
On 26.04.2024 8:33 PM, Connor Abbott wrote:
> This is doubled compared to previous GPUs. We can't access the new
> SW_FUSE_VALUE register without this.
> 
> Fixes: db33633b05c0 ("arm64: dts: qcom: sm8650: add GPU nodes")
> Signed-off-by: Connor Abbott 
> ---

Reviewed-by: Konrad Dybcio 

Konrad


Re: [PATCH v2 2/6] firmware: qcom_scm: Add gpu_init_regs call

2024-04-27 Thread Konrad Dybcio
On 26.04.2024 8:34 PM, Connor Abbott wrote:
> This will used by drm/msm.
> 
> Signed-off-by: Connor Abbott 
> ---

[...]

> +/**
> + * Request TZ to program set of access controlled registers necessary
> + * irrespective of any features
> + */

kerneldoc abuse, please make it a regular comment

Konrad


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

2024-04-27 Thread Konrad Dybcio
On 26.04.2024 8:34 PM, 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 
> ---

[...]

> +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(&gpu->pdev->dev, "SW fuse violation 
> status=%8.8x\n", status);
> +
> + /* Ignore FASTBLEND violations, because the HW will silently fall back
> +  * to legacy blending.

/*
 * foo



> +  */
> + if (status & (A7XX_CX_MISC_SW_FUSE_VALUE_RAYTRACING |
> +   A7XX_CX_MISC_SW_FUSE_VALUE_LPAC)) {
> + del_timer(&gpu->hangcheck_timer);
> +
> + kthread_queue_work(gpu->worker, &gpu->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(&gpu->pdev->dev, "UCHE | Out of bounds 
> access\n");
>  
> + if (status & A6XX_RBBM_INT_0_MASK_SWFUSEVIOLATION)

Does this field actualy exist on a6 too?

> + a7xx_sw_fuse_violation_irq(gpu);
> +
>   if (status & A6XX_RBBM_INT_0_MASK_CP_CACHE_FLUSH_TS)
>   msm_gpu_retire(gpu);
>  
> @@ -2525,6 +2550,59 @@ 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 = &a6xx_gpu->base;
> + struct msm_gpu *gpu = &adreno_gpu->base;
> + u32 fuse_val;
> + int ret = 0;
> +
> + if (adreno_is_a750(adreno_gpu)) {
> + /* 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 (!qcom_scm_is_available()) {
> + 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;

I'm not 100% sure. I'm afraid there may be SKUs with RT cores fused
off (as in, cut off from the rest, not "indicated unavailable") or
otherwise dysfunctional..

My guess would be that TZ probably has some sort of a LUT/match table
based on other SoC identifiers

> + return 0;
> + }
> +
> + ret = qcom_scm_gpu_init_regs(QCOM_SCM_GPU_ALWAYS_EN_REQ |
> +  QCOM_SCM_GPU_TSENSE_EN_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.
> +  */
> + fuse_val = a6xx_llc_read(a6xx_gpu, 
> REG_A7XX_CX_MISC_SW_FUSE_VALUE);
> + adreno_gpu->has_ray_tracing =
> + !!(fuse_val & A7XX_CX_MISC_SW_FUSE_VALUE_RAYTRACING);
> + } else {
> + if (adreno_is_a740(adreno_gpu)) {
> + /* Raytracing is always enabled on a740 */
> + adreno_gpu->has_ray_tracing = true;
> + }
> +
> + if (!qcom_scm_is_available())
> + return 0;
> +
> + ret = qcom_scm_gpu_init_regs(QCOM_SCM_GPU_ALWAYS_EN_REQ);
> + }
> +
> + return ret;

if (qcom_scm_is_available())
return qcom_scm_gpu_init_regs(QCOM_SCM_GPU_ALWAYS_EN_REQ);
}

return 0;

?

Konrad


Re: [PATCH v2 5/6] drm/msm: Add MSM_PARAM_RAYTRACING uapi

2024-04-27 Thread Konrad Dybcio
On 26.04.2024 8:34 PM, Connor Abbott wrote:
> Expose the value of the software fuse to userspace.
> 
> Signed-off-by: Connor Abbott 
> ---
>  drivers/gpu/drm/msm/adreno/adreno_gpu.c | 3 +++
>  include/uapi/drm/msm_drm.h  | 1 +
>  2 files changed, 4 insertions(+)
> 
> diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c 
> b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
> index 074fb498706f..99ad651857b2 100644
> --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c
> +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
> @@ -376,6 +376,9 @@ int adreno_get_param(struct msm_gpu *gpu, struct 
> msm_file_private *ctx,
>   case MSM_PARAM_HIGHEST_BANK_BIT:
>   *value = adreno_gpu->ubwc_config.highest_bank_bit;
>   return 0;
> + case MSM_PARAM_RAYTRACING:
> + *value = adreno_gpu->has_ray_tracing;
> + return 0;

I'd personally go with MSM_PARAM_FEATURES as a u64 bitmap, but it's
not me that'll have to deal with this on the userland side, so:

Reviewed-by: Konrad Dybcio 

Konrad


Re: [PATCH v2 6/6] drm/msm/a7xx: Add missing register writes from downstream

2024-04-27 Thread Konrad Dybcio
On 26.04.2024 8:34 PM, Connor Abbott wrote:
> This isn't known to fix anything yet, but it's a good idea to add it.
> 
> Signed-off-by: Connor Abbott 
> ---
>  drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 8 
>  1 file changed, 8 insertions(+)
> 
> diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c 
> b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> index 4a3b12b20802..d88ec857f1cb 100644
> --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> @@ -1953,6 +1953,14 @@ static int hw_init(struct msm_gpu *gpu)
> BIT(6) | BIT(5) | BIT(3) | BIT(2) | BIT(1));
>   }
>  
> + if (adreno_is_a750(adreno_gpu)) {
> + gpu_rmw(gpu, REG_A6XX_RB_CMP_DBG_ECO_CNTL, BIT(19), BIT(19));

"/* Disable ubwc merged UFC request feature */"

> +
> + gpu_write(gpu, REG_A6XX_TPL1_DBG_ECO_CNTL1, 0xc0700);

"/* Enable TP flaghint and other performance settings */"

> + } else if (adreno_is_a7xx(adreno_gpu)) {
> + gpu_rmw(gpu, REG_A6XX_RB_CMP_DBG_ECO_CNTL, BIT(19), BIT(19));

This is supposed to be bit(11) on !A750:

"/* Disable non-ubwc read reqs from passing write reqs */"

Konrad