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,
85 tmp_rate = DIV_ROUND_CLOSEST(tmp_parent_rate, div);
86 if (tmp_rate < req->rate)
87 tmp_diff = req->rate - tmp_rate;
89 tmp_diff = tmp_rate - req->rate;
91 if (best_diff < 0 || best_diff > tmp_diff) {
94 req->best_parent_rate = tmp_parent_rate;
95 req->best_parent_hw = parent;
98 if (!best_diff || tmp_rate < req->rate)
109 req->rate = best_rate;
113 static int at91sam9x5_clk_usb_set_parent(struct clk_hw *hw, u8 index)
116 struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw);
117 struct at91_pmc *pmc = usb->pmc;
121 tmp = pmc_read(pmc, AT91_PMC_USB) & ~AT91_PMC_USBS;
123 tmp |= AT91_PMC_USBS;
124 pmc_write(pmc, AT91_PMC_USB, tmp);
128 static u8 at91sam9x5_clk_usb_get_parent(struct clk_hw *hw)
130 struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw);
131 struct at91_pmc *pmc = usb->pmc;
133 return pmc_read(pmc, AT91_PMC_USB) & AT91_PMC_USBS;
136 static int at91sam9x5_clk_usb_set_rate(struct clk_hw *hw, unsigned long rate,
137 unsigned long parent_rate)
140 struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw);
141 struct at91_pmc *pmc = usb->pmc;
147 div = DIV_ROUND_CLOSEST(parent_rate, rate);
148 if (div > SAM9X5_USB_MAX_DIV + 1 || !div)
151 tmp = pmc_read(pmc, AT91_PMC_USB) & ~AT91_PMC_OHCIUSBDIV;
152 tmp |= (div - 1) << SAM9X5_USB_DIV_SHIFT;
153 pmc_write(pmc, AT91_PMC_USB, tmp);
158 static const struct clk_ops at91sam9x5_usb_ops = {
159 .recalc_rate = at91sam9x5_clk_usb_recalc_rate,
160 .determine_rate = at91sam9x5_clk_usb_determine_rate,
161 .get_parent = at91sam9x5_clk_usb_get_parent,
162 .set_parent = at91sam9x5_clk_usb_set_parent,
163 .set_rate = at91sam9x5_clk_usb_set_rate,
166 static int at91sam9n12_clk_usb_enable(struct clk_hw *hw)
168 struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw);
169 struct at91_pmc *pmc = usb->pmc;
171 pmc_write(pmc, AT91_PMC_USB,
172 pmc_read(pmc, AT91_PMC_USB) | AT91_PMC_USBS);
176 static void at91sam9n12_clk_usb_disable(struct clk_hw *hw)
178 struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw);
179 struct at91_pmc *pmc = usb->pmc;
181 pmc_write(pmc, AT91_PMC_USB,
182 pmc_read(pmc, AT91_PMC_USB) & ~AT91_PMC_USBS);
185 static int at91sam9n12_clk_usb_is_enabled(struct clk_hw *hw)
187 struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw);
188 struct at91_pmc *pmc = usb->pmc;
190 return !!(pmc_read(pmc, AT91_PMC_USB) & AT91_PMC_USBS);
193 static const struct clk_ops at91sam9n12_usb_ops = {
194 .enable = at91sam9n12_clk_usb_enable,
195 .disable = at91sam9n12_clk_usb_disable,
196 .is_enabled = at91sam9n12_clk_usb_is_enabled,
197 .recalc_rate = at91sam9x5_clk_usb_recalc_rate,
198 .determine_rate = at91sam9x5_clk_usb_determine_rate,
199 .set_rate = at91sam9x5_clk_usb_set_rate,
202 static struct clk * __init
203 at91sam9x5_clk_register_usb(struct at91_pmc *pmc, const char *name,
204 const char **parent_names, u8 num_parents)
206 struct at91sam9x5_clk_usb *usb;
207 struct clk *clk = NULL;
208 struct clk_init_data init;
210 usb = kzalloc(sizeof(*usb), GFP_KERNEL);
212 return ERR_PTR(-ENOMEM);
215 init.ops = &at91sam9x5_usb_ops;
216 init.parent_names = parent_names;
217 init.num_parents = num_parents;
218 init.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE |
221 usb->hw.init = &init;
224 clk = clk_register(NULL, &usb->hw);
231 static struct clk * __init
232 at91sam9n12_clk_register_usb(struct at91_pmc *pmc, const char *name,
233 const char *parent_name)
235 struct at91sam9x5_clk_usb *usb;
236 struct clk *clk = NULL;
237 struct clk_init_data init;
239 usb = kzalloc(sizeof(*usb), GFP_KERNEL);
241 return ERR_PTR(-ENOMEM);
244 init.ops = &at91sam9n12_usb_ops;
245 init.parent_names = &parent_name;
246 init.num_parents = 1;
247 init.flags = CLK_SET_RATE_GATE | CLK_SET_RATE_PARENT;
249 usb->hw.init = &init;
252 clk = clk_register(NULL, &usb->hw);
259 static unsigned long at91rm9200_clk_usb_recalc_rate(struct clk_hw *hw,
260 unsigned long parent_rate)
262 struct at91rm9200_clk_usb *usb = to_at91rm9200_clk_usb(hw);
263 struct at91_pmc *pmc = usb->pmc;
267 tmp = pmc_read(pmc, AT91_CKGR_PLLBR);
268 usbdiv = (tmp & AT91_PMC_USBDIV) >> RM9200_USB_DIV_SHIFT;
269 if (usb->divisors[usbdiv])
270 return parent_rate / usb->divisors[usbdiv];
275 static long at91rm9200_clk_usb_round_rate(struct clk_hw *hw, unsigned long rate,
276 unsigned long *parent_rate)
278 struct at91rm9200_clk_usb *usb = to_at91rm9200_clk_usb(hw);
279 struct clk_hw *parent = clk_hw_get_parent(hw);
280 unsigned long bestrate = 0;
282 unsigned long tmprate;
286 for (i = 0; i < RM9200_USB_DIV_TAB_SIZE; i++) {
287 unsigned long tmp_parent_rate;
289 if (!usb->divisors[i])
292 tmp_parent_rate = rate * usb->divisors[i];
293 tmp_parent_rate = clk_hw_round_rate(parent, tmp_parent_rate);
294 tmprate = DIV_ROUND_CLOSEST(tmp_parent_rate, usb->divisors[i]);
296 tmpdiff = rate - tmprate;
298 tmpdiff = tmprate - rate;
300 if (bestdiff < 0 || bestdiff > tmpdiff) {
303 *parent_rate = tmp_parent_rate;
313 static int at91rm9200_clk_usb_set_rate(struct clk_hw *hw, unsigned long rate,
314 unsigned long parent_rate)
318 struct at91rm9200_clk_usb *usb = to_at91rm9200_clk_usb(hw);
319 struct at91_pmc *pmc = usb->pmc;
325 div = DIV_ROUND_CLOSEST(parent_rate, rate);
327 for (i = 0; i < RM9200_USB_DIV_TAB_SIZE; i++) {
328 if (usb->divisors[i] == div) {
329 tmp = pmc_read(pmc, AT91_CKGR_PLLBR) &
331 tmp |= i << RM9200_USB_DIV_SHIFT;
332 pmc_write(pmc, AT91_CKGR_PLLBR, tmp);
340 static const struct clk_ops at91rm9200_usb_ops = {
341 .recalc_rate = at91rm9200_clk_usb_recalc_rate,
342 .round_rate = at91rm9200_clk_usb_round_rate,
343 .set_rate = at91rm9200_clk_usb_set_rate,
346 static struct clk * __init
347 at91rm9200_clk_register_usb(struct at91_pmc *pmc, const char *name,
348 const char *parent_name, const u32 *divisors)
350 struct at91rm9200_clk_usb *usb;
351 struct clk *clk = NULL;
352 struct clk_init_data init;
354 usb = kzalloc(sizeof(*usb), GFP_KERNEL);
356 return ERR_PTR(-ENOMEM);
359 init.ops = &at91rm9200_usb_ops;
360 init.parent_names = &parent_name;
361 init.num_parents = 1;
362 init.flags = CLK_SET_RATE_PARENT;
364 usb->hw.init = &init;
366 memcpy(usb->divisors, divisors, sizeof(usb->divisors));
368 clk = clk_register(NULL, &usb->hw);
375 void __init of_at91sam9x5_clk_usb_setup(struct device_node *np,
376 struct at91_pmc *pmc)
380 const char *parent_names[USB_SOURCE_MAX];
381 const char *name = np->name;
383 num_parents = of_clk_get_parent_count(np);
384 if (num_parents <= 0 || num_parents > USB_SOURCE_MAX)
387 of_clk_parent_fill(np, parent_names, num_parents);
389 of_property_read_string(np, "clock-output-names", &name);
391 clk = at91sam9x5_clk_register_usb(pmc, name, parent_names, num_parents);
395 of_clk_add_provider(np, of_clk_src_simple_get, clk);
398 void __init of_at91sam9n12_clk_usb_setup(struct device_node *np,
399 struct at91_pmc *pmc)
402 const char *parent_name;
403 const char *name = np->name;
405 parent_name = of_clk_get_parent_name(np, 0);
409 of_property_read_string(np, "clock-output-names", &name);
411 clk = at91sam9n12_clk_register_usb(pmc, name, parent_name);
415 of_clk_add_provider(np, of_clk_src_simple_get, clk);
418 void __init of_at91rm9200_clk_usb_setup(struct device_node *np,
419 struct at91_pmc *pmc)
422 const char *parent_name;
423 const char *name = np->name;
424 u32 divisors[4] = {0, 0, 0, 0};
426 parent_name = of_clk_get_parent_name(np, 0);
430 of_property_read_u32_array(np, "atmel,clk-divisors", divisors, 4);
434 of_property_read_string(np, "clock-output-names", &name);
436 clk = at91rm9200_clk_register_usb(pmc, name, parent_name, divisors);
440 of_clk_add_provider(np, of_clk_src_simple_get, clk);