mirror of
https://github.com/torvalds/linux.git
synced 2026-04-29 03:52:30 -04:00
Currently the rust compiler warns that certain fields in the TyrDriver are 'never read'. The fields are needed, but they are not read directly, they are only written into an 'impl PinInit' that is returned by probe. When warnings are compiled as errors, these warnings prevent Tyr from building. Suppress the warnings by adding underscores to the problematic variables. This allows Tyr to build again. Signed-off-by: Deborah Brouwer <deborah.brouwer@collabora.com> Link: https://patch.msgid.link/20260123175235.209092-1-deborah.brouwer@collabora.com Signed-off-by: Alice Ryhl <aliceryhl@google.com>
199 lines
5.6 KiB
Rust
199 lines
5.6 KiB
Rust
// SPDX-License-Identifier: GPL-2.0 or MIT
|
|
|
|
use kernel::clk::Clk;
|
|
use kernel::clk::OptionalClk;
|
|
use kernel::device::Bound;
|
|
use kernel::device::Core;
|
|
use kernel::device::Device;
|
|
use kernel::devres::Devres;
|
|
use kernel::drm;
|
|
use kernel::drm::ioctl;
|
|
use kernel::io::poll;
|
|
use kernel::new_mutex;
|
|
use kernel::of;
|
|
use kernel::platform;
|
|
use kernel::prelude::*;
|
|
use kernel::regulator;
|
|
use kernel::regulator::Regulator;
|
|
use kernel::sizes::SZ_2M;
|
|
use kernel::sync::aref::ARef;
|
|
use kernel::sync::Arc;
|
|
use kernel::sync::Mutex;
|
|
use kernel::time;
|
|
|
|
use crate::file::File;
|
|
use crate::gem::TyrObject;
|
|
use crate::gpu;
|
|
use crate::gpu::GpuInfo;
|
|
use crate::regs;
|
|
|
|
pub(crate) type IoMem = kernel::io::mem::IoMem<SZ_2M>;
|
|
|
|
/// Convenience type alias for the DRM device type for this driver.
|
|
pub(crate) type TyrDevice = drm::Device<TyrDriver>;
|
|
|
|
#[pin_data(PinnedDrop)]
|
|
pub(crate) struct TyrDriver {
|
|
_device: ARef<TyrDevice>,
|
|
}
|
|
|
|
#[pin_data(PinnedDrop)]
|
|
pub(crate) struct TyrData {
|
|
pub(crate) pdev: ARef<platform::Device>,
|
|
|
|
#[pin]
|
|
clks: Mutex<Clocks>,
|
|
|
|
#[pin]
|
|
regulators: Mutex<Regulators>,
|
|
|
|
/// Some information on the GPU.
|
|
///
|
|
/// This is mainly queried by userspace, i.e.: Mesa.
|
|
pub(crate) gpu_info: GpuInfo,
|
|
}
|
|
|
|
// Both `Clk` and `Regulator` do not implement `Send` or `Sync`, but they
|
|
// should. There are patches on the mailing list to address this, but they have
|
|
// not landed yet.
|
|
//
|
|
// For now, add this workaround so that this patch compiles with the promise
|
|
// that it will be removed in a future patch.
|
|
//
|
|
// SAFETY: This will be removed in a future patch.
|
|
unsafe impl Send for TyrData {}
|
|
// SAFETY: This will be removed in a future patch.
|
|
unsafe impl Sync for TyrData {}
|
|
|
|
fn issue_soft_reset(dev: &Device<Bound>, iomem: &Devres<IoMem>) -> Result {
|
|
regs::GPU_CMD.write(dev, iomem, regs::GPU_CMD_SOFT_RESET)?;
|
|
|
|
poll::read_poll_timeout(
|
|
|| regs::GPU_IRQ_RAWSTAT.read(dev, iomem),
|
|
|status| *status & regs::GPU_IRQ_RAWSTAT_RESET_COMPLETED != 0,
|
|
time::Delta::from_millis(1),
|
|
time::Delta::from_millis(100),
|
|
)
|
|
.inspect_err(|_| dev_err!(dev, "GPU reset failed."))?;
|
|
|
|
Ok(())
|
|
}
|
|
|
|
kernel::of_device_table!(
|
|
OF_TABLE,
|
|
MODULE_OF_TABLE,
|
|
<TyrDriver as platform::Driver>::IdInfo,
|
|
[
|
|
(of::DeviceId::new(c"rockchip,rk3588-mali"), ()),
|
|
(of::DeviceId::new(c"arm,mali-valhall-csf"), ())
|
|
]
|
|
);
|
|
|
|
impl platform::Driver for TyrDriver {
|
|
type IdInfo = ();
|
|
const OF_ID_TABLE: Option<of::IdTable<Self::IdInfo>> = Some(&OF_TABLE);
|
|
|
|
fn probe(
|
|
pdev: &platform::Device<Core>,
|
|
_info: Option<&Self::IdInfo>,
|
|
) -> impl PinInit<Self, Error> {
|
|
let core_clk = Clk::get(pdev.as_ref(), Some(c"core"))?;
|
|
let stacks_clk = OptionalClk::get(pdev.as_ref(), Some(c"stacks"))?;
|
|
let coregroup_clk = OptionalClk::get(pdev.as_ref(), Some(c"coregroup"))?;
|
|
|
|
core_clk.prepare_enable()?;
|
|
stacks_clk.prepare_enable()?;
|
|
coregroup_clk.prepare_enable()?;
|
|
|
|
let mali_regulator = Regulator::<regulator::Enabled>::get(pdev.as_ref(), c"mali")?;
|
|
let sram_regulator = Regulator::<regulator::Enabled>::get(pdev.as_ref(), c"sram")?;
|
|
|
|
let request = pdev.io_request_by_index(0).ok_or(ENODEV)?;
|
|
let iomem = Arc::pin_init(request.iomap_sized::<SZ_2M>(), GFP_KERNEL)?;
|
|
|
|
issue_soft_reset(pdev.as_ref(), &iomem)?;
|
|
gpu::l2_power_on(pdev.as_ref(), &iomem)?;
|
|
|
|
let gpu_info = GpuInfo::new(pdev.as_ref(), &iomem)?;
|
|
gpu_info.log(pdev);
|
|
|
|
let platform: ARef<platform::Device> = pdev.into();
|
|
|
|
let data = try_pin_init!(TyrData {
|
|
pdev: platform.clone(),
|
|
clks <- new_mutex!(Clocks {
|
|
core: core_clk,
|
|
stacks: stacks_clk,
|
|
coregroup: coregroup_clk,
|
|
}),
|
|
regulators <- new_mutex!(Regulators {
|
|
_mali: mali_regulator,
|
|
_sram: sram_regulator,
|
|
}),
|
|
gpu_info,
|
|
});
|
|
|
|
let tdev: ARef<TyrDevice> = drm::Device::new(pdev.as_ref(), data)?;
|
|
drm::driver::Registration::new_foreign_owned(&tdev, pdev.as_ref(), 0)?;
|
|
|
|
let driver = TyrDriver { _device: tdev };
|
|
|
|
// We need this to be dev_info!() because dev_dbg!() does not work at
|
|
// all in Rust for now, and we need to see whether probe succeeded.
|
|
dev_info!(pdev.as_ref(), "Tyr initialized correctly.\n");
|
|
Ok(driver)
|
|
}
|
|
}
|
|
|
|
#[pinned_drop]
|
|
impl PinnedDrop for TyrDriver {
|
|
fn drop(self: Pin<&mut Self>) {}
|
|
}
|
|
|
|
#[pinned_drop]
|
|
impl PinnedDrop for TyrData {
|
|
fn drop(self: Pin<&mut Self>) {
|
|
// TODO: the type-state pattern for Clks will fix this.
|
|
let clks = self.clks.lock();
|
|
clks.core.disable_unprepare();
|
|
clks.stacks.disable_unprepare();
|
|
clks.coregroup.disable_unprepare();
|
|
}
|
|
}
|
|
|
|
// We need to retain the name "panthor" to achieve drop-in compatibility with
|
|
// the C driver in the userspace stack.
|
|
const INFO: drm::DriverInfo = drm::DriverInfo {
|
|
major: 1,
|
|
minor: 5,
|
|
patchlevel: 0,
|
|
name: c"panthor",
|
|
desc: c"ARM Mali Tyr DRM driver",
|
|
};
|
|
|
|
#[vtable]
|
|
impl drm::Driver for TyrDriver {
|
|
type Data = TyrData;
|
|
type File = File;
|
|
type Object = drm::gem::Object<TyrObject>;
|
|
|
|
const INFO: drm::DriverInfo = INFO;
|
|
|
|
kernel::declare_drm_ioctls! {
|
|
(PANTHOR_DEV_QUERY, drm_panthor_dev_query, ioctl::RENDER_ALLOW, File::dev_query),
|
|
}
|
|
}
|
|
|
|
#[pin_data]
|
|
struct Clocks {
|
|
core: Clk,
|
|
stacks: OptionalClk,
|
|
coregroup: OptionalClk,
|
|
}
|
|
|
|
#[pin_data]
|
|
struct Regulators {
|
|
_mali: Regulator<regulator::Enabled>,
|
|
_sram: Regulator<regulator::Enabled>,
|
|
}
|