@@ -120,9 +120,11 @@ static const struct clk_ops utmi_ops = {
120120 .recalc_rate = clk_utmi_recalc_rate ,
121121};
122122
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 )
126128{
127129 struct clk_utmi * utmi ;
128130 struct clk_hw * hw ;
@@ -134,10 +136,10 @@ at91_clk_register_utmi(struct regmap *regmap_pmc, struct regmap *regmap_sfr,
134136 return ERR_PTR (- ENOMEM );
135137
136138 init .name = name ;
137- init .ops = & utmi_ops ;
139+ init .ops = ops ;
138140 init .parent_names = parent_name ? & parent_name : NULL ;
139141 init .num_parents = parent_name ? 1 : 0 ;
140- init .flags = CLK_SET_RATE_GATE ;
142+ init .flags = flags ;
141143
142144 utmi -> hw .init = & init ;
143145 utmi -> regmap_pmc = regmap_pmc ;
@@ -152,3 +154,94 @@ at91_clk_register_utmi(struct regmap *regmap_pmc, struct regmap *regmap_sfr,
152154
153155 return hw ;
154156}
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