diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index 1cb5a4f1929335fcf0a135ccf7cc30acf958da8c..f6019a4c53206694b6f630e8be7d2096ca19908c 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -452,6 +452,7 @@ source "drivers/gpu/drm/lima/Kconfig" source "drivers/gpu/drm/panfrost/Kconfig" source "drivers/gpu/drm/panthor/Kconfig" +source "drivers/gpu/drm/panthor-rs/Kconfig" source "drivers/gpu/drm/aspeed/Kconfig" diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index 784229d4504dcb7d4ad6427fe238b024c5946946..f13d37d6d76871a42caa32f9565cca0df6283d1e 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -209,6 +209,7 @@ obj-$(CONFIG_DRM_VBOXVIDEO) += vboxvideo/ obj-$(CONFIG_DRM_LIMA) += lima/ obj-$(CONFIG_DRM_PANFROST) += panfrost/ obj-$(CONFIG_DRM_PANTHOR) += panthor/ +obj-$(CONFIG_DRM_PANTHOR_RS) += panthor-rs/ obj-$(CONFIG_DRM_ASPEED_GFX) += aspeed/ obj-$(CONFIG_DRM_MCDE) += mcde/ obj-$(CONFIG_DRM_TIDSS) += tidss/ diff --git a/drivers/gpu/drm/panthor-rs/Kconfig b/drivers/gpu/drm/panthor-rs/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..9356325f778cd2695b92b561e402c73c4fc32dec --- /dev/null +++ b/drivers/gpu/drm/panthor-rs/Kconfig @@ -0,0 +1,25 @@ +# SPDX-License-Identifier: GPL-2.0 or MIT + +config DRM_PANTHOR_RS + tristate "Panthor Rust-based (DRM support for ARM Mali CSF-based GPUs)" + depends on DRM=y + depends on RUST + depends on ARM || ARM64 || COMPILE_TEST + depends on !GENERIC_ATOMIC64 # for IOMMU_IO_PGTABLE_LPAE + depends on MMU + depends on DRM_PANTHOR=n + select DEVFREQ_GOV_SIMPLE_ONDEMAND + select DRM_EXEC + select DRM_GEM_SHMEM_HELPER + select DRM_GPUVM + select DRM_SCHED + select IOMMU_IO_PGTABLE_LPAE + depends on IOMMU_SUPPORT + select PM_DEVFREQ + help + DRM driver for ARM Mali CSF-based GPUs. + + This driver is for Mali (or Immortalis) Valhall Gxxx GPUs. + + Note that the Mali-G68 and Mali-G78, while Valhall architecture, will + be supported with the panfrost driver as they are not CSF GPUs. diff --git a/drivers/gpu/drm/panthor-rs/Makefile b/drivers/gpu/drm/panthor-rs/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..c39521d5ca9e3aa8929f113e65b51cf5f0215415 --- /dev/null +++ b/drivers/gpu/drm/panthor-rs/Makefile @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: GPL-2.0 or MIT + +panthor_rs-y := \ + panthor.o + +obj-$(CONFIG_DRM_PANTHOR_RS) += panthor_rs.o + +CFLAGS_panthor_drv.o := -Wno-missing-prototypes -Wno-unused-function -Wno-unused-const-variable diff --git a/drivers/gpu/drm/panthor-rs/driver.rs b/drivers/gpu/drm/panthor-rs/driver.rs new file mode 100644 index 0000000000000000000000000000000000000000..546c1df47b95e4baa23323688b5d7e5dced3fb81 --- /dev/null +++ b/drivers/gpu/drm/panthor-rs/driver.rs @@ -0,0 +1,145 @@ +// SPDX-License-Identifier: GPL-2.0-only OR MIT + +//! Top-level GPU driver implementation. + +use kernel::{ + bindings, c_str, drm, drm::drv, drm::ioctl, error::Result, of, platform, prelude::*, sync::Arc, +}; + +use core::ffi; +use kernel::macros::vtable; +use kernel::types::ARef; + +extern "C" { + fn panthor_device_init(ptdev: *mut bindings::panthor_device) -> ffi::c_int; +} + +/// Driver metadata +const INFO: drm::drv::DriverInfo = drm::drv::DriverInfo { + major: 0, + minor: 0, + patchlevel: 0, + name: c_str!("panthor"), + desc: c_str!("Panthor DRM driver"), + date: c_str!("20230801"), +}; + +/// Device data for the driver registration. +/// +/// Holds a reference to the top-level `GpuManager` object. +#[allow(dead_code)] +#[pin_data] +pub(crate) struct PanthorData { + #[pin] + pub(crate) ptdev: *mut bindings::panthor_device, + pub(crate) pdev: platform::Device, +} + +//HACK +unsafe impl Send for PanthorData {} +unsafe impl Sync for PanthorData {} + +pub(crate) struct PanthorDriver(ARef<PanthorDevice>); + +/// Convenience type alias for the DRM device type for this driver. +pub(crate) type PanthorDevice = kernel::drm::device::Device<PanthorDriver>; +pub(crate) type PanthorDevRef = ARef<PanthorDevice>; + +/// DRM Driver implementation for `PanthorDriver`. +#[vtable] +impl drv::Driver for PanthorDriver { + /// Our `DeviceData` type, reference-counted + type Data = Arc<PanthorData>; + /// Our `File` type. + type File = crate::file::File; + /// Our `Object` type. + type Object = crate::gem::Object; + + const INFO: drv::DriverInfo = INFO; + const FEATURES: u32 = drv::FEAT_GEM + | drv::FEAT_RENDER + | drv::FEAT_SYNCOBJ + | drv::FEAT_SYNCOBJ_TIMELINE + | drv::FEAT_GEM_GPUVA; + + kernel::declare_drm_ioctls! { + (PANTHOR_DEV_QUERY, drm_panthor_dev_query, + ioctl::RENDER_ALLOW, crate::file::File::dev_query), + (PANTHOR_VM_CREATE, drm_panthor_vm_create, + ioctl::RENDER_ALLOW, crate::file::File::vm_create), + (PANTHOR_VM_DESTROY, drm_panthor_vm_destroy, + ioctl::RENDER_ALLOW, crate::file::File::vm_destroy), + (PANTHOR_VM_BIND, drm_panthor_vm_bind, + ioctl::RENDER_ALLOW, crate::file::File::vm_bind), + (PANTHOR_VM_GET_STATE, drm_panthor_vm_get_state, + ioctl::RENDER_ALLOW, crate::file::File::vm_get_state), + (PANTHOR_BO_CREATE, drm_panthor_bo_create, + ioctl::RENDER_ALLOW, crate::file::File::bo_create), + (PANTHOR_BO_MMAP_OFFSET, drm_panthor_bo_mmap_offset, + ioctl::RENDER_ALLOW, crate::file::File::bo_mmap_offset), + (PANTHOR_GROUP_CREATE, drm_panthor_group_create, + ioctl::RENDER_ALLOW, crate::file::File::group_create), + (PANTHOR_GROUP_DESTROY, drm_panthor_group_destroy, + ioctl::RENDER_ALLOW, crate::file::File::group_destroy), + (PANTHOR_GROUP_SUBMIT, drm_panthor_group_submit, + ioctl::RENDER_ALLOW, crate::file::File::group_submit), + (PANTHOR_GROUP_GET_STATE, drm_panthor_group_get_state, + ioctl::RENDER_ALLOW, crate::file::File::group_get_state), + (PANTHOR_TILER_HEAP_CREATE, drm_panthor_tiler_heap_create, + ioctl::RENDER_ALLOW, crate::file::File::tiler_heap_create), + (PANTHOR_TILER_HEAP_DESTROY, drm_panthor_tiler_heap_destroy, + ioctl::RENDER_ALLOW, crate::file::File::tiler_heap_destroy), + } +} + +kernel::of_device_table!( + OF_TABLE, + MODULE_OF_TABLE, + <PanthorDriver as platform::Driver>::IdInfo, + [ + (of::DeviceId::new(c_str!("rockchip,rk3588-mali")), ()), + (of::DeviceId::new(c_str!("arm,mali-valhall-csf")), ()), + ] +); + +/// Platform Driver implementation for `PanthorDriver`. +impl platform::Driver for PanthorDriver { + type IdInfo = (); + const ID_TABLE: platform::IdTable<Self::IdInfo> = &OF_TABLE; + + /// Device probe function. + fn probe( + pdev: &mut platform::Device, + id_info: Option<&Self::IdInfo>, + ) -> Result<Pin<KBox<Self>>> { + dev_info!(pdev.as_ref(), "Probing...\n"); + + let data = Arc::new( + PanthorData { + ptdev: unsafe { bindings::panthor_device_alloc() }, + pdev: pdev.clone(), + }, + GFP_KERNEL, + )?; + + let drm = drm::device::Device::<PanthorDriver>::new(pdev.as_ref(), data.clone())?; + + unsafe { + (*data.ptdev).base = drm.as_raw(); + panthor_device_init(data.ptdev); + } + + drm::drv::Registration::new_foreign_owned(drm.clone(), 0)?; + + dev_info!(pdev.as_ref(), "Probed!\n"); + Ok(KBox::new(Self(drm), GFP_KERNEL)?.into()) + } +} + +impl Drop for PanthorDriver { + fn drop(&mut self) { + let data = self.0.data(); + + dev_dbg!(data.pdev.as_ref(), "Remove Panthor GPU driver.\n"); + } +} diff --git a/drivers/gpu/drm/panthor-rs/file.rs b/drivers/gpu/drm/panthor-rs/file.rs new file mode 100644 index 0000000000000000000000000000000000000000..1146fbefda5bf0c51524dc4106b6ac6a9df2c811 --- /dev/null +++ b/drivers/gpu/drm/panthor-rs/file.rs @@ -0,0 +1,164 @@ +// SPDX-License-Identifier: GPL-2.0-only OR MIT +#![allow(clippy::unusual_byte_groupings)] + +//! File implementation, which represents a single DRM client. +//! +//! This is in charge of managing the resources associated with one GPU client, including an +//! arbitrary number of submission queues and Vm objects, and reporting hardware/driver +//! information to userspace and accepting submissions. + +//use crate::debug::*; +use crate::driver::PanthorDevice; +use crate::driver::PanthorDriver; +//use crate::{alloc, buffer, driver, gem, mmu, queue, util::RangeExt}; +//use kernel::drm::gem::BaseObject; +//use kernel::io_buffer::{IoBufferReader, IoBufferWriter}; +use core; +use core::ffi; +use core::ptr; +use kernel::prelude::*; +use kernel::{ + drm::file::GenericFile, + drm::{self, device::Device as DrmDevice}, + error::to_result, + uapi, +}; + +/// Convenience type alias for our DRM `File` type. +pub(crate) type DrmFile = drm::file::File<File>; + +/// State associated with a client. +pub(crate) struct File(); + +impl drm::file::DriverFile for File { + type Driver = PanthorDriver; + + fn open(_dev: &DrmDevice<Self::Driver>) -> Result<Pin<Box<Self>>> { + pr_info!("DRM Device :: open()\n"); + + Ok(Box::into_pin(Box::new(Self(), GFP_KERNEL)?)) + } +} + +impl File { + /// IOCTL: dev_query + pub(crate) fn dev_query( + device: &PanthorDevice, + data: &mut uapi::drm_panthor_dev_query, + _file: &DrmFile, + ) -> Result<u32> { + Ok(0) + } + + /// IOCTL: vm_create + pub(crate) fn vm_create( + device: &PanthorDevice, + data: &mut uapi::drm_panthor_vm_create, + file: &DrmFile, + ) -> Result<u32> { + Ok(0) + } + + /// IOCTL: vm_destroy + pub(crate) fn vm_destroy( + _device: &PanthorDevice, + data: &mut uapi::drm_panthor_vm_destroy, + file: &DrmFile, + ) -> Result<u32> { + Ok(0) + } + + /// IOCTL: vm_bind + pub(crate) fn vm_bind( + _device: &PanthorDevice, + data: &mut uapi::drm_panthor_vm_bind, + file: &DrmFile, + ) -> Result<u32> { + Ok(0) + } + + /// IOCTL: vm_get_state + pub(crate) fn vm_get_state( + _device: &PanthorDevice, + data: &mut uapi::drm_panthor_vm_get_state, + file: &DrmFile, + ) -> Result<u32> { + Ok(0) + } + + /// IOCTL: bo_create + pub(crate) fn bo_create( + device: &PanthorDevice, + data: &mut uapi::drm_panthor_bo_create, + file: &DrmFile, + ) -> Result<u32> { + Ok(0) + } + + /// IOCTL: bo_mmap_offset + pub(crate) fn bo_mmap_offset( + _device: &PanthorDevice, + _data: &mut uapi::drm_panthor_bo_mmap_offset, + _file: &DrmFile, + ) -> Result<u32> { + Ok(0) + } + + /// IOCTL: group_create + pub(crate) fn group_create( + _device: &PanthorDevice, + data: &mut uapi::drm_panthor_group_create, + file: &DrmFile, + ) -> Result<u32> { + Ok(0) + } + + /// IOCTL: group_destroy + pub(crate) fn group_destroy( + _device: &PanthorDevice, + data: &mut uapi::drm_panthor_group_destroy, + file: &DrmFile, + ) -> Result<u32> { + Ok(0) + } + + /// IOCTL: group_get_state + pub(crate) fn group_get_state( + _device: &PanthorDevice, + data: &mut uapi::drm_panthor_group_get_state, + file: &DrmFile, + ) -> Result<u32> { + Ok(0) + } + + /// IOCTL: tiler_heap_create + pub(crate) fn tiler_heap_create( + _device: &PanthorDevice, + data: &mut uapi::drm_panthor_tiler_heap_create, + file: &DrmFile, + ) -> Result<u32> { + Ok(0) + } + + /// IOCTL: tiler_heap_destroy + pub(crate) fn tiler_heap_destroy( + _device: &PanthorDevice, + data: &mut uapi::drm_panthor_tiler_heap_destroy, + file: &DrmFile, + ) -> Result<u32> { + Ok(0) + } + + /// IOCTL: group_submit + pub(crate) fn group_submit( + device: &PanthorDevice, + data: &mut uapi::drm_panthor_group_submit, + file: &DrmFile, + ) -> Result<u32> { + Ok(0) + } +} + +impl Drop for File { + fn drop(&mut self) {} +} diff --git a/drivers/gpu/drm/panthor-rs/gem.rs b/drivers/gpu/drm/panthor-rs/gem.rs new file mode 100644 index 0000000000000000000000000000000000000000..8e824bcd591f98c4d7f15741b9d0052e7b577f7d --- /dev/null +++ b/drivers/gpu/drm/panthor-rs/gem.rs @@ -0,0 +1,29 @@ +use core::sync::atomic::{AtomicU64, Ordering}; + +use kernel::{drm::gem, prelude::*}; + +use crate::driver::{PanthorDevice, PanthorDriver}; + +static GEM_ID: AtomicU64 = AtomicU64::new(0); + +/// GEM Object implementation +#[pin_data] +pub(crate) struct DriverObject { + /// ID for debugging + id: u64, +} + +pub(crate) type Object = gem::Object<DriverObject>; + +impl gem::BaseDriverObject<Object> for DriverObject { + fn new(_dev: &PanthorDevice, _size: usize) -> impl PinInit<Self, Error> { + let id = GEM_ID.fetch_add(1, Ordering::Relaxed); + + pr_debug!("DriverObject::new() id={}\n", id); + DriverObject { id } + } +} + +impl gem::DriverObject for DriverObject { + type Driver = PanthorDriver; +} diff --git a/drivers/gpu/drm/panthor-rs/panthor.rs b/drivers/gpu/drm/panthor-rs/panthor.rs new file mode 100644 index 0000000000000000000000000000000000000000..a177f8b6eee9e987353b262d9751499cbf1b58af --- /dev/null +++ b/drivers/gpu/drm/panthor-rs/panthor.rs @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: GPL-2.0-only OR MIT +#![recursion_limit = "2048"] + +//! Driver for the Arm Mali CSF-based GPUs. + +#![allow(improper_ctypes)] +#![allow(dead_code)] +#![allow(unused_variables)] + +mod driver; +mod file; +mod gem; + +use kernel::module_platform_driver; + +module_platform_driver! { + type: driver::PanthorDriver, + name: "panthor_rs", + author: "Arm", + license: "Dual MIT/GPL", +} diff --git a/drivers/gpu/drm/panthor-rs/panthor_device.c b/drivers/gpu/drm/panthor-rs/panthor_device.c index 6dcc4b55c05a0389f9a0c4a7613f1f874ede003f..e4a88a8dcb4e16047ccd7bf7f0ad40295799272d 100644 --- a/drivers/gpu/drm/panthor-rs/panthor_device.c +++ b/drivers/gpu/drm/panthor-rs/panthor_device.c @@ -271,6 +271,13 @@ int panthor_device_init(struct panthor_device *ptdev) return ret; } +struct panthor_device *panthor_device_alloc(void) +{ + struct panthor_device *ptdev = kzalloc(sizeof(struct panthor_device), GFP_KERNEL); + return ptdev; +} + + #define PANTHOR_EXCEPTION(id) \ [DRM_PANTHOR_EXCEPTION_ ## id] = { \ .name = #id, \ diff --git a/drivers/gpu/drm/panthor-rs/panthor_device.h b/drivers/gpu/drm/panthor-rs/panthor_device.h index 2bdf6270d06806ed1556b6771cd4f51147547f71..cfc832110b3ecf654cb298ccc7c2de1c80eec024 100644 --- a/drivers/gpu/drm/panthor-rs/panthor_device.h +++ b/drivers/gpu/drm/panthor-rs/panthor_device.h @@ -180,6 +180,8 @@ struct panthor_file { }; int panthor_device_init(struct panthor_device *ptdev); +struct panthor_device *panthor_device_alloc(void); + void panthor_device_unplug(struct panthor_device *ptdev); /** diff --git a/rust/bindings/bindings_helper.h b/rust/bindings/bindings_helper.h index e1ddee135d12a0fdc5595843919e43e905e31b04..8de125de722545cd2965f03a45e96273b2f89b59 100644 --- a/rust/bindings/bindings_helper.h +++ b/rust/bindings/bindings_helper.h @@ -32,6 +32,8 @@ #include <linux/wait.h> #include <linux/workqueue.h> +#include <../drivers/gpu/drm/panthor-rs/panthor_device.h> + /* `bindgen` gets confused at certain things. */ const size_t RUST_CONST_HELPER_ARCH_SLAB_MINALIGN = ARCH_SLAB_MINALIGN; const size_t RUST_CONST_HELPER_PAGE_SIZE = PAGE_SIZE; diff --git a/rust/kernel/drm/gem/mod.rs b/rust/kernel/drm/gem/mod.rs index e4e060d93ad12e1cb577cec5499389adf66e36a9..d0baf52b7a6241d7b73f2f3bb29d611a9264f7a4 100644 --- a/rust/kernel/drm/gem/mod.rs +++ b/rust/kernel/drm/gem/mod.rs @@ -412,5 +412,6 @@ pub(super) const fn create_fops() -> bindings::file_operations { fops.mmap = Some(bindings::drm_gem_mmap); fops.fop_flags = bindings::FOP_UNSIGNED_OFFSET; + fops.fop_flags = 1 << 5; // FIXME use FOP_UNSIGNED_OFFSET fops } diff --git a/rust/uapi/uapi_helper.h b/rust/uapi/uapi_helper.h index 19587e55e604128d405a0cffa5059e75273199d3..7a78013c3ecb5f185b09b705d3bc6a16fe95c305 100644 --- a/rust/uapi/uapi_helper.h +++ b/rust/uapi/uapi_helper.h @@ -8,6 +8,7 @@ #include <uapi/asm-generic/ioctl.h> #include <uapi/drm/drm.h> +#include <uapi/drm/panthor_drm.h> #include <uapi/linux/mdio.h> #include <uapi/linux/mii.h> #include <uapi/linux/ethtool.h>