2 * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
11 #include <linux/clk-provider.h>
12 #include <linux/clkdev.h>
13 #include <linux/clk/at91_pmc.h>
15 #include <linux/of_address.h>
20 #define USB_SOURCE_MAX 2
22 #define SAM9X5_USB_DIV_SHIFT 8
23 #define SAM9X5_USB_MAX_DIV 0xf
25 #define RM9200_USB_DIV_SHIFT 28
26 #define RM9200_USB_DIV_TAB_SIZE 4
28 struct at91sam9x5_clk_usb
{
33 #define to_at91sam9x5_clk_usb(hw) \
34 container_of(hw, struct at91sam9x5_clk_usb, hw)
36 struct at91rm9200_clk_usb
{
42 #define to_at91rm9200_clk_usb(hw) \
43 container_of(hw, struct at91rm9200_clk_usb, hw)
45 static unsigned long at91sam9x5_clk_usb_recalc_rate(struct clk_hw
*hw
,
46 unsigned long parent_rate
)
50 struct at91sam9x5_clk_usb
*usb
= to_at91sam9x5_clk_usb(hw
);
51 struct at91_pmc
*pmc
= usb
->pmc
;
53 tmp
= pmc_read(pmc
, AT91_PMC_USB
);
54 usbdiv
= (tmp
& AT91_PMC_OHCIUSBDIV
) >> SAM9X5_USB_DIV_SHIFT
;
56 return DIV_ROUND_CLOSEST(parent_rate
, (usbdiv
+ 1));
59 static int at91sam9x5_clk_usb_determine_rate(struct clk_hw
*hw
,
60 struct clk_rate_request
*req
)
62 struct clk_hw
*parent
;
63 long best_rate
= -EINVAL
;
64 unsigned long tmp_rate
;
69 for (i
= 0; i
< clk_hw_get_num_parents(hw
); i
++) {
72 parent
= clk_hw_get_parent_by_index(hw
, i
);
76 for (div
= 1; div
< SAM9X5_USB_MAX_DIV
+ 2; div
++) {
77 unsigned long tmp_parent_rate
;
79 tmp_parent_rate
= req
->rate
* div
;
80 tmp_parent_rate
= clk_hw_round_rate(parent
,
82 tmp_rate
= DIV_ROUND_CLOSEST(tmp_parent_rate
, div
);
83 if (tmp_rate
< req
->rate
)
84 tmp_diff
= req
->rate
- tmp_rate
;
86 tmp_diff
= tmp_rate
- req
->rate
;
88 if (best_diff
< 0 || best_diff
> tmp_diff
) {
91 req
->best_parent_rate
= tmp_parent_rate
;
92 req
->best_parent_hw
= parent
;
95 if (!best_diff
|| tmp_rate
< req
->rate
)
106 req
->rate
= best_rate
;
110 static int at91sam9x5_clk_usb_set_parent(struct clk_hw
*hw
, u8 index
)
113 struct at91sam9x5_clk_usb
*usb
= to_at91sam9x5_clk_usb(hw
);
114 struct at91_pmc
*pmc
= usb
->pmc
;
118 tmp
= pmc_read(pmc
, AT91_PMC_USB
) & ~AT91_PMC_USBS
;
120 tmp
|= AT91_PMC_USBS
;
121 pmc_write(pmc
, AT91_PMC_USB
, tmp
);
125 static u8
at91sam9x5_clk_usb_get_parent(struct clk_hw
*hw
)
127 struct at91sam9x5_clk_usb
*usb
= to_at91sam9x5_clk_usb(hw
);
128 struct at91_pmc
*pmc
= usb
->pmc
;
130 return pmc_read(pmc
, AT91_PMC_USB
) & AT91_PMC_USBS
;
133 static int at91sam9x5_clk_usb_set_rate(struct clk_hw
*hw
, unsigned long rate
,
134 unsigned long parent_rate
)
137 struct at91sam9x5_clk_usb
*usb
= to_at91sam9x5_clk_usb(hw
);
138 struct at91_pmc
*pmc
= usb
->pmc
;
144 div
= DIV_ROUND_CLOSEST(parent_rate
, rate
);
145 if (div
> SAM9X5_USB_MAX_DIV
+ 1 || !div
)
148 tmp
= pmc_read(pmc
, AT91_PMC_USB
) & ~AT91_PMC_OHCIUSBDIV
;
149 tmp
|= (div
- 1) << SAM9X5_USB_DIV_SHIFT
;
150 pmc_write(pmc
, AT91_PMC_USB
, tmp
);
155 static const struct clk_ops at91sam9x5_usb_ops
= {
156 .recalc_rate
= at91sam9x5_clk_usb_recalc_rate
,
157 .determine_rate
= at91sam9x5_clk_usb_determine_rate
,
158 .get_parent
= at91sam9x5_clk_usb_get_parent
,
159 .set_parent
= at91sam9x5_clk_usb_set_parent
,
160 .set_rate
= at91sam9x5_clk_usb_set_rate
,
163 static int at91sam9n12_clk_usb_enable(struct clk_hw
*hw
)
165 struct at91sam9x5_clk_usb
*usb
= to_at91sam9x5_clk_usb(hw
);
166 struct at91_pmc
*pmc
= usb
->pmc
;
168 pmc_write(pmc
, AT91_PMC_USB
,
169 pmc_read(pmc
, AT91_PMC_USB
) | AT91_PMC_USBS
);
173 static void at91sam9n12_clk_usb_disable(struct clk_hw
*hw
)
175 struct at91sam9x5_clk_usb
*usb
= to_at91sam9x5_clk_usb(hw
);
176 struct at91_pmc
*pmc
= usb
->pmc
;
178 pmc_write(pmc
, AT91_PMC_USB
,
179 pmc_read(pmc
, AT91_PMC_USB
) & ~AT91_PMC_USBS
);
182 static int at91sam9n12_clk_usb_is_enabled(struct clk_hw
*hw
)
184 struct at91sam9x5_clk_usb
*usb
= to_at91sam9x5_clk_usb(hw
);
185 struct at91_pmc
*pmc
= usb
->pmc
;
187 return !!(pmc_read(pmc
, AT91_PMC_USB
) & AT91_PMC_USBS
);
190 static const struct clk_ops at91sam9n12_usb_ops
= {
191 .enable
= at91sam9n12_clk_usb_enable
,
192 .disable
= at91sam9n12_clk_usb_disable
,
193 .is_enabled
= at91sam9n12_clk_usb_is_enabled
,
194 .recalc_rate
= at91sam9x5_clk_usb_recalc_rate
,
195 .determine_rate
= at91sam9x5_clk_usb_determine_rate
,
196 .set_rate
= at91sam9x5_clk_usb_set_rate
,
199 static struct clk
* __init
200 at91sam9x5_clk_register_usb(struct at91_pmc
*pmc
, const char *name
,
201 const char **parent_names
, u8 num_parents
)
203 struct at91sam9x5_clk_usb
*usb
;
204 struct clk
*clk
= NULL
;
205 struct clk_init_data init
;
207 usb
= kzalloc(sizeof(*usb
), GFP_KERNEL
);
209 return ERR_PTR(-ENOMEM
);
212 init
.ops
= &at91sam9x5_usb_ops
;
213 init
.parent_names
= parent_names
;
214 init
.num_parents
= num_parents
;
215 init
.flags
= CLK_SET_RATE_GATE
| CLK_SET_PARENT_GATE
|
218 usb
->hw
.init
= &init
;
221 clk
= clk_register(NULL
, &usb
->hw
);
228 static struct clk
* __init
229 at91sam9n12_clk_register_usb(struct at91_pmc
*pmc
, const char *name
,
230 const char *parent_name
)
232 struct at91sam9x5_clk_usb
*usb
;
233 struct clk
*clk
= NULL
;
234 struct clk_init_data init
;
236 usb
= kzalloc(sizeof(*usb
), GFP_KERNEL
);
238 return ERR_PTR(-ENOMEM
);
241 init
.ops
= &at91sam9n12_usb_ops
;
242 init
.parent_names
= &parent_name
;
243 init
.num_parents
= 1;
244 init
.flags
= CLK_SET_RATE_GATE
| CLK_SET_RATE_PARENT
;
246 usb
->hw
.init
= &init
;
249 clk
= clk_register(NULL
, &usb
->hw
);
256 static unsigned long at91rm9200_clk_usb_recalc_rate(struct clk_hw
*hw
,
257 unsigned long parent_rate
)
259 struct at91rm9200_clk_usb
*usb
= to_at91rm9200_clk_usb(hw
);
260 struct at91_pmc
*pmc
= usb
->pmc
;
264 tmp
= pmc_read(pmc
, AT91_CKGR_PLLBR
);
265 usbdiv
= (tmp
& AT91_PMC_USBDIV
) >> RM9200_USB_DIV_SHIFT
;
266 if (usb
->divisors
[usbdiv
])
267 return parent_rate
/ usb
->divisors
[usbdiv
];
272 static long at91rm9200_clk_usb_round_rate(struct clk_hw
*hw
, unsigned long rate
,
273 unsigned long *parent_rate
)
275 struct at91rm9200_clk_usb
*usb
= to_at91rm9200_clk_usb(hw
);
276 struct clk_hw
*parent
= clk_hw_get_parent(hw
);
277 unsigned long bestrate
= 0;
279 unsigned long tmprate
;
283 for (i
= 0; i
< RM9200_USB_DIV_TAB_SIZE
; i
++) {
284 unsigned long tmp_parent_rate
;
286 if (!usb
->divisors
[i
])
289 tmp_parent_rate
= rate
* usb
->divisors
[i
];
290 tmp_parent_rate
= clk_hw_round_rate(parent
, tmp_parent_rate
);
291 tmprate
= DIV_ROUND_CLOSEST(tmp_parent_rate
, usb
->divisors
[i
]);
293 tmpdiff
= rate
- tmprate
;
295 tmpdiff
= tmprate
- rate
;
297 if (bestdiff
< 0 || bestdiff
> tmpdiff
) {
300 *parent_rate
= tmp_parent_rate
;
310 static int at91rm9200_clk_usb_set_rate(struct clk_hw
*hw
, unsigned long rate
,
311 unsigned long parent_rate
)
315 struct at91rm9200_clk_usb
*usb
= to_at91rm9200_clk_usb(hw
);
316 struct at91_pmc
*pmc
= usb
->pmc
;
322 div
= DIV_ROUND_CLOSEST(parent_rate
, rate
);
324 for (i
= 0; i
< RM9200_USB_DIV_TAB_SIZE
; i
++) {
325 if (usb
->divisors
[i
] == div
) {
326 tmp
= pmc_read(pmc
, AT91_CKGR_PLLBR
) &
328 tmp
|= i
<< RM9200_USB_DIV_SHIFT
;
329 pmc_write(pmc
, AT91_CKGR_PLLBR
, tmp
);
337 static const struct clk_ops at91rm9200_usb_ops
= {
338 .recalc_rate
= at91rm9200_clk_usb_recalc_rate
,
339 .round_rate
= at91rm9200_clk_usb_round_rate
,
340 .set_rate
= at91rm9200_clk_usb_set_rate
,
343 static struct clk
* __init
344 at91rm9200_clk_register_usb(struct at91_pmc
*pmc
, const char *name
,
345 const char *parent_name
, const u32
*divisors
)
347 struct at91rm9200_clk_usb
*usb
;
348 struct clk
*clk
= NULL
;
349 struct clk_init_data init
;
351 usb
= kzalloc(sizeof(*usb
), GFP_KERNEL
);
353 return ERR_PTR(-ENOMEM
);
356 init
.ops
= &at91rm9200_usb_ops
;
357 init
.parent_names
= &parent_name
;
358 init
.num_parents
= 1;
359 init
.flags
= CLK_SET_RATE_PARENT
;
361 usb
->hw
.init
= &init
;
363 memcpy(usb
->divisors
, divisors
, sizeof(usb
->divisors
));
365 clk
= clk_register(NULL
, &usb
->hw
);
372 void __init
of_at91sam9x5_clk_usb_setup(struct device_node
*np
,
373 struct at91_pmc
*pmc
)
377 const char *parent_names
[USB_SOURCE_MAX
];
378 const char *name
= np
->name
;
380 num_parents
= of_clk_get_parent_count(np
);
381 if (num_parents
<= 0 || num_parents
> USB_SOURCE_MAX
)
384 of_clk_parent_fill(np
, parent_names
, num_parents
);
386 of_property_read_string(np
, "clock-output-names", &name
);
388 clk
= at91sam9x5_clk_register_usb(pmc
, name
, parent_names
, num_parents
);
392 of_clk_add_provider(np
, of_clk_src_simple_get
, clk
);
395 void __init
of_at91sam9n12_clk_usb_setup(struct device_node
*np
,
396 struct at91_pmc
*pmc
)
399 const char *parent_name
;
400 const char *name
= np
->name
;
402 parent_name
= of_clk_get_parent_name(np
, 0);
406 of_property_read_string(np
, "clock-output-names", &name
);
408 clk
= at91sam9n12_clk_register_usb(pmc
, name
, parent_name
);
412 of_clk_add_provider(np
, of_clk_src_simple_get
, clk
);
415 void __init
of_at91rm9200_clk_usb_setup(struct device_node
*np
,
416 struct at91_pmc
*pmc
)
419 const char *parent_name
;
420 const char *name
= np
->name
;
421 u32 divisors
[4] = {0, 0, 0, 0};
423 parent_name
= of_clk_get_parent_name(np
, 0);
427 of_property_read_u32_array(np
, "atmel,clk-divisors", divisors
, 4);
431 of_property_read_string(np
, "clock-output-names", &name
);
433 clk
= at91rm9200_clk_register_usb(pmc
, name
, parent_name
, divisors
);
437 of_clk_add_provider(np
, of_clk_src_simple_get
, clk
);