panfrost: Back panfrost_device with pan_kmod_dev object

Back panfrost_device with pan_kmod_dev object and query all props using
the pan_kmod_dev_query_props().

Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
Reviewed-by: Erik Faye-Lund <erik.faye-lund@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/26357>
This commit is contained in:
Boris Brezillon 2023-11-20 16:54:13 +01:00 committed by Marge Bot
parent 70bcdbee6c
commit 91fe8a0d28
2 changed files with 51 additions and 92 deletions

View file

@ -41,6 +41,8 @@
#include "pan_pool.h" #include "pan_pool.h"
#include "pan_util.h" #include "pan_util.h"
#include "kmod/pan_kmod.h"
#include <genxml/gen_macros.h> #include <genxml/gen_macros.h>
#if defined(__cplusplus) #if defined(__cplusplus)
@ -128,15 +130,20 @@ struct panfrost_device {
/* For ralloc */ /* For ralloc */
void *memctx; void *memctx;
int fd; /* Kmod objects. */
struct {
/* The pan_kmod_dev object backing this device. */
struct pan_kmod_dev *dev;
/* Cached pan_kmod_dev_props properties queried at device create time. */
struct pan_kmod_dev_props props;
} kmod;
/* For pandecode */ /* For pandecode */
struct pandecode_context *decode_ctx; struct pandecode_context *decode_ctx;
/* Properties of the GPU in use */ /* Properties of the GPU in use */
unsigned arch; unsigned arch;
unsigned gpu_id;
unsigned revision;
/* Number of shader cores */ /* Number of shader cores */
unsigned core_count; unsigned core_count;
@ -164,8 +171,6 @@ struct panfrost_device {
/* debug flags, see pan_util.h how to interpret */ /* debug flags, see pan_util.h how to interpret */
unsigned debug; unsigned debug;
drmVersionPtr kernel_version;
struct renderonly *ro; struct renderonly *ro;
pthread_mutex_t bo_map_lock; pthread_mutex_t bo_map_lock;
@ -218,31 +223,31 @@ struct panfrost_device {
static inline int static inline int
panfrost_device_fd(const struct panfrost_device *dev) panfrost_device_fd(const struct panfrost_device *dev)
{ {
return dev->fd; return dev->kmod.dev->fd;
} }
static inline uint32_t static inline uint32_t
panfrost_device_gpu_id(const struct panfrost_device *dev) panfrost_device_gpu_id(const struct panfrost_device *dev)
{ {
return dev->gpu_id; return dev->kmod.props.gpu_prod_id;
} }
static inline uint32_t static inline uint32_t
panfrost_device_gpu_rev(const struct panfrost_device *dev) panfrost_device_gpu_rev(const struct panfrost_device *dev)
{ {
return dev->revision; return dev->kmod.props.gpu_revision;
} }
static inline int static inline int
panfrost_device_kmod_version_major(const struct panfrost_device *dev) panfrost_device_kmod_version_major(const struct panfrost_device *dev)
{ {
return dev->kernel_version->version_major; return dev->kmod.dev->driver.version.major;
} }
static inline int static inline int
panfrost_device_kmod_version_minor(const struct panfrost_device *dev) panfrost_device_kmod_version_minor(const struct panfrost_device *dev)
{ {
return dev->kernel_version->version_minor; return dev->kmod.dev->driver.version.minor;
} }
void panfrost_open_device(void *memctx, int fd, struct panfrost_device *dev); void panfrost_open_device(void *memctx, int fd, struct panfrost_device *dev);

View file

@ -93,58 +93,18 @@ panfrost_get_model(uint32_t gpu_id)
return NULL; return NULL;
} }
/* Abstraction over the raw drm_panfrost_get_param ioctl for fetching
* information about devices */
static __u64
panfrost_query_raw(int fd, enum drm_panfrost_param param, bool required,
unsigned default_value)
{
struct drm_panfrost_get_param get_param = {
0,
};
ASSERTED int ret;
get_param.param = param;
ret = drmIoctl(fd, DRM_IOCTL_PANFROST_GET_PARAM, &get_param);
if (ret) {
assert(!required);
return default_value;
}
return get_param.value;
}
static unsigned
panfrost_query_gpu_version(int fd)
{
return panfrost_query_raw(fd, DRM_PANFROST_PARAM_GPU_PROD_ID, true, 0);
}
static unsigned
panfrost_query_gpu_revision(int fd)
{
return panfrost_query_raw(fd, DRM_PANFROST_PARAM_GPU_REVISION, true, 0);
}
unsigned unsigned
panfrost_query_l2_slices(const struct panfrost_device *dev) panfrost_query_l2_slices(const struct panfrost_device *dev)
{ {
/* Query MEM_FEATURES register */
uint32_t mem_features = panfrost_query_raw(
panfrost_device_fd(dev), DRM_PANFROST_PARAM_MEM_FEATURES, true, 0);
/* L2_SLICES is MEM_FEATURES[11:8] minus(1) */ /* L2_SLICES is MEM_FEATURES[11:8] minus(1) */
return ((mem_features >> 8) & 0xF) + 1; return ((dev->kmod.props.mem_features >> 8) & 0xF) + 1;
} }
static struct panfrost_tiler_features static struct panfrost_tiler_features
panfrost_query_tiler_features(int fd) panfrost_query_tiler_features(const struct panfrost_device *dev)
{ {
/* Default value (2^9 bytes and 8 levels) to match old behaviour */ /* Default value (2^9 bytes and 8 levels) to match old behaviour */
uint32_t raw = uint32_t raw = dev->kmod.props.tiler_features;
panfrost_query_raw(fd, DRM_PANFROST_PARAM_TILER_FEATURES, false, 0x809);
/* Bin size is log2 in the first byte, max levels in the second byte */ /* Bin size is log2 in the first byte, max levels in the second byte */
return (struct panfrost_tiler_features){ return (struct panfrost_tiler_features){
@ -154,12 +114,12 @@ panfrost_query_tiler_features(int fd)
} }
static unsigned static unsigned
panfrost_query_core_count(int fd, unsigned *core_id_range) panfrost_query_core_count(const struct panfrost_device *dev,
unsigned *core_id_range)
{ {
/* On older kernels, worst-case to 16 cores */ /* On older kernels, worst-case to 16 cores */
unsigned mask = unsigned mask = dev->kmod.props.shader_present;
panfrost_query_raw(fd, DRM_PANFROST_PARAM_SHADER_PRESENT, false, 0xffff);
/* Some cores might be absent. In some cases, we care /* Some cores might be absent. In some cases, we care
* about the range of core IDs (that is, the greatest core ID + 1). If * about the range of core IDs (that is, the greatest core ID + 1). If
@ -172,31 +132,18 @@ panfrost_query_core_count(int fd, unsigned *core_id_range)
} }
static unsigned static unsigned
panfrost_query_thread_tls_alloc(int fd, unsigned major) panfrost_query_thread_tls_alloc(const struct panfrost_device *dev,
unsigned major)
{ {
unsigned tls = unsigned tls = dev->kmod.props.thread_tls_alloc;
panfrost_query_raw(fd, DRM_PANFROST_PARAM_THREAD_TLS_ALLOC, false, 0);
return (tls > 0) ? tls : panfrost_max_thread_count(major, 0); return (tls > 0) ? tls : panfrost_max_thread_count(major, 0);
} }
static uint32_t static uint32_t
panfrost_query_compressed_formats(int fd) panfrost_query_compressed_formats(const struct panfrost_device *dev)
{ {
/* If unspecified, assume ASTC/ETC only. Factory default for Juno, and return dev->kmod.props.texture_features[0];
* should exist on any Mali configuration. All hardware should report
* these texture formats but the kernel might not be new enough. */
uint32_t default_set = (1 << MALI_ETC2_RGB8) | (1 << MALI_ETC2_R11_UNORM) |
(1 << MALI_ETC2_RGBA8) | (1 << MALI_ETC2_RG11_UNORM) |
(1 << MALI_ETC2_R11_SNORM) |
(1 << MALI_ETC2_RG11_SNORM) |
(1 << MALI_ETC2_RGB8A1) | (1 << MALI_ASTC_3D_LDR) |
(1 << MALI_ASTC_3D_HDR) | (1 << MALI_ASTC_2D_LDR) |
(1 << MALI_ASTC_2D_HDR);
return panfrost_query_raw(fd, DRM_PANFROST_PARAM_TEXTURE_FEATURES0, false,
default_set);
} }
/* DRM_PANFROST_PARAM_TEXTURE_FEATURES0 will return a bitmask of supported /* DRM_PANFROST_PARAM_TEXTURE_FEATURES0 will return a bitmask of supported
@ -218,10 +165,9 @@ panfrost_supports_compressed_format(struct panfrost_device *dev, unsigned fmt)
* may omit it, signaled as a nonzero value in the AFBC_FEATURES property. */ * may omit it, signaled as a nonzero value in the AFBC_FEATURES property. */
static bool static bool
panfrost_query_afbc(int fd, unsigned arch) panfrost_query_afbc(struct panfrost_device *dev, unsigned arch)
{ {
unsigned reg = unsigned reg = dev->kmod.props.afbc_features;
panfrost_query_raw(fd, DRM_PANFROST_PARAM_AFBC_FEATURES, false, 0);
return (arch >= 5) && (reg == 0); return (arch >= 5) && (reg == 0);
} }
@ -248,27 +194,30 @@ panfrost_query_optimal_tib_size(const struct panfrost_device *dev)
void void
panfrost_open_device(void *memctx, int fd, struct panfrost_device *dev) panfrost_open_device(void *memctx, int fd, struct panfrost_device *dev)
{ {
dev->fd = fd;
dev->memctx = memctx; dev->memctx = memctx;
dev->gpu_id = panfrost_query_gpu_version(fd);
dev->arch = pan_arch(panfrost_device_gpu_id(dev));
dev->kernel_version = drmGetVersion(fd);
dev->revision = panfrost_query_gpu_revision(fd);
dev->model = panfrost_get_model(panfrost_device_gpu_id(dev));
if (!dev->kernel_version) dev->kmod.dev = pan_kmod_dev_create(fd, PAN_KMOD_DEV_FLAG_OWNS_FD, NULL);
if (!dev->kmod.dev) {
close(fd);
return; return;
}
pan_kmod_dev_query_props(dev->kmod.dev, &dev->kmod.props);
dev->arch = pan_arch(dev->kmod.props.gpu_prod_id);
dev->model = panfrost_get_model(dev->kmod.props.gpu_prod_id);
/* If we don't recognize the model, bail early */ /* If we don't recognize the model, bail early */
if (!dev->model) if (!dev->model)
return; goto err_free_kmod_dev;
dev->core_count = panfrost_query_core_count(fd, &dev->core_id_range);
dev->thread_tls_alloc = panfrost_query_thread_tls_alloc(fd, dev->arch); dev->core_count = panfrost_query_core_count(dev, &dev->core_id_range);
dev->thread_tls_alloc = panfrost_query_thread_tls_alloc(dev, dev->arch);
dev->optimal_tib_size = panfrost_query_optimal_tib_size(dev); dev->optimal_tib_size = panfrost_query_optimal_tib_size(dev);
dev->compressed_formats = panfrost_query_compressed_formats(fd); dev->compressed_formats = panfrost_query_compressed_formats(dev);
dev->tiler_features = panfrost_query_tiler_features(fd); dev->tiler_features = panfrost_query_tiler_features(dev);
dev->has_afbc = panfrost_query_afbc(fd, dev->arch); dev->has_afbc = panfrost_query_afbc(dev, dev->arch);
if (dev->arch <= 6) { if (dev->arch <= 6) {
dev->formats = panfrost_pipe_format_v6; dev->formats = panfrost_pipe_format_v6;
@ -304,6 +253,11 @@ panfrost_open_device(void *memctx, int fd, struct panfrost_device *dev)
/* Done once on init */ /* Done once on init */
panfrost_upload_sample_positions(dev); panfrost_upload_sample_positions(dev);
return;
err_free_kmod_dev:
pan_kmod_dev_destroy(dev->kmod.dev);
dev->kmod.dev = NULL;
} }
void void
@ -321,6 +275,6 @@ panfrost_close_device(struct panfrost_device *dev)
util_sparse_array_finish(&dev->bo_map); util_sparse_array_finish(&dev->bo_map);
} }
drmFreeVersion(dev->kernel_version); if (dev->kmod.dev)
close(dev->fd); pan_kmod_dev_destroy(dev->kmod.dev);
} }