diff options
Diffstat (limited to 'drivers/reset/reset-rockchip.c')
-rw-r--r-- | drivers/reset/reset-rockchip.c | 46 |
1 files changed, 35 insertions, 11 deletions
diff --git a/drivers/reset/reset-rockchip.c b/drivers/reset/reset-rockchip.c index 732ac343b2b..2ebe3382f70 100644 --- a/drivers/reset/reset-rockchip.c +++ b/drivers/reset/reset-rockchip.c @@ -21,6 +21,7 @@ struct rockchip_reset_priv { void __iomem *base; + const int *lut; /* Rockchip reset reg locate at cru controller */ u32 reset_reg_offset; /* Rockchip reset reg number */ @@ -30,11 +31,15 @@ struct rockchip_reset_priv { static int rockchip_reset_request(struct reset_ctl *reset_ctl) { struct rockchip_reset_priv *priv = dev_get_priv(reset_ctl->dev); + unsigned long id = reset_ctl->id; + + if (priv->lut) + id = priv->lut[id]; debug("%s(reset_ctl=%p) (dev=%p, id=%lu) (reg_num=%d)\n", __func__, - reset_ctl, reset_ctl->dev, reset_ctl->id, priv->reset_reg_num); + reset_ctl, reset_ctl->dev, id, priv->reset_reg_num); - if (reset_ctl->id / ROCKCHIP_RESET_NUM_IN_REG >= priv->reset_reg_num) + if (id / ROCKCHIP_RESET_NUM_IN_REG >= priv->reset_reg_num) return -EINVAL; return 0; @@ -43,12 +48,17 @@ static int rockchip_reset_request(struct reset_ctl *reset_ctl) static int rockchip_reset_assert(struct reset_ctl *reset_ctl) { struct rockchip_reset_priv *priv = dev_get_priv(reset_ctl->dev); - int bank = reset_ctl->id / ROCKCHIP_RESET_NUM_IN_REG; - int offset = reset_ctl->id % ROCKCHIP_RESET_NUM_IN_REG; + unsigned long id = reset_ctl->id; + int bank, offset; + + if (priv->lut) + id = priv->lut[id]; + + bank = id / ROCKCHIP_RESET_NUM_IN_REG; + offset = id % ROCKCHIP_RESET_NUM_IN_REG; debug("%s(reset_ctl=%p) (dev=%p, id=%lu) (reg_addr=%p)\n", __func__, - reset_ctl, reset_ctl->dev, reset_ctl->id, - priv->base + (bank * 4)); + reset_ctl, reset_ctl->dev, id, priv->base + (bank * 4)); rk_setreg(priv->base + (bank * 4), BIT(offset)); @@ -58,12 +68,17 @@ static int rockchip_reset_assert(struct reset_ctl *reset_ctl) static int rockchip_reset_deassert(struct reset_ctl *reset_ctl) { struct rockchip_reset_priv *priv = dev_get_priv(reset_ctl->dev); - int bank = reset_ctl->id / ROCKCHIP_RESET_NUM_IN_REG; - int offset = reset_ctl->id % ROCKCHIP_RESET_NUM_IN_REG; + unsigned long id = reset_ctl->id; + int bank, offset; + + if (priv->lut) + id = priv->lut[id]; + + bank = id / ROCKCHIP_RESET_NUM_IN_REG; + offset = id % ROCKCHIP_RESET_NUM_IN_REG; debug("%s(reset_ctl=%p) (dev=%p, id=%lu) (reg_addr=%p)\n", __func__, - reset_ctl, reset_ctl->dev, reset_ctl->id, - priv->base + (bank * 4)); + reset_ctl, reset_ctl->dev, id, priv->base + (bank * 4)); rk_clrreg(priv->base + (bank * 4), BIT(offset)); @@ -98,7 +113,10 @@ static int rockchip_reset_probe(struct udevice *dev) return 0; } -int rockchip_reset_bind(struct udevice *pdev, u32 reg_offset, u32 reg_number) +int rockchip_reset_bind_lut(struct udevice *pdev, + const int *lookup_table, + u32 reg_offset, + u32 reg_number) { struct udevice *rst_dev; struct rockchip_reset_priv *priv; @@ -113,11 +131,17 @@ int rockchip_reset_bind(struct udevice *pdev, u32 reg_offset, u32 reg_number) priv = malloc(sizeof(struct rockchip_reset_priv)); priv->reset_reg_offset = reg_offset; priv->reset_reg_num = reg_number; + priv->lut = lookup_table; dev_set_priv(rst_dev, priv); return 0; } +int rockchip_reset_bind(struct udevice *pdev, u32 reg_offset, u32 reg_number) +{ + return rockchip_reset_bind_lut(pdev, NULL, reg_offset, reg_number); +} + U_BOOT_DRIVER(rockchip_reset) = { .name = "rockchip_reset", .id = UCLASS_RESET, |