aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoel Stanley <joel@jms.id.au>2018-04-26 22:55:47 -0400
committerStephen Boyd <sboyd@kernel.org>2018-05-15 17:59:35 -0400
commitdcb899c47da9ff32e5156ddb9b2867f63ff7c4d0 (patch)
tree205d7715f5702b8f85d8a93a2f926862bac9e08f
parent60cc43fc888428bb2f18f08997432d426a243338 (diff)
clk: aspeed: Support second reset register
The ast2500 has an additional reset register that contains resets not present in the ast2400. This enables support for this register, and adds the one reset line that is controlled by it. Reviewed-by: Andrew Jeffery <andrew@aj.id.au> Signed-off-by: Joel Stanley <joel@jms.id.au> Signed-off-by: Stephen Boyd <sboyd@kernel.org>
-rw-r--r--drivers/clk/clk-aspeed.c44
-rw-r--r--include/dt-bindings/clock/aspeed-clock.h1
2 files changed, 37 insertions, 8 deletions
diff --git a/drivers/clk/clk-aspeed.c b/drivers/clk/clk-aspeed.c
index 5eb50c31e455..dd17a818dff8 100644
--- a/drivers/clk/clk-aspeed.c
+++ b/drivers/clk/clk-aspeed.c
@@ -16,6 +16,8 @@
16 16
17#define ASPEED_NUM_CLKS 35 17#define ASPEED_NUM_CLKS 35
18 18
19#define ASPEED_RESET2_OFFSET 32
20
19#define ASPEED_RESET_CTRL 0x04 21#define ASPEED_RESET_CTRL 0x04
20#define ASPEED_CLK_SELECTION 0x08 22#define ASPEED_CLK_SELECTION 0x08
21#define ASPEED_CLK_STOP_CTRL 0x0c 23#define ASPEED_CLK_STOP_CTRL 0x0c
@@ -30,6 +32,7 @@
30#define CLKIN_25MHZ_EN BIT(23) 32#define CLKIN_25MHZ_EN BIT(23)
31#define AST2400_CLK_SOURCE_SEL BIT(18) 33#define AST2400_CLK_SOURCE_SEL BIT(18)
32#define ASPEED_CLK_SELECTION_2 0xd8 34#define ASPEED_CLK_SELECTION_2 0xd8
35#define ASPEED_RESET_CTRL2 0xd4
33 36
34/* Globally visible clocks */ 37/* Globally visible clocks */
35static DEFINE_SPINLOCK(aspeed_clk_lock); 38static DEFINE_SPINLOCK(aspeed_clk_lock);
@@ -291,6 +294,7 @@ struct aspeed_reset {
291#define to_aspeed_reset(p) container_of((p), struct aspeed_reset, rcdev) 294#define to_aspeed_reset(p) container_of((p), struct aspeed_reset, rcdev)
292 295
293static const u8 aspeed_resets[] = { 296static const u8 aspeed_resets[] = {
297 /* SCU04 resets */
294 [ASPEED_RESET_XDMA] = 25, 298 [ASPEED_RESET_XDMA] = 25,
295 [ASPEED_RESET_MCTP] = 24, 299 [ASPEED_RESET_MCTP] = 24,
296 [ASPEED_RESET_ADC] = 23, 300 [ASPEED_RESET_ADC] = 23,
@@ -300,38 +304,62 @@ static const u8 aspeed_resets[] = {
300 [ASPEED_RESET_PCIVGA] = 8, 304 [ASPEED_RESET_PCIVGA] = 8,
301 [ASPEED_RESET_I2C] = 2, 305 [ASPEED_RESET_I2C] = 2,
302 [ASPEED_RESET_AHB] = 1, 306 [ASPEED_RESET_AHB] = 1,
307
308 /*
309 * SCUD4 resets start at an offset to separate them from
310 * the SCU04 resets.
311 */
312 [ASPEED_RESET_CRT1] = ASPEED_RESET2_OFFSET + 5,
303}; 313};
304 314
305static int aspeed_reset_deassert(struct reset_controller_dev *rcdev, 315static int aspeed_reset_deassert(struct reset_controller_dev *rcdev,
306 unsigned long id) 316 unsigned long id)
307{ 317{
308 struct aspeed_reset *ar = to_aspeed_reset(rcdev); 318 struct aspeed_reset *ar = to_aspeed_reset(rcdev);
309 u32 rst = BIT(aspeed_resets[id]); 319 u32 reg = ASPEED_RESET_CTRL;
320 u32 bit = aspeed_resets[id];
321
322 if (bit >= ASPEED_RESET2_OFFSET) {
323 bit -= ASPEED_RESET2_OFFSET;
324 reg = ASPEED_RESET_CTRL2;
325 }
310 326
311 return regmap_update_bits(ar->map, ASPEED_RESET_CTRL, rst, 0); 327 return regmap_update_bits(ar->map, reg, BIT(bit), 0);
312} 328}
313 329
314static int aspeed_reset_assert(struct reset_controller_dev *rcdev, 330static int aspeed_reset_assert(struct reset_controller_dev *rcdev,
315 unsigned long id) 331 unsigned long id)
316{ 332{
317 struct aspeed_reset *ar = to_aspeed_reset(rcdev); 333 struct aspeed_reset *ar = to_aspeed_reset(rcdev);
318 u32 rst = BIT(aspeed_resets[id]); 334 u32 reg = ASPEED_RESET_CTRL;
335 u32 bit = aspeed_resets[id];
319 336
320 return regmap_update_bits(ar->map, ASPEED_RESET_CTRL, rst, rst); 337 if (bit >= ASPEED_RESET2_OFFSET) {
338 bit -= ASPEED_RESET2_OFFSET;
339 reg = ASPEED_RESET_CTRL2;
340 }
341
342 return regmap_update_bits(ar->map, reg, BIT(bit), BIT(bit));
321} 343}
322 344
323static int aspeed_reset_status(struct reset_controller_dev *rcdev, 345static int aspeed_reset_status(struct reset_controller_dev *rcdev,
324 unsigned long id) 346 unsigned long id)
325{ 347{
326 struct aspeed_reset *ar = to_aspeed_reset(rcdev); 348 struct aspeed_reset *ar = to_aspeed_reset(rcdev);
327 u32 val, rst = BIT(aspeed_resets[id]); 349 u32 reg = ASPEED_RESET_CTRL;
328 int ret; 350 u32 bit = aspeed_resets[id];
351 int ret, val;
352
353 if (bit >= ASPEED_RESET2_OFFSET) {
354 bit -= ASPEED_RESET2_OFFSET;
355 reg = ASPEED_RESET_CTRL2;
356 }
329 357
330 ret = regmap_read(ar->map, ASPEED_RESET_CTRL, &val); 358 ret = regmap_read(ar->map, reg, &val);
331 if (ret) 359 if (ret)
332 return ret; 360 return ret;
333 361
334 return !!(val & rst); 362 return !!(val & BIT(bit));
335} 363}
336 364
337static const struct reset_control_ops aspeed_reset_ops = { 365static const struct reset_control_ops aspeed_reset_ops = {
diff --git a/include/dt-bindings/clock/aspeed-clock.h b/include/dt-bindings/clock/aspeed-clock.h
index d3558d897a4d..513c1b4af7a8 100644
--- a/include/dt-bindings/clock/aspeed-clock.h
+++ b/include/dt-bindings/clock/aspeed-clock.h
@@ -48,5 +48,6 @@
48#define ASPEED_RESET_PCIVGA 6 48#define ASPEED_RESET_PCIVGA 6
49#define ASPEED_RESET_I2C 7 49#define ASPEED_RESET_I2C 7
50#define ASPEED_RESET_AHB 8 50#define ASPEED_RESET_AHB 8
51#define ASPEED_RESET_CRT1 9
51 52
52#endif 53#endif