aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/drivers/clk/clk-aspeed.c
diff options
context:
space:
mode:
authorJoel Stanley <joel@jms.id.au>2018-04-27 12:25:47 +0930
committerStephen Boyd <sboyd@kernel.org>2018-05-15 14:59:35 -0700
commitdcb899c47da9ff32e5156ddb9b2867f63ff7c4d0 (patch)
tree205d7715f5702b8f85d8a93a2f926862bac9e08f /drivers/clk/clk-aspeed.c
parentLinux 4.17-rc1 (diff)
downloadwireguard-linux-dcb899c47da9ff32e5156ddb9b2867f63ff7c4d0.tar.xz
wireguard-linux-dcb899c47da9ff32e5156ddb9b2867f63ff7c4d0.zip
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>
Diffstat (limited to 'drivers/clk/clk-aspeed.c')
-rw-r--r--drivers/clk/clk-aspeed.c44
1 files changed, 36 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 @@
#define ASPEED_NUM_CLKS 35
+#define ASPEED_RESET2_OFFSET 32
+
#define ASPEED_RESET_CTRL 0x04
#define ASPEED_CLK_SELECTION 0x08
#define ASPEED_CLK_STOP_CTRL 0x0c
@@ -30,6 +32,7 @@
#define CLKIN_25MHZ_EN BIT(23)
#define AST2400_CLK_SOURCE_SEL BIT(18)
#define ASPEED_CLK_SELECTION_2 0xd8
+#define ASPEED_RESET_CTRL2 0xd4
/* Globally visible clocks */
static DEFINE_SPINLOCK(aspeed_clk_lock);
@@ -291,6 +294,7 @@ struct aspeed_reset {
#define to_aspeed_reset(p) container_of((p), struct aspeed_reset, rcdev)
static const u8 aspeed_resets[] = {
+ /* SCU04 resets */
[ASPEED_RESET_XDMA] = 25,
[ASPEED_RESET_MCTP] = 24,
[ASPEED_RESET_ADC] = 23,
@@ -300,38 +304,62 @@ static const u8 aspeed_resets[] = {
[ASPEED_RESET_PCIVGA] = 8,
[ASPEED_RESET_I2C] = 2,
[ASPEED_RESET_AHB] = 1,
+
+ /*
+ * SCUD4 resets start at an offset to separate them from
+ * the SCU04 resets.
+ */
+ [ASPEED_RESET_CRT1] = ASPEED_RESET2_OFFSET + 5,
};
static int aspeed_reset_deassert(struct reset_controller_dev *rcdev,
unsigned long id)
{
struct aspeed_reset *ar = to_aspeed_reset(rcdev);
- u32 rst = BIT(aspeed_resets[id]);
+ u32 reg = ASPEED_RESET_CTRL;
+ u32 bit = aspeed_resets[id];
+
+ if (bit >= ASPEED_RESET2_OFFSET) {
+ bit -= ASPEED_RESET2_OFFSET;
+ reg = ASPEED_RESET_CTRL2;
+ }
- return regmap_update_bits(ar->map, ASPEED_RESET_CTRL, rst, 0);
+ return regmap_update_bits(ar->map, reg, BIT(bit), 0);
}
static int aspeed_reset_assert(struct reset_controller_dev *rcdev,
unsigned long id)
{
struct aspeed_reset *ar = to_aspeed_reset(rcdev);
- u32 rst = BIT(aspeed_resets[id]);
+ u32 reg = ASPEED_RESET_CTRL;
+ u32 bit = aspeed_resets[id];
- return regmap_update_bits(ar->map, ASPEED_RESET_CTRL, rst, rst);
+ if (bit >= ASPEED_RESET2_OFFSET) {
+ bit -= ASPEED_RESET2_OFFSET;
+ reg = ASPEED_RESET_CTRL2;
+ }
+
+ return regmap_update_bits(ar->map, reg, BIT(bit), BIT(bit));
}
static int aspeed_reset_status(struct reset_controller_dev *rcdev,
unsigned long id)
{
struct aspeed_reset *ar = to_aspeed_reset(rcdev);
- u32 val, rst = BIT(aspeed_resets[id]);
- int ret;
+ u32 reg = ASPEED_RESET_CTRL;
+ u32 bit = aspeed_resets[id];
+ int ret, val;
+
+ if (bit >= ASPEED_RESET2_OFFSET) {
+ bit -= ASPEED_RESET2_OFFSET;
+ reg = ASPEED_RESET_CTRL2;
+ }
- ret = regmap_read(ar->map, ASPEED_RESET_CTRL, &val);
+ ret = regmap_read(ar->map, reg, &val);
if (ret)
return ret;
- return !!(val & rst);
+ return !!(val & BIT(bit));
}
static const struct reset_control_ops aspeed_reset_ops = {