blob: a3e1f0b2c9d524d02b18515dcdd28778e93daa73 [file] [log] [blame]
Steven Liu9128fe72025-04-07 22:46:50 +00001// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Copyright (c) 2022 Rockchip Electronics Co., Ltd.
4 */
5
6#include <dm.h>
7#include <dm/pinctrl.h>
8#include <regmap.h>
9#include <syscon.h>
10
11#include "pinctrl-rockchip.h"
12#include <dt-bindings/pinctrl/rockchip.h>
13
14static int rk3528_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
15{
16 struct rockchip_pinctrl_priv *priv = bank->priv;
17 int iomux_num = (pin / 8);
18 struct regmap *regmap;
19 int reg, mask;
20 u8 bit;
21 u32 data, rmask;
22
23 regmap = priv->regmap_base;
24 reg = bank->iomux[iomux_num].offset;
25 if ((pin % 8) >= 4)
26 reg += 0x4;
27 bit = (pin % 4) * 4;
28 mask = 0xf;
29
30 data = (mask << (bit + 16));
31 rmask = data | (data >> 16);
32 data |= (mux & mask) << bit;
33
34 return regmap_update_bits(regmap, reg, rmask, data);
35}
36
37#define RK3528_DRV_BITS_PER_PIN 8
38#define RK3528_DRV_PINS_PER_REG 2
39#define RK3528_DRV_GPIO0_OFFSET 0x100
40#define RK3528_DRV_GPIO1_OFFSET 0x20120
41#define RK3528_DRV_GPIO2_OFFSET 0x30160
42#define RK3528_DRV_GPIO3_OFFSET 0x20190
43#define RK3528_DRV_GPIO4_OFFSET 0x101C0
44
45static void rk3528_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
46 int pin_num, struct regmap **regmap,
47 int *reg, u8 *bit)
48{
49 struct rockchip_pinctrl_priv *priv = bank->priv;
50
51 *regmap = priv->regmap_base;
52
53 if (bank->bank_num == 0) {
54 *reg = RK3528_DRV_GPIO0_OFFSET;
55 } else if (bank->bank_num == 1) {
56 *reg = RK3528_DRV_GPIO1_OFFSET;
57 } else if (bank->bank_num == 2) {
58 *reg = RK3528_DRV_GPIO2_OFFSET;
59 } else if (bank->bank_num == 3) {
60 *reg = RK3528_DRV_GPIO3_OFFSET;
61 } else if (bank->bank_num == 4) {
62 *reg = RK3528_DRV_GPIO4_OFFSET;
63 } else {
64 *reg = 0;
65 debug("unsupported bank_num %d\n", bank->bank_num);
66 }
67
68 *reg += ((pin_num / RK3528_DRV_PINS_PER_REG) * 4);
69 *bit = pin_num % RK3528_DRV_PINS_PER_REG;
70 *bit *= RK3528_DRV_BITS_PER_PIN;
71}
72
73static int rk3528_set_drive(struct rockchip_pin_bank *bank,
74 int pin_num, int strength)
75{
76 struct regmap *regmap;
77 int reg;
78 u32 data, rmask;
79 u8 bit;
80 int drv = (1 << (strength + 1)) - 1;
81
82 rk3528_calc_drv_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
83
84 /* enable the write to the equivalent lower bits */
85 data = ((1 << RK3528_DRV_BITS_PER_PIN) - 1) << (bit + 16);
86 rmask = data | (data >> 16);
87 data |= (drv << bit);
88
89 return regmap_update_bits(regmap, reg, rmask, data);
90}
91
92#define RK3528_PULL_BITS_PER_PIN 2
93#define RK3528_PULL_PINS_PER_REG 8
94#define RK3528_PULL_GPIO0_OFFSET 0x200
95#define RK3528_PULL_GPIO1_OFFSET 0x20210
96#define RK3528_PULL_GPIO2_OFFSET 0x30220
97#define RK3528_PULL_GPIO3_OFFSET 0x20230
98#define RK3528_PULL_GPIO4_OFFSET 0x10240
99
100static void rk3528_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
101 int pin_num, struct regmap **regmap,
102 int *reg, u8 *bit)
103{
104 struct rockchip_pinctrl_priv *priv = bank->priv;
105
106 *regmap = priv->regmap_base;
107
108 if (bank->bank_num == 0) {
109 *reg = RK3528_PULL_GPIO0_OFFSET;
110 } else if (bank->bank_num == 1) {
111 *reg = RK3528_PULL_GPIO1_OFFSET;
112 } else if (bank->bank_num == 2) {
113 *reg = RK3528_PULL_GPIO2_OFFSET;
114 } else if (bank->bank_num == 3) {
115 *reg = RK3528_PULL_GPIO3_OFFSET;
116 } else if (bank->bank_num == 4) {
117 *reg = RK3528_PULL_GPIO4_OFFSET;
118 } else {
119 *reg = 0;
120 debug("unsupported bank_num %d\n", bank->bank_num);
121 }
122
123 *reg += ((pin_num / RK3528_PULL_PINS_PER_REG) * 4);
124 *bit = pin_num % RK3528_PULL_PINS_PER_REG;
125 *bit *= RK3528_PULL_BITS_PER_PIN;
126}
127
128static int rk3528_set_pull(struct rockchip_pin_bank *bank,
129 int pin_num, int pull)
130{
131 struct regmap *regmap;
132 int reg, ret;
133 u8 bit, type;
134 u32 data, rmask;
135
136 if (pull == PIN_CONFIG_BIAS_PULL_PIN_DEFAULT)
137 return -EOPNOTSUPP;
138
139 rk3528_calc_pull_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
140 type = bank->pull_type[pin_num / 8];
141 ret = rockchip_translate_pull_value(type, pull);
142 if (ret < 0) {
143 debug("unsupported pull setting %d\n", pull);
144 return ret;
145 }
146
147 /* enable the write to the equivalent lower bits */
148 data = ((1 << RK3528_PULL_BITS_PER_PIN) - 1) << (bit + 16);
149 rmask = data | (data >> 16);
150 data |= (ret << bit);
151
152 return regmap_update_bits(regmap, reg, rmask, data);
153}
154
155#define RK3528_SMT_BITS_PER_PIN 1
156#define RK3528_SMT_PINS_PER_REG 8
157#define RK3528_SMT_GPIO0_OFFSET 0x400
158#define RK3528_SMT_GPIO1_OFFSET 0x20410
159#define RK3528_SMT_GPIO2_OFFSET 0x30420
160#define RK3528_SMT_GPIO3_OFFSET 0x20430
161#define RK3528_SMT_GPIO4_OFFSET 0x10440
162
163static int rk3528_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank,
164 int pin_num,
165 struct regmap **regmap,
166 int *reg, u8 *bit)
167{
168 struct rockchip_pinctrl_priv *priv = bank->priv;
169
170 *regmap = priv->regmap_base;
171
172 if (bank->bank_num == 0) {
173 *reg = RK3528_SMT_GPIO0_OFFSET;
174 } else if (bank->bank_num == 1) {
175 *reg = RK3528_SMT_GPIO1_OFFSET;
176 } else if (bank->bank_num == 2) {
177 *reg = RK3528_SMT_GPIO2_OFFSET;
178 } else if (bank->bank_num == 3) {
179 *reg = RK3528_SMT_GPIO3_OFFSET;
180 } else if (bank->bank_num == 4) {
181 *reg = RK3528_SMT_GPIO4_OFFSET;
182 } else {
183 *reg = 0;
184 debug("unsupported bank_num %d\n", bank->bank_num);
185 }
186
187 *reg += ((pin_num / RK3528_SMT_PINS_PER_REG) * 4);
188 *bit = pin_num % RK3528_SMT_PINS_PER_REG;
189 *bit *= RK3528_SMT_BITS_PER_PIN;
190
191 return 0;
192}
193
194static int rk3528_set_schmitt(struct rockchip_pin_bank *bank,
195 int pin_num, int enable)
196{
197 struct regmap *regmap;
198 int reg;
199 u32 data, rmask;
200 u8 bit;
201
202 rk3528_calc_schmitt_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
203
204 /* enable the write to the equivalent lower bits */
205 data = ((1 << RK3528_SMT_BITS_PER_PIN) - 1) << (bit + 16);
206 rmask = data | (data >> 16);
207 data |= (enable << bit);
208
209 return regmap_update_bits(regmap, reg, rmask, data);
210}
211
212static struct rockchip_pin_bank rk3528_pin_banks[] = {
213 PIN_BANK_IOMUX_FLAGS_OFFSET(0, 32, "gpio0",
214 IOMUX_WIDTH_4BIT,
215 IOMUX_WIDTH_4BIT,
216 IOMUX_WIDTH_4BIT,
217 IOMUX_WIDTH_4BIT,
218 0, 0, 0, 0),
219 PIN_BANK_IOMUX_FLAGS_OFFSET(1, 32, "gpio1",
220 IOMUX_WIDTH_4BIT,
221 IOMUX_WIDTH_4BIT,
222 IOMUX_WIDTH_4BIT,
223 IOMUX_WIDTH_4BIT,
224 0x20020, 0x20028, 0x20030, 0x20038),
225 PIN_BANK_IOMUX_FLAGS_OFFSET(2, 32, "gpio2",
226 IOMUX_WIDTH_4BIT,
227 IOMUX_WIDTH_4BIT,
228 IOMUX_WIDTH_4BIT,
229 IOMUX_WIDTH_4BIT,
230 0x30040, 0, 0, 0),
231 PIN_BANK_IOMUX_FLAGS_OFFSET(3, 32, "gpio3",
232 IOMUX_WIDTH_4BIT,
233 IOMUX_WIDTH_4BIT,
234 IOMUX_WIDTH_4BIT,
235 IOMUX_WIDTH_4BIT,
236 0x20060, 0x20068, 0x20070, 0),
237 PIN_BANK_IOMUX_FLAGS_OFFSET(4, 32, "gpio4",
238 IOMUX_WIDTH_4BIT,
239 IOMUX_WIDTH_4BIT,
240 IOMUX_WIDTH_4BIT,
241 IOMUX_WIDTH_4BIT,
242 0x10080, 0x10088, 0x10090, 0x10098),
243};
244
245static const struct rockchip_pin_ctrl rk3528_pin_ctrl = {
246 .pin_banks = rk3528_pin_banks,
247 .nr_banks = ARRAY_SIZE(rk3528_pin_banks),
248 .grf_mux_offset = 0x0,
249 .set_mux = rk3528_set_mux,
250 .set_pull = rk3528_set_pull,
251 .set_drive = rk3528_set_drive,
252 .set_schmitt = rk3528_set_schmitt,
253};
254
255static const struct udevice_id rk3528_pinctrl_ids[] = {
256 {
257 .compatible = "rockchip,rk3528-pinctrl",
258 .data = (ulong)&rk3528_pin_ctrl
259 },
260 { }
261};
262
263U_BOOT_DRIVER(rockchip_rk3528_pinctrl) = {
264 .name = "rockchip_rk3528_pinctrl",
265 .id = UCLASS_PINCTRL,
266 .of_match = rk3528_pinctrl_ids,
267 .priv_auto = sizeof(struct rockchip_pinctrl_priv),
268 .ops = &rockchip_pinctrl_ops,
269#if CONFIG_IS_ENABLED(OF_REAL)
270 .bind = dm_scan_fdt_dev,
271#endif
272 .probe = rockchip_pinctrl_probe,
273};