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
;
55 return parent_rate
/ (usbdiv
+ 1);
58 static long at91sam9x5_clk_usb_round_rate(struct clk_hw
*hw
, unsigned long rate
,
59 unsigned long *parent_rate
)
62 unsigned long bestrate
;
65 if (rate
>= *parent_rate
)
68 div
= *parent_rate
/ rate
;
69 if (div
>= SAM9X5_USB_MAX_DIV
)
70 return *parent_rate
/ (SAM9X5_USB_MAX_DIV
+ 1);
72 bestrate
= *parent_rate
/ div
;
73 tmp
= *parent_rate
/ (div
+ 1);
74 if (bestrate
- rate
> rate
- tmp
)
80 static int at91sam9x5_clk_usb_set_parent(struct clk_hw
*hw
, u8 index
)
83 struct at91sam9x5_clk_usb
*usb
= to_at91sam9x5_clk_usb(hw
);
84 struct at91_pmc
*pmc
= usb
->pmc
;
88 tmp
= pmc_read(pmc
, AT91_PMC_USB
) & ~AT91_PMC_USBS
;
91 pmc_write(pmc
, AT91_PMC_USB
, tmp
);
95 static u8
at91sam9x5_clk_usb_get_parent(struct clk_hw
*hw
)
97 struct at91sam9x5_clk_usb
*usb
= to_at91sam9x5_clk_usb(hw
);
98 struct at91_pmc
*pmc
= usb
->pmc
;
100 return pmc_read(pmc
, AT91_PMC_USB
) & AT91_PMC_USBS
;
103 static int at91sam9x5_clk_usb_set_rate(struct clk_hw
*hw
, unsigned long rate
,
104 unsigned long parent_rate
)
107 struct at91sam9x5_clk_usb
*usb
= to_at91sam9x5_clk_usb(hw
);
108 struct at91_pmc
*pmc
= usb
->pmc
;
109 unsigned long div
= parent_rate
/ rate
;
111 if (parent_rate
% rate
|| div
< 1 || div
>= SAM9X5_USB_MAX_DIV
)
114 tmp
= pmc_read(pmc
, AT91_PMC_USB
) & ~AT91_PMC_OHCIUSBDIV
;
115 tmp
|= (div
- 1) << SAM9X5_USB_DIV_SHIFT
;
116 pmc_write(pmc
, AT91_PMC_USB
, tmp
);
121 static const struct clk_ops at91sam9x5_usb_ops
= {
122 .recalc_rate
= at91sam9x5_clk_usb_recalc_rate
,
123 .round_rate
= at91sam9x5_clk_usb_round_rate
,
124 .get_parent
= at91sam9x5_clk_usb_get_parent
,
125 .set_parent
= at91sam9x5_clk_usb_set_parent
,
126 .set_rate
= at91sam9x5_clk_usb_set_rate
,
129 static int at91sam9n12_clk_usb_enable(struct clk_hw
*hw
)
131 struct at91sam9x5_clk_usb
*usb
= to_at91sam9x5_clk_usb(hw
);
132 struct at91_pmc
*pmc
= usb
->pmc
;
134 pmc_write(pmc
, AT91_PMC_USB
,
135 pmc_read(pmc
, AT91_PMC_USB
) | AT91_PMC_USBS
);
139 static void at91sam9n12_clk_usb_disable(struct clk_hw
*hw
)
141 struct at91sam9x5_clk_usb
*usb
= to_at91sam9x5_clk_usb(hw
);
142 struct at91_pmc
*pmc
= usb
->pmc
;
144 pmc_write(pmc
, AT91_PMC_USB
,
145 pmc_read(pmc
, AT91_PMC_USB
) & ~AT91_PMC_USBS
);
148 static int at91sam9n12_clk_usb_is_enabled(struct clk_hw
*hw
)
150 struct at91sam9x5_clk_usb
*usb
= to_at91sam9x5_clk_usb(hw
);
151 struct at91_pmc
*pmc
= usb
->pmc
;
153 return !!(pmc_read(pmc
, AT91_PMC_USB
) & AT91_PMC_USBS
);
156 static const struct clk_ops at91sam9n12_usb_ops
= {
157 .enable
= at91sam9n12_clk_usb_enable
,
158 .disable
= at91sam9n12_clk_usb_disable
,
159 .is_enabled
= at91sam9n12_clk_usb_is_enabled
,
160 .recalc_rate
= at91sam9x5_clk_usb_recalc_rate
,
161 .round_rate
= at91sam9x5_clk_usb_round_rate
,
162 .set_rate
= at91sam9x5_clk_usb_set_rate
,
165 static struct clk
* __init
166 at91sam9x5_clk_register_usb(struct at91_pmc
*pmc
, const char *name
,
167 const char **parent_names
, u8 num_parents
)
169 struct at91sam9x5_clk_usb
*usb
;
170 struct clk
*clk
= NULL
;
171 struct clk_init_data init
;
173 usb
= kzalloc(sizeof(*usb
), GFP_KERNEL
);
175 return ERR_PTR(-ENOMEM
);
178 init
.ops
= &at91sam9x5_usb_ops
;
179 init
.parent_names
= parent_names
;
180 init
.num_parents
= num_parents
;
181 init
.flags
= CLK_SET_RATE_GATE
| CLK_SET_PARENT_GATE
;
183 usb
->hw
.init
= &init
;
186 clk
= clk_register(NULL
, &usb
->hw
);
193 static struct clk
* __init
194 at91sam9n12_clk_register_usb(struct at91_pmc
*pmc
, const char *name
,
195 const char *parent_name
)
197 struct at91sam9x5_clk_usb
*usb
;
198 struct clk
*clk
= NULL
;
199 struct clk_init_data init
;
201 usb
= kzalloc(sizeof(*usb
), GFP_KERNEL
);
203 return ERR_PTR(-ENOMEM
);
206 init
.ops
= &at91sam9n12_usb_ops
;
207 init
.parent_names
= &parent_name
;
208 init
.num_parents
= 1;
209 init
.flags
= CLK_SET_RATE_GATE
;
211 usb
->hw
.init
= &init
;
214 clk
= clk_register(NULL
, &usb
->hw
);
221 static unsigned long at91rm9200_clk_usb_recalc_rate(struct clk_hw
*hw
,
222 unsigned long parent_rate
)
224 struct at91rm9200_clk_usb
*usb
= to_at91rm9200_clk_usb(hw
);
225 struct at91_pmc
*pmc
= usb
->pmc
;
229 tmp
= pmc_read(pmc
, AT91_CKGR_PLLBR
);
230 usbdiv
= (tmp
& AT91_PMC_USBDIV
) >> RM9200_USB_DIV_SHIFT
;
231 if (usb
->divisors
[usbdiv
])
232 return parent_rate
/ usb
->divisors
[usbdiv
];
237 static long at91rm9200_clk_usb_round_rate(struct clk_hw
*hw
, unsigned long rate
,
238 unsigned long *parent_rate
)
240 struct at91rm9200_clk_usb
*usb
= to_at91rm9200_clk_usb(hw
);
241 unsigned long bestrate
= 0;
243 unsigned long tmprate
;
247 for (i
= 0; i
< 4; i
++) {
248 if (!usb
->divisors
[i
])
250 tmprate
= *parent_rate
/ usb
->divisors
[i
];
252 tmpdiff
= rate
- tmprate
;
254 tmpdiff
= tmprate
- rate
;
256 if (bestdiff
< 0 || bestdiff
> tmpdiff
) {
268 static int at91rm9200_clk_usb_set_rate(struct clk_hw
*hw
, unsigned long rate
,
269 unsigned long parent_rate
)
273 struct at91rm9200_clk_usb
*usb
= to_at91rm9200_clk_usb(hw
);
274 struct at91_pmc
*pmc
= usb
->pmc
;
275 unsigned long div
= parent_rate
/ rate
;
277 if (parent_rate
% rate
)
279 for (i
= 0; i
< RM9200_USB_DIV_TAB_SIZE
; i
++) {
280 if (usb
->divisors
[i
] == div
) {
281 tmp
= pmc_read(pmc
, AT91_CKGR_PLLBR
) &
283 tmp
|= i
<< RM9200_USB_DIV_SHIFT
;
284 pmc_write(pmc
, AT91_CKGR_PLLBR
, tmp
);
292 static const struct clk_ops at91rm9200_usb_ops
= {
293 .recalc_rate
= at91rm9200_clk_usb_recalc_rate
,
294 .round_rate
= at91rm9200_clk_usb_round_rate
,
295 .set_rate
= at91rm9200_clk_usb_set_rate
,
298 static struct clk
* __init
299 at91rm9200_clk_register_usb(struct at91_pmc
*pmc
, const char *name
,
300 const char *parent_name
, const u32
*divisors
)
302 struct at91rm9200_clk_usb
*usb
;
303 struct clk
*clk
= NULL
;
304 struct clk_init_data init
;
306 usb
= kzalloc(sizeof(*usb
), GFP_KERNEL
);
308 return ERR_PTR(-ENOMEM
);
311 init
.ops
= &at91rm9200_usb_ops
;
312 init
.parent_names
= &parent_name
;
313 init
.num_parents
= 1;
316 usb
->hw
.init
= &init
;
318 memcpy(usb
->divisors
, divisors
, sizeof(usb
->divisors
));
320 clk
= clk_register(NULL
, &usb
->hw
);
327 void __init
of_at91sam9x5_clk_usb_setup(struct device_node
*np
,
328 struct at91_pmc
*pmc
)
333 const char *parent_names
[USB_SOURCE_MAX
];
334 const char *name
= np
->name
;
336 num_parents
= of_count_phandle_with_args(np
, "clocks", "#clock-cells");
337 if (num_parents
<= 0 || num_parents
> USB_SOURCE_MAX
)
340 for (i
= 0; i
< num_parents
; i
++) {
341 parent_names
[i
] = of_clk_get_parent_name(np
, i
);
342 if (!parent_names
[i
])
346 of_property_read_string(np
, "clock-output-names", &name
);
348 clk
= at91sam9x5_clk_register_usb(pmc
, name
, parent_names
, num_parents
);
352 of_clk_add_provider(np
, of_clk_src_simple_get
, clk
);
355 void __init
of_at91sam9n12_clk_usb_setup(struct device_node
*np
,
356 struct at91_pmc
*pmc
)
359 const char *parent_name
;
360 const char *name
= np
->name
;
362 parent_name
= of_clk_get_parent_name(np
, 0);
366 of_property_read_string(np
, "clock-output-names", &name
);
368 clk
= at91sam9n12_clk_register_usb(pmc
, name
, parent_name
);
372 of_clk_add_provider(np
, of_clk_src_simple_get
, clk
);
375 void __init
of_at91rm9200_clk_usb_setup(struct device_node
*np
,
376 struct at91_pmc
*pmc
)
379 const char *parent_name
;
380 const char *name
= np
->name
;
381 u32 divisors
[4] = {0, 0, 0, 0};
383 parent_name
= of_clk_get_parent_name(np
, 0);
387 of_property_read_u32_array(np
, "atmel,clk-divisors", divisors
, 4);
391 of_property_read_string(np
, "clock-output-names", &name
);
393 clk
= at91rm9200_clk_register_usb(pmc
, name
, parent_name
, divisors
);
397 of_clk_add_provider(np
, of_clk_src_simple_get
, clk
);