@@ -120,9 +120,11 @@ static const struct clk_ops utmi_ops = {
120
120
.recalc_rate = clk_utmi_recalc_rate ,
121
121
};
122
122
123
- struct clk_hw * __init
124
- at91_clk_register_utmi (struct regmap * regmap_pmc , struct regmap * regmap_sfr ,
125
- const char * name , const char * parent_name )
123
+ static struct clk_hw * __init
124
+ at91_clk_register_utmi_internal (struct regmap * regmap_pmc ,
125
+ struct regmap * regmap_sfr ,
126
+ const char * name , const char * parent_name ,
127
+ const struct clk_ops * ops , unsigned long flags )
126
128
{
127
129
struct clk_utmi * utmi ;
128
130
struct clk_hw * hw ;
@@ -134,10 +136,10 @@ at91_clk_register_utmi(struct regmap *regmap_pmc, struct regmap *regmap_sfr,
134
136
return ERR_PTR (- ENOMEM );
135
137
136
138
init .name = name ;
137
- init .ops = & utmi_ops ;
139
+ init .ops = ops ;
138
140
init .parent_names = parent_name ? & parent_name : NULL ;
139
141
init .num_parents = parent_name ? 1 : 0 ;
140
- init .flags = CLK_SET_RATE_GATE ;
142
+ init .flags = flags ;
141
143
142
144
utmi -> hw .init = & init ;
143
145
utmi -> regmap_pmc = regmap_pmc ;
@@ -152,3 +154,94 @@ at91_clk_register_utmi(struct regmap *regmap_pmc, struct regmap *regmap_sfr,
152
154
153
155
return hw ;
154
156
}
157
+
158
+ struct clk_hw * __init
159
+ at91_clk_register_utmi (struct regmap * regmap_pmc , struct regmap * regmap_sfr ,
160
+ const char * name , const char * parent_name )
161
+ {
162
+ return at91_clk_register_utmi_internal (regmap_pmc , regmap_sfr , name ,
163
+ parent_name , & utmi_ops , CLK_SET_RATE_GATE );
164
+ }
165
+
166
+ static int clk_utmi_sama7g5_prepare (struct clk_hw * hw )
167
+ {
168
+ struct clk_utmi * utmi = to_clk_utmi (hw );
169
+ struct clk_hw * hw_parent ;
170
+ unsigned long parent_rate ;
171
+ unsigned int val ;
172
+
173
+ hw_parent = clk_hw_get_parent (hw );
174
+ parent_rate = clk_hw_get_rate (hw_parent );
175
+
176
+ switch (parent_rate ) {
177
+ case 16000000 :
178
+ val = 0 ;
179
+ break ;
180
+ case 20000000 :
181
+ val = 2 ;
182
+ break ;
183
+ case 24000000 :
184
+ val = 3 ;
185
+ break ;
186
+ case 32000000 :
187
+ val = 5 ;
188
+ break ;
189
+ default :
190
+ pr_err ("UTMICK: unsupported main_xtal rate\n" );
191
+ return - EINVAL ;
192
+ }
193
+
194
+ regmap_write (utmi -> regmap_pmc , AT91_PMC_XTALF , val );
195
+
196
+ return 0 ;
197
+
198
+ }
199
+
200
+ static int clk_utmi_sama7g5_is_prepared (struct clk_hw * hw )
201
+ {
202
+ struct clk_utmi * utmi = to_clk_utmi (hw );
203
+ struct clk_hw * hw_parent ;
204
+ unsigned long parent_rate ;
205
+ unsigned int val ;
206
+
207
+ hw_parent = clk_hw_get_parent (hw );
208
+ parent_rate = clk_hw_get_rate (hw_parent );
209
+
210
+ regmap_read (utmi -> regmap_pmc , AT91_PMC_XTALF , & val );
211
+ switch (val & 0x7 ) {
212
+ case 0 :
213
+ if (parent_rate == 16000000 )
214
+ return 1 ;
215
+ break ;
216
+ case 2 :
217
+ if (parent_rate == 20000000 )
218
+ return 1 ;
219
+ break ;
220
+ case 3 :
221
+ if (parent_rate == 24000000 )
222
+ return 1 ;
223
+ break ;
224
+ case 5 :
225
+ if (parent_rate == 32000000 )
226
+ return 1 ;
227
+ break ;
228
+ default :
229
+ break ;
230
+ }
231
+
232
+ return 0 ;
233
+ }
234
+
235
+ static const struct clk_ops sama7g5_utmi_ops = {
236
+ .prepare = clk_utmi_sama7g5_prepare ,
237
+ .is_prepared = clk_utmi_sama7g5_is_prepared ,
238
+ .recalc_rate = clk_utmi_recalc_rate ,
239
+ };
240
+
241
+ struct clk_hw * __init
242
+ at91_clk_sama7g5_register_utmi (struct regmap * regmap_pmc , const char * name ,
243
+ const char * parent_name )
244
+ {
245
+ return at91_clk_register_utmi_internal (regmap_pmc , NULL , name ,
246
+ parent_name , & sama7g5_utmi_ops , 0 );
247
+ }
0 commit comments