diff options
author | Alexandre Belloni <alexandre.belloni@bootlin.com> | 2019-04-02 08:50:52 -0400 |
---|---|---|
committer | Stephen Boyd <sboyd@kernel.org> | 2019-04-25 15:34:04 -0400 |
commit | 2423eeaead6f83f289c85394313e693cdefb728c (patch) | |
tree | 13e2bd64ca8f3a73b1191a991fcf0a8ae53ecd3b | |
parent | e4cfb823bd71c785fe482e4d7491ef04ac561a7d (diff) |
clk: at91: usb: Add sam9x60 support
The sam9x60 USB clock supports four different parents, ensure they can be
selected.
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
-rw-r--r-- | drivers/clk/at91/clk-usb.c | 33 | ||||
-rw-r--r-- | drivers/clk/at91/pmc.h | 3 |
2 files changed, 30 insertions, 6 deletions
diff --git a/drivers/clk/at91/clk-usb.c b/drivers/clk/at91/clk-usb.c index 79ee1c760f2a..ebc37ee33518 100644 --- a/drivers/clk/at91/clk-usb.c +++ b/drivers/clk/at91/clk-usb.c | |||
@@ -23,9 +23,13 @@ | |||
23 | #define RM9200_USB_DIV_SHIFT 28 | 23 | #define RM9200_USB_DIV_SHIFT 28 |
24 | #define RM9200_USB_DIV_TAB_SIZE 4 | 24 | #define RM9200_USB_DIV_TAB_SIZE 4 |
25 | 25 | ||
26 | #define SAM9X5_USBS_MASK GENMASK(0, 0) | ||
27 | #define SAM9X60_USBS_MASK GENMASK(1, 0) | ||
28 | |||
26 | struct at91sam9x5_clk_usb { | 29 | struct at91sam9x5_clk_usb { |
27 | struct clk_hw hw; | 30 | struct clk_hw hw; |
28 | struct regmap *regmap; | 31 | struct regmap *regmap; |
32 | u32 usbs_mask; | ||
29 | }; | 33 | }; |
30 | 34 | ||
31 | #define to_at91sam9x5_clk_usb(hw) \ | 35 | #define to_at91sam9x5_clk_usb(hw) \ |
@@ -111,8 +115,7 @@ static int at91sam9x5_clk_usb_set_parent(struct clk_hw *hw, u8 index) | |||
111 | if (index > 1) | 115 | if (index > 1) |
112 | return -EINVAL; | 116 | return -EINVAL; |
113 | 117 | ||
114 | regmap_update_bits(usb->regmap, AT91_PMC_USB, AT91_PMC_USBS, | 118 | regmap_update_bits(usb->regmap, AT91_PMC_USB, usb->usbs_mask, index); |
115 | index ? AT91_PMC_USBS : 0); | ||
116 | 119 | ||
117 | return 0; | 120 | return 0; |
118 | } | 121 | } |
@@ -124,7 +127,7 @@ static u8 at91sam9x5_clk_usb_get_parent(struct clk_hw *hw) | |||
124 | 127 | ||
125 | regmap_read(usb->regmap, AT91_PMC_USB, &usbr); | 128 | regmap_read(usb->regmap, AT91_PMC_USB, &usbr); |
126 | 129 | ||
127 | return usbr & AT91_PMC_USBS; | 130 | return usbr & usb->usbs_mask; |
128 | } | 131 | } |
129 | 132 | ||
130 | static int at91sam9x5_clk_usb_set_rate(struct clk_hw *hw, unsigned long rate, | 133 | static int at91sam9x5_clk_usb_set_rate(struct clk_hw *hw, unsigned long rate, |
@@ -190,9 +193,10 @@ static const struct clk_ops at91sam9n12_usb_ops = { | |||
190 | .set_rate = at91sam9x5_clk_usb_set_rate, | 193 | .set_rate = at91sam9x5_clk_usb_set_rate, |
191 | }; | 194 | }; |
192 | 195 | ||
193 | struct clk_hw * __init | 196 | static struct clk_hw * __init |
194 | at91sam9x5_clk_register_usb(struct regmap *regmap, const char *name, | 197 | _at91sam9x5_clk_register_usb(struct regmap *regmap, const char *name, |
195 | const char **parent_names, u8 num_parents) | 198 | const char **parent_names, u8 num_parents, |
199 | u32 usbs_mask) | ||
196 | { | 200 | { |
197 | struct at91sam9x5_clk_usb *usb; | 201 | struct at91sam9x5_clk_usb *usb; |
198 | struct clk_hw *hw; | 202 | struct clk_hw *hw; |
@@ -212,6 +216,7 @@ at91sam9x5_clk_register_usb(struct regmap *regmap, const char *name, | |||
212 | 216 | ||
213 | usb->hw.init = &init; | 217 | usb->hw.init = &init; |
214 | usb->regmap = regmap; | 218 | usb->regmap = regmap; |
219 | usb->usbs_mask = SAM9X5_USBS_MASK; | ||
215 | 220 | ||
216 | hw = &usb->hw; | 221 | hw = &usb->hw; |
217 | ret = clk_hw_register(NULL, &usb->hw); | 222 | ret = clk_hw_register(NULL, &usb->hw); |
@@ -224,6 +229,22 @@ at91sam9x5_clk_register_usb(struct regmap *regmap, const char *name, | |||
224 | } | 229 | } |
225 | 230 | ||
226 | struct clk_hw * __init | 231 | struct clk_hw * __init |
232 | at91sam9x5_clk_register_usb(struct regmap *regmap, const char *name, | ||
233 | const char **parent_names, u8 num_parents) | ||
234 | { | ||
235 | return _at91sam9x5_clk_register_usb(regmap, name, parent_names, | ||
236 | num_parents, SAM9X5_USBS_MASK); | ||
237 | } | ||
238 | |||
239 | struct clk_hw * __init | ||
240 | sam9x60_clk_register_usb(struct regmap *regmap, const char *name, | ||
241 | const char **parent_names, u8 num_parents) | ||
242 | { | ||
243 | return _at91sam9x5_clk_register_usb(regmap, name, parent_names, | ||
244 | num_parents, SAM9X60_USBS_MASK); | ||
245 | } | ||
246 | |||
247 | struct clk_hw * __init | ||
227 | at91sam9n12_clk_register_usb(struct regmap *regmap, const char *name, | 248 | at91sam9n12_clk_register_usb(struct regmap *regmap, const char *name, |
228 | const char *parent_name) | 249 | const char *parent_name) |
229 | { | 250 | { |
diff --git a/drivers/clk/at91/pmc.h b/drivers/clk/at91/pmc.h index 4027306b904c..44345e4ab1c9 100644 --- a/drivers/clk/at91/pmc.h +++ b/drivers/clk/at91/pmc.h | |||
@@ -194,6 +194,9 @@ struct clk_hw * __init | |||
194 | at91sam9n12_clk_register_usb(struct regmap *regmap, const char *name, | 194 | at91sam9n12_clk_register_usb(struct regmap *regmap, const char *name, |
195 | const char *parent_name); | 195 | const char *parent_name); |
196 | struct clk_hw * __init | 196 | struct clk_hw * __init |
197 | sam9x60_clk_register_usb(struct regmap *regmap, const char *name, | ||
198 | const char **parent_names, u8 num_parents); | ||
199 | struct clk_hw * __init | ||
197 | at91rm9200_clk_register_usb(struct regmap *regmap, const char *name, | 200 | at91rm9200_clk_register_usb(struct regmap *regmap, const char *name, |
198 | const char *parent_name, const u32 *divisors); | 201 | const char *parent_name, const u32 *divisors); |
199 | 202 | ||