1*e7ae4cf2SDavid Wu // SPDX-License-Identifier: GPL-2.0+
2*e7ae4cf2SDavid Wu /*
3*e7ae4cf2SDavid Wu  * (C) Copyright 2019 Rockchip Electronics Co., Ltd
4*e7ae4cf2SDavid Wu  */
5*e7ae4cf2SDavid Wu 
6*e7ae4cf2SDavid Wu #include <common.h>
7*e7ae4cf2SDavid Wu #include <dm.h>
8*e7ae4cf2SDavid Wu #include <dm/pinctrl.h>
9*e7ae4cf2SDavid Wu #include <regmap.h>
10*e7ae4cf2SDavid Wu #include <syscon.h>
11*e7ae4cf2SDavid Wu 
12*e7ae4cf2SDavid Wu #include "pinctrl-rockchip.h"
13*e7ae4cf2SDavid Wu 
14*e7ae4cf2SDavid Wu static struct rockchip_mux_route_data rk3228_mux_route_data[] = {
15*e7ae4cf2SDavid Wu 	{
16*e7ae4cf2SDavid Wu 		/* pwm0-0 */
17*e7ae4cf2SDavid Wu 		.bank_num = 0,
18*e7ae4cf2SDavid Wu 		.pin = 26,
19*e7ae4cf2SDavid Wu 		.func = 1,
20*e7ae4cf2SDavid Wu 		.route_offset = 0x50,
21*e7ae4cf2SDavid Wu 		.route_val = BIT(16),
22*e7ae4cf2SDavid Wu 	}, {
23*e7ae4cf2SDavid Wu 		/* pwm0-1 */
24*e7ae4cf2SDavid Wu 		.bank_num = 3,
25*e7ae4cf2SDavid Wu 		.pin = 21,
26*e7ae4cf2SDavid Wu 		.func = 1,
27*e7ae4cf2SDavid Wu 		.route_offset = 0x50,
28*e7ae4cf2SDavid Wu 		.route_val = BIT(16) | BIT(0),
29*e7ae4cf2SDavid Wu 	}, {
30*e7ae4cf2SDavid Wu 		/* pwm1-0 */
31*e7ae4cf2SDavid Wu 		.bank_num = 0,
32*e7ae4cf2SDavid Wu 		.pin = 27,
33*e7ae4cf2SDavid Wu 		.func = 1,
34*e7ae4cf2SDavid Wu 		.route_offset = 0x50,
35*e7ae4cf2SDavid Wu 		.route_val = BIT(16 + 1),
36*e7ae4cf2SDavid Wu 	}, {
37*e7ae4cf2SDavid Wu 		/* pwm1-1 */
38*e7ae4cf2SDavid Wu 		.bank_num = 0,
39*e7ae4cf2SDavid Wu 		.pin = 30,
40*e7ae4cf2SDavid Wu 		.func = 2,
41*e7ae4cf2SDavid Wu 		.route_offset = 0x50,
42*e7ae4cf2SDavid Wu 		.route_val = BIT(16 + 1) | BIT(1),
43*e7ae4cf2SDavid Wu 	}, {
44*e7ae4cf2SDavid Wu 		/* pwm2-0 */
45*e7ae4cf2SDavid Wu 		.bank_num = 0,
46*e7ae4cf2SDavid Wu 		.pin = 28,
47*e7ae4cf2SDavid Wu 		.func = 1,
48*e7ae4cf2SDavid Wu 		.route_offset = 0x50,
49*e7ae4cf2SDavid Wu 		.route_val = BIT(16 + 2),
50*e7ae4cf2SDavid Wu 	}, {
51*e7ae4cf2SDavid Wu 		/* pwm2-1 */
52*e7ae4cf2SDavid Wu 		.bank_num = 1,
53*e7ae4cf2SDavid Wu 		.pin = 12,
54*e7ae4cf2SDavid Wu 		.func = 2,
55*e7ae4cf2SDavid Wu 		.route_offset = 0x50,
56*e7ae4cf2SDavid Wu 		.route_val = BIT(16 + 2) | BIT(2),
57*e7ae4cf2SDavid Wu 	}, {
58*e7ae4cf2SDavid Wu 		/* pwm3-0 */
59*e7ae4cf2SDavid Wu 		.bank_num = 3,
60*e7ae4cf2SDavid Wu 		.pin = 26,
61*e7ae4cf2SDavid Wu 		.func = 1,
62*e7ae4cf2SDavid Wu 		.route_offset = 0x50,
63*e7ae4cf2SDavid Wu 		.route_val = BIT(16 + 3),
64*e7ae4cf2SDavid Wu 	}, {
65*e7ae4cf2SDavid Wu 		/* pwm3-1 */
66*e7ae4cf2SDavid Wu 		.bank_num = 1,
67*e7ae4cf2SDavid Wu 		.pin = 11,
68*e7ae4cf2SDavid Wu 		.func = 2,
69*e7ae4cf2SDavid Wu 		.route_offset = 0x50,
70*e7ae4cf2SDavid Wu 		.route_val = BIT(16 + 3) | BIT(3),
71*e7ae4cf2SDavid Wu 	}, {
72*e7ae4cf2SDavid Wu 		/* sdio-0_d0 */
73*e7ae4cf2SDavid Wu 		.bank_num = 1,
74*e7ae4cf2SDavid Wu 		.pin = 1,
75*e7ae4cf2SDavid Wu 		.func = 1,
76*e7ae4cf2SDavid Wu 		.route_offset = 0x50,
77*e7ae4cf2SDavid Wu 		.route_val = BIT(16 + 4),
78*e7ae4cf2SDavid Wu 	}, {
79*e7ae4cf2SDavid Wu 		/* sdio-1_d0 */
80*e7ae4cf2SDavid Wu 		.bank_num = 3,
81*e7ae4cf2SDavid Wu 		.pin = 2,
82*e7ae4cf2SDavid Wu 		.func = 1,
83*e7ae4cf2SDavid Wu 		.route_offset = 0x50,
84*e7ae4cf2SDavid Wu 		.route_val = BIT(16 + 4) | BIT(4),
85*e7ae4cf2SDavid Wu 	}, {
86*e7ae4cf2SDavid Wu 		/* spi-0_rx */
87*e7ae4cf2SDavid Wu 		.bank_num = 0,
88*e7ae4cf2SDavid Wu 		.pin = 13,
89*e7ae4cf2SDavid Wu 		.func = 2,
90*e7ae4cf2SDavid Wu 		.route_offset = 0x50,
91*e7ae4cf2SDavid Wu 		.route_val = BIT(16 + 5),
92*e7ae4cf2SDavid Wu 	}, {
93*e7ae4cf2SDavid Wu 		/* spi-1_rx */
94*e7ae4cf2SDavid Wu 		.bank_num = 2,
95*e7ae4cf2SDavid Wu 		.pin = 0,
96*e7ae4cf2SDavid Wu 		.func = 2,
97*e7ae4cf2SDavid Wu 		.route_offset = 0x50,
98*e7ae4cf2SDavid Wu 		.route_val = BIT(16 + 5) | BIT(5),
99*e7ae4cf2SDavid Wu 	}, {
100*e7ae4cf2SDavid Wu 		/* emmc-0_cmd */
101*e7ae4cf2SDavid Wu 		.bank_num = 1,
102*e7ae4cf2SDavid Wu 		.pin = 22,
103*e7ae4cf2SDavid Wu 		.func = 2,
104*e7ae4cf2SDavid Wu 		.route_offset = 0x50,
105*e7ae4cf2SDavid Wu 		.route_val = BIT(16 + 7),
106*e7ae4cf2SDavid Wu 	}, {
107*e7ae4cf2SDavid Wu 		/* emmc-1_cmd */
108*e7ae4cf2SDavid Wu 		.bank_num = 2,
109*e7ae4cf2SDavid Wu 		.pin = 4,
110*e7ae4cf2SDavid Wu 		.func = 2,
111*e7ae4cf2SDavid Wu 		.route_offset = 0x50,
112*e7ae4cf2SDavid Wu 		.route_val = BIT(16 + 7) | BIT(7),
113*e7ae4cf2SDavid Wu 	}, {
114*e7ae4cf2SDavid Wu 		/* uart2-0_rx */
115*e7ae4cf2SDavid Wu 		.bank_num = 1,
116*e7ae4cf2SDavid Wu 		.pin = 19,
117*e7ae4cf2SDavid Wu 		.func = 2,
118*e7ae4cf2SDavid Wu 		.route_offset = 0x50,
119*e7ae4cf2SDavid Wu 		.route_val = BIT(16 + 8),
120*e7ae4cf2SDavid Wu 	}, {
121*e7ae4cf2SDavid Wu 		/* uart2-1_rx */
122*e7ae4cf2SDavid Wu 		.bank_num = 1,
123*e7ae4cf2SDavid Wu 		.pin = 10,
124*e7ae4cf2SDavid Wu 		.func = 2,
125*e7ae4cf2SDavid Wu 		.route_offset = 0x50,
126*e7ae4cf2SDavid Wu 		.route_val = BIT(16 + 8) | BIT(8),
127*e7ae4cf2SDavid Wu 	}, {
128*e7ae4cf2SDavid Wu 		/* uart1-0_rx */
129*e7ae4cf2SDavid Wu 		.bank_num = 1,
130*e7ae4cf2SDavid Wu 		.pin = 10,
131*e7ae4cf2SDavid Wu 		.func = 1,
132*e7ae4cf2SDavid Wu 		.route_offset = 0x50,
133*e7ae4cf2SDavid Wu 		.route_val = BIT(16 + 11),
134*e7ae4cf2SDavid Wu 	}, {
135*e7ae4cf2SDavid Wu 		/* uart1-1_rx */
136*e7ae4cf2SDavid Wu 		.bank_num = 3,
137*e7ae4cf2SDavid Wu 		.pin = 13,
138*e7ae4cf2SDavid Wu 		.func = 1,
139*e7ae4cf2SDavid Wu 		.route_offset = 0x50,
140*e7ae4cf2SDavid Wu 		.route_val = BIT(16 + 11) | BIT(11),
141*e7ae4cf2SDavid Wu 	},
142*e7ae4cf2SDavid Wu };
143*e7ae4cf2SDavid Wu 
144*e7ae4cf2SDavid Wu #define RK3228_PULL_OFFSET		0x100
145*e7ae4cf2SDavid Wu 
rk3228_calc_pull_reg_and_bit(struct rockchip_pin_bank * bank,int pin_num,struct regmap ** regmap,int * reg,u8 * bit)146*e7ae4cf2SDavid Wu static void rk3228_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
147*e7ae4cf2SDavid Wu 					 int pin_num, struct regmap **regmap,
148*e7ae4cf2SDavid Wu 					 int *reg, u8 *bit)
149*e7ae4cf2SDavid Wu {
150*e7ae4cf2SDavid Wu 	struct rockchip_pinctrl_priv *priv = bank->priv;
151*e7ae4cf2SDavid Wu 
152*e7ae4cf2SDavid Wu 	*regmap = priv->regmap_base;
153*e7ae4cf2SDavid Wu 	*reg = RK3228_PULL_OFFSET;
154*e7ae4cf2SDavid Wu 	*reg += bank->bank_num * ROCKCHIP_PULL_BANK_STRIDE;
155*e7ae4cf2SDavid Wu 	*reg += ((pin_num / ROCKCHIP_PULL_PINS_PER_REG) * 4);
156*e7ae4cf2SDavid Wu 
157*e7ae4cf2SDavid Wu 	*bit = (pin_num % ROCKCHIP_PULL_PINS_PER_REG);
158*e7ae4cf2SDavid Wu 	*bit *= ROCKCHIP_PULL_BITS_PER_PIN;
159*e7ae4cf2SDavid Wu }
160*e7ae4cf2SDavid Wu 
161*e7ae4cf2SDavid Wu #define RK3228_DRV_GRF_OFFSET		0x200
162*e7ae4cf2SDavid Wu 
rk3228_calc_drv_reg_and_bit(struct rockchip_pin_bank * bank,int pin_num,struct regmap ** regmap,int * reg,u8 * bit)163*e7ae4cf2SDavid Wu static void rk3228_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
164*e7ae4cf2SDavid Wu 					int pin_num, struct regmap **regmap,
165*e7ae4cf2SDavid Wu 					int *reg, u8 *bit)
166*e7ae4cf2SDavid Wu {
167*e7ae4cf2SDavid Wu 	struct rockchip_pinctrl_priv *priv = bank->priv;
168*e7ae4cf2SDavid Wu 
169*e7ae4cf2SDavid Wu 	*regmap = priv->regmap_base;
170*e7ae4cf2SDavid Wu 	*reg = RK3228_DRV_GRF_OFFSET;
171*e7ae4cf2SDavid Wu 	*reg += bank->bank_num * ROCKCHIP_DRV_BANK_STRIDE;
172*e7ae4cf2SDavid Wu 	*reg += ((pin_num / ROCKCHIP_DRV_PINS_PER_REG) * 4);
173*e7ae4cf2SDavid Wu 
174*e7ae4cf2SDavid Wu 	*bit = (pin_num % ROCKCHIP_DRV_PINS_PER_REG);
175*e7ae4cf2SDavid Wu 	*bit *= ROCKCHIP_DRV_BITS_PER_PIN;
176*e7ae4cf2SDavid Wu }
177*e7ae4cf2SDavid Wu 
178*e7ae4cf2SDavid Wu static struct rockchip_pin_bank rk3228_pin_banks[] = {
179*e7ae4cf2SDavid Wu 	PIN_BANK(0, 32, "gpio0"),
180*e7ae4cf2SDavid Wu 	PIN_BANK(1, 32, "gpio1"),
181*e7ae4cf2SDavid Wu 	PIN_BANK(2, 32, "gpio2"),
182*e7ae4cf2SDavid Wu 	PIN_BANK(3, 32, "gpio3"),
183*e7ae4cf2SDavid Wu };
184*e7ae4cf2SDavid Wu 
185*e7ae4cf2SDavid Wu static struct rockchip_pin_ctrl rk3228_pin_ctrl = {
186*e7ae4cf2SDavid Wu 		.pin_banks		= rk3228_pin_banks,
187*e7ae4cf2SDavid Wu 		.nr_banks		= ARRAY_SIZE(rk3228_pin_banks),
188*e7ae4cf2SDavid Wu 		.label			= "RK3228-GPIO",
189*e7ae4cf2SDavid Wu 		.type			= RK3288,
190*e7ae4cf2SDavid Wu 		.grf_mux_offset		= 0x0,
191*e7ae4cf2SDavid Wu 		.iomux_routes		= rk3228_mux_route_data,
192*e7ae4cf2SDavid Wu 		.niomux_routes		= ARRAY_SIZE(rk3228_mux_route_data),
193*e7ae4cf2SDavid Wu 		.pull_calc_reg		= rk3228_calc_pull_reg_and_bit,
194*e7ae4cf2SDavid Wu 		.drv_calc_reg		= rk3228_calc_drv_reg_and_bit,
195*e7ae4cf2SDavid Wu };
196*e7ae4cf2SDavid Wu 
197*e7ae4cf2SDavid Wu static const struct udevice_id rk3228_pinctrl_ids[] = {
198*e7ae4cf2SDavid Wu 	{
199*e7ae4cf2SDavid Wu 		.compatible = "rockchip,rk3228-pinctrl",
200*e7ae4cf2SDavid Wu 		.data = (ulong)&rk3228_pin_ctrl
201*e7ae4cf2SDavid Wu 	},
202*e7ae4cf2SDavid Wu 	{ }
203*e7ae4cf2SDavid Wu };
204*e7ae4cf2SDavid Wu 
205*e7ae4cf2SDavid Wu U_BOOT_DRIVER(pinctrl_rk3228) = {
206*e7ae4cf2SDavid Wu 	.name		= "rockchip_rk3228_pinctrl",
207*e7ae4cf2SDavid Wu 	.id		= UCLASS_PINCTRL,
208*e7ae4cf2SDavid Wu 	.of_match	= rk3228_pinctrl_ids,
209*e7ae4cf2SDavid Wu 	.priv_auto_alloc_size = sizeof(struct rockchip_pinctrl_priv),
210*e7ae4cf2SDavid Wu 	.ops		= &rockchip_pinctrl_ops,
211*e7ae4cf2SDavid Wu #if !CONFIG_IS_ENABLED(OF_PLATDATA)
212*e7ae4cf2SDavid Wu 	.bind		= dm_scan_fdt_dev,
213*e7ae4cf2SDavid Wu #endif
214*e7ae4cf2SDavid Wu 	.probe		= rockchip_pinctrl_probe,
215*e7ae4cf2SDavid Wu };
216