On Thu, 20 Mar 2025 11:17:35 +0000
Karunika Choo <karunika.c...@arm.com> wrote:

> This patch aims to lay the foundation to provide support for multiple
> Mali GPUs through a framework by which differences in registers,
> functionality, and features can be managed.
> 
> It introduces the concept of the arch_id which is a 32-bit ID in the
> format of ((arch_major << 16) | (arch_minor << 8) | arch_rev). The 8-bit
> fields of the arch_id provides future proofing past the 4-bit fields of
> the GPU_ID's arch_major, arch_minor, and arch_rev.
> 
> The arch_id is used to select the correct abstraction for the GPU, such
> as function pointers for operations specific to the GPU, base addresses
> describing changes in register offsets, and supported features.
> 
> Signed-off-by: Karunika Choo <karunika.c...@arm.com>
> ---
>  drivers/gpu/drm/panthor/Makefile         |  1 +
>  drivers/gpu/drm/panthor/panthor_device.c |  5 ++
>  drivers/gpu/drm/panthor/panthor_device.h |  3 +
>  drivers/gpu/drm/panthor/panthor_hw.c     | 70 ++++++++++++++++++++++++
>  drivers/gpu/drm/panthor/panthor_hw.h     | 63 +++++++++++++++++++++
>  drivers/gpu/drm/panthor/panthor_regs.h   |  2 +
>  6 files changed, 144 insertions(+)
>  create mode 100644 drivers/gpu/drm/panthor/panthor_hw.c
>  create mode 100644 drivers/gpu/drm/panthor/panthor_hw.h
> 
> diff --git a/drivers/gpu/drm/panthor/Makefile 
> b/drivers/gpu/drm/panthor/Makefile
> index 15294719b09c..02db21748c12 100644
> --- a/drivers/gpu/drm/panthor/Makefile
> +++ b/drivers/gpu/drm/panthor/Makefile
> @@ -8,6 +8,7 @@ panthor-y := \
>       panthor_gem.o \
>       panthor_gpu.o \
>       panthor_heap.o \
> +     panthor_hw.o \
>       panthor_mmu.o \
>       panthor_sched.o
>  
> diff --git a/drivers/gpu/drm/panthor/panthor_device.c 
> b/drivers/gpu/drm/panthor/panthor_device.c
> index a9da1d1eeb70..a6fca6b3fabd 100644
> --- a/drivers/gpu/drm/panthor/panthor_device.c
> +++ b/drivers/gpu/drm/panthor/panthor_device.c
> @@ -18,6 +18,7 @@
>  #include "panthor_device.h"
>  #include "panthor_fw.h"
>  #include "panthor_gpu.h"
> +#include "panthor_hw.h"
>  #include "panthor_mmu.h"
>  #include "panthor_regs.h"
>  #include "panthor_sched.h"
> @@ -243,6 +244,10 @@ int panthor_device_init(struct panthor_device *ptdev)
>                       return ret;
>       }
>  
> +     ret = panthor_hw_init(ptdev);
> +     if (ret)
> +             goto err_rpm_put;
> +
>       ret = panthor_gpu_init(ptdev);
>       if (ret)
>               goto err_rpm_put;
> diff --git a/drivers/gpu/drm/panthor/panthor_device.h 
> b/drivers/gpu/drm/panthor/panthor_device.h
> index da6574021664..82741bf1a49b 100644
> --- a/drivers/gpu/drm/panthor/panthor_device.h
> +++ b/drivers/gpu/drm/panthor/panthor_device.h
> @@ -120,6 +120,9 @@ struct panthor_device {
>       /** @csif_info: Command stream interface information. */
>       struct drm_panthor_csif_info csif_info;
>  
> +     /** @hw: GPU specific data. */
> +     struct panthor_hw *hw;
> +
>       /** @gpu: GPU management data. */
>       struct panthor_gpu *gpu;
>  
> diff --git a/drivers/gpu/drm/panthor/panthor_hw.c 
> b/drivers/gpu/drm/panthor/panthor_hw.c
> new file mode 100644
> index 000000000000..234bfd50cf0d
> --- /dev/null
> +++ b/drivers/gpu/drm/panthor/panthor_hw.c
> @@ -0,0 +1,70 @@
> +// SPDX-License-Identifier: GPL-2.0 or MIT
> +/* Copyright 2025 ARM Limited. All rights reserved. */
> +
> +#include "panthor_device.h"
> +#include "panthor_hw.h"
> +#include "panthor_regs.h"
> +
> +static struct panthor_hw panthor_hw_devices[] = {
> +     {
> +             .arch_id = GPU_ARCH_ID_MAKE(10, 0, 0),
> +             .arch_mask = GPU_ARCH_ID_MAKE(0xFF, 0, 0),
> +     },
> +};
> +
> +static int init_gpu_id(struct panthor_device *ptdev)
> +{
> +     ptdev->gpu_info.gpu_id = gpu_read(ptdev, GPU_ID);
> +
> +     if (!ptdev->gpu_info.gpu_id) {
> +             drm_err(&ptdev->base, "Invalid GPU ID (0x0)");
> +             return -ENXIO;
> +     }
> +
> +     return 0;
> +}
> +
> +int panthor_hw_init(struct panthor_device *ptdev)
> +{
> +     struct panthor_hw *hdev = NULL;
> +     u32 arch_id = 0;
> +     int i, ret;
> +
> +     ret = init_gpu_id(ptdev);
> +     if (ret)
> +             return ret;
> +
> +     arch_id = GPU_ARCH_ID_MAKE(GPU_ARCH_MAJOR(ptdev->gpu_info.gpu_id),
> +                                GPU_ARCH_MINOR(ptdev->gpu_info.gpu_id),
> +                                GPU_ARCH_REV(ptdev->gpu_info.gpu_id));
> +     if (!arch_id) {
> +             drm_err(&ptdev->base, "Invalid arch_id (0x0)");
> +             return -ENXIO;
> +     }
> +
> +     for (i = 0; i < ARRAY_SIZE(panthor_hw_devices); i++) {
> +             u32 mask = panthor_hw_devices[i].arch_mask;
> +             u32 hw_arch_id = panthor_hw_devices[i].arch_id;
> +
> +             if ((arch_id & mask) == (hw_arch_id & mask)) {
> +                     hdev = &panthor_hw_devices[i];
> +                     break;
> +             }
> +     }
> +
> +     if (!hdev) {
> +             drm_err(&ptdev->base, "Unsupported GPU (arch 0x%x)", arch_id);
> +             return -ENODEV;
> +     }
> +
> +     ptdev->hw = hdev;
> +
> +     return 0;
> +}
> +
> +bool panthor_hw_supports(struct panthor_device *ptdev,
> +                      enum panthor_hw_feature feature)
> +{
> +     return test_bit(feature, ptdev->hw->features);
> +}
> +
> diff --git a/drivers/gpu/drm/panthor/panthor_hw.h 
> b/drivers/gpu/drm/panthor/panthor_hw.h
> new file mode 100644
> index 000000000000..5eb0549ad333
> --- /dev/null
> +++ b/drivers/gpu/drm/panthor/panthor_hw.h
> @@ -0,0 +1,63 @@
> +/* SPDX-License-Identifier: GPL-2.0 or MIT */
> +/* Copyright 2025 ARM Limited. All rights reserved. */
> +
> +#ifndef __PANTHOR_HW_H__
> +#define __PANTHOR_HW_H__
> +
> +#include <linux/types.h>
> +#include <linux/bitmap.h>
> +
> +struct panthor_device;
> +
> +/**
> + * enum panthor_hw_feature - Bit position of each HW feature
> + *
> + * Used to define GPU specific features based on the GPU architecture ID.
> + * New feature flags will be added with support for newer GPU architectures.
> + */
> +enum panthor_hw_feature {
> +     /** @PANTHOR_HW_FEATURES_END: Must be last. */
> +     PANTHOR_HW_FEATURES_END
> +};
> +
> +/**
> + * struct panthor_hw_regmap - Register offsets for specific register blocks
> + */
> +struct panthor_hw_regmap {
> +
> +};
> +
> +/**
> + * struct panthor_hw_ops - HW operations that are specific to a GPU
> + */
> +struct panthor_hw_ops {
> +
> +};
> +
> +/**
> + * struct panthor_hw - GPU specific register mapping and functions
> + */
> +struct panthor_hw {
> +     /** @arch_id: Architecture id to match against */
> +     u32 arch_id;
> +
> +     /** @arch_mask: Mask for architecture id comparison */
> +     u32 arch_mask;
> +
> +     /** @features: Bitmap containing panthor_hw_feature */
> +     DECLARE_BITMAP(features, PANTHOR_HW_FEATURES_END);
> +
> +     /** @map: Panthor regmap */
> +     struct panthor_hw_regmap map;
> +
> +     /** @ops: Panthor HW specific operations */
> +     struct panthor_hw_ops ops;

Do we really need per minor arch specialization if we already have per
GPU information through panthor_model?

The way I see it, we can have a device operation specialization per
major arch, then some tweaking done in the arch major init callback
based on the minor version. And the final tweaks applied per GPU model.

> +};
> +
> +int panthor_hw_init(struct panthor_device *ptdev);
> +
> +bool panthor_hw_supports(struct panthor_device *ptdev,
> +                      enum panthor_hw_feature feature);
> +
> +#endif /* __PANTHOR_HW_H__ */
> +
> diff --git a/drivers/gpu/drm/panthor/panthor_regs.h 
> b/drivers/gpu/drm/panthor/panthor_regs.h
> index 7ec4a1d04e20..ba452c1dd644 100644
> --- a/drivers/gpu/drm/panthor/panthor_regs.h
> +++ b/drivers/gpu/drm/panthor/panthor_regs.h
> @@ -19,6 +19,8 @@
>  #define   GPU_VER_MINOR(x)                           (((x) & GENMASK(11, 4)) 
> >> 4)
>  #define   GPU_VER_STATUS(x)                          ((x) & GENMASK(3, 0))
>  
> +#define GPU_ARCH_ID_MAKE(major, minor, rev)          (((major) << 16) | 
> ((minor) << 8) | (rev))
> +
>  #define GPU_L2_FEATURES                                      0x4
>  #define  GPU_L2_FEATURES_LINE_SIZE(x)                        (1 << ((x) & 
> GENMASK(7, 0)))
>  

Reply via email to