@@ -66,214 +66,48 @@ void cpg_simple_notifier_register(struct raw_notifier_head *notifiers,
6666 * SDn Clock
6767 */
6868
69- struct clk * __init cpg_sdh_clk_register (const char * name ,
70- void __iomem * sdnckcr , const char * parent_name ,
71- struct raw_notifier_head * notifiers )
72- {
73- /* placeholder during transition */
74- return clk_register_fixed_factor (NULL , name , parent_name , 0 , 1 , 1 );
75- }
76-
77- #define CPG_SD_STP_HCK BIT(9)
78- #define CPG_SD_STP_CK BIT(8)
79-
80- #define CPG_SD_STP_MASK (CPG_SD_STP_HCK | CPG_SD_STP_CK)
81- #define CPG_SD_FC_MASK (0x7 << 2 | 0x3 << 0)
82-
83- #define CPG_SD_DIV_TABLE_DATA (stp_hck , sd_srcfc , sd_fc , sd_div ) \
84- { \
85- .val = ((stp_hck) ? CPG_SD_STP_HCK : 0) | \
86- ((sd_srcfc) << 2) | \
87- ((sd_fc) << 0), \
88- .div = (sd_div), \
89- }
90-
91- struct sd_div_table {
92- u32 val ;
93- unsigned int div ;
94- };
69+ #define SDnSRCFC_SHIFT 2
70+ #define STPnHCK BIT(9 - SDnSRCFC_SHIFT)
9571
96- struct sd_clock {
97- struct clk_hw hw ;
98- const struct sd_div_table * div_table ;
99- struct cpg_simple_notifier csn ;
100- unsigned int div_num ;
101- unsigned int cur_div_idx ;
102- };
103-
104- /* SDn divider
105- * sd_srcfc sd_fc div
106- * stp_hck (div) (div) = sd_srcfc x sd_fc
107- *---------------------------------------------------------
108- * 0 0 (1) 1 (4) 4 : SDR104 / HS200 / HS400 (8 TAP)
109- * 0 1 (2) 1 (4) 8 : SDR50
110- * 1 2 (4) 1 (4) 16 : HS / SDR25
111- * 1 3 (8) 1 (4) 32 : NS / SDR12
112- * 1 4 (16) 1 (4) 64
113- * 0 0 (1) 0 (2) 2
114- * 0 1 (2) 0 (2) 4 : SDR104 / HS200 / HS400 (4 TAP)
115- * 1 2 (4) 0 (2) 8
116- * 1 3 (8) 0 (2) 16
117- * 1 4 (16) 0 (2) 32
118- *
119- * NOTE: There is a quirk option to ignore the first row of the dividers
120- * table when searching for suitable settings. This is because HS400 on
121- * early ES versions of H3 and M3-W requires a specific setting to work.
122- */
123- static const struct sd_div_table cpg_sd_div_table [] = {
124- /* CPG_SD_DIV_TABLE_DATA(stp_hck, sd_srcfc, sd_fc, sd_div) */
125- CPG_SD_DIV_TABLE_DATA (0 , 0 , 1 , 4 ),
126- CPG_SD_DIV_TABLE_DATA (0 , 1 , 1 , 8 ),
127- CPG_SD_DIV_TABLE_DATA (1 , 2 , 1 , 16 ),
128- CPG_SD_DIV_TABLE_DATA (1 , 3 , 1 , 32 ),
129- CPG_SD_DIV_TABLE_DATA (1 , 4 , 1 , 64 ),
130- CPG_SD_DIV_TABLE_DATA (0 , 0 , 0 , 2 ),
131- CPG_SD_DIV_TABLE_DATA (0 , 1 , 0 , 4 ),
132- CPG_SD_DIV_TABLE_DATA (1 , 2 , 0 , 8 ),
133- CPG_SD_DIV_TABLE_DATA (1 , 3 , 0 , 16 ),
134- CPG_SD_DIV_TABLE_DATA (1 , 4 , 0 , 32 ),
72+ static const struct clk_div_table cpg_sdh_div_table [] = {
73+ { 0 , 1 }, { 1 , 2 }, { STPnHCK | 2 , 4 }, { STPnHCK | 3 , 8 },
74+ { STPnHCK | 4 , 16 }, { 0 , 0 },
13575};
13676
137- #define to_sd_clock (_hw ) container_of(_hw, struct sd_clock, hw)
138-
139- static int cpg_sd_clock_enable (struct clk_hw * hw )
140- {
141- struct sd_clock * clock = to_sd_clock (hw );
142-
143- cpg_reg_modify (clock -> csn .reg , CPG_SD_STP_MASK ,
144- clock -> div_table [clock -> cur_div_idx ].val &
145- CPG_SD_STP_MASK );
146-
147- return 0 ;
148- }
149-
150- static void cpg_sd_clock_disable (struct clk_hw * hw )
151- {
152- struct sd_clock * clock = to_sd_clock (hw );
153-
154- cpg_reg_modify (clock -> csn .reg , 0 , CPG_SD_STP_MASK );
155- }
156-
157- static int cpg_sd_clock_is_enabled (struct clk_hw * hw )
77+ struct clk * __init cpg_sdh_clk_register (const char * name ,
78+ void __iomem * sdnckcr , const char * parent_name ,
79+ struct raw_notifier_head * notifiers )
15880{
159- struct sd_clock * clock = to_sd_clock (hw );
160-
161- return !(readl (clock -> csn .reg ) & CPG_SD_STP_MASK );
162- }
81+ struct cpg_simple_notifier * csn ;
82+ struct clk * clk ;
16383
164- static unsigned long cpg_sd_clock_recalc_rate (struct clk_hw * hw ,
165- unsigned long parent_rate )
166- {
167- struct sd_clock * clock = to_sd_clock (hw );
84+ csn = kzalloc (sizeof (* csn ), GFP_KERNEL );
85+ if (!csn )
86+ return ERR_PTR (- ENOMEM );
16887
169- return DIV_ROUND_CLOSEST (parent_rate ,
170- clock -> div_table [clock -> cur_div_idx ].div );
171- }
88+ csn -> reg = sdnckcr ;
17289
173- static int cpg_sd_clock_determine_rate (struct clk_hw * hw ,
174- struct clk_rate_request * req )
175- {
176- unsigned long best_rate = ULONG_MAX , diff_min = ULONG_MAX ;
177- struct sd_clock * clock = to_sd_clock (hw );
178- unsigned long calc_rate , diff ;
179- unsigned int i ;
180-
181- for (i = 0 ; i < clock -> div_num ; i ++ ) {
182- calc_rate = DIV_ROUND_CLOSEST (req -> best_parent_rate ,
183- clock -> div_table [i ].div );
184- if (calc_rate < req -> min_rate || calc_rate > req -> max_rate )
185- continue ;
186-
187- diff = calc_rate > req -> rate ? calc_rate - req -> rate
188- : req -> rate - calc_rate ;
189- if (diff < diff_min ) {
190- best_rate = calc_rate ;
191- diff_min = diff ;
192- }
90+ clk = clk_register_divider_table (NULL , name , parent_name , 0 , sdnckcr ,
91+ SDnSRCFC_SHIFT , 8 , 0 , cpg_sdh_div_table ,
92+ & cpg_lock );
93+ if (IS_ERR (clk )) {
94+ kfree (csn );
95+ return clk ;
19396 }
19497
195- if (best_rate == ULONG_MAX )
196- return - EINVAL ;
197-
198- req -> rate = best_rate ;
199- return 0 ;
200- }
201-
202- static int cpg_sd_clock_set_rate (struct clk_hw * hw , unsigned long rate ,
203- unsigned long parent_rate )
204- {
205- struct sd_clock * clock = to_sd_clock (hw );
206- unsigned int i ;
207-
208- for (i = 0 ; i < clock -> div_num ; i ++ )
209- if (rate == DIV_ROUND_CLOSEST (parent_rate ,
210- clock -> div_table [i ].div ))
211- break ;
212-
213- if (i >= clock -> div_num )
214- return - EINVAL ;
215-
216- clock -> cur_div_idx = i ;
217-
218- cpg_reg_modify (clock -> csn .reg , CPG_SD_STP_MASK | CPG_SD_FC_MASK ,
219- clock -> div_table [i ].val &
220- (CPG_SD_STP_MASK | CPG_SD_FC_MASK ));
221-
222- return 0 ;
98+ cpg_simple_notifier_register (notifiers , csn );
99+ return clk ;
223100}
224101
225- static const struct clk_ops cpg_sd_clock_ops = {
226- .enable = cpg_sd_clock_enable ,
227- .disable = cpg_sd_clock_disable ,
228- .is_enabled = cpg_sd_clock_is_enabled ,
229- .recalc_rate = cpg_sd_clock_recalc_rate ,
230- .determine_rate = cpg_sd_clock_determine_rate ,
231- .set_rate = cpg_sd_clock_set_rate ,
102+ static const struct clk_div_table cpg_sd_div_table [] = {
103+ { 0 , 2 }, { 1 , 4 }, { 0 , 0 },
232104};
233105
234106struct clk * __init cpg_sd_clk_register (const char * name ,
235- void __iomem * base , unsigned int offset , const char * parent_name ,
236- struct raw_notifier_head * notifiers , bool skip_first )
107+ void __iomem * sdnckcr , const char * parent_name )
237108{
238- struct clk_init_data init = {};
239- struct sd_clock * clock ;
240- struct clk * clk ;
241- u32 val ;
242-
243- clock = kzalloc (sizeof (* clock ), GFP_KERNEL );
244- if (!clock )
245- return ERR_PTR (- ENOMEM );
246-
247- init .name = name ;
248- init .ops = & cpg_sd_clock_ops ;
249- init .flags = CLK_SET_RATE_PARENT ;
250- init .parent_names = & parent_name ;
251- init .num_parents = 1 ;
252-
253- clock -> csn .reg = base + offset ;
254- clock -> hw .init = & init ;
255- clock -> div_table = cpg_sd_div_table ;
256- clock -> div_num = ARRAY_SIZE (cpg_sd_div_table );
257-
258- if (skip_first ) {
259- clock -> div_table ++ ;
260- clock -> div_num -- ;
261- }
262-
263- val = readl (clock -> csn .reg ) & ~CPG_SD_FC_MASK ;
264- val |= CPG_SD_STP_MASK | (clock -> div_table [0 ].val & CPG_SD_FC_MASK );
265- writel (val , clock -> csn .reg );
266-
267- clk = clk_register (NULL , & clock -> hw );
268- if (IS_ERR (clk ))
269- goto free_clock ;
270-
271- cpg_simple_notifier_register (notifiers , & clock -> csn );
272- return clk ;
273-
274- free_clock :
275- kfree (clock );
276- return clk ;
109+ return clk_register_divider_table (NULL , name , parent_name , 0 , sdnckcr ,
110+ 0 , 2 , 0 , cpg_sd_div_table , & cpg_lock );
277111}
278112
279113struct rpc_clock {
0 commit comments