reset: rockchip: implement rk3588 lookup table

The current DT bindings for the rk3588 clock use a different ID than the
one that is supposed to be written to the hardware registers.
Thus, we cannot use directly the id provided in the phandle, but rather
use a lookup table to correctly setup the hardware.

This approach has been implemented already in Linux, by commit :
f1c506d152ff ("clk: rockchip: add clock controller for the RK3588")

Hence, implement a similar approach using the lookup table, and adapt
the existing reset driver to work with SoCs using lookup table.
The file rst-rk3588.c has been copied as much as possible from Linux.

Adapt the clk rk3588 driver as well to bind the reset driver with the
lookup table.

Reviewed-by: Kever Yang <kever.yang@rock-chips.com>
Signed-off-by: Eugen Hristev <eugen.hristev@collabora.com>
diff --git a/drivers/reset/reset-rockchip.c b/drivers/reset/reset-rockchip.c
index 732ac34..2ebe338 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 @@
 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_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_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 @@
 	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 @@
 	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,