]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
Merge tag 'v7.0-rc4' into drm-rust-next
authorDanilo Krummrich <dakr@kernel.org>
Sun, 15 Mar 2026 20:55:47 +0000 (21:55 +0100)
committerDanilo Krummrich <dakr@kernel.org>
Sun, 15 Mar 2026 21:58:48 +0000 (22:58 +0100)
We need the latest fixes from drm-rust-fixes in drm-rust-next as well to
build on top of.

Signed-off-by: Danilo Krummrich <dakr@kernel.org>
1  2 
drivers/gpu/nova-core/gsp/boot.rs
drivers/gpu/nova-core/gsp/cmdq.rs
drivers/gpu/nova-core/gsp/fw.rs

Simple merge
index e0b096546d2337ed1060822288805f4f0f9b66d9,03a4f359984988c6c6a3ed3b4c8f7df89f1a0d0f..efa1aab1568f2ae5e57a578cadc0cb80f763be66
@@@ -1,14 -1,9 +1,8 @@@
  // SPDX-License-Identifier: GPL-2.0
  
 -use core::{
 -    cmp,
 -    mem, //
 -};
 +mod continuation;
 +
- use core::{
-     mem,
-     sync::atomic::{
-         fence,
-         Ordering, //
-     }, //
- };
++use core::mem;
  
  use kernel::{
      device,
@@@ -170,21 -154,24 +165,26 @@@ pub(super) struct Msgq 
  
  /// Structure shared between the driver and the GSP and containing the command and message queues.
  #[repr(C)]
- struct GspMem {
+ // TODO: Revert to private once `IoView` projections replace the `gsp_mem` module.
+ pub(super) struct GspMem {
      /// Self-mapping page table entries.
-     ptes: PteArray<{ GSP_PAGE_SIZE / size_of::<u64>() }>,
+     ptes: PteArray<{ Self::PTE_ARRAY_SIZE }>,
      /// CPU queue: the driver writes commands here, and the GSP reads them. It also contains the
 -    /// write and read pointers that the CPU updates.
 +    /// write and read pointers that the CPU updates. This means that the read pointer here is an
 +    /// index into the GSP queue.
      ///
      /// This member is read-only for the GSP.
-     cpuq: Msgq,
+     pub(super) cpuq: Msgq,
      /// GSP queue: the GSP writes messages here, and the driver reads them. It also contains the
 -    /// write and read pointers that the GSP updates.
 +    /// write and read pointers that the GSP updates. This means that the read pointer here is an
 +    /// index into the CPU queue.
      ///
      /// This member is read-only for the driver.
-     gspq: Msgq,
+     pub(super) gspq: Msgq,
+ }
+ impl GspMem {
+     const PTE_ARRAY_SIZE: usize = GSP_PAGE_SIZE / size_of::<u64>();
  }
  
  // SAFETY: These structs don't meet the no-padding requirements of AsBytes but
@@@ -359,42 -327,27 +369,27 @@@ impl DmaGspMem 
      //
      // # Invariants
      //
 -    // - The returned value is between `0` and `MSGQ_NUM_PAGES`.
 +    // - The returned value is within `0..MSGQ_NUM_PAGES`.
      fn gsp_write_ptr(&self) -> u32 {
-         let gsp_mem = self.0.start_ptr();
-         // SAFETY:
-         //  - The 'CoherentAllocation' contains at least one object.
-         //  - By the invariants of `CoherentAllocation` the pointer is valid.
-         (unsafe { (*gsp_mem).gspq.tx.write_ptr() } % MSGQ_NUM_PAGES)
+         super::fw::gsp_mem::gsp_write_ptr(&self.0)
      }
  
      // Returns the index of the memory page the GSP will read the next command from.
      //
      // # Invariants
      //
 -    // - The returned value is between `0` and `MSGQ_NUM_PAGES`.
 +    // - The returned value is within `0..MSGQ_NUM_PAGES`.
      fn gsp_read_ptr(&self) -> u32 {
-         let gsp_mem = self.0.start_ptr();
-         // SAFETY:
-         //  - The 'CoherentAllocation' contains at least one object.
-         //  - By the invariants of `CoherentAllocation` the pointer is valid.
-         (unsafe { (*gsp_mem).gspq.rx.read_ptr() } % MSGQ_NUM_PAGES)
+         super::fw::gsp_mem::gsp_read_ptr(&self.0)
      }
  
      // Returns the index of the memory page the CPU can read the next message from.
      //
      // # Invariants
      //
 -    // - The returned value is between `0` and `MSGQ_NUM_PAGES`.
 +    // - The returned value is within `0..MSGQ_NUM_PAGES`.
      fn cpu_read_ptr(&self) -> u32 {
-         let gsp_mem = self.0.start_ptr();
-         // SAFETY:
-         //  - The ['CoherentAllocation'] contains at least one object.
-         //  - By the invariants of CoherentAllocation the pointer is valid.
-         (unsafe { (*gsp_mem).cpuq.rx.read_ptr() } % MSGQ_NUM_PAGES)
+         super::fw::gsp_mem::cpu_read_ptr(&self.0)
      }
  
      // Informs the GSP that it can send `elem_count` new pages into the message queue.
      //
      // # Invariants
      //
 -    // - The returned value is between `0` and `MSGQ_NUM_PAGES`.
 +    // - The returned value is within `0..MSGQ_NUM_PAGES`.
      fn cpu_write_ptr(&self) -> u32 {
-         let gsp_mem = self.0.start_ptr();
-         // SAFETY:
-         //  - The 'CoherentAllocation' contains at least one object.
-         //  - By the invariants of `CoherentAllocation` the pointer is valid.
-         (unsafe { (*gsp_mem).cpuq.tx.write_ptr() } % MSGQ_NUM_PAGES)
+         super::fw::gsp_mem::cpu_write_ptr(&self.0)
      }
  
      // Informs the GSP that it can process `elem_count` new pages from the command queue.
index 25fca1f6db2c8e5e2857a92d6bf9f662759b26fc,040b30ec3089b102c36f2296e5ee43195f2830fb..a061131b54125194a22edda7dfa9a7260306b483
@@@ -39,10 -40,75 +39,79 @@@ use crate::
      },
  };
  
+ // TODO: Replace with `IoView` projections once available; the `unwrap()` calls go away once we
+ // switch to the new `dma::Coherent` API.
+ pub(super) mod gsp_mem {
+     use core::sync::atomic::{
+         fence,
+         Ordering, //
+     };
+     use kernel::{
+         dma::CoherentAllocation,
+         dma_read,
+         dma_write,
+         prelude::*, //
+     };
+     use crate::gsp::cmdq::{
+         GspMem,
+         MSGQ_NUM_PAGES, //
+     };
+     pub(in crate::gsp) fn gsp_write_ptr(qs: &CoherentAllocation<GspMem>) -> u32 {
+         // PANIC: A `dma::CoherentAllocation` always contains at least one element.
+         || -> Result<u32> { Ok(dma_read!(qs, [0]?.gspq.tx.0.writePtr) % MSGQ_NUM_PAGES) }().unwrap()
+     }
+     pub(in crate::gsp) fn gsp_read_ptr(qs: &CoherentAllocation<GspMem>) -> u32 {
+         // PANIC: A `dma::CoherentAllocation` always contains at least one element.
+         || -> Result<u32> { Ok(dma_read!(qs, [0]?.gspq.rx.0.readPtr) % MSGQ_NUM_PAGES) }().unwrap()
+     }
+     pub(in crate::gsp) fn cpu_read_ptr(qs: &CoherentAllocation<GspMem>) -> u32 {
+         // PANIC: A `dma::CoherentAllocation` always contains at least one element.
+         || -> Result<u32> { Ok(dma_read!(qs, [0]?.cpuq.rx.0.readPtr) % MSGQ_NUM_PAGES) }().unwrap()
+     }
+     pub(in crate::gsp) fn advance_cpu_read_ptr(qs: &CoherentAllocation<GspMem>, count: u32) {
+         let rptr = cpu_read_ptr(qs).wrapping_add(count) % MSGQ_NUM_PAGES;
+         // Ensure read pointer is properly ordered.
+         fence(Ordering::SeqCst);
+         // PANIC: A `dma::CoherentAllocation` always contains at least one element.
+         || -> Result {
+             dma_write!(qs, [0]?.cpuq.rx.0.readPtr, rptr);
+             Ok(())
+         }()
+         .unwrap()
+     }
+     pub(in crate::gsp) fn cpu_write_ptr(qs: &CoherentAllocation<GspMem>) -> u32 {
+         // PANIC: A `dma::CoherentAllocation` always contains at least one element.
+         || -> Result<u32> { Ok(dma_read!(qs, [0]?.cpuq.tx.0.writePtr) % MSGQ_NUM_PAGES) }().unwrap()
+     }
+     pub(in crate::gsp) fn advance_cpu_write_ptr(qs: &CoherentAllocation<GspMem>, count: u32) {
+         let wptr = cpu_write_ptr(qs).wrapping_add(count) % MSGQ_NUM_PAGES;
+         // PANIC: A `dma::CoherentAllocation` always contains at least one element.
+         || -> Result {
+             dma_write!(qs, [0]?.cpuq.tx.0.writePtr, wptr);
+             Ok(())
+         }()
+         .unwrap();
+         // Ensure all command data is visible before triggering the GSP read.
+         fence(Ordering::SeqCst);
+     }
+ }
 +/// Maximum size of a single GSP message queue element in bytes.
 +pub(crate) const GSP_MSG_QUEUE_ELEMENT_SIZE_MAX: usize =
 +    num::u32_as_usize(bindings::GSP_MSG_QUEUE_ELEMENT_SIZE_MAX);
 +
  /// Empty type to group methods related to heap parameters for running the GSP firmware.
  enum GspFwHeapParams {}