diff --git a/modules/axhal/src/platform/aarch64_phytium_pi/clock.rs b/modules/axhal/src/platform/aarch64_phytium_pi/clock.rs index 2eb9b1971b..04bd9dc6e9 100644 --- a/modules/axhal/src/platform/aarch64_phytium_pi/clock.rs +++ b/modules/axhal/src/platform/aarch64_phytium_pi/clock.rs @@ -1,132 +1,48 @@ -use core::ptr::NonNull; -use tock_registers::{ - interfaces::{Readable, ReadWriteable}, - register_bitfields, register_structs, - registers::{ReadOnly, ReadWrite}, -}; -use kspin::SpinNoIrq; -use crate::mem::{phys_to_virt, PhysAddr}; +use aarch64_cpu::registers::CNTFRQ_EL0; +use aarch64_cpu::registers::Readable; - -register_structs! { - pub ClockRegs { - (0x00 => clk_con: ReadWrite), - (0x04 => clk_div: ReadWrite), - (0x08 => clk_status: ReadOnly), - (0x0c => @END), - } +static mut GLOBAL_CLOCK: Option = None; +#[derive(Debug, Clone, Copy)] +pub struct Clock { + pub frequency: u32, // 系统时钟频率(Hz) + pub div:u32, + pub sys_frequency:u32, } -register_bitfields![u32, - CLK_CON [ - ENABLE OFFSET(0) NUMBITS(1) [], // 1=使能时钟 - SOURCE OFFSET(1) NUMBITS(3) [], // 时钟源选择 - ], - CLK_DIV [ - DIV OFFSET(0) NUMBITS(8) [], // 分频系数 - ], - CLK_STATUS [ - READY OFFSET(0) NUMBITS(1) [], // 1=时钟准备好 - ], -]; - -// Clock 控制器结构体 -pub struct ClockCtrl { - regs: NonNull, -} +impl Clock { + /// 构造函数,自动从CNTFRQ_EL0寄存器读取频率 + pub fn new() -> Self { + let freq = CNTFRQ_EL0.get() as u32; + Clock { frequency: freq, div: 1, sys_frequency: freq } + } -unsafe impl Send for ClockCtrl {} + /// 获取系统时钟频率(Hz) + pub fn get_frequency(&self) -> u32 { + self.frequency + } -impl ClockCtrl { - pub const fn new(base: *mut u8) -> Self { - Self { - regs: NonNull::new(base).unwrap().cast(), - } - } - const fn regs(&self) -> &ClockRegs { - unsafe { self.regs.as_ref() } + pub fn set_frequency(&mut self, freq: u32) { + self.frequency = freq; + self.div = freq / self.sys_frequency; } - const fn regs_mut(&mut self) -> &mut ClockRegs { - unsafe { self.regs.as_mut() } - } -} - -// API 实现 -#[derive(Debug, Clone, Copy, Default)] -pub struct FClockConfig { - pub instance_id: u32, - pub base_address: usize, -} - -#[derive(Clone, Copy)] -pub struct FClockCtrl { - pub config: FClockConfig, - pub is_ready: u32, -} -static CLOCK_CONFIG: [FClockConfig; 1] = [FClockConfig { - instance_id: 0, - base_address: 0x2800_0000usize, -}]; - -pub static CLOCK: SpinNoIrq = SpinNoIrq::new(FClockCtrl { - config: FClockConfig { - instance_id: 0, - base_address: 0, - }, - is_ready: 0, -}); - -pub fn FClockInit(instance_p: &mut FClockCtrl, config_p: &FClockConfig) -> bool { - assert!(instance_p as *const _ as usize != 0 && config_p as *const _ as usize != 0); - let ret = true; - if instance_p.is_ready == 0x11111111u32 { - info!("Clock already initialized."); - return false; - } - FClockDeInit(instance_p); - instance_p.config = *config_p; - instance_p.is_ready = 0x11111111u32; - ret -} - -pub fn FClockDeInit(instance_p: &mut FClockCtrl) -> bool { - if instance_p.is_ready == 0 { - return true; + pub fn get_div(&self) -> u32 { + self.div } - instance_p.is_ready = 0; - unsafe { - core::ptr::write_bytes(instance_p as *mut FClockCtrl, 0, core::mem::size_of::()); + pub fn get_sys_frequency(&self) -> u32 { + self.sys_frequency } - true -} -pub fn FClockLookupConfig(instance_id: u32) -> Option { - if instance_id >= 1 { - return None; - } - Some(CLOCK_CONFIG[instance_id as usize]) -} + pub fn init_global() { + // 将基地址转换为NonNull + let mut clock = Clock::new(); // 初始化时钟 + info!("Clock frequency: {} Hz", clock.get_frequency()); + clock.set_frequency(200_000_000); + info!("Clock frequency: {} Hz", clock.get_frequency()); -pub fn FClockSetFreq(instance_p: &mut FClockCtrl, freq: u32) -> bool { - let base = instance_p.config.base_address; - let clock = ClockCtrl::new(phys_to_virt(PhysAddr::from(base)).as_mut_ptr()); - let sys_clk = 50000000; // 50MHz 系统时钟 - let div = sys_clk / freq; - clock.regs().clk_div.modify(CLK_DIV::DIV.val(div)); - clock.regs().clk_con.modify(CLK_CON::ENABLE::SET); - let mut timeout = 0; - while clock.regs().clk_status.read(CLK_STATUS::READY) != 1 && timeout < 500 { - timeout += 1; - crate::time::busy_wait(core::time::Duration::from_millis(1)); + // 存储到全局静态变量 + unsafe { + GLOBAL_CLOCK = Some(clock); + } } - timeout < 500 -} - -pub fn FClockGetFreq(instance_p: &mut FClockCtrl) -> u32 { - let base = instance_p.config.base_address; - let clock = ClockCtrl::new(phys_to_virt(PhysAddr::from(base)).as_mut_ptr()); - let sys_clk = 50000000; // 50MHz 系统时钟 - let div = clock.regs().clk_div.read(CLK_DIV::DIV); - sys_clk / div } \ No newline at end of file diff --git a/modules/axhal/src/platform/aarch64_phytium_pi/mod.rs b/modules/axhal/src/platform/aarch64_phytium_pi/mod.rs index f59a21ce69..999e5f7eca 100644 --- a/modules/axhal/src/platform/aarch64_phytium_pi/mod.rs +++ b/modules/axhal/src/platform/aarch64_phytium_pi/mod.rs @@ -126,10 +126,7 @@ pub fn platform_init() { &mut pinctrl::PAD.lock(), &pinctrl::FIOPadLookupConfig(0).unwrap(), ); - clock::FClockInit( - &mut clock::CLOCK.lock(), - &clock::FClockLookupConfig(0).unwrap(), - ); + clock::Clock::init_global(); pwm::PwmCtrl::init_global(); driver_gpio::init_gpio(); driver_watchdog::init_watchdog();