xref: /rk3399_rockchip-uboot/drivers/pinctrl/rockchip/pinctrl-rk1808.c (revision e20d80255b781bd7c9ec7bbdaa007391e6de2e99)
1*e20d8025SJianqun Xu // SPDX-License-Identifier: GPL-2.0+
2*e20d8025SJianqun Xu /*
3*e20d8025SJianqun Xu  * (C) Copyright 2020 Rockchip Electronics Co., Ltd
4*e20d8025SJianqun Xu  */
5*e20d8025SJianqun Xu 
6*e20d8025SJianqun Xu #include <common.h>
7*e20d8025SJianqun Xu #include <dm.h>
8*e20d8025SJianqun Xu #include <dm/pinctrl.h>
9*e20d8025SJianqun Xu #include <regmap.h>
10*e20d8025SJianqun Xu #include <syscon.h>
11*e20d8025SJianqun Xu 
12*e20d8025SJianqun Xu #include "pinctrl-rockchip.h"
13*e20d8025SJianqun Xu 
14*e20d8025SJianqun Xu static struct rockchip_mux_route_data rk1808_mux_route_data[] = {
15*e20d8025SJianqun Xu 	{
16*e20d8025SJianqun Xu 		/* i2c2m0_sda */
17*e20d8025SJianqun Xu 		.bank_num = 3,
18*e20d8025SJianqun Xu 		.pin = 12,
19*e20d8025SJianqun Xu 		.func = 2,
20*e20d8025SJianqun Xu 		.route_offset = 0x190,
21*e20d8025SJianqun Xu 		.route_val = BIT(16 + 3),
22*e20d8025SJianqun Xu 	}, {
23*e20d8025SJianqun Xu 		/* i2c2m1_sda */
24*e20d8025SJianqun Xu 		.bank_num = 1,
25*e20d8025SJianqun Xu 		.pin = 13,
26*e20d8025SJianqun Xu 		.func = 2,
27*e20d8025SJianqun Xu 		.route_offset = 0x190,
28*e20d8025SJianqun Xu 		.route_val = BIT(16 + 3) | BIT(3),
29*e20d8025SJianqun Xu 	}, {
30*e20d8025SJianqun Xu 		/* uart2_rxm0 */
31*e20d8025SJianqun Xu 		.bank_num = 4,
32*e20d8025SJianqun Xu 		.pin = 3,
33*e20d8025SJianqun Xu 		.func = 2,
34*e20d8025SJianqun Xu 		.route_offset = 0x190,
35*e20d8025SJianqun Xu 		.route_val = BIT(16 + 14) | BIT(16 + 15),
36*e20d8025SJianqun Xu 	}, {
37*e20d8025SJianqun Xu 		/* uart2_rxm1 */
38*e20d8025SJianqun Xu 		.bank_num = 2,
39*e20d8025SJianqun Xu 		.pin = 25,
40*e20d8025SJianqun Xu 		.func = 2,
41*e20d8025SJianqun Xu 		.route_offset = 0x190,
42*e20d8025SJianqun Xu 		.route_val = BIT(16 + 14) | BIT(14) | BIT(16 + 15),
43*e20d8025SJianqun Xu 	}, {
44*e20d8025SJianqun Xu 		/* uart2_rxm2 */
45*e20d8025SJianqun Xu 		.bank_num = 3,
46*e20d8025SJianqun Xu 		.pin = 4,
47*e20d8025SJianqun Xu 		.func = 2,
48*e20d8025SJianqun Xu 		.route_offset = 0x190,
49*e20d8025SJianqun Xu 		.route_val = BIT(16 + 14) | BIT(16 + 15) | BIT(15),
50*e20d8025SJianqun Xu 	},
51*e20d8025SJianqun Xu };
52*e20d8025SJianqun Xu 
rk1808_set_mux(struct rockchip_pin_bank * bank,int pin,int mux)53*e20d8025SJianqun Xu static int rk1808_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
54*e20d8025SJianqun Xu {
55*e20d8025SJianqun Xu 	struct rockchip_pinctrl_priv *priv = bank->priv;
56*e20d8025SJianqun Xu 	int iomux_num = (pin / 8);
57*e20d8025SJianqun Xu 	struct regmap *regmap;
58*e20d8025SJianqun Xu 	int reg, ret, mask, mux_type;
59*e20d8025SJianqun Xu 	u8 bit;
60*e20d8025SJianqun Xu 	u32 data;
61*e20d8025SJianqun Xu 
62*e20d8025SJianqun Xu 	debug("setting mux of GPIO%d-%d to %d\n", bank->bank_num, pin, mux);
63*e20d8025SJianqun Xu 
64*e20d8025SJianqun Xu 	if (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU)
65*e20d8025SJianqun Xu 		regmap = priv->regmap_pmu;
66*e20d8025SJianqun Xu 	else if (bank->iomux[iomux_num].type & IOMUX_L_SOURCE_PMU)
67*e20d8025SJianqun Xu 		regmap = (pin % 8 < 4) ? priv->regmap_pmu : priv->regmap_base;
68*e20d8025SJianqun Xu 	else
69*e20d8025SJianqun Xu 		regmap = priv->regmap_base;
70*e20d8025SJianqun Xu 
71*e20d8025SJianqun Xu 	/* get basic quadrupel of mux registers and the correct reg inside */
72*e20d8025SJianqun Xu 	mux_type = bank->iomux[iomux_num].type;
73*e20d8025SJianqun Xu 	reg = bank->iomux[iomux_num].offset;
74*e20d8025SJianqun Xu 	if (mux_type & IOMUX_WIDTH_4BIT) {
75*e20d8025SJianqun Xu 		if ((pin % 8) >= 4)
76*e20d8025SJianqun Xu 			reg += 0x4;
77*e20d8025SJianqun Xu 		bit = (pin % 4) * 4;
78*e20d8025SJianqun Xu 		mask = 0xf;
79*e20d8025SJianqun Xu 	} else {
80*e20d8025SJianqun Xu 		bit = (pin % 8) * 2;
81*e20d8025SJianqun Xu 		mask = 0x3;
82*e20d8025SJianqun Xu 	}
83*e20d8025SJianqun Xu 
84*e20d8025SJianqun Xu 	if (bank->recalced_mask & BIT(pin))
85*e20d8025SJianqun Xu 		rockchip_get_recalced_mux(bank, pin, &reg, &bit, &mask);
86*e20d8025SJianqun Xu 
87*e20d8025SJianqun Xu 	data = (mask << (bit + 16));
88*e20d8025SJianqun Xu 	data |= (mux & mask) << bit;
89*e20d8025SJianqun Xu 	ret = regmap_write(regmap, reg, data);
90*e20d8025SJianqun Xu 
91*e20d8025SJianqun Xu 	return ret;
92*e20d8025SJianqun Xu }
93*e20d8025SJianqun Xu 
94*e20d8025SJianqun Xu #define RK1808_PULL_PMU_OFFSET		0x10
95*e20d8025SJianqun Xu #define RK1808_PULL_GRF_OFFSET		0x80
96*e20d8025SJianqun Xu #define RK1808_PULL_PINS_PER_REG	8
97*e20d8025SJianqun Xu #define RK1808_PULL_BITS_PER_PIN	2
98*e20d8025SJianqun Xu #define RK1808_PULL_BANK_STRIDE		16
99*e20d8025SJianqun Xu 
rk1808_calc_pull_reg_and_bit(struct rockchip_pin_bank * bank,int pin_num,struct regmap ** regmap,int * reg,u8 * bit)100*e20d8025SJianqun Xu static void rk1808_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
101*e20d8025SJianqun Xu 					 int pin_num,
102*e20d8025SJianqun Xu 					 struct regmap **regmap,
103*e20d8025SJianqun Xu 					 int *reg, u8 *bit)
104*e20d8025SJianqun Xu {
105*e20d8025SJianqun Xu 	struct rockchip_pinctrl_priv *priv = bank->priv;
106*e20d8025SJianqun Xu 
107*e20d8025SJianqun Xu 	if (bank->bank_num == 0) {
108*e20d8025SJianqun Xu 		*regmap = priv->regmap_pmu;
109*e20d8025SJianqun Xu 		*reg = RK1808_PULL_PMU_OFFSET;
110*e20d8025SJianqun Xu 	} else {
111*e20d8025SJianqun Xu 		*reg = RK1808_PULL_GRF_OFFSET;
112*e20d8025SJianqun Xu 		*regmap = priv->regmap_base;
113*e20d8025SJianqun Xu 	}
114*e20d8025SJianqun Xu 
115*e20d8025SJianqun Xu 	*reg += ((pin_num / RK1808_PULL_PINS_PER_REG) * 4);
116*e20d8025SJianqun Xu 	*bit = (pin_num % RK1808_PULL_PINS_PER_REG);
117*e20d8025SJianqun Xu 	*bit *= RK1808_PULL_BITS_PER_PIN;
118*e20d8025SJianqun Xu }
119*e20d8025SJianqun Xu 
120*e20d8025SJianqun Xu #define RK1808_DRV_PMU_OFFSET		0x20
121*e20d8025SJianqun Xu #define RK1808_DRV_GRF_OFFSET		0x140
122*e20d8025SJianqun Xu #define RK1808_DRV_BITS_PER_PIN		2
123*e20d8025SJianqun Xu #define RK1808_DRV_PINS_PER_REG		8
124*e20d8025SJianqun Xu #define RK1808_DRV_BANK_STRIDE		16
125*e20d8025SJianqun Xu 
rk1808_calc_drv_reg_and_bit(struct rockchip_pin_bank * bank,int pin_num,struct regmap ** regmap,int * reg,u8 * bit)126*e20d8025SJianqun Xu static void rk1808_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
127*e20d8025SJianqun Xu 					int pin_num,
128*e20d8025SJianqun Xu 					struct regmap **regmap,
129*e20d8025SJianqun Xu 					int *reg, u8 *bit)
130*e20d8025SJianqun Xu {
131*e20d8025SJianqun Xu 	struct rockchip_pinctrl_priv *priv = bank->priv;
132*e20d8025SJianqun Xu 
133*e20d8025SJianqun Xu 	if (bank->bank_num == 0) {
134*e20d8025SJianqun Xu 		*regmap = priv->regmap_pmu;
135*e20d8025SJianqun Xu 		*reg = RK1808_DRV_PMU_OFFSET;
136*e20d8025SJianqun Xu 	} else {
137*e20d8025SJianqun Xu 		*regmap = priv->regmap_base;
138*e20d8025SJianqun Xu 		*reg = RK1808_DRV_GRF_OFFSET;
139*e20d8025SJianqun Xu 	}
140*e20d8025SJianqun Xu 
141*e20d8025SJianqun Xu 	*reg += ((pin_num / RK1808_DRV_PINS_PER_REG) * 4);
142*e20d8025SJianqun Xu 	*bit = pin_num % RK1808_DRV_PINS_PER_REG;
143*e20d8025SJianqun Xu 	*bit *= RK1808_DRV_BITS_PER_PIN;
144*e20d8025SJianqun Xu }
145*e20d8025SJianqun Xu 
146*e20d8025SJianqun Xu #define RK1808_SCHMITT_PMU_OFFSET		0x0040
147*e20d8025SJianqun Xu #define RK1808_SCHMITT_GRF_OFFSET		0x0100
148*e20d8025SJianqun Xu #define RK1808_SCHMITT_BANK_STRIDE		16
149*e20d8025SJianqun Xu #define RK1808_SCHMITT_PINS_PER_REG		8
150*e20d8025SJianqun Xu 
rk1808_calc_schmitt_reg_and_bit(struct rockchip_pin_bank * bank,int pin_num,struct regmap ** regmap,int * reg,u8 * bit)151*e20d8025SJianqun Xu static int rk1808_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank,
152*e20d8025SJianqun Xu 					   int pin_num,
153*e20d8025SJianqun Xu 					   struct regmap **regmap,
154*e20d8025SJianqun Xu 					   int *reg, u8 *bit)
155*e20d8025SJianqun Xu {
156*e20d8025SJianqun Xu 	struct rockchip_pinctrl_priv *priv = bank->priv;
157*e20d8025SJianqun Xu 
158*e20d8025SJianqun Xu 	if (bank->bank_num == 0) {
159*e20d8025SJianqun Xu 		*regmap = priv->regmap_pmu;
160*e20d8025SJianqun Xu 		*reg = RK1808_SCHMITT_PMU_OFFSET;
161*e20d8025SJianqun Xu 	} else {
162*e20d8025SJianqun Xu 		*regmap = priv->regmap_base;
163*e20d8025SJianqun Xu 		*reg = RK1808_SCHMITT_GRF_OFFSET;
164*e20d8025SJianqun Xu 		*reg += (bank->bank_num  - 1) * RK1808_SCHMITT_BANK_STRIDE;
165*e20d8025SJianqun Xu 	}
166*e20d8025SJianqun Xu 	*reg += ((pin_num / RK1808_SCHMITT_PINS_PER_REG) * 4);
167*e20d8025SJianqun Xu 	*bit = pin_num % RK1808_SCHMITT_PINS_PER_REG;
168*e20d8025SJianqun Xu 
169*e20d8025SJianqun Xu 	return 0;
170*e20d8025SJianqun Xu }
171*e20d8025SJianqun Xu 
rk1808_set_pull(struct rockchip_pin_bank * bank,int pin_num,int pull)172*e20d8025SJianqun Xu static int rk1808_set_pull(struct rockchip_pin_bank *bank,
173*e20d8025SJianqun Xu 			   int pin_num, int pull)
174*e20d8025SJianqun Xu {
175*e20d8025SJianqun Xu 	struct regmap *regmap;
176*e20d8025SJianqun Xu 	int reg, ret;
177*e20d8025SJianqun Xu 	u8 bit, type;
178*e20d8025SJianqun Xu 	u32 data;
179*e20d8025SJianqun Xu 
180*e20d8025SJianqun Xu 	if (pull == PIN_CONFIG_BIAS_PULL_PIN_DEFAULT)
181*e20d8025SJianqun Xu 		return -ENOTSUPP;
182*e20d8025SJianqun Xu 
183*e20d8025SJianqun Xu 	rk1808_calc_pull_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
184*e20d8025SJianqun Xu 	type = bank->pull_type[pin_num / 8];
185*e20d8025SJianqun Xu 	ret = rockchip_translate_pull_value(type, pull);
186*e20d8025SJianqun Xu 	if (ret < 0) {
187*e20d8025SJianqun Xu 		debug("unsupported pull setting %d\n", pull);
188*e20d8025SJianqun Xu 		return ret;
189*e20d8025SJianqun Xu 	}
190*e20d8025SJianqun Xu 
191*e20d8025SJianqun Xu 	/* enable the write to the equivalent lower bits */
192*e20d8025SJianqun Xu 	data = ((1 << ROCKCHIP_PULL_BITS_PER_PIN) - 1) << (bit + 16);
193*e20d8025SJianqun Xu 
194*e20d8025SJianqun Xu 	data |= (ret << bit);
195*e20d8025SJianqun Xu 	ret = regmap_write(regmap, reg, data);
196*e20d8025SJianqun Xu 
197*e20d8025SJianqun Xu 	return ret;
198*e20d8025SJianqun Xu }
199*e20d8025SJianqun Xu 
rk1808_set_drive(struct rockchip_pin_bank * bank,int pin_num,int strength)200*e20d8025SJianqun Xu static int rk1808_set_drive(struct rockchip_pin_bank *bank,
201*e20d8025SJianqun Xu 			    int pin_num, int strength)
202*e20d8025SJianqun Xu {
203*e20d8025SJianqun Xu 	struct regmap *regmap;
204*e20d8025SJianqun Xu 	int reg;
205*e20d8025SJianqun Xu 	u32 data;
206*e20d8025SJianqun Xu 	u8 bit;
207*e20d8025SJianqun Xu 
208*e20d8025SJianqun Xu 	rk1808_calc_drv_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
209*e20d8025SJianqun Xu 
210*e20d8025SJianqun Xu 	/* enable the write to the equivalent lower bits */
211*e20d8025SJianqun Xu 	data = ((1 << ROCKCHIP_DRV_BITS_PER_PIN) - 1) << (bit + 16);
212*e20d8025SJianqun Xu 	data |= (strength << bit);
213*e20d8025SJianqun Xu 
214*e20d8025SJianqun Xu 	return regmap_write(regmap, reg, data);
215*e20d8025SJianqun Xu }
216*e20d8025SJianqun Xu 
rk1808_set_schmitt(struct rockchip_pin_bank * bank,int pin_num,int enable)217*e20d8025SJianqun Xu static int rk1808_set_schmitt(struct rockchip_pin_bank *bank,
218*e20d8025SJianqun Xu 			      int pin_num, int enable)
219*e20d8025SJianqun Xu {
220*e20d8025SJianqun Xu 	struct regmap *regmap;
221*e20d8025SJianqun Xu 	int reg;
222*e20d8025SJianqun Xu 	u8 bit;
223*e20d8025SJianqun Xu 	u32 data;
224*e20d8025SJianqun Xu 
225*e20d8025SJianqun Xu 	rk1808_calc_schmitt_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
226*e20d8025SJianqun Xu 	/* enable the write to the equivalent lower bits */
227*e20d8025SJianqun Xu 	data = BIT(bit + 16) | (enable << bit);
228*e20d8025SJianqun Xu 
229*e20d8025SJianqun Xu 	return regmap_write(regmap, reg, data);
230*e20d8025SJianqun Xu }
231*e20d8025SJianqun Xu 
232*e20d8025SJianqun Xu static struct rockchip_pin_bank rk1808_pin_banks[] = {
233*e20d8025SJianqun Xu 	PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0",
234*e20d8025SJianqun Xu 			     IOMUX_SOURCE_PMU,
235*e20d8025SJianqun Xu 			     IOMUX_SOURCE_PMU,
236*e20d8025SJianqun Xu 			     IOMUX_SOURCE_PMU,
237*e20d8025SJianqun Xu 			     IOMUX_SOURCE_PMU),
238*e20d8025SJianqun Xu 	PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1",
239*e20d8025SJianqun Xu 			     IOMUX_WIDTH_4BIT,
240*e20d8025SJianqun Xu 			     IOMUX_WIDTH_4BIT,
241*e20d8025SJianqun Xu 			     IOMUX_WIDTH_4BIT,
242*e20d8025SJianqun Xu 			     IOMUX_WIDTH_4BIT),
243*e20d8025SJianqun Xu 	PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2",
244*e20d8025SJianqun Xu 			     IOMUX_WIDTH_4BIT,
245*e20d8025SJianqun Xu 			     IOMUX_WIDTH_4BIT,
246*e20d8025SJianqun Xu 			     IOMUX_WIDTH_4BIT,
247*e20d8025SJianqun Xu 			     IOMUX_WIDTH_4BIT),
248*e20d8025SJianqun Xu 	PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3",
249*e20d8025SJianqun Xu 			     IOMUX_WIDTH_4BIT,
250*e20d8025SJianqun Xu 			     IOMUX_WIDTH_4BIT,
251*e20d8025SJianqun Xu 			     IOMUX_WIDTH_4BIT,
252*e20d8025SJianqun Xu 			     IOMUX_WIDTH_4BIT),
253*e20d8025SJianqun Xu 	PIN_BANK_IOMUX_FLAGS(4, 32, "gpio4",
254*e20d8025SJianqun Xu 			     IOMUX_WIDTH_4BIT,
255*e20d8025SJianqun Xu 			     IOMUX_WIDTH_4BIT,
256*e20d8025SJianqun Xu 			     IOMUX_WIDTH_4BIT,
257*e20d8025SJianqun Xu 			     IOMUX_WIDTH_4BIT),
258*e20d8025SJianqun Xu };
259*e20d8025SJianqun Xu 
260*e20d8025SJianqun Xu static const struct rockchip_pin_ctrl rk1808_pin_ctrl = {
261*e20d8025SJianqun Xu 	.pin_banks		= rk1808_pin_banks,
262*e20d8025SJianqun Xu 	.nr_banks		= ARRAY_SIZE(rk1808_pin_banks),
263*e20d8025SJianqun Xu 	.nr_pins		= 160,
264*e20d8025SJianqun Xu 	.iomux_routes		= rk1808_mux_route_data,
265*e20d8025SJianqun Xu 	.niomux_routes		= ARRAY_SIZE(rk1808_mux_route_data),
266*e20d8025SJianqun Xu 	.grf_mux_offset		= 0x0,
267*e20d8025SJianqun Xu 	.pmu_mux_offset		= 0x0,
268*e20d8025SJianqun Xu 	.set_mux		= rk1808_set_mux,
269*e20d8025SJianqun Xu 	.set_pull		= rk1808_set_pull,
270*e20d8025SJianqun Xu 	.set_drive		= rk1808_set_drive,
271*e20d8025SJianqun Xu 	.set_schmitt		= rk1808_set_schmitt,
272*e20d8025SJianqun Xu };
273*e20d8025SJianqun Xu 
274*e20d8025SJianqun Xu static const struct udevice_id rk1808_pinctrl_ids[] = {
275*e20d8025SJianqun Xu 	{
276*e20d8025SJianqun Xu 		.compatible = "rockchip,rk1808-pinctrl",
277*e20d8025SJianqun Xu 		.data = (ulong)&rk1808_pin_ctrl
278*e20d8025SJianqun Xu 	},
279*e20d8025SJianqun Xu 	{ }
280*e20d8025SJianqun Xu };
281*e20d8025SJianqun Xu 
282*e20d8025SJianqun Xu U_BOOT_DRIVER(pinctrl_rk1808) = {
283*e20d8025SJianqun Xu 	.name		= "rockchip_rk1808_pinctrl",
284*e20d8025SJianqun Xu 	.id		= UCLASS_PINCTRL,
285*e20d8025SJianqun Xu 	.of_match	= rk1808_pinctrl_ids,
286*e20d8025SJianqun Xu 	.priv_auto_alloc_size = sizeof(struct rockchip_pinctrl_priv),
287*e20d8025SJianqun Xu 	.ops		= &rockchip_pinctrl_ops,
288*e20d8025SJianqun Xu #if !CONFIG_IS_ENABLED(OF_PLATDATA)
289*e20d8025SJianqun Xu 	.bind		= dm_scan_fdt_dev,
290*e20d8025SJianqun Xu #endif
291*e20d8025SJianqun Xu 	.probe		= rockchip_pinctrl_probe,
292*e20d8025SJianqun Xu };
293