1+ use core:: ops:: Deref ;
2+
3+ use alloc:: { string:: { String , ToString } , vec:: Vec } ;
4+ use fdt_raw:: Phandle ;
5+
6+ use crate :: node:: gerneric:: NodeRefGen ;
7+
8+ /// 时钟提供者类型
9+ #[ derive( Clone , Debug , PartialEq ) ]
10+ pub enum ClockType {
11+ /// 固定时钟
12+ Fixed ( FixedClock ) ,
13+ /// 普通时钟提供者
14+ Normal ,
15+ }
16+
17+ /// 固定时钟
18+ #[ derive( Clone , Debug , PartialEq ) ]
19+ pub struct FixedClock {
20+ pub name : Option < String > ,
21+ /// 时钟频率 (Hz)
22+ pub frequency : u32 ,
23+ /// 时钟精度
24+ pub accuracy : Option < u32 > ,
25+ }
26+
27+ /// 时钟引用,用于解析 clocks 属性
28+ ///
29+ /// 根据设备树规范,clocks 属性格式为:
30+ /// `clocks = <&clock_provider specifier [specifier ...]> [<&clock_provider2 ...>]`
31+ ///
32+ /// 每个时钟引用由一个 phandle 和若干个 specifier cells 组成,
33+ /// specifier 的数量由目标 clock provider 的 `#clock-cells` 属性决定。
34+ #[ derive( Clone , Debug ) ]
35+ pub struct ClockRef {
36+ /// 时钟的名称,来自 clock-names 属性
37+ pub name : Option < String > ,
38+ /// 时钟提供者的 phandle
39+ pub phandle : Phandle ,
40+ /// provider 的 #clock-cells 值
41+ pub cells : u32 ,
42+ /// 时钟选择器(specifier),通常第一个值用于选择时钟输出
43+ /// 长度由 provider 的 #clock-cells 决定
44+ pub specifier : Vec < u32 > ,
45+ }
46+
47+ impl ClockRef {
48+ /// 创建一个新的时钟引用
49+ pub fn new ( phandle : Phandle , cells : u32 , specifier : Vec < u32 > ) -> Self {
50+ Self {
51+ name : None ,
52+ phandle,
53+ cells,
54+ specifier,
55+ }
56+ }
57+
58+ /// 创建一个带名称的时钟引用
59+ pub fn with_name (
60+ name : Option < String > ,
61+ phandle : Phandle ,
62+ cells : u32 ,
63+ specifier : Vec < u32 > ,
64+ ) -> Self {
65+ Self {
66+ name,
67+ phandle,
68+ cells,
69+ specifier,
70+ }
71+ }
72+
73+ /// 获取选择器的第一个值(通常用于选择时钟输出)
74+ ///
75+ /// 只有当 `cells > 0` 时才返回选择器值,
76+ /// 因为 `#clock-cells = 0` 的 provider 不需要选择器。
77+ pub fn select ( & self ) -> Option < u32 > {
78+ if self . cells > 0 {
79+ self . specifier . first ( ) . copied ( )
80+ } else {
81+ None
82+ }
83+ }
84+ }
85+
86+ /// 时钟提供者节点引用
87+ #[ derive( Clone , Debug ) ]
88+ pub struct NodeRefClock < ' a > {
89+ pub node : NodeRefGen < ' a > ,
90+ pub clock_output_names : Vec < String > ,
91+ pub clock_cells : u32 ,
92+ pub kind : ClockType ,
93+ }
94+
95+ impl < ' a > NodeRefClock < ' a > {
96+ pub fn try_from ( node : NodeRefGen < ' a > ) -> Result < Self , NodeRefGen < ' a > > {
97+ // 检查是否有时钟提供者属性
98+ if node. find_property ( "#clock-cells" ) . is_none ( ) {
99+ return Err ( node) ;
100+ }
101+
102+ // 获取 clock-output-names 属性
103+ let clock_output_names = if let Some ( prop) = node. find_property ( "clock-output-names" ) {
104+ let iter = prop. as_str_iter ( ) ;
105+ iter. map ( |s| s. to_string ( ) ) . collect ( )
106+ } else {
107+ Vec :: new ( )
108+ } ;
109+
110+ // 获取 #clock-cells
111+ let clock_cells = node
112+ . find_property ( "#clock-cells" )
113+ . and_then ( |prop| prop. get_u32 ( ) )
114+ . unwrap_or ( 0 ) ;
115+
116+ // 判断时钟类型
117+ let kind = if node. compatibles ( ) . any ( |c| c == "fixed-clock" ) {
118+ let frequency = node
119+ . find_property ( "clock-frequency" )
120+ . and_then ( |prop| prop. get_u32 ( ) )
121+ . unwrap_or ( 0 ) ;
122+ let accuracy = node
123+ . find_property ( "clock-accuracy" )
124+ . and_then ( |prop| prop. get_u32 ( ) ) ;
125+ let name = clock_output_names. first ( ) . cloned ( ) ;
126+
127+ ClockType :: Fixed ( FixedClock {
128+ name,
129+ frequency,
130+ accuracy,
131+ } )
132+ } else {
133+ ClockType :: Normal
134+ } ;
135+
136+ Ok ( Self {
137+ node,
138+ clock_output_names,
139+ clock_cells,
140+ kind,
141+ } )
142+ }
143+
144+ /// 获取时钟输出名称(用于 provider)
145+ pub fn output_name ( & self , index : usize ) -> Option < & str > {
146+ self . clock_output_names . get ( index) . map ( |s| s. as_str ( ) )
147+ }
148+
149+ /// 解析 clocks 属性,返回时钟引用列表
150+ ///
151+ /// 通过查找每个 phandle 对应的 clock provider 的 #clock-cells,
152+ /// 正确解析 specifier 的长度。
153+ pub fn clocks ( & self ) -> Vec < ClockRef > {
154+ let Some ( prop) = self . find_property ( "clocks" ) else {
155+ return Vec :: new ( ) ;
156+ } ;
157+
158+ let mut clocks = Vec :: new ( ) ;
159+ let mut data = prop. as_reader ( ) ;
160+ let mut index = 0 ;
161+
162+ // 获取 clock-names 用于命名
163+ let clock_names = if let Some ( prop) = self . find_property ( "clock-names" ) {
164+ let iter = prop. as_str_iter ( ) ;
165+ iter. map ( |s| s. to_string ( ) ) . collect ( )
166+ } else {
167+ Vec :: new ( )
168+ } ;
169+
170+ while let Some ( phandle_raw) = data. read_u32 ( ) {
171+ let phandle = Phandle :: from ( phandle_raw) ;
172+
173+ // 通过 phandle 查找 provider 节点,获取其 #clock-cells
174+ let clock_cells = if let Some ( provider) = self . ctx . find_by_phandle ( phandle) {
175+ provider
176+ . get_property ( "#clock-cells" )
177+ . and_then ( |p| p. get_u32 ( ) )
178+ . unwrap_or ( 1 ) // 默认 1 cell
179+ } else {
180+ 1 // 默认 1 cell
181+ } ;
182+
183+ // 读取 specifier(根据 provider 的 #clock-cells)
184+ let mut specifier = Vec :: with_capacity ( clock_cells as usize ) ;
185+ let mut complete = true ;
186+ for _ in 0 ..clock_cells {
187+ if let Some ( val) = data. read_u32 ( ) {
188+ specifier. push ( val) ;
189+ } else {
190+ // 数据不足,停止解析
191+ complete = false ;
192+ break ;
193+ }
194+ }
195+
196+ // 只有完整的 clock reference 才添加
197+ if !complete {
198+ break ;
199+ }
200+
201+ // 从 clock-names 获取对应的名称
202+ let name = clock_names. get ( index) . cloned ( ) ;
203+
204+ clocks. push ( ClockRef :: with_name (
205+ name,
206+ phandle,
207+ clock_cells,
208+ specifier,
209+ ) ) ;
210+ index += 1 ;
211+ }
212+
213+ clocks
214+ }
215+ }
216+
217+ impl < ' a > Deref for NodeRefClock < ' a > {
218+ type Target = NodeRefGen < ' a > ;
219+
220+ fn deref ( & self ) -> & Self :: Target {
221+ & self . node
222+ }
223+ }
0 commit comments