2 * (C) Copyright 2017 Rockchip Electronics Co., Ltd
4 * SPDX-License-Identifier: GPL-2.0
9 #include <reset-uclass.h>
11 #include <asm/arch/hardware.h>
14 * Each reg has 16 bits reset signal for devices
15 * Note: Not including rk2818 and older SoCs
17 #define ROCKCHIP_RESET_NUM_IN_REG 16
19 struct rockchip_reset_priv
{
21 /* Rockchip reset reg locate at cru controller */
23 /* Rockchip reset reg number */
27 static int rockchip_reset_request(struct reset_ctl
*reset_ctl
)
29 struct rockchip_reset_priv
*priv
= dev_get_priv(reset_ctl
->dev
);
31 debug("%s(reset_ctl=%p) (dev=%p, id=%lu) (reg_num=%d)\n", __func__
,
32 reset_ctl
, reset_ctl
->dev
, reset_ctl
->id
, priv
->reset_reg_num
);
34 if (reset_ctl
->id
/ ROCKCHIP_RESET_NUM_IN_REG
>= priv
->reset_reg_num
)
40 static int rockchip_reset_free(struct reset_ctl
*reset_ctl
)
42 debug("%s(reset_ctl=%p) (dev=%p, id=%lu)\n", __func__
, reset_ctl
,
43 reset_ctl
->dev
, reset_ctl
->id
);
48 static int rockchip_reset_assert(struct reset_ctl
*reset_ctl
)
50 struct rockchip_reset_priv
*priv
= dev_get_priv(reset_ctl
->dev
);
51 int bank
= reset_ctl
->id
/ ROCKCHIP_RESET_NUM_IN_REG
;
52 int offset
= reset_ctl
->id
% ROCKCHIP_RESET_NUM_IN_REG
;
54 debug("%s(reset_ctl=%p) (dev=%p, id=%lu) (reg_addr=%p)\n", __func__
,
55 reset_ctl
, reset_ctl
->dev
, reset_ctl
->id
,
56 priv
->base
+ (bank
* 4));
58 rk_setreg(priv
->base
+ (bank
* 4), BIT(offset
));
63 static int rockchip_reset_deassert(struct reset_ctl
*reset_ctl
)
65 struct rockchip_reset_priv
*priv
= dev_get_priv(reset_ctl
->dev
);
66 int bank
= reset_ctl
->id
/ ROCKCHIP_RESET_NUM_IN_REG
;
67 int offset
= reset_ctl
->id
% ROCKCHIP_RESET_NUM_IN_REG
;
69 debug("%s(reset_ctl=%p) (dev=%p, id=%lu) (reg_addr=%p)\n", __func__
,
70 reset_ctl
, reset_ctl
->dev
, reset_ctl
->id
,
71 priv
->base
+ (bank
* 4));
73 rk_clrreg(priv
->base
+ (bank
* 4), BIT(offset
));
78 struct reset_ops rockchip_reset_ops
= {
79 .request
= rockchip_reset_request
,
80 .free
= rockchip_reset_free
,
81 .rst_assert
= rockchip_reset_assert
,
82 .rst_deassert
= rockchip_reset_deassert
,
85 static int rockchip_reset_probe(struct udevice
*dev
)
87 struct rockchip_reset_priv
*priv
= dev_get_priv(dev
);
91 addr
= dev_read_addr_size(dev
, "reg", &size
);
92 if (addr
== FDT_ADDR_T_NONE
)
95 if ((priv
->reset_reg_offset
== 0) && (priv
->reset_reg_num
== 0))
98 addr
+= priv
->reset_reg_offset
;
99 priv
->base
= ioremap(addr
, size
);
101 debug("%s(base=%p) (reg_offset=%x, reg_num=%d)\n", __func__
,
102 priv
->base
, priv
->reset_reg_offset
, priv
->reset_reg_num
);
107 int rockchip_reset_bind(struct udevice
*pdev
, u32 reg_offset
, u32 reg_number
)
109 struct udevice
*rst_dev
;
110 struct rockchip_reset_priv
*priv
;
113 ret
= device_bind_driver_to_node(pdev
, "rockchip_reset", "reset",
114 dev_ofnode(pdev
), &rst_dev
);
116 debug("Warning: No rockchip reset driver: ret=%d\n", ret
);
119 priv
= malloc(sizeof(struct rockchip_reset_priv
));
120 priv
->reset_reg_offset
= reg_offset
;
121 priv
->reset_reg_num
= reg_number
;
122 rst_dev
->priv
= priv
;
127 U_BOOT_DRIVER(rockchip_reset
) = {
128 .name
= "rockchip_reset",
130 .probe
= rockchip_reset_probe
,
131 .ops
= &rockchip_reset_ops
,
132 .priv_auto_alloc_size
= sizeof(struct rockchip_reset_priv
),