@@ -66,214 +66,48 @@ void cpg_simple_notifier_register(struct raw_notifier_head *notifiers,
66
66
* SDn Clock
67
67
*/
68
68
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)
95
71
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 },
135
75
};
136
76
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 )
158
80
{
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 ;
163
83
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 );
168
87
169
- return DIV_ROUND_CLOSEST (parent_rate ,
170
- clock -> div_table [clock -> cur_div_idx ].div );
171
- }
88
+ csn -> reg = sdnckcr ;
172
89
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 ;
193
96
}
194
97
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 ;
223
100
}
224
101
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 },
232
104
};
233
105
234
106
struct 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 )
237
108
{
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 );
277
111
}
278
112
279
113
struct rpc_clock {
0 commit comments