aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBoris BREZILLON <b.brezillon@overkiz.com>2013-10-17 12:55:41 -0400
committerNicolas Ferre <nicolas.ferre@atmel.com>2013-12-02 09:31:25 -0500
commitc84a61d87261f91d378cf26be4ffd3199ffd2493 (patch)
tree92da0de1acda1b70872958baaa251b142092efc0
parentf090fb37def3eb9ea49b71751dbe43f423f3a152 (diff)
clk: at91: add PMC usb clock
This patch adds new at91 usb clock implementation using common clk framework. This clock is used to clock usb ports (ohci, ehci and udc). Signed-off-by: Boris BREZILLON <b.brezillon@overkiz.com> Acked-by: Mike Turquette <mturquette@linaro.org> Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
-rw-r--r--arch/arm/mach-at91/Kconfig11
-rw-r--r--drivers/clk/at91/Makefile1
-rw-r--r--drivers/clk/at91/clk-usb.c398
-rw-r--r--drivers/clk/at91/pmc.c15
-rw-r--r--drivers/clk/at91/pmc.h9
5 files changed, 434 insertions, 0 deletions
diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
index 6ad37daca971..b76dc4c62af9 100644
--- a/arch/arm/mach-at91/Kconfig
+++ b/arch/arm/mach-at91/Kconfig
@@ -3,6 +3,9 @@ if ARCH_AT91
3config HAVE_AT91_UTMI 3config HAVE_AT91_UTMI
4 bool 4 bool
5 5
6config HAVE_AT91_USB_CLK
7 bool
8
6config HAVE_AT91_DBGU0 9config HAVE_AT91_DBGU0
7 bool 10 bool
8 11
@@ -82,6 +85,7 @@ config SOC_SAMA5D3
82 select HAVE_AT91_DBGU1 85 select HAVE_AT91_DBGU1
83 select AT91_USE_OLD_CLK 86 select AT91_USE_OLD_CLK
84 select HAVE_AT91_UTMI 87 select HAVE_AT91_UTMI
88 select HAVE_AT91_USB_CLK
85 help 89 help
86 Select this if you are using one of Atmel's SAMA5D3 family SoC. 90 Select this if you are using one of Atmel's SAMA5D3 family SoC.
87 This support covers SAMA5D31, SAMA5D33, SAMA5D34, SAMA5D35. 91 This support covers SAMA5D31, SAMA5D33, SAMA5D34, SAMA5D35.
@@ -96,12 +100,14 @@ config SOC_AT91RM9200
96 select MULTI_IRQ_HANDLER 100 select MULTI_IRQ_HANDLER
97 select SPARSE_IRQ 101 select SPARSE_IRQ
98 select AT91_USE_OLD_CLK 102 select AT91_USE_OLD_CLK
103 select HAVE_AT91_USB_CLK
99 104
100config SOC_AT91SAM9260 105config SOC_AT91SAM9260
101 bool "AT91SAM9260, AT91SAM9XE or AT91SAM9G20" 106 bool "AT91SAM9260, AT91SAM9XE or AT91SAM9G20"
102 select HAVE_AT91_DBGU0 107 select HAVE_AT91_DBGU0
103 select SOC_AT91SAM9 108 select SOC_AT91SAM9
104 select AT91_USE_OLD_CLK 109 select AT91_USE_OLD_CLK
110 select HAVE_AT91_USB_CLK
105 help 111 help
106 Select this if you are using one of Atmel's AT91SAM9260, AT91SAM9XE 112 Select this if you are using one of Atmel's AT91SAM9260, AT91SAM9XE
107 or AT91SAM9G20 SoC. 113 or AT91SAM9G20 SoC.
@@ -112,6 +118,7 @@ config SOC_AT91SAM9261
112 select HAVE_FB_ATMEL 118 select HAVE_FB_ATMEL
113 select SOC_AT91SAM9 119 select SOC_AT91SAM9
114 select AT91_USE_OLD_CLK 120 select AT91_USE_OLD_CLK
121 select HAVE_AT91_USB_CLK
115 help 122 help
116 Select this if you are using one of Atmel's AT91SAM9261 or AT91SAM9G10 SoC. 123 Select this if you are using one of Atmel's AT91SAM9261 or AT91SAM9G10 SoC.
117 124
@@ -121,6 +128,7 @@ config SOC_AT91SAM9263
121 select HAVE_FB_ATMEL 128 select HAVE_FB_ATMEL
122 select SOC_AT91SAM9 129 select SOC_AT91SAM9
123 select AT91_USE_OLD_CLK 130 select AT91_USE_OLD_CLK
131 select HAVE_AT91_USB_CLK
124 132
125config SOC_AT91SAM9RL 133config SOC_AT91SAM9RL
126 bool "AT91SAM9RL" 134 bool "AT91SAM9RL"
@@ -137,6 +145,7 @@ config SOC_AT91SAM9G45
137 select SOC_AT91SAM9 145 select SOC_AT91SAM9
138 select AT91_USE_OLD_CLK 146 select AT91_USE_OLD_CLK
139 select HAVE_AT91_UTMI 147 select HAVE_AT91_UTMI
148 select HAVE_AT91_USB_CLK
140 help 149 help
141 Select this if you are using one of Atmel's AT91SAM9G45 family SoC. 150 Select this if you are using one of Atmel's AT91SAM9G45 family SoC.
142 This support covers AT91SAM9G45, AT91SAM9G46, AT91SAM9M10 and AT91SAM9M11. 151 This support covers AT91SAM9G45, AT91SAM9G46, AT91SAM9M10 and AT91SAM9M11.
@@ -148,6 +157,7 @@ config SOC_AT91SAM9X5
148 select SOC_AT91SAM9 157 select SOC_AT91SAM9
149 select AT91_USE_OLD_CLK 158 select AT91_USE_OLD_CLK
150 select HAVE_AT91_UTMI 159 select HAVE_AT91_UTMI
160 select HAVE_AT91_USB_CLK
151 help 161 help
152 Select this if you are using one of Atmel's AT91SAM9x5 family SoC. 162 Select this if you are using one of Atmel's AT91SAM9x5 family SoC.
153 This means that your SAM9 name finishes with a '5' (except if it is 163 This means that your SAM9 name finishes with a '5' (except if it is
@@ -161,6 +171,7 @@ config SOC_AT91SAM9N12
161 select HAVE_FB_ATMEL 171 select HAVE_FB_ATMEL
162 select SOC_AT91SAM9 172 select SOC_AT91SAM9
163 select AT91_USE_OLD_CLK 173 select AT91_USE_OLD_CLK
174 select HAVE_AT91_USB_CLK
164 help 175 help
165 Select this if you are using Atmel's AT91SAM9N12 SoC. 176 Select this if you are using Atmel's AT91SAM9N12 SoC.
166 177
diff --git a/drivers/clk/at91/Makefile b/drivers/clk/at91/Makefile
index a82488323ea4..61db058be0c0 100644
--- a/drivers/clk/at91/Makefile
+++ b/drivers/clk/at91/Makefile
@@ -8,3 +8,4 @@ obj-y += clk-system.o clk-peripheral.o
8 8
9obj-$(CONFIG_AT91_PROGRAMMABLE_CLOCKS) += clk-programmable.o 9obj-$(CONFIG_AT91_PROGRAMMABLE_CLOCKS) += clk-programmable.o
10obj-$(CONFIG_HAVE_AT91_UTMI) += clk-utmi.o 10obj-$(CONFIG_HAVE_AT91_UTMI) += clk-utmi.o
11obj-$(CONFIG_HAVE_AT91_USB_CLK) += clk-usb.o
diff --git a/drivers/clk/at91/clk-usb.c b/drivers/clk/at91/clk-usb.c
new file mode 100644
index 000000000000..7d1d26a4bd04
--- /dev/null
+++ b/drivers/clk/at91/clk-usb.c
@@ -0,0 +1,398 @@
1/*
2 * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>
3 *
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.
8 *
9 */
10
11#include <linux/clk-provider.h>
12#include <linux/clkdev.h>
13#include <linux/clk/at91_pmc.h>
14#include <linux/of.h>
15#include <linux/of_address.h>
16#include <linux/io.h>
17
18#include "pmc.h"
19
20#define USB_SOURCE_MAX 2
21
22#define SAM9X5_USB_DIV_SHIFT 8
23#define SAM9X5_USB_MAX_DIV 0xf
24
25#define RM9200_USB_DIV_SHIFT 28
26#define RM9200_USB_DIV_TAB_SIZE 4
27
28struct at91sam9x5_clk_usb {
29 struct clk_hw hw;
30 struct at91_pmc *pmc;
31};
32
33#define to_at91sam9x5_clk_usb(hw) \
34 container_of(hw, struct at91sam9x5_clk_usb, hw)
35
36struct at91rm9200_clk_usb {
37 struct clk_hw hw;
38 struct at91_pmc *pmc;
39 u32 divisors[4];
40};
41
42#define to_at91rm9200_clk_usb(hw) \
43 container_of(hw, struct at91rm9200_clk_usb, hw)
44
45static unsigned long at91sam9x5_clk_usb_recalc_rate(struct clk_hw *hw,
46 unsigned long parent_rate)
47{
48 u32 tmp;
49 u8 usbdiv;
50 struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw);
51 struct at91_pmc *pmc = usb->pmc;
52
53 tmp = pmc_read(pmc, AT91_PMC_USB);
54 usbdiv = (tmp & AT91_PMC_OHCIUSBDIV) >> SAM9X5_USB_DIV_SHIFT;
55 return parent_rate / (usbdiv + 1);
56}
57
58static long at91sam9x5_clk_usb_round_rate(struct clk_hw *hw, unsigned long rate,
59 unsigned long *parent_rate)
60{
61 unsigned long div;
62 unsigned long bestrate;
63 unsigned long tmp;
64
65 if (rate >= *parent_rate)
66 return *parent_rate;
67
68 div = *parent_rate / rate;
69 if (div >= SAM9X5_USB_MAX_DIV)
70 return *parent_rate / (SAM9X5_USB_MAX_DIV + 1);
71
72 bestrate = *parent_rate / div;
73 tmp = *parent_rate / (div + 1);
74 if (bestrate - rate > rate - tmp)
75 bestrate = tmp;
76
77 return bestrate;
78}
79
80static int at91sam9x5_clk_usb_set_parent(struct clk_hw *hw, u8 index)
81{
82 u32 tmp;
83 struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw);
84 struct at91_pmc *pmc = usb->pmc;
85