drm/tyr: use read_poll_timeout
Subsystems (4)
PATCH v2 1/1 drm/tyr: use read_poll_timeout
The L2 power-on sequence and soft reset in Tyr previously relied on fixed sleeps followed by a single register check, since polling helpers were not available in Rust at the time.
Now that read_poll_timeout() is available, poll the relevant registers until the hardware reports readiness or a timeout is reached.
This avoids unnecessary delays on start-up.
---
Changes in v2:
- Changed the commit message prefix to drm/tyr
- Replace if-let-Err blocks with inspect_err()
- Remove redundant register read from issue_soft_reset() error path,
to avoid nested error handling
- Link to v1: https://lore.kernel.org/rust-for-linux/[email protected]/
drivers/gpu/drm/tyr/driver.rs | 22 ++++++++-------------- drivers/gpu/drm/tyr/gpu.rs | 18 +++++++++--------- 2 files changed, 17 insertions(+), 23 deletions(-)
drivers/gpu/drm/tyr/driver.rs +8 -14
@@ -8,6 +8,7 @@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;
@@ -67,20 +68,13 @@ 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 )?; -// TODO: We cannot poll, as there is no support in Rust currently, so we -// sleep. Change this when read_poll_timeout() is implemented in Rust. - kernel::time::delay::fsleep (time::Delta ::from_millis (100 )); - -if regs::GPU_IRQ_RAWSTAT .read (dev, iomem)? & regs::GPU_IRQ_RAWSTAT_RESET_COMPLETED ==0 { -dev_err! (dev,"GPU reset failed with errno\n" ); -dev_err! ( - dev, -"GPU_INT_RAWSTAT is {}\n" , - regs::GPU_IRQ_RAWSTAT .read (dev, iomem)? - ); - -return Err (EIO ); - } + 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 (()) }
drivers/gpu/drm/tyr/gpu.rs +9 -9
@@ -6,9 +6,10 @@use kernel::device::Bound ;use kernel::device::Device ;use kernel::devres::Devres ; +use kernel::io::poll;use kernel::platform;use kernel::prelude::*; -use kernel::time; +use kernel::time::Delta ;use kernel::transmute::AsBytes ;use kernel::uapi;
@@ -204,14 +205,13 @@ fn from(value: u32) -> Self {pub (crate )fn l2_power_on (dev: &Device <Bound >, iomem: &Devres <IoMem >) ->Result { regs::L2_PWRON_LO .write (dev, iomem,1 )?; -// TODO: We cannot poll, as there is no support in Rust currently, so we -// sleep. Change this when read_poll_timeout() is implemented in Rust. - kernel::time::delay::fsleep (time::Delta ::from_millis (100 )); - -if regs::L2_READY_LO .read (dev, iomem)? !=1 { -dev_err! (dev,"Failed to power on the GPU\n" ); -return Err (EIO ); - } + poll::read_poll_timeout ( + || regs::L2_READY_LO .read (dev, iomem), + |status| *status ==1 , +Delta ::from_millis (1 ), +Delta ::from_millis (100 ), + ) + .inspect_err (|_|dev_err! (dev,"Failed to power on the GPU." ))?;Ok (()) }
Signature · 1 line
2.52.0
Quoted 10 lines · Deborah Brouwer
The L2 power-on sequence and soft reset in Tyr previously relied on fixed sleeps followed by a single register check, since polling helpers were not available in Rust at the time.
Now that
read_poll_timeout()is available, poll the relevant registers until the hardware reports readiness or a timeout is reached.This avoids unnecessary delays on start-up.
Signed-off-by Deborah Brouwer <[email protected]>
Overall looks good to me.
Quoted 10 lines · Deborah Brouwer
The L2 power-on sequence and soft reset in Tyr previously relied on fixed sleeps followed by a single register check, since polling helpers were not available in Rust at the time.
Now that
read_poll_timeout()is available, poll the relevant registers until the hardware reports readiness or a timeout is reached.This avoids unnecessary delays on start-up.
Signed-off-by Deborah Brouwer <[email protected]>
Merged into drm-rust-next, thanks!