summaryrefslogtreecommitdiff
path: root/drivers/clk/clk-aspeed.c
diff options
context:
space:
mode:
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 = {