Commit 4babef07 authored by Sarah Walker's avatar Sarah Walker Committed by Maxime Ripard

drm/imagination: Add skeleton PowerVR driver

This adds the basic skeleton of the driver. The driver registers
itself with DRM on probe. Ioctl handlers are currently implemented
as stubs.

Changes since v8:
- Corrected license identifiers

Changes since v5:
- Update compatible string & description to match marketing name
- Checkpatch fixes in to/from_pvr_device/file macros

Changes since v3:
- Clarify supported GPU generations in driver description
- Use drm_dev_unplug() when removing device
- Change from_* and to_* functions to macros
- Fix IS_PTR/PTR_ERR confusion in pvr_probe()
- Remove err_out labels in favour of direct returning
- Remove specific am62 compatible match string
- Drop MODULE_FIRMWARE()
Co-developed-by: default avatarFrank Binns <frank.binns@imgtec.com>
Signed-off-by: default avatarFrank Binns <frank.binns@imgtec.com>
Co-developed-by: default avatarMatt Coster <matt.coster@imgtec.com>
Signed-off-by: default avatarMatt Coster <matt.coster@imgtec.com>
Signed-off-by: default avatarSarah Walker <sarah.walker@imgtec.com>
Signed-off-by: default avatarDonald Robson <donald.robson@imgtec.com>
Reviewed-by: default avatarMaxime Ripard <mripard@kernel.org>
Link: https://lore.kernel.org/r/fed8a77e29620a61aed2684f802339759082cf1b.1700668843.git.donald.robson@imgtec.comSigned-off-by: default avatarMaxime Ripard <mripard@kernel.org>
parent 1088d89e
......@@ -10398,6 +10398,7 @@ M: Donald Robson <donald.robson@imgtec.com>
M: Matt Coster <matt.coster@imgtec.com>
S: Supported
F: Documentation/devicetree/bindings/gpu/img,powervr.yaml
F: drivers/gpu/drm/imagination/
F: include/uapi/drm/pvr_drm.h
IMON SOUNDGRAPH USB IR RECEIVER
......
......@@ -394,6 +394,8 @@ source "drivers/gpu/drm/solomon/Kconfig"
source "drivers/gpu/drm/sprd/Kconfig"
source "drivers/gpu/drm/imagination/Kconfig"
config DRM_HYPERV
tristate "DRM Support for Hyper-V synthetic video device"
depends on DRM && PCI && MMU && HYPERV
......
......@@ -199,3 +199,4 @@ obj-$(CONFIG_DRM_HYPERV) += hyperv/
obj-y += solomon/
obj-$(CONFIG_DRM_SPRD) += sprd/
obj-$(CONFIG_DRM_LOONGSON) += loongson/
obj-$(CONFIG_DRM_POWERVR) += imagination/
# SPDX-License-Identifier: GPL-2.0-only OR MIT
# Copyright (c) 2023 Imagination Technologies Ltd.
config DRM_POWERVR
tristate "Imagination Technologies PowerVR (Series 6 and later) & IMG Graphics"
depends on ARM64
depends on DRM
select DRM_GEM_SHMEM_HELPER
select DRM_SCHED
select FW_LOADER
help
Choose this option if you have a system that has an Imagination
Technologies PowerVR (Series 6 or later) or IMG GPU.
If "M" is selected, the module will be called powervr.
# SPDX-License-Identifier: GPL-2.0-only OR MIT
# Copyright (c) 2023 Imagination Technologies Ltd.
subdir-ccflags-y := -I$(srctree)/$(src)
powervr-y := \
pvr_drv.o \
obj-$(CONFIG_DRM_POWERVR) += powervr.o
/* SPDX-License-Identifier: GPL-2.0-only OR MIT */
/* Copyright (c) 2023 Imagination Technologies Ltd. */
#ifndef PVR_DEVICE_H
#define PVR_DEVICE_H
#include <drm/drm_device.h>
#include <drm/drm_file.h>
#include <drm/drm_mm.h>
#include <linux/bits.h>
#include <linux/compiler_attributes.h>
#include <linux/compiler_types.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/wait.h>
/**
* struct pvr_device - powervr-specific wrapper for &struct drm_device
*/
struct pvr_device {
/**
* @base: The underlying &struct drm_device.
*
* Do not access this member directly, instead call
* from_pvr_device().
*/
struct drm_device base;
};
/**
* struct pvr_file - powervr-specific data to be assigned to &struct
* drm_file.driver_priv
*/
struct pvr_file {
/**
* @file: A reference to the parent &struct drm_file.
*
* Do not access this member directly, instead call from_pvr_file().
*/
struct drm_file *file;
/**
* @pvr_dev: A reference to the powervr-specific wrapper for the
* associated device. Saves on repeated calls to
* to_pvr_device().
*/
struct pvr_device *pvr_dev;
};
#define from_pvr_device(pvr_dev) (&(pvr_dev)->base)
#define to_pvr_device(drm_dev) container_of_const(drm_dev, struct pvr_device, base)
#define from_pvr_file(pvr_file) ((pvr_file)->file)
#define to_pvr_file(file) ((file)->driver_priv)
/**
* DOC: IOCTL validation helpers
*
* To validate the constraints imposed on IOCTL argument structs, a collection
* of macros and helper functions exist in ``pvr_device.h``.
*
* Of the current helpers, it should only be necessary to call
* PVR_IOCTL_UNION_PADDING_CHECK() directly. This macro should be used once in
* every code path which extracts a union member from a struct passed from
* userspace.
*/
/**
* pvr_ioctl_union_padding_check() - Validate that the implicit padding between
* the end of a union member and the end of the union itself is zeroed.
* @instance: Pointer to the instance of the struct to validate.
* @union_offset: Offset into the type of @instance of the target union. Must
* be 64-bit aligned.
* @union_size: Size of the target union in the type of @instance. Must be
* 64-bit aligned.
* @member_size: Size of the target member in the target union specified by
* @union_offset and @union_size. It is assumed that the offset of the target
* member is zero relative to @union_offset. Must be 64-bit aligned.
*
* You probably want to use PVR_IOCTL_UNION_PADDING_CHECK() instead of calling
* this function directly, since that macro abstracts away much of the setup,
* and also provides some static validation. See its docs for details.
*
* Return:
* * %true if every byte between the end of the used member of the union and
* the end of that union is zeroed, or
* * %false otherwise.
*/
static __always_inline bool
pvr_ioctl_union_padding_check(void *instance, size_t union_offset,
size_t union_size, size_t member_size)
{
/*
* void pointer arithmetic is technically illegal - cast to a byte
* pointer so this addition works safely.
*/
void *padding_start = ((u8 *)instance) + union_offset + member_size;
size_t padding_size = union_size - member_size;
return !memchr_inv(padding_start, 0, padding_size);
}
/**
* PVR_STATIC_ASSERT_64BIT_ALIGNED() - Inline assertion for 64-bit alignment.
* @static_expr_: Target expression to evaluate.
*
* If @static_expr_ does not evaluate to a constant integer which would be a
* 64-bit aligned address (i.e. a multiple of 8), compilation will fail.
*
* Return:
* The value of @static_expr_.
*/
#define PVR_STATIC_ASSERT_64BIT_ALIGNED(static_expr_) \
({ \
static_assert(((static_expr_) & (sizeof(u64) - 1)) == 0); \
(static_expr_); \
})
/**
* PVR_IOCTL_UNION_PADDING_CHECK() - Validate that the implicit padding between
* the end of a union member and the end of the union itself is zeroed.
* @struct_instance_: An expression which evaluates to a pointer to a UAPI data
* struct.
* @union_: The name of the union member of @struct_instance_ to check. If the
* union member is nested within the type of @struct_instance_, this may
* contain the member access operator (".").
* @member_: The name of the member of @union_ to assess.
*
* This is a wrapper around pvr_ioctl_union_padding_check() which performs
* alignment checks and simplifies things for the caller.
*
* Return:
* * %true if every byte in @struct_instance_ between the end of @member_ and
* the end of @union_ is zeroed, or
* * %false otherwise.
*/
#define PVR_IOCTL_UNION_PADDING_CHECK(struct_instance_, union_, member_) \
({ \
typeof(struct_instance_) __instance = (struct_instance_); \
size_t __union_offset = PVR_STATIC_ASSERT_64BIT_ALIGNED( \
offsetof(typeof(*__instance), union_)); \
size_t __union_size = PVR_STATIC_ASSERT_64BIT_ALIGNED( \
sizeof(__instance->union_)); \
size_t __member_size = PVR_STATIC_ASSERT_64BIT_ALIGNED( \
sizeof(__instance->union_.member_)); \
pvr_ioctl_union_padding_check(__instance, __union_offset, \
__union_size, __member_size); \
})
#endif /* PVR_DEVICE_H */
This diff is collapsed.
/* SPDX-License-Identifier: GPL-2.0-only OR MIT */
/* Copyright (c) 2023 Imagination Technologies Ltd. */
#ifndef PVR_DRV_H
#define PVR_DRV_H
#include "linux/compiler_attributes.h"
#include <uapi/drm/pvr_drm.h>
#define PVR_DRIVER_NAME "powervr"
#define PVR_DRIVER_DESC "Imagination PowerVR (Series 6 and later) & IMG Graphics"
#define PVR_DRIVER_DATE "20230904"
/*
* Driver interface version:
* - 1.0: Initial interface
*/
#define PVR_DRIVER_MAJOR 1
#define PVR_DRIVER_MINOR 0
#define PVR_DRIVER_PATCHLEVEL 0
#endif /* PVR_DRV_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment