Add scu peripheral to the ast10x0 peripheral crate
diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index 0ecaa0c..367e137 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock
@@ -2698,7 +2698,7 @@ "bzlTransitiveDigest": "3kVt1CoIJVJiOv5hhXwKcnZWdFwwoEOhc/OeC2GrMQU=", "usagesDigest": "/Nz9QH+EBlDXoVXWiAEH8owsAo1cu+GkXjlRdolG7Sk=", "recordedFileInputs": { - "@@//third_party/crates_io/Cargo.lock": "bbc7b14d634194e289a36caa99b437e0c1b88162219fa5aa719a915fbe86c261", + "@@//third_party/crates_io/Cargo.lock": "3e43f044148e1cf344654ede226b070849ed6b56be5b1a013ee0a63c56718d85", "@@//third_party/crates_io/Cargo.toml": "e8006d3d6342dc0bf39342da3c6359fafa48e5660e085347f89a01cba529dbd0", "@@caliptra_deps+//crates_io/embedded/Cargo.lock": "d6c0101f48da22f2bc2d339f358de79bad3dd03218c6db29a14099b9f7757691", "@@caliptra_deps+//crates_io/embedded/Cargo.toml": "8f9f4ed2721db13476b12fdac045dac2142b38f189a8abb5f4c446dc0c6ac3dd",
diff --git a/target/ast10x0/peripherals/BUILD.bazel b/target/ast10x0/peripherals/BUILD.bazel index d534467..254e9d4 100644 --- a/target/ast10x0/peripherals/BUILD.bazel +++ b/target/ast10x0/peripherals/BUILD.bazel
@@ -10,6 +10,13 @@ name = "peripherals", srcs = [ "lib.rs", + "scu/mod.rs", + "scu/registers.rs", + "scu/types.rs", + "scu/reset.rs", + "scu/clock.rs", + "scu/status.rs", + "scu/pinctrl.rs", "uart/mod.rs", ], crate_name = "ast10x0_peripherals", @@ -23,4 +30,7 @@ "@rust_crates//:embedded-io", "@rust_crates//:nb", ], + proc_macro_deps = [ + "@rust_crates//:paste", + ], )
diff --git a/target/ast10x0/peripherals/lib.rs b/target/ast10x0/peripherals/lib.rs index 8f15bfa..b9084e9 100644 --- a/target/ast10x0/peripherals/lib.rs +++ b/target/ast10x0/peripherals/lib.rs
@@ -3,4 +3,5 @@ #![no_std] +pub mod scu; pub mod uart;
diff --git a/target/ast10x0/peripherals/scu/clock.rs b/target/ast10x0/peripherals/scu/clock.rs new file mode 100644 index 0000000..b1e21db --- /dev/null +++ b/target/ast10x0/peripherals/scu/clock.rs
@@ -0,0 +1,46 @@ +// Licensed under the Apache-2.0 license +// SPDX-License-Identifier: Apache-2.0 + +//! SCU clock gate helpers. + +use super::registers::ScuRegisters; +use super::types::ClockRegisterHalf; + +impl ScuRegisters { + /// Gate clocks by setting bits in the selected clock-stop register half. + /// + /// Caller must call `unlock_write_protection()` before this. + pub fn gate_clock_mask(&self, half: ClockRegisterHalf, mask: u32) { + match half { + ClockRegisterHalf::Lower => { + self.regs().scu080().write(|w| unsafe { w.bits(mask) }); + } + ClockRegisterHalf::Upper => { + self.regs().scu090().write(|w| unsafe { w.bits(mask) }); + } + } + } + + /// Ungate clocks by clearing bits in the selected clock-stop register half. + /// + /// Caller must call `unlock_write_protection()` before this. + pub fn ungate_clock_mask(&self, half: ClockRegisterHalf, mask: u32) { + match half { + ClockRegisterHalf::Lower => { + self.regs().scu084().write(|w| unsafe { w.bits(mask) }); + } + ClockRegisterHalf::Upper => { + self.regs().scu094().write(|w| unsafe { w.bits(mask) }); + } + } + } + + /// Read the selected clock-stop register half. + #[must_use] + pub fn gated_clock_mask(&self, half: ClockRegisterHalf) -> u32 { + match half { + ClockRegisterHalf::Lower => self.regs().scu080().read().bits(), + ClockRegisterHalf::Upper => self.regs().scu090().read().bits(), + } + } +} \ No newline at end of file
diff --git a/target/ast10x0/peripherals/scu/mod.rs b/target/ast10x0/peripherals/scu/mod.rs new file mode 100644 index 0000000..fc6468a --- /dev/null +++ b/target/ast10x0/peripherals/scu/mod.rs
@@ -0,0 +1,15 @@ +// Licensed under the Apache-2.0 license +// SPDX-License-Identifier: Apache-2.0 + +//! AST10x0 System Control Unit (SCU) module. + +pub mod registers; +pub mod types; +pub mod reset; +pub mod clock; +pub mod status; +pub mod pinctrl; + +pub use registers::ScuRegisters; +pub use pinctrl::PinctrlPin; +pub use types::{ClockRegisterHalf, ScuRegisterHalf}; \ No newline at end of file
diff --git a/target/ast10x0/peripherals/scu/pinctrl.rs b/target/ast10x0/peripherals/scu/pinctrl.rs new file mode 100644 index 0000000..bd92529 --- /dev/null +++ b/target/ast10x0/peripherals/scu/pinctrl.rs
@@ -0,0 +1,593 @@ +// Licensed under the Apache-2.0 license +// SPDX-License-Identifier: Apache-2.0 + +//! SCU Pin Control (Pinctrl) for multi-function pin configuration. +//! +//! Provides register-level access to configure AST1060 pins for different +//! functions (I2C, I3C, GPIO, etc.) via SCU multiplex registers. + +use super::ScuRegisters; +use paste::paste; + +/// Describes a single pin configuration operation. +#[derive(Clone, Copy, Debug)] +pub struct PinctrlPin { + /// SCU register offset (0x410, 0x414, 0x690, etc.) + pub offset: u32, + /// Bit position within the register (0-31) + pub bit: u32, + /// true = clear bit, false = set bit + pub clear: bool, +} + +/// Macro to generate paired pin constants for set/clear operations. +macro_rules! gen_pin_pairs { + ($reg_name:ident, $offset:expr, $bit:expr) => { + paste! { + pub const [<PIN_ $reg_name _ $bit>]: PinctrlPin = PinctrlPin { + offset: $offset, + bit: $bit, + clear: false, + }; + + pub const [<CLR_PIN_ $reg_name _ $bit>]: PinctrlPin = PinctrlPin { + offset: $offset, + bit: $bit, + clear: true, + }; + } + }; +} + +// Generate individual pin constants for each SCU register and bit position +paste! { + gen_pin_pairs!(SCU410, 0x410, 0); + gen_pin_pairs!(SCU410, 0x410, 1); + gen_pin_pairs!(SCU410, 0x410, 2); + gen_pin_pairs!(SCU410, 0x410, 3); + gen_pin_pairs!(SCU410, 0x410, 4); + gen_pin_pairs!(SCU410, 0x410, 5); + gen_pin_pairs!(SCU410, 0x410, 6); + gen_pin_pairs!(SCU410, 0x410, 7); + gen_pin_pairs!(SCU410, 0x410, 8); + gen_pin_pairs!(SCU410, 0x410, 9); + gen_pin_pairs!(SCU410, 0x410, 10); + gen_pin_pairs!(SCU410, 0x410, 11); + gen_pin_pairs!(SCU410, 0x410, 12); + gen_pin_pairs!(SCU410, 0x410, 13); + gen_pin_pairs!(SCU410, 0x410, 14); + gen_pin_pairs!(SCU410, 0x410, 15); + gen_pin_pairs!(SCU410, 0x410, 16); + gen_pin_pairs!(SCU410, 0x410, 17); + gen_pin_pairs!(SCU410, 0x410, 18); + gen_pin_pairs!(SCU410, 0x410, 19); + gen_pin_pairs!(SCU410, 0x410, 20); + gen_pin_pairs!(SCU410, 0x410, 21); + gen_pin_pairs!(SCU410, 0x410, 22); + gen_pin_pairs!(SCU410, 0x410, 23); + gen_pin_pairs!(SCU410, 0x410, 24); + gen_pin_pairs!(SCU410, 0x410, 25); + gen_pin_pairs!(SCU410, 0x410, 26); + gen_pin_pairs!(SCU410, 0x410, 27); + gen_pin_pairs!(SCU410, 0x410, 28); + gen_pin_pairs!(SCU410, 0x410, 29); + gen_pin_pairs!(SCU410, 0x410, 30); + gen_pin_pairs!(SCU410, 0x410, 31); + + gen_pin_pairs!(SCU414, 0x414, 0); + gen_pin_pairs!(SCU414, 0x414, 1); + gen_pin_pairs!(SCU414, 0x414, 2); + gen_pin_pairs!(SCU414, 0x414, 3); + gen_pin_pairs!(SCU414, 0x414, 4); + gen_pin_pairs!(SCU414, 0x414, 5); + gen_pin_pairs!(SCU414, 0x414, 6); + gen_pin_pairs!(SCU414, 0x414, 7); + gen_pin_pairs!(SCU414, 0x414, 8); + gen_pin_pairs!(SCU414, 0x414, 9); + gen_pin_pairs!(SCU414, 0x414, 10); + gen_pin_pairs!(SCU414, 0x414, 11); + gen_pin_pairs!(SCU414, 0x414, 12); + gen_pin_pairs!(SCU414, 0x414, 13); + gen_pin_pairs!(SCU414, 0x414, 14); + gen_pin_pairs!(SCU414, 0x414, 15); + gen_pin_pairs!(SCU414, 0x414, 16); + gen_pin_pairs!(SCU414, 0x414, 17); + gen_pin_pairs!(SCU414, 0x414, 18); + gen_pin_pairs!(SCU414, 0x414, 19); + gen_pin_pairs!(SCU414, 0x414, 20); + gen_pin_pairs!(SCU414, 0x414, 21); + gen_pin_pairs!(SCU414, 0x414, 22); + gen_pin_pairs!(SCU414, 0x414, 23); + gen_pin_pairs!(SCU414, 0x414, 24); + gen_pin_pairs!(SCU414, 0x414, 25); + gen_pin_pairs!(SCU414, 0x414, 26); + gen_pin_pairs!(SCU414, 0x414, 27); + gen_pin_pairs!(SCU414, 0x414, 28); + gen_pin_pairs!(SCU414, 0x414, 29); + gen_pin_pairs!(SCU414, 0x414, 30); + gen_pin_pairs!(SCU414, 0x414, 31); + + gen_pin_pairs!(SCU418, 0x418, 0); + gen_pin_pairs!(SCU418, 0x418, 1); + gen_pin_pairs!(SCU418, 0x418, 2); + gen_pin_pairs!(SCU418, 0x418, 3); + gen_pin_pairs!(SCU418, 0x418, 4); + gen_pin_pairs!(SCU418, 0x418, 5); + gen_pin_pairs!(SCU418, 0x418, 6); + gen_pin_pairs!(SCU418, 0x418, 7); + gen_pin_pairs!(SCU418, 0x418, 8); + gen_pin_pairs!(SCU418, 0x418, 9); + gen_pin_pairs!(SCU418, 0x418, 10); + gen_pin_pairs!(SCU418, 0x418, 11); + gen_pin_pairs!(SCU418, 0x418, 12); + gen_pin_pairs!(SCU418, 0x418, 13); + gen_pin_pairs!(SCU418, 0x418, 14); + gen_pin_pairs!(SCU418, 0x418, 15); + gen_pin_pairs!(SCU418, 0x418, 16); + gen_pin_pairs!(SCU418, 0x418, 17); + gen_pin_pairs!(SCU418, 0x418, 18); + gen_pin_pairs!(SCU418, 0x418, 19); + gen_pin_pairs!(SCU418, 0x418, 20); + gen_pin_pairs!(SCU418, 0x418, 21); + gen_pin_pairs!(SCU418, 0x418, 22); + gen_pin_pairs!(SCU418, 0x418, 23); + gen_pin_pairs!(SCU418, 0x418, 24); + gen_pin_pairs!(SCU418, 0x418, 25); + gen_pin_pairs!(SCU418, 0x418, 26); + gen_pin_pairs!(SCU418, 0x418, 27); + gen_pin_pairs!(SCU418, 0x418, 28); + gen_pin_pairs!(SCU418, 0x418, 29); + gen_pin_pairs!(SCU418, 0x418, 30); + gen_pin_pairs!(SCU418, 0x418, 31); + + gen_pin_pairs!(SCU41C, 0x41C, 0); + gen_pin_pairs!(SCU41C, 0x41C, 1); + gen_pin_pairs!(SCU41C, 0x41C, 2); + gen_pin_pairs!(SCU41C, 0x41C, 3); + gen_pin_pairs!(SCU41C, 0x41C, 4); + gen_pin_pairs!(SCU41C, 0x41C, 5); + gen_pin_pairs!(SCU41C, 0x41C, 6); + gen_pin_pairs!(SCU41C, 0x41C, 7); + gen_pin_pairs!(SCU41C, 0x41C, 8); + gen_pin_pairs!(SCU41C, 0x41C, 9); + gen_pin_pairs!(SCU41C, 0x41C, 10); + gen_pin_pairs!(SCU41C, 0x41C, 11); + gen_pin_pairs!(SCU41C, 0x41C, 12); + gen_pin_pairs!(SCU41C, 0x41C, 13); + gen_pin_pairs!(SCU41C, 0x41C, 14); + gen_pin_pairs!(SCU41C, 0x41C, 15); + gen_pin_pairs!(SCU41C, 0x41C, 16); + gen_pin_pairs!(SCU41C, 0x41C, 17); + gen_pin_pairs!(SCU41C, 0x41C, 18); + gen_pin_pairs!(SCU41C, 0x41C, 19); + gen_pin_pairs!(SCU41C, 0x41C, 20); + gen_pin_pairs!(SCU41C, 0x41C, 21); + gen_pin_pairs!(SCU41C, 0x41C, 22); + gen_pin_pairs!(SCU41C, 0x41C, 23); + gen_pin_pairs!(SCU41C, 0x41C, 24); + gen_pin_pairs!(SCU41C, 0x41C, 25); + gen_pin_pairs!(SCU41C, 0x41C, 26); + gen_pin_pairs!(SCU41C, 0x41C, 27); + gen_pin_pairs!(SCU41C, 0x41C, 28); + gen_pin_pairs!(SCU41C, 0x41C, 29); + gen_pin_pairs!(SCU41C, 0x41C, 30); + gen_pin_pairs!(SCU41C, 0x41C, 31); + + gen_pin_pairs!(SCU430, 0x430, 0); + gen_pin_pairs!(SCU430, 0x430, 1); + gen_pin_pairs!(SCU430, 0x430, 2); + gen_pin_pairs!(SCU430, 0x430, 3); + gen_pin_pairs!(SCU430, 0x430, 4); + gen_pin_pairs!(SCU430, 0x430, 5); + gen_pin_pairs!(SCU430, 0x430, 6); + gen_pin_pairs!(SCU430, 0x430, 7); + gen_pin_pairs!(SCU430, 0x430, 8); + gen_pin_pairs!(SCU430, 0x430, 9); + gen_pin_pairs!(SCU430, 0x430, 10); + gen_pin_pairs!(SCU430, 0x430, 11); + gen_pin_pairs!(SCU430, 0x430, 12); + gen_pin_pairs!(SCU430, 0x430, 13); + gen_pin_pairs!(SCU430, 0x430, 14); + gen_pin_pairs!(SCU430, 0x430, 15); + gen_pin_pairs!(SCU430, 0x430, 16); + gen_pin_pairs!(SCU430, 0x430, 17); + gen_pin_pairs!(SCU430, 0x430, 18); + gen_pin_pairs!(SCU430, 0x430, 19); + gen_pin_pairs!(SCU430, 0x430, 20); + gen_pin_pairs!(SCU430, 0x430, 21); + gen_pin_pairs!(SCU430, 0x430, 22); + gen_pin_pairs!(SCU430, 0x430, 23); + gen_pin_pairs!(SCU430, 0x430, 24); + gen_pin_pairs!(SCU430, 0x430, 25); + gen_pin_pairs!(SCU430, 0x430, 26); + gen_pin_pairs!(SCU430, 0x430, 27); + gen_pin_pairs!(SCU430, 0x430, 28); + gen_pin_pairs!(SCU430, 0x430, 29); + gen_pin_pairs!(SCU430, 0x430, 30); + gen_pin_pairs!(SCU430, 0x430, 31); + + gen_pin_pairs!(SCU434, 0x434, 0); + gen_pin_pairs!(SCU434, 0x434, 1); + gen_pin_pairs!(SCU434, 0x434, 2); + gen_pin_pairs!(SCU434, 0x434, 3); + gen_pin_pairs!(SCU434, 0x434, 4); + gen_pin_pairs!(SCU434, 0x434, 5); + gen_pin_pairs!(SCU434, 0x434, 6); + gen_pin_pairs!(SCU434, 0x434, 7); + gen_pin_pairs!(SCU434, 0x434, 8); + gen_pin_pairs!(SCU434, 0x434, 9); + gen_pin_pairs!(SCU434, 0x434, 10); + gen_pin_pairs!(SCU434, 0x434, 11); + gen_pin_pairs!(SCU434, 0x434, 12); + gen_pin_pairs!(SCU434, 0x434, 13); + gen_pin_pairs!(SCU434, 0x434, 14); + gen_pin_pairs!(SCU434, 0x434, 15); + gen_pin_pairs!(SCU434, 0x434, 16); + gen_pin_pairs!(SCU434, 0x434, 17); + gen_pin_pairs!(SCU434, 0x434, 18); + gen_pin_pairs!(SCU434, 0x434, 19); + gen_pin_pairs!(SCU434, 0x434, 20); + gen_pin_pairs!(SCU434, 0x434, 21); + gen_pin_pairs!(SCU434, 0x434, 22); + gen_pin_pairs!(SCU434, 0x434, 23); + gen_pin_pairs!(SCU434, 0x434, 24); + gen_pin_pairs!(SCU434, 0x434, 25); + gen_pin_pairs!(SCU434, 0x434, 26); + gen_pin_pairs!(SCU434, 0x434, 27); + gen_pin_pairs!(SCU434, 0x434, 28); + gen_pin_pairs!(SCU434, 0x434, 29); + gen_pin_pairs!(SCU434, 0x434, 30); + gen_pin_pairs!(SCU434, 0x434, 31); + + gen_pin_pairs!(SCU4B0, 0x4B0, 0); + gen_pin_pairs!(SCU4B0, 0x4B0, 1); + gen_pin_pairs!(SCU4B0, 0x4B0, 2); + gen_pin_pairs!(SCU4B0, 0x4B0, 3); + gen_pin_pairs!(SCU4B0, 0x4B0, 4); + gen_pin_pairs!(SCU4B0, 0x4B0, 5); + gen_pin_pairs!(SCU4B0, 0x4B0, 6); + gen_pin_pairs!(SCU4B0, 0x4B0, 7); + gen_pin_pairs!(SCU4B0, 0x4B0, 8); + gen_pin_pairs!(SCU4B0, 0x4B0, 9); + gen_pin_pairs!(SCU4B0, 0x4B0, 10); + gen_pin_pairs!(SCU4B0, 0x4B0, 11); + gen_pin_pairs!(SCU4B0, 0x4B0, 12); + gen_pin_pairs!(SCU4B0, 0x4B0, 13); + gen_pin_pairs!(SCU4B0, 0x4B0, 14); + gen_pin_pairs!(SCU4B0, 0x4B0, 15); + gen_pin_pairs!(SCU4B0, 0x4B0, 16); + gen_pin_pairs!(SCU4B0, 0x4B0, 17); + gen_pin_pairs!(SCU4B0, 0x4B0, 18); + gen_pin_pairs!(SCU4B0, 0x4B0, 19); + gen_pin_pairs!(SCU4B0, 0x4B0, 20); + gen_pin_pairs!(SCU4B0, 0x4B0, 21); + gen_pin_pairs!(SCU4B0, 0x4B0, 22); + gen_pin_pairs!(SCU4B0, 0x4B0, 23); + gen_pin_pairs!(SCU4B0, 0x4B0, 24); + gen_pin_pairs!(SCU4B0, 0x4B0, 25); + gen_pin_pairs!(SCU4B0, 0x4B0, 26); + gen_pin_pairs!(SCU4B0, 0x4B0, 27); + gen_pin_pairs!(SCU4B0, 0x4B0, 28); + gen_pin_pairs!(SCU4B0, 0x4B0, 29); + gen_pin_pairs!(SCU4B0, 0x4B0, 30); + gen_pin_pairs!(SCU4B0, 0x4B0, 31); + + gen_pin_pairs!(SCU4B4, 0x4B4, 0); + gen_pin_pairs!(SCU4B4, 0x4B4, 1); + gen_pin_pairs!(SCU4B4, 0x4B4, 2); + gen_pin_pairs!(SCU4B4, 0x4B4, 3); + gen_pin_pairs!(SCU4B4, 0x4B4, 4); + gen_pin_pairs!(SCU4B4, 0x4B4, 5); + gen_pin_pairs!(SCU4B4, 0x4B4, 6); + gen_pin_pairs!(SCU4B4, 0x4B4, 7); + gen_pin_pairs!(SCU4B4, 0x4B4, 8); + gen_pin_pairs!(SCU4B4, 0x4B4, 9); + gen_pin_pairs!(SCU4B4, 0x4B4, 10); + gen_pin_pairs!(SCU4B4, 0x4B4, 11); + gen_pin_pairs!(SCU4B4, 0x4B4, 12); + gen_pin_pairs!(SCU4B4, 0x4B4, 13); + gen_pin_pairs!(SCU4B4, 0x4B4, 14); + gen_pin_pairs!(SCU4B4, 0x4B4, 15); + gen_pin_pairs!(SCU4B4, 0x4B4, 16); + gen_pin_pairs!(SCU4B4, 0x4B4, 17); + gen_pin_pairs!(SCU4B4, 0x4B4, 18); + gen_pin_pairs!(SCU4B4, 0x4B4, 19); + gen_pin_pairs!(SCU4B4, 0x4B4, 20); + gen_pin_pairs!(SCU4B4, 0x4B4, 21); + gen_pin_pairs!(SCU4B4, 0x4B4, 22); + gen_pin_pairs!(SCU4B4, 0x4B4, 23); + gen_pin_pairs!(SCU4B4, 0x4B4, 24); + gen_pin_pairs!(SCU4B4, 0x4B4, 25); + gen_pin_pairs!(SCU4B4, 0x4B4, 26); + gen_pin_pairs!(SCU4B4, 0x4B4, 27); + gen_pin_pairs!(SCU4B4, 0x4B4, 28); + gen_pin_pairs!(SCU4B4, 0x4B4, 29); + gen_pin_pairs!(SCU4B4, 0x4B4, 30); + gen_pin_pairs!(SCU4B4, 0x4B4, 31); + + gen_pin_pairs!(SCU4B8, 0x4B8, 0); + gen_pin_pairs!(SCU4B8, 0x4B8, 1); + gen_pin_pairs!(SCU4B8, 0x4B8, 2); + gen_pin_pairs!(SCU4B8, 0x4B8, 3); + gen_pin_pairs!(SCU4B8, 0x4B8, 4); + gen_pin_pairs!(SCU4B8, 0x4B8, 5); + gen_pin_pairs!(SCU4B8, 0x4B8, 6); + gen_pin_pairs!(SCU4B8, 0x4B8, 7); + gen_pin_pairs!(SCU4B8, 0x4B8, 8); + gen_pin_pairs!(SCU4B8, 0x4B8, 9); + gen_pin_pairs!(SCU4B8, 0x4B8, 10); + gen_pin_pairs!(SCU4B8, 0x4B8, 11); + gen_pin_pairs!(SCU4B8, 0x4B8, 12); + gen_pin_pairs!(SCU4B8, 0x4B8, 13); + gen_pin_pairs!(SCU4B8, 0x4B8, 14); + gen_pin_pairs!(SCU4B8, 0x4B8, 15); + gen_pin_pairs!(SCU4B8, 0x4B8, 16); + gen_pin_pairs!(SCU4B8, 0x4B8, 17); + gen_pin_pairs!(SCU4B8, 0x4B8, 18); + gen_pin_pairs!(SCU4B8, 0x4B8, 19); + gen_pin_pairs!(SCU4B8, 0x4B8, 20); + gen_pin_pairs!(SCU4B8, 0x4B8, 21); + gen_pin_pairs!(SCU4B8, 0x4B8, 22); + gen_pin_pairs!(SCU4B8, 0x4B8, 23); + gen_pin_pairs!(SCU4B8, 0x4B8, 24); + gen_pin_pairs!(SCU4B8, 0x4B8, 25); + gen_pin_pairs!(SCU4B8, 0x4B8, 26); + gen_pin_pairs!(SCU4B8, 0x4B8, 27); + gen_pin_pairs!(SCU4B8, 0x4B8, 28); + gen_pin_pairs!(SCU4B8, 0x4B8, 29); + gen_pin_pairs!(SCU4B8, 0x4B8, 30); + gen_pin_pairs!(SCU4B8, 0x4B8, 31); + + gen_pin_pairs!(SCU4BC, 0x4BC, 0); + gen_pin_pairs!(SCU4BC, 0x4BC, 1); + gen_pin_pairs!(SCU4BC, 0x4BC, 2); + gen_pin_pairs!(SCU4BC, 0x4BC, 3); + gen_pin_pairs!(SCU4BC, 0x4BC, 4); + gen_pin_pairs!(SCU4BC, 0x4BC, 5); + gen_pin_pairs!(SCU4BC, 0x4BC, 6); + gen_pin_pairs!(SCU4BC, 0x4BC, 7); + gen_pin_pairs!(SCU4BC, 0x4BC, 8); + gen_pin_pairs!(SCU4BC, 0x4BC, 9); + gen_pin_pairs!(SCU4BC, 0x4BC, 10); + gen_pin_pairs!(SCU4BC, 0x4BC, 11); + gen_pin_pairs!(SCU4BC, 0x4BC, 12); + gen_pin_pairs!(SCU4BC, 0x4BC, 13); + gen_pin_pairs!(SCU4BC, 0x4BC, 14); + gen_pin_pairs!(SCU4BC, 0x4BC, 15); + gen_pin_pairs!(SCU4BC, 0x4BC, 16); + gen_pin_pairs!(SCU4BC, 0x4BC, 17); + gen_pin_pairs!(SCU4BC, 0x4BC, 18); + gen_pin_pairs!(SCU4BC, 0x4BC, 19); + gen_pin_pairs!(SCU4BC, 0x4BC, 20); + gen_pin_pairs!(SCU4BC, 0x4BC, 21); + gen_pin_pairs!(SCU4BC, 0x4BC, 22); + gen_pin_pairs!(SCU4BC, 0x4BC, 23); + gen_pin_pairs!(SCU4BC, 0x4BC, 24); + gen_pin_pairs!(SCU4BC, 0x4BC, 25); + gen_pin_pairs!(SCU4BC, 0x4BC, 26); + gen_pin_pairs!(SCU4BC, 0x4BC, 27); + gen_pin_pairs!(SCU4BC, 0x4BC, 28); + gen_pin_pairs!(SCU4BC, 0x4BC, 29); + gen_pin_pairs!(SCU4BC, 0x4BC, 30); + gen_pin_pairs!(SCU4BC, 0x4BC, 31); + + gen_pin_pairs!(SCU690, 0x690, 0); + gen_pin_pairs!(SCU690, 0x690, 1); + gen_pin_pairs!(SCU690, 0x690, 2); + gen_pin_pairs!(SCU690, 0x690, 3); + gen_pin_pairs!(SCU690, 0x690, 4); + gen_pin_pairs!(SCU690, 0x690, 5); + gen_pin_pairs!(SCU690, 0x690, 6); + gen_pin_pairs!(SCU690, 0x690, 7); + gen_pin_pairs!(SCU690, 0x690, 8); + gen_pin_pairs!(SCU690, 0x690, 9); + gen_pin_pairs!(SCU690, 0x690, 10); + gen_pin_pairs!(SCU690, 0x690, 11); + gen_pin_pairs!(SCU690, 0x690, 12); + gen_pin_pairs!(SCU690, 0x690, 13); + gen_pin_pairs!(SCU690, 0x690, 14); + gen_pin_pairs!(SCU690, 0x690, 15); + gen_pin_pairs!(SCU690, 0x690, 16); + gen_pin_pairs!(SCU690, 0x690, 17); + gen_pin_pairs!(SCU690, 0x690, 18); + gen_pin_pairs!(SCU690, 0x690, 19); + gen_pin_pairs!(SCU690, 0x690, 20); + gen_pin_pairs!(SCU690, 0x690, 21); + gen_pin_pairs!(SCU690, 0x690, 22); + gen_pin_pairs!(SCU690, 0x690, 23); + gen_pin_pairs!(SCU690, 0x690, 24); + gen_pin_pairs!(SCU690, 0x690, 25); + gen_pin_pairs!(SCU690, 0x690, 26); + gen_pin_pairs!(SCU690, 0x690, 27); + gen_pin_pairs!(SCU690, 0x690, 28); + gen_pin_pairs!(SCU690, 0x690, 29); + gen_pin_pairs!(SCU690, 0x690, 30); + gen_pin_pairs!(SCU690, 0x690, 31); + + gen_pin_pairs!(SCU694, 0x694, 0); + gen_pin_pairs!(SCU694, 0x694, 1); + gen_pin_pairs!(SCU694, 0x694, 2); + gen_pin_pairs!(SCU694, 0x694, 3); + gen_pin_pairs!(SCU694, 0x694, 4); + gen_pin_pairs!(SCU694, 0x694, 5); + gen_pin_pairs!(SCU694, 0x694, 6); + gen_pin_pairs!(SCU694, 0x694, 7); + gen_pin_pairs!(SCU694, 0x694, 8); + gen_pin_pairs!(SCU694, 0x694, 9); + gen_pin_pairs!(SCU694, 0x694, 10); + gen_pin_pairs!(SCU694, 0x694, 11); + gen_pin_pairs!(SCU694, 0x694, 12); + gen_pin_pairs!(SCU694, 0x694, 13); + gen_pin_pairs!(SCU694, 0x694, 14); + gen_pin_pairs!(SCU694, 0x694, 15); + gen_pin_pairs!(SCU694, 0x694, 16); + gen_pin_pairs!(SCU694, 0x694, 17); + gen_pin_pairs!(SCU694, 0x694, 18); + gen_pin_pairs!(SCU694, 0x694, 19); + gen_pin_pairs!(SCU694, 0x694, 20); + gen_pin_pairs!(SCU694, 0x694, 21); + gen_pin_pairs!(SCU694, 0x694, 22); + gen_pin_pairs!(SCU694, 0x694, 23); + gen_pin_pairs!(SCU694, 0x694, 24); + gen_pin_pairs!(SCU694, 0x694, 25); + gen_pin_pairs!(SCU694, 0x694, 26); + gen_pin_pairs!(SCU694, 0x694, 27); + gen_pin_pairs!(SCU694, 0x694, 28); + gen_pin_pairs!(SCU694, 0x694, 29); + gen_pin_pairs!(SCU694, 0x694, 30); + gen_pin_pairs!(SCU694, 0x694, 31); + + gen_pin_pairs!(SCU698, 0x698, 0); + gen_pin_pairs!(SCU698, 0x698, 1); + gen_pin_pairs!(SCU698, 0x698, 2); + gen_pin_pairs!(SCU698, 0x698, 3); + gen_pin_pairs!(SCU698, 0x698, 4); + gen_pin_pairs!(SCU698, 0x698, 5); + gen_pin_pairs!(SCU698, 0x698, 6); + gen_pin_pairs!(SCU698, 0x698, 7); + gen_pin_pairs!(SCU698, 0x698, 8); + gen_pin_pairs!(SCU698, 0x698, 9); + gen_pin_pairs!(SCU698, 0x698, 10); + gen_pin_pairs!(SCU698, 0x698, 11); + gen_pin_pairs!(SCU698, 0x698, 12); + gen_pin_pairs!(SCU698, 0x698, 13); + gen_pin_pairs!(SCU698, 0x698, 14); + gen_pin_pairs!(SCU698, 0x698, 15); + gen_pin_pairs!(SCU698, 0x698, 16); + gen_pin_pairs!(SCU698, 0x698, 17); + gen_pin_pairs!(SCU698, 0x698, 18); + gen_pin_pairs!(SCU698, 0x698, 19); + gen_pin_pairs!(SCU698, 0x698, 20); + gen_pin_pairs!(SCU698, 0x698, 21); + gen_pin_pairs!(SCU698, 0x698, 22); + gen_pin_pairs!(SCU698, 0x698, 23); + gen_pin_pairs!(SCU698, 0x698, 24); + gen_pin_pairs!(SCU698, 0x698, 25); + gen_pin_pairs!(SCU698, 0x698, 26); + gen_pin_pairs!(SCU698, 0x698, 27); + gen_pin_pairs!(SCU698, 0x698, 28); + gen_pin_pairs!(SCU698, 0x698, 29); + gen_pin_pairs!(SCU698, 0x698, 30); + gen_pin_pairs!(SCU698, 0x698, 31); + + gen_pin_pairs!(SCU69C, 0x69C, 0); + gen_pin_pairs!(SCU69C, 0x69C, 1); + gen_pin_pairs!(SCU69C, 0x69C, 2); + gen_pin_pairs!(SCU69C, 0x69C, 3); + gen_pin_pairs!(SCU69C, 0x69C, 4); + gen_pin_pairs!(SCU69C, 0x69C, 5); + gen_pin_pairs!(SCU69C, 0x69C, 6); + gen_pin_pairs!(SCU69C, 0x69C, 7); + gen_pin_pairs!(SCU69C, 0x69C, 8); + gen_pin_pairs!(SCU69C, 0x69C, 9); + gen_pin_pairs!(SCU69C, 0x69C, 10); + gen_pin_pairs!(SCU69C, 0x69C, 11); + gen_pin_pairs!(SCU69C, 0x69C, 12); + gen_pin_pairs!(SCU69C, 0x69C, 13); + gen_pin_pairs!(SCU69C, 0x69C, 14); + gen_pin_pairs!(SCU69C, 0x69C, 15); + gen_pin_pairs!(SCU69C, 0x69C, 16); + gen_pin_pairs!(SCU69C, 0x69C, 17); + gen_pin_pairs!(SCU69C, 0x69C, 18); + gen_pin_pairs!(SCU69C, 0x69C, 19); + gen_pin_pairs!(SCU69C, 0x69C, 20); + gen_pin_pairs!(SCU69C, 0x69C, 21); + gen_pin_pairs!(SCU69C, 0x69C, 22); + gen_pin_pairs!(SCU69C, 0x69C, 23); + gen_pin_pairs!(SCU69C, 0x69C, 24); + gen_pin_pairs!(SCU69C, 0x69C, 25); + gen_pin_pairs!(SCU69C, 0x69C, 26); + gen_pin_pairs!(SCU69C, 0x69C, 27); + gen_pin_pairs!(SCU69C, 0x69C, 28); + gen_pin_pairs!(SCU69C, 0x69C, 29); + gen_pin_pairs!(SCU69C, 0x69C, 30); + gen_pin_pairs!(SCU69C, 0x69C, 31); + + gen_pin_pairs!(SCU6B0, 0x6B0, 0); + gen_pin_pairs!(SCU6B0, 0x6B0, 1); + gen_pin_pairs!(SCU6B0, 0x6B0, 2); + gen_pin_pairs!(SCU6B0, 0x6B0, 3); + gen_pin_pairs!(SCU6B0, 0x6B0, 4); + gen_pin_pairs!(SCU6B0, 0x6B0, 5); + gen_pin_pairs!(SCU6B0, 0x6B0, 6); + gen_pin_pairs!(SCU6B0, 0x6B0, 7); + gen_pin_pairs!(SCU6B0, 0x6B0, 8); + gen_pin_pairs!(SCU6B0, 0x6B0, 9); + gen_pin_pairs!(SCU6B0, 0x6B0, 10); + gen_pin_pairs!(SCU6B0, 0x6B0, 11); + gen_pin_pairs!(SCU6B0, 0x6B0, 12); + gen_pin_pairs!(SCU6B0, 0x6B0, 13); + gen_pin_pairs!(SCU6B0, 0x6B0, 14); + gen_pin_pairs!(SCU6B0, 0x6B0, 15); + gen_pin_pairs!(SCU6B0, 0x6B0, 16); + gen_pin_pairs!(SCU6B0, 0x6B0, 17); + gen_pin_pairs!(SCU6B0, 0x6B0, 18); + gen_pin_pairs!(SCU6B0, 0x6B0, 19); + gen_pin_pairs!(SCU6B0, 0x6B0, 20); + gen_pin_pairs!(SCU6B0, 0x6B0, 21); + gen_pin_pairs!(SCU6B0, 0x6B0, 22); + gen_pin_pairs!(SCU6B0, 0x6B0, 23); + gen_pin_pairs!(SCU6B0, 0x6B0, 24); + gen_pin_pairs!(SCU6B0, 0x6B0, 25); + gen_pin_pairs!(SCU6B0, 0x6B0, 26); + gen_pin_pairs!(SCU6B0, 0x6B0, 27); + gen_pin_pairs!(SCU6B0, 0x6B0, 28); + gen_pin_pairs!(SCU6B0, 0x6B0, 29); + gen_pin_pairs!(SCU6B0, 0x6B0, 30); + gen_pin_pairs!(SCU6B0, 0x6B0, 31); +} + +/// I2C1 pin group: SCL/SDA mux selection on SCU414[30:31]. +pub const PINCTRL_I2C1: &[PinctrlPin] = &[PIN_SCU414_30, PIN_SCU414_31]; + +/// Macro to safely modify a register bit (set or clear). +macro_rules! modify_reg { + ($reg:expr, $bit:expr, $clear:expr) => {{ + let mut val: u32 = $reg.read().bits(); + if $clear { + val &= !(1 << $bit); + } else { + val |= (1 << $bit); + } + $reg.write(|w| unsafe { w.bits(val) }); + }}; +} + +impl ScuRegisters { + /// Apply a pinctrl group configuration. + /// + /// Iterates through pin descriptors and applies each to the corresponding + /// SCU register offset and bit position. + /// + /// # Example + /// ```no_run + /// # use ast10x0_peripherals::scu::{ScuRegisters, pinctrl}; + /// # unsafe { + /// let scu = ScuRegisters::new_global(); + /// scu.apply_pinctrl_group(&[pinctrl::CLR_PIN_SCU41C_0]); + /// # } + /// ``` + pub fn apply_pinctrl_group(&self, pins: &[PinctrlPin]) { + let regs = self.regs(); + for pin in pins { + match pin.offset { + 0x410 => modify_reg!(regs.scu410(), pin.bit, pin.clear), + 0x414 => modify_reg!(regs.scu414(), pin.bit, pin.clear), + 0x418 => modify_reg!(regs.scu418(), pin.bit, pin.clear), + 0x41C => modify_reg!(regs.scu41c(), pin.bit, pin.clear), + 0x430 => modify_reg!(regs.scu430(), pin.bit, pin.clear), + 0x434 => modify_reg!(regs.scu434(), pin.bit, pin.clear), + 0x4B0 => modify_reg!(regs.scu4b0(), pin.bit, pin.clear), + 0x4B4 => modify_reg!(regs.scu4b4(), pin.bit, pin.clear), + 0x4B8 => modify_reg!(regs.scu4b8(), pin.bit, pin.clear), + 0x4BC => modify_reg!(regs.scu4bc(), pin.bit, pin.clear), + 0x690 => modify_reg!(regs.scu690(), pin.bit, pin.clear), + 0x694 => modify_reg!(regs.scu694(), pin.bit, pin.clear), + 0x698 => modify_reg!(regs.scu698(), pin.bit, pin.clear), + 0x69C => modify_reg!(regs.scu69c(), pin.bit, pin.clear), + 0x6B0 => modify_reg!(regs.scu6b0(), pin.bit, pin.clear), + _ => {} // Unknown offset, silently ignore + } + } + } +}
diff --git a/target/ast10x0/peripherals/scu/registers.rs b/target/ast10x0/peripherals/scu/registers.rs new file mode 100644 index 0000000..255f735 --- /dev/null +++ b/target/ast10x0/peripherals/scu/registers.rs
@@ -0,0 +1,72 @@ +// Licensed under the Apache-2.0 license +// SPDX-License-Identifier: Apache-2.0 + +//! AST10x0 SCU low-level register access. + +use ast1060_pac as device; +use core::cell::UnsafeCell; +use core::marker::PhantomData; + +const SCU_UNLOCK_KEY: u32 = 0x1688_A8A8; + +/// Safe wrapper around the AST10x0 SCU register block. +pub struct ScuRegisters { + base: *const device::scu::RegisterBlock, + _not_sync: PhantomData<UnsafeCell<()>>, // Prevent Sync, allow Send. +} + +impl ScuRegisters { + /// Create a register accessor from a raw SCU register block pointer. + /// + /// # Safety + /// Caller must ensure: + /// - `base` points to a valid SCU register block. + /// - access to the SCU instance is serialized appropriately. + const unsafe fn new(base: *const device::scu::RegisterBlock) -> Self { + Self { + base, + _not_sync: PhantomData, + } + } + + /// Create a register accessor for the global SCU instance. + /// + /// # Safety + /// Caller must ensure access to the singleton SCU is coordinated. + const unsafe fn new_global() -> Self { + // SAFETY: Caller upholds the singleton access contract. + unsafe { Self::new(device::Scu::ptr()) } + } + + /// Create a register accessor for the global SCU instance, with write + /// protection immediately unlocked. + /// + /// Follows the aspeed-rust pattern: unlock once, then perform all + /// register writes in sequence without re-locking between operations. + /// + /// # Safety + /// Caller must ensure access to the singleton SCU is coordinated. + pub unsafe fn new_global_unlocked() -> Self { + // SAFETY: Caller upholds the singleton access contract. + let scu = unsafe { Self::new_global() }; + scu.unlock_write_protection(); + scu + } + + #[inline] + pub fn regs(&self) -> &device::scu::RegisterBlock { + // SAFETY: Constructor guarantees a valid SCU register block pointer. + unsafe { &*self.base } + } + + /// Unlock SCU write-protected registers for subsequent write operations. + /// + /// Call this once before a sequence of SCU writes, following the aspeed-rust + /// pattern of a single unlock per batch of register operations. + #[inline] + fn unlock_write_protection(&self) { + self.regs() + .scu000() + .write(|w| unsafe { w.bits(SCU_UNLOCK_KEY) }); + } +} \ No newline at end of file
diff --git a/target/ast10x0/peripherals/scu/reset.rs b/target/ast10x0/peripherals/scu/reset.rs new file mode 100644 index 0000000..76f7ece --- /dev/null +++ b/target/ast10x0/peripherals/scu/reset.rs
@@ -0,0 +1,46 @@ +// Licensed under the Apache-2.0 license +// SPDX-License-Identifier: Apache-2.0 + +//! SCU reset helpers. + +use super::registers::ScuRegisters; +use super::types::ScuRegisterHalf; + +impl ScuRegisters { + /// Assert reset bits in the selected reset-control register half. + /// + /// Caller must call `unlock_write_protection()` before this. + pub fn assert_reset_mask(&self, half: ScuRegisterHalf, mask: u32) { + match half { + ScuRegisterHalf::Lower => { + self.regs().scu040().write(|w| unsafe { w.bits(mask) }); + } + ScuRegisterHalf::Upper => { + self.regs().scu050().write(|w| unsafe { w.bits(mask) }); + } + } + } + + /// Deassert reset bits in the selected reset-control register half. + /// + /// Caller must call `unlock_write_protection()` before this. + pub fn deassert_reset_mask(&self, half: ScuRegisterHalf, mask: u32) { + match half { + ScuRegisterHalf::Lower => { + self.regs().scu044().write(|w| unsafe { w.bits(mask) }); + } + ScuRegisterHalf::Upper => { + self.regs().scu054().write(|w| unsafe { w.bits(mask) }); + } + } + } + + /// Read the selected reset-control register half. + #[must_use] + pub fn reset_mask(&self, half: ScuRegisterHalf) -> u32 { + match half { + ScuRegisterHalf::Lower => self.regs().scu040().read().bits(), + ScuRegisterHalf::Upper => self.regs().scu050().read().bits(), + } + } +} \ No newline at end of file
diff --git a/target/ast10x0/peripherals/scu/status.rs b/target/ast10x0/peripherals/scu/status.rs new file mode 100644 index 0000000..0fb276b --- /dev/null +++ b/target/ast10x0/peripherals/scu/status.rs
@@ -0,0 +1,32 @@ +// Licensed under the Apache-2.0 license +// SPDX-License-Identifier: Apache-2.0 + +//! Read-only SCU status helpers. + +use super::registers::ScuRegisters; + +impl ScuRegisters { + /// Read the raw hardware-revision register value. + #[must_use] + pub fn hardware_revision_raw(&self) -> u32 { + self.regs().scu004().read().bits() + } + + /// Read the raw route-control register value. + #[must_use] + pub fn route_control_raw(&self) -> u32 { + self.regs().scu0f0().read().bits() + } + + /// Read the raw SCU690 multi-function control register value. + #[must_use] + pub fn multi_func_690_raw(&self) -> u32 { + self.regs().scu690().read().bits() + } + + /// Read the raw SCU694 multi-function control register value. + #[must_use] + pub fn multi_func_694_raw(&self) -> u32 { + self.regs().scu694().read().bits() + } +} \ No newline at end of file
diff --git a/target/ast10x0/peripherals/scu/types.rs b/target/ast10x0/peripherals/scu/types.rs new file mode 100644 index 0000000..cf0314b --- /dev/null +++ b/target/ast10x0/peripherals/scu/types.rs
@@ -0,0 +1,18 @@ +// Licensed under the Apache-2.0 license +// SPDX-License-Identifier: Apache-2.0 + +//! Public SCU types. + +/// Selects the lower or upper 32-bit control register half for reset domains. +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +pub enum ScuRegisterHalf { + Lower, + Upper, +} + +/// Selects the lower or upper 32-bit control register half for clock domains. +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +pub enum ClockRegisterHalf { + Lower, + Upper, +} \ No newline at end of file