Commit 3e066bcaefb51adcf5c0594d42abe145f701dbeb
Committed by
Tom Rini
1 parent
37cbd8918c
Exists in
smarc_8mq_lf_v2020.04
and in
12 other branches
reset: MedaiTek: add reset controller driver for MediaTek SoCs
This patch adds reset controller driver for MediaTek SoCs. Signed-off-by: Ryder Lee <ryder.lee@mediatek.com> Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
Showing 5 changed files with 141 additions and 0 deletions Side-by-side Diff
arch/arm/include/asm/arch-mediatek/reset.h
1 | +/* SPDX-License-Identifier: GPL-2.0 */ | |
2 | +/* | |
3 | + * Copyright (C) 2018 MediaTek Inc. | |
4 | + */ | |
5 | + | |
6 | +#ifndef __MEDIATEK_RESET_H | |
7 | +#define __MEDIATEK_RESET_H | |
8 | + | |
9 | +#include <dm.h> | |
10 | + | |
11 | +int mediatek_reset_bind(struct udevice *pdev, u32 regofs, u32 num_regs); | |
12 | + | |
13 | +#endif /* __MEDIATEK_RESET_H */ |
drivers/reset/Kconfig
... | ... | @@ -106,5 +106,12 @@ |
106 | 106 | help |
107 | 107 | Support for reset controller on SoCFPGA platform. |
108 | 108 | |
109 | +config RESET_MEDIATEK | |
110 | + bool "Reset controller driver for MediaTek SoCs" | |
111 | + depends on DM_RESET && ARCH_MEDIATEK && CLK | |
112 | + default y | |
113 | + help | |
114 | + Support for reset controller on MediaTek SoCs. | |
115 | + | |
109 | 116 | endmenu |
drivers/reset/Makefile
drivers/reset/reset-mediatek.c
1 | +// SPDX-License-Identifier: GPL-2.0 | |
2 | +/* | |
3 | + * Copyright (C) 2018 MediaTek Inc. | |
4 | + * | |
5 | + * Author: Ryder Lee <ryder.lee@mediatek.com> | |
6 | + * Weijie Gao <weijie.gao@mediatek.com> | |
7 | + */ | |
8 | + | |
9 | +#include <common.h> | |
10 | +#include <dm.h> | |
11 | +#include <dm/lists.h> | |
12 | +#include <regmap.h> | |
13 | +#include <reset-uclass.h> | |
14 | +#include <syscon.h> | |
15 | + | |
16 | +struct mediatek_reset_priv { | |
17 | + struct regmap *regmap; | |
18 | + u32 regofs; | |
19 | + u32 nr_resets; | |
20 | +}; | |
21 | + | |
22 | +static int mediatek_reset_request(struct reset_ctl *reset_ctl) | |
23 | +{ | |
24 | + return 0; | |
25 | +} | |
26 | + | |
27 | +static int mediatek_reset_free(struct reset_ctl *reset_ctl) | |
28 | +{ | |
29 | + return 0; | |
30 | +} | |
31 | + | |
32 | +static int mediatek_reset_assert(struct reset_ctl *reset_ctl) | |
33 | +{ | |
34 | + struct mediatek_reset_priv *priv = dev_get_priv(reset_ctl->dev); | |
35 | + int id = reset_ctl->id; | |
36 | + | |
37 | + if (id >= priv->nr_resets) | |
38 | + return -EINVAL; | |
39 | + | |
40 | + return regmap_update_bits(priv->regmap, | |
41 | + priv->regofs + ((id / 32) << 2), BIT(id % 32), BIT(id % 32)); | |
42 | +} | |
43 | + | |
44 | +static int mediatek_reset_deassert(struct reset_ctl *reset_ctl) | |
45 | +{ | |
46 | + struct mediatek_reset_priv *priv = dev_get_priv(reset_ctl->dev); | |
47 | + int id = reset_ctl->id; | |
48 | + | |
49 | + if (id >= priv->nr_resets) | |
50 | + return -EINVAL; | |
51 | + | |
52 | + return regmap_update_bits(priv->regmap, | |
53 | + priv->regofs + ((id / 32) << 2), BIT(id % 32), 0); | |
54 | +} | |
55 | + | |
56 | +struct reset_ops mediatek_reset_ops = { | |
57 | + .request = mediatek_reset_request, | |
58 | + .free = mediatek_reset_free, | |
59 | + .rst_assert = mediatek_reset_assert, | |
60 | + .rst_deassert = mediatek_reset_deassert, | |
61 | +}; | |
62 | + | |
63 | +static int mediatek_reset_probe(struct udevice *dev) | |
64 | +{ | |
65 | + struct mediatek_reset_priv *priv = dev_get_priv(dev); | |
66 | + | |
67 | + if (!priv->regofs && !priv->nr_resets) | |
68 | + return -EINVAL; | |
69 | + | |
70 | + priv->regmap = syscon_node_to_regmap(dev_ofnode(dev)); | |
71 | + if (IS_ERR(priv->regmap)) | |
72 | + return PTR_ERR(priv->regmap); | |
73 | + | |
74 | + return 0; | |
75 | +} | |
76 | + | |
77 | +int mediatek_reset_bind(struct udevice *pdev, u32 regofs, u32 num_regs) | |
78 | +{ | |
79 | + struct udevice *rst_dev; | |
80 | + struct mediatek_reset_priv *priv; | |
81 | + int ret; | |
82 | + | |
83 | + ret = device_bind_driver_to_node(pdev, "mediatek_reset", "reset", | |
84 | + dev_ofnode(pdev), &rst_dev); | |
85 | + if (ret) | |
86 | + return ret; | |
87 | + | |
88 | + priv = malloc(sizeof(struct mediatek_reset_priv)); | |
89 | + priv->regofs = regofs; | |
90 | + priv->nr_resets = num_regs * 32; | |
91 | + rst_dev->priv = priv; | |
92 | + | |
93 | + return 0; | |
94 | +} | |
95 | + | |
96 | +U_BOOT_DRIVER(mediatek_reset) = { | |
97 | + .name = "mediatek_reset", | |
98 | + .id = UCLASS_RESET, | |
99 | + .probe = mediatek_reset_probe, | |
100 | + .ops = &mediatek_reset_ops, | |
101 | + .priv_auto_alloc_size = sizeof(struct mediatek_reset_priv), | |
102 | +}; |
include/dt-bindings/reset/mtk-reset.h
1 | +/* SPDX-License-Identifier: GPL-2.0 */ | |
2 | +/* | |
3 | + * Copyright (C) 2018 MediaTek Inc. | |
4 | + */ | |
5 | + | |
6 | +#ifndef _DT_BINDINGS_MTK_RESET_H_ | |
7 | +#define _DT_BINDINGS_MTK_RESET_H_ | |
8 | + | |
9 | +/* ETHSYS */ | |
10 | +#define ETHSYS_PPE_RST 31 | |
11 | +#define ETHSYS_EPHY_RST 24 | |
12 | +#define ETHSYS_GMAC_RST 23 | |
13 | +#define ETHSYS_ESW_RST 16 | |
14 | +#define ETHSYS_FE_RST 6 | |
15 | +#define ETHSYS_MCM_RST 2 | |
16 | +#define ETHSYS_SYS_RST 0 | |
17 | + | |
18 | +#endif /* _DT_BINDINGS_MTK_RESET_H_ */ |