xref: /rk3399_rockchip-uboot/drivers/pinctrl/pinctrl-rockchip.c (revision 55a89bc67a8219df1210e52f877b9fe7bb424b62)
149c55878SDavid Wu /*
249c55878SDavid Wu  * (C) Copyright 2018 Rockchip Electronics Co., Ltd
349c55878SDavid Wu  *
449c55878SDavid Wu  * SPDX-License-Identifier:     GPL-2.0+
549c55878SDavid Wu  */
649c55878SDavid Wu 
749c55878SDavid Wu #include <common.h>
849c55878SDavid Wu #include <dm.h>
949c55878SDavid Wu #include <dm/pinctrl.h>
102208cfa9SKever Yang #include <dm/ofnode.h>
1149c55878SDavid Wu #include <regmap.h>
1249c55878SDavid Wu #include <syscon.h>
1349c55878SDavid Wu 
1449c55878SDavid Wu #define MAX_ROCKCHIP_GPIO_PER_BANK	32
1549c55878SDavid Wu #define RK_FUNC_GPIO			0
1687f0ac57SDavid Wu #define MAX_ROCKCHIP_PINS_ENTRIES	30
1749c55878SDavid Wu 
1849c55878SDavid Wu enum rockchip_pinctrl_type {
1949c55878SDavid Wu 	PX30,
2049c55878SDavid Wu 	RV1108,
2149c55878SDavid Wu 	RK2928,
2249c55878SDavid Wu 	RK3066B,
2349c55878SDavid Wu 	RK3128,
2449c55878SDavid Wu 	RK3188,
2549c55878SDavid Wu 	RK3288,
26b3077611SDavid Wu 	RK3308,
2749c55878SDavid Wu 	RK3368,
2849c55878SDavid Wu 	RK3399,
2949c55878SDavid Wu };
3049c55878SDavid Wu 
3149c55878SDavid Wu /**
3249c55878SDavid Wu  * Encode variants of iomux registers into a type variable
3349c55878SDavid Wu  */
3449c55878SDavid Wu #define IOMUX_GPIO_ONLY		BIT(0)
3549c55878SDavid Wu #define IOMUX_WIDTH_4BIT	BIT(1)
3649c55878SDavid Wu #define IOMUX_SOURCE_PMU	BIT(2)
3749c55878SDavid Wu #define IOMUX_UNROUTED		BIT(3)
3849c55878SDavid Wu #define IOMUX_WIDTH_3BIT	BIT(4)
39b3077611SDavid Wu #define IOMUX_8WIDTH_2BIT	BIT(5)
404bafc2daSDavid Wu #define IOMUX_WRITABLE_32BIT	BIT(6)
4149c55878SDavid Wu 
4249c55878SDavid Wu /**
4349c55878SDavid Wu  * @type: iomux variant using IOMUX_* constants
4449c55878SDavid Wu  * @offset: if initialized to -1 it will be autocalculated, by specifying
4549c55878SDavid Wu  *	    an initial offset value the relevant source offset can be reset
4649c55878SDavid Wu  *	    to a new value for autocalculating the following iomux registers.
4749c55878SDavid Wu  */
4849c55878SDavid Wu struct rockchip_iomux {
4949c55878SDavid Wu 	int				type;
5049c55878SDavid Wu 	int				offset;
5149c55878SDavid Wu };
5249c55878SDavid Wu 
53*55a89bc6SDavid Wu #define DRV_TYPE_IO_MASK		GENMASK(31, 16)
54*55a89bc6SDavid Wu #define DRV_TYPE_WRITABLE_32BIT		BIT(31)
55*55a89bc6SDavid Wu 
5649c55878SDavid Wu /**
5749c55878SDavid Wu  * enum type index corresponding to rockchip_perpin_drv_list arrays index.
5849c55878SDavid Wu  */
5949c55878SDavid Wu enum rockchip_pin_drv_type {
6049c55878SDavid Wu 	DRV_TYPE_IO_DEFAULT = 0,
6149c55878SDavid Wu 	DRV_TYPE_IO_1V8_OR_3V0,
6249c55878SDavid Wu 	DRV_TYPE_IO_1V8_ONLY,
6349c55878SDavid Wu 	DRV_TYPE_IO_1V8_3V0_AUTO,
6449c55878SDavid Wu 	DRV_TYPE_IO_3V3_ONLY,
6549c55878SDavid Wu 	DRV_TYPE_MAX
6649c55878SDavid Wu };
6749c55878SDavid Wu 
68*55a89bc6SDavid Wu #define PULL_TYPE_IO_MASK		GENMASK(31, 16)
69*55a89bc6SDavid Wu #define PULL_TYPE_WRITABLE_32BIT	BIT(31)
70*55a89bc6SDavid Wu 
7149c55878SDavid Wu /**
7249c55878SDavid Wu  * enum type index corresponding to rockchip_pull_list arrays index.
7349c55878SDavid Wu  */
7449c55878SDavid Wu enum rockchip_pin_pull_type {
7549c55878SDavid Wu 	PULL_TYPE_IO_DEFAULT = 0,
7649c55878SDavid Wu 	PULL_TYPE_IO_1V8_ONLY,
7749c55878SDavid Wu 	PULL_TYPE_MAX
7849c55878SDavid Wu };
7949c55878SDavid Wu 
8049c55878SDavid Wu /**
8149c55878SDavid Wu  * @drv_type: drive strength variant using rockchip_perpin_drv_type
8249c55878SDavid Wu  * @offset: if initialized to -1 it will be autocalculated, by specifying
8349c55878SDavid Wu  *	    an initial offset value the relevant source offset can be reset
8449c55878SDavid Wu  *	    to a new value for autocalculating the following drive strength
8549c55878SDavid Wu  *	    registers. if used chips own cal_drv func instead to calculate
8649c55878SDavid Wu  *	    registers offset, the variant could be ignored.
8749c55878SDavid Wu  */
8849c55878SDavid Wu struct rockchip_drv {
8949c55878SDavid Wu 	enum rockchip_pin_drv_type	drv_type;
9049c55878SDavid Wu 	int				offset;
9149c55878SDavid Wu };
9249c55878SDavid Wu 
9349c55878SDavid Wu /**
9449c55878SDavid Wu  * @priv: common pinctrl private basedata
9549c55878SDavid Wu  * @pin_base: first pin number
9649c55878SDavid Wu  * @nr_pins: number of pins in this bank
9749c55878SDavid Wu  * @name: name of the bank
9849c55878SDavid Wu  * @bank_num: number of the bank, to account for holes
9949c55878SDavid Wu  * @iomux: array describing the 4 iomux sources of the bank
10049c55878SDavid Wu  * @drv: array describing the 4 drive strength sources of the bank
10149c55878SDavid Wu  * @pull_type: array describing the 4 pull type sources of the bank
10249c55878SDavid Wu  * @recalced_mask: bits describing the mux recalced pins of per bank
10349c55878SDavid Wu  * @route_mask: bits describing the routing pins of per bank
10449c55878SDavid Wu  */
10549c55878SDavid Wu struct rockchip_pin_bank {
10649c55878SDavid Wu 	struct rockchip_pinctrl_priv	*priv;
10749c55878SDavid Wu 	u32				pin_base;
10849c55878SDavid Wu 	u8				nr_pins;
10949c55878SDavid Wu 	char				*name;
11049c55878SDavid Wu 	u8				bank_num;
11149c55878SDavid Wu 	struct rockchip_iomux		iomux[4];
11249c55878SDavid Wu 	struct rockchip_drv		drv[4];
11349c55878SDavid Wu 	enum rockchip_pin_pull_type	pull_type[4];
11449c55878SDavid Wu 	u32				recalced_mask;
11549c55878SDavid Wu 	u32				route_mask;
11649c55878SDavid Wu };
11749c55878SDavid Wu 
11849c55878SDavid Wu #define PIN_BANK(id, pins, label)			\
11949c55878SDavid Wu 	{						\
12049c55878SDavid Wu 		.bank_num	= id,			\
12149c55878SDavid Wu 		.nr_pins	= pins,			\
12249c55878SDavid Wu 		.name		= label,		\
12349c55878SDavid Wu 		.iomux		= {			\
12449c55878SDavid Wu 			{ .offset = -1 },		\
12549c55878SDavid Wu 			{ .offset = -1 },		\
12649c55878SDavid Wu 			{ .offset = -1 },		\
12749c55878SDavid Wu 			{ .offset = -1 },		\
12849c55878SDavid Wu 		},					\
12949c55878SDavid Wu 	}
13049c55878SDavid Wu 
13149c55878SDavid Wu #define PIN_BANK_IOMUX_FLAGS(id, pins, label, iom0, iom1, iom2, iom3)	\
13249c55878SDavid Wu 	{								\
13349c55878SDavid Wu 		.bank_num	= id,					\
13449c55878SDavid Wu 		.nr_pins	= pins,					\
13549c55878SDavid Wu 		.name		= label,				\
13649c55878SDavid Wu 		.iomux		= {					\
13749c55878SDavid Wu 			{ .type = iom0, .offset = -1 },			\
13849c55878SDavid Wu 			{ .type = iom1, .offset = -1 },			\
13949c55878SDavid Wu 			{ .type = iom2, .offset = -1 },			\
14049c55878SDavid Wu 			{ .type = iom3, .offset = -1 },			\
14149c55878SDavid Wu 		},							\
14249c55878SDavid Wu 	}
14349c55878SDavid Wu 
14449c55878SDavid Wu #define PIN_BANK_DRV_FLAGS(id, pins, label, type0, type1, type2, type3) \
14549c55878SDavid Wu 	{								\
14649c55878SDavid Wu 		.bank_num	= id,					\
14749c55878SDavid Wu 		.nr_pins	= pins,					\
14849c55878SDavid Wu 		.name		= label,				\
14949c55878SDavid Wu 		.iomux		= {					\
15049c55878SDavid Wu 			{ .offset = -1 },				\
15149c55878SDavid Wu 			{ .offset = -1 },				\
15249c55878SDavid Wu 			{ .offset = -1 },				\
15349c55878SDavid Wu 			{ .offset = -1 },				\
15449c55878SDavid Wu 		},							\
15549c55878SDavid Wu 		.drv		= {					\
15649c55878SDavid Wu 			{ .drv_type = type0, .offset = -1 },		\
15749c55878SDavid Wu 			{ .drv_type = type1, .offset = -1 },		\
15849c55878SDavid Wu 			{ .drv_type = type2, .offset = -1 },		\
15949c55878SDavid Wu 			{ .drv_type = type3, .offset = -1 },		\
16049c55878SDavid Wu 		},							\
16149c55878SDavid Wu 	}
16249c55878SDavid Wu 
16349c55878SDavid Wu #define PIN_BANK_DRV_FLAGS_PULL_FLAGS(id, pins, label, drv0, drv1,	\
16449c55878SDavid Wu 				      drv2, drv3, pull0, pull1,		\
16549c55878SDavid Wu 				      pull2, pull3)			\
16649c55878SDavid Wu 	{								\
16749c55878SDavid Wu 		.bank_num	= id,					\
16849c55878SDavid Wu 		.nr_pins	= pins,					\
16949c55878SDavid Wu 		.name		= label,				\
17049c55878SDavid Wu 		.iomux		= {					\
17149c55878SDavid Wu 			{ .offset = -1 },				\
17249c55878SDavid Wu 			{ .offset = -1 },				\
17349c55878SDavid Wu 			{ .offset = -1 },				\
17449c55878SDavid Wu 			{ .offset = -1 },				\
17549c55878SDavid Wu 		},							\
17649c55878SDavid Wu 		.drv		= {					\
17749c55878SDavid Wu 			{ .drv_type = drv0, .offset = -1 },		\
17849c55878SDavid Wu 			{ .drv_type = drv1, .offset = -1 },		\
17949c55878SDavid Wu 			{ .drv_type = drv2, .offset = -1 },		\
18049c55878SDavid Wu 			{ .drv_type = drv3, .offset = -1 },		\
18149c55878SDavid Wu 		},							\
18249c55878SDavid Wu 		.pull_type[0] = pull0,					\
18349c55878SDavid Wu 		.pull_type[1] = pull1,					\
18449c55878SDavid Wu 		.pull_type[2] = pull2,					\
18549c55878SDavid Wu 		.pull_type[3] = pull3,					\
18649c55878SDavid Wu 	}
18749c55878SDavid Wu 
18849c55878SDavid Wu #define PIN_BANK_IOMUX_DRV_FLAGS_OFFSET(id, pins, label, iom0, iom1,	\
18949c55878SDavid Wu 					iom2, iom3, drv0, drv1, drv2,	\
19049c55878SDavid Wu 					drv3, offset0, offset1,		\
19149c55878SDavid Wu 					offset2, offset3)		\
19249c55878SDavid Wu 	{								\
19349c55878SDavid Wu 		.bank_num	= id,					\
19449c55878SDavid Wu 		.nr_pins	= pins,					\
19549c55878SDavid Wu 		.name		= label,				\
19649c55878SDavid Wu 		.iomux		= {					\
19749c55878SDavid Wu 			{ .type = iom0, .offset = -1 },			\
19849c55878SDavid Wu 			{ .type = iom1, .offset = -1 },			\
19949c55878SDavid Wu 			{ .type = iom2, .offset = -1 },			\
20049c55878SDavid Wu 			{ .type = iom3, .offset = -1 },			\
20149c55878SDavid Wu 		},							\
20249c55878SDavid Wu 		.drv		= {					\
20349c55878SDavid Wu 			{ .drv_type = drv0, .offset = offset0 },	\
20449c55878SDavid Wu 			{ .drv_type = drv1, .offset = offset1 },	\
20549c55878SDavid Wu 			{ .drv_type = drv2, .offset = offset2 },	\
20649c55878SDavid Wu 			{ .drv_type = drv3, .offset = offset3 },	\
20749c55878SDavid Wu 		},							\
20849c55878SDavid Wu 	}
20949c55878SDavid Wu 
210*55a89bc6SDavid Wu #define PIN_BANK_IOMUX_DRV_PULL_FLAGS(id, pins, label, iom0, iom1,	\
211*55a89bc6SDavid Wu 				      iom2, iom3, drv0, drv1, drv2,	\
212*55a89bc6SDavid Wu 				      drv3, pull0, pull1, pull2,	\
213*55a89bc6SDavid Wu 				      pull3)				\
214*55a89bc6SDavid Wu 	{								\
215*55a89bc6SDavid Wu 		.bank_num	= id,					\
216*55a89bc6SDavid Wu 		.nr_pins	= pins,					\
217*55a89bc6SDavid Wu 		.name		= label,				\
218*55a89bc6SDavid Wu 		.iomux		= {					\
219*55a89bc6SDavid Wu 			{ .type = iom0, .offset = -1 },			\
220*55a89bc6SDavid Wu 			{ .type = iom1, .offset = -1 },			\
221*55a89bc6SDavid Wu 			{ .type = iom2, .offset = -1 },			\
222*55a89bc6SDavid Wu 			{ .type = iom3, .offset = -1 },			\
223*55a89bc6SDavid Wu 		},							\
224*55a89bc6SDavid Wu 		.drv		= {					\
225*55a89bc6SDavid Wu 			{ .drv_type = drv0, .offset = -1 },		\
226*55a89bc6SDavid Wu 			{ .drv_type = drv1, .offset = -1 },		\
227*55a89bc6SDavid Wu 			{ .drv_type = drv2, .offset = -1 },		\
228*55a89bc6SDavid Wu 			{ .drv_type = drv3, .offset = -1 },		\
229*55a89bc6SDavid Wu 		},							\
230*55a89bc6SDavid Wu 		.pull_type[0] = pull0,					\
231*55a89bc6SDavid Wu 		.pull_type[1] = pull1,					\
232*55a89bc6SDavid Wu 		.pull_type[2] = pull2,					\
233*55a89bc6SDavid Wu 		.pull_type[3] = pull3,					\
234*55a89bc6SDavid Wu 	}
235*55a89bc6SDavid Wu 
23649c55878SDavid Wu #define PIN_BANK_IOMUX_FLAGS_DRV_FLAGS_OFFSET_PULL_FLAGS(id, pins,	\
23749c55878SDavid Wu 					      label, iom0, iom1, iom2,  \
23849c55878SDavid Wu 					      iom3, drv0, drv1, drv2,   \
23949c55878SDavid Wu 					      drv3, offset0, offset1,   \
24049c55878SDavid Wu 					      offset2, offset3, pull0,  \
24149c55878SDavid Wu 					      pull1, pull2, pull3)	\
24249c55878SDavid Wu 	{								\
24349c55878SDavid Wu 		.bank_num	= id,					\
24449c55878SDavid Wu 		.nr_pins	= pins,					\
24549c55878SDavid Wu 		.name		= label,				\
24649c55878SDavid Wu 		.iomux		= {					\
24749c55878SDavid Wu 			{ .type = iom0, .offset = -1 },			\
24849c55878SDavid Wu 			{ .type = iom1, .offset = -1 },			\
24949c55878SDavid Wu 			{ .type = iom2, .offset = -1 },			\
25049c55878SDavid Wu 			{ .type = iom3, .offset = -1 },			\
25149c55878SDavid Wu 		},							\
25249c55878SDavid Wu 		.drv		= {					\
25349c55878SDavid Wu 			{ .drv_type = drv0, .offset = offset0 },	\
25449c55878SDavid Wu 			{ .drv_type = drv1, .offset = offset1 },	\
25549c55878SDavid Wu 			{ .drv_type = drv2, .offset = offset2 },	\
25649c55878SDavid Wu 			{ .drv_type = drv3, .offset = offset3 },	\
25749c55878SDavid Wu 		},							\
25849c55878SDavid Wu 		.pull_type[0] = pull0,					\
25949c55878SDavid Wu 		.pull_type[1] = pull1,					\
26049c55878SDavid Wu 		.pull_type[2] = pull2,					\
26149c55878SDavid Wu 		.pull_type[3] = pull3,					\
26249c55878SDavid Wu 	}
26349c55878SDavid Wu 
26449c55878SDavid Wu /**
26549c55878SDavid Wu  * struct rockchip_mux_recalced_data: represent a pin iomux data.
26649c55878SDavid Wu  * @num: bank number.
26749c55878SDavid Wu  * @pin: pin number.
26849c55878SDavid Wu  * @bit: index at register.
26949c55878SDavid Wu  * @reg: register offset.
27049c55878SDavid Wu  * @mask: mask bit
27149c55878SDavid Wu  */
27249c55878SDavid Wu struct rockchip_mux_recalced_data {
27349c55878SDavid Wu 	u8 num;
27449c55878SDavid Wu 	u8 pin;
27549c55878SDavid Wu 	u32 reg;
27649c55878SDavid Wu 	u8 bit;
27749c55878SDavid Wu 	u8 mask;
27849c55878SDavid Wu };
27949c55878SDavid Wu 
28049c55878SDavid Wu /**
28149c55878SDavid Wu  * struct rockchip_mux_recalced_data: represent a pin iomux data.
28249c55878SDavid Wu  * @bank_num: bank number.
28349c55878SDavid Wu  * @pin: index at register or used to calc index.
28449c55878SDavid Wu  * @func: the min pin.
28549c55878SDavid Wu  * @route_offset: the max pin.
28649c55878SDavid Wu  * @route_val: the register offset.
28749c55878SDavid Wu  */
28849c55878SDavid Wu struct rockchip_mux_route_data {
28949c55878SDavid Wu 	u8 bank_num;
29049c55878SDavid Wu 	u8 pin;
29149c55878SDavid Wu 	u8 func;
29249c55878SDavid Wu 	u32 route_offset;
29349c55878SDavid Wu 	u32 route_val;
29449c55878SDavid Wu };
29549c55878SDavid Wu 
29649c55878SDavid Wu /**
29749c55878SDavid Wu  */
29849c55878SDavid Wu struct rockchip_pin_ctrl {
29949c55878SDavid Wu 	struct rockchip_pin_bank	*pin_banks;
30049c55878SDavid Wu 	u32				nr_banks;
30149c55878SDavid Wu 	u32				nr_pins;
30249c55878SDavid Wu 	char				*label;
30349c55878SDavid Wu 	enum rockchip_pinctrl_type	type;
30449c55878SDavid Wu 	int				grf_mux_offset;
30549c55878SDavid Wu 	int				pmu_mux_offset;
30649c55878SDavid Wu 	int				grf_drv_offset;
30749c55878SDavid Wu 	int				pmu_drv_offset;
30849c55878SDavid Wu 	struct rockchip_mux_recalced_data *iomux_recalced;
30949c55878SDavid Wu 	u32				niomux_recalced;
31049c55878SDavid Wu 	struct rockchip_mux_route_data *iomux_routes;
31149c55878SDavid Wu 	u32				niomux_routes;
31249c55878SDavid Wu 
31349c55878SDavid Wu 	void	(*pull_calc_reg)(struct rockchip_pin_bank *bank,
31449c55878SDavid Wu 				 int pin_num, struct regmap **regmap,
31549c55878SDavid Wu 				 int *reg, u8 *bit);
31649c55878SDavid Wu 	void	(*drv_calc_reg)(struct rockchip_pin_bank *bank,
31749c55878SDavid Wu 				int pin_num, struct regmap **regmap,
31849c55878SDavid Wu 				int *reg, u8 *bit);
31949c55878SDavid Wu 	int	(*schmitt_calc_reg)(struct rockchip_pin_bank *bank,
32049c55878SDavid Wu 				    int pin_num, struct regmap **regmap,
32149c55878SDavid Wu 				    int *reg, u8 *bit);
32249c55878SDavid Wu };
32349c55878SDavid Wu 
32449c55878SDavid Wu /**
32549c55878SDavid Wu  */
32649c55878SDavid Wu struct rockchip_pinctrl_priv {
32749c55878SDavid Wu 	struct rockchip_pin_ctrl	*ctrl;
32849c55878SDavid Wu 	struct regmap			*regmap_base;
32949c55878SDavid Wu 	struct regmap			*regmap_pmu;
33049c55878SDavid Wu 
33149c55878SDavid Wu };
33249c55878SDavid Wu 
33349c55878SDavid Wu static int rockchip_verify_config(struct udevice *dev, u32 bank, u32 pin)
33449c55878SDavid Wu {
33549c55878SDavid Wu 	struct rockchip_pinctrl_priv *priv = dev_get_priv(dev);
33649c55878SDavid Wu 	struct rockchip_pin_ctrl *ctrl = priv->ctrl;
33749c55878SDavid Wu 
33849c55878SDavid Wu 	if (bank >= ctrl->nr_banks) {
33949c55878SDavid Wu 		debug("pin conf bank %d >= nbanks %d\n", bank, ctrl->nr_banks);
34049c55878SDavid Wu 		return -EINVAL;
34149c55878SDavid Wu 	}
34249c55878SDavid Wu 
34349c55878SDavid Wu 	if (pin >= MAX_ROCKCHIP_GPIO_PER_BANK) {
34449c55878SDavid Wu 		debug("pin conf pin %d >= %d\n", pin,
34549c55878SDavid Wu 		      MAX_ROCKCHIP_GPIO_PER_BANK);
34649c55878SDavid Wu 		return -EINVAL;
34749c55878SDavid Wu 	}
34849c55878SDavid Wu 
34949c55878SDavid Wu 	return 0;
35049c55878SDavid Wu }
35149c55878SDavid Wu 
35249c55878SDavid Wu static struct rockchip_mux_recalced_data rv1108_mux_recalced_data[] = {
35349c55878SDavid Wu 	{
35449c55878SDavid Wu 		.num = 1,
35549c55878SDavid Wu 		.pin = 0,
35649c55878SDavid Wu 		.reg = 0x418,
35749c55878SDavid Wu 		.bit = 0,
35849c55878SDavid Wu 		.mask = 0x3
35949c55878SDavid Wu 	}, {
36049c55878SDavid Wu 		.num = 1,
36149c55878SDavid Wu 		.pin = 1,
36249c55878SDavid Wu 		.reg = 0x418,
36349c55878SDavid Wu 		.bit = 2,
36449c55878SDavid Wu 		.mask = 0x3
36549c55878SDavid Wu 	}, {
36649c55878SDavid Wu 		.num = 1,
36749c55878SDavid Wu 		.pin = 2,
36849c55878SDavid Wu 		.reg = 0x418,
36949c55878SDavid Wu 		.bit = 4,
37049c55878SDavid Wu 		.mask = 0x3
37149c55878SDavid Wu 	}, {
37249c55878SDavid Wu 		.num = 1,
37349c55878SDavid Wu 		.pin = 3,
37449c55878SDavid Wu 		.reg = 0x418,
37549c55878SDavid Wu 		.bit = 6,
37649c55878SDavid Wu 		.mask = 0x3
37749c55878SDavid Wu 	}, {
37849c55878SDavid Wu 		.num = 1,
37949c55878SDavid Wu 		.pin = 4,
38049c55878SDavid Wu 		.reg = 0x418,
38149c55878SDavid Wu 		.bit = 8,
38249c55878SDavid Wu 		.mask = 0x3
38349c55878SDavid Wu 	}, {
38449c55878SDavid Wu 		.num = 1,
38549c55878SDavid Wu 		.pin = 5,
38649c55878SDavid Wu 		.reg = 0x418,
38749c55878SDavid Wu 		.bit = 10,
38849c55878SDavid Wu 		.mask = 0x3
38949c55878SDavid Wu 	}, {
39049c55878SDavid Wu 		.num = 1,
39149c55878SDavid Wu 		.pin = 6,
39249c55878SDavid Wu 		.reg = 0x418,
39349c55878SDavid Wu 		.bit = 12,
39449c55878SDavid Wu 		.mask = 0x3
39549c55878SDavid Wu 	}, {
39649c55878SDavid Wu 		.num = 1,
39749c55878SDavid Wu 		.pin = 7,
39849c55878SDavid Wu 		.reg = 0x418,
39949c55878SDavid Wu 		.bit = 14,
40049c55878SDavid Wu 		.mask = 0x3
40149c55878SDavid Wu 	}, {
40249c55878SDavid Wu 		.num = 1,
40349c55878SDavid Wu 		.pin = 8,
40449c55878SDavid Wu 		.reg = 0x41c,
40549c55878SDavid Wu 		.bit = 0,
40649c55878SDavid Wu 		.mask = 0x3
40749c55878SDavid Wu 	}, {
40849c55878SDavid Wu 		.num = 1,
40949c55878SDavid Wu 		.pin = 9,
41049c55878SDavid Wu 		.reg = 0x41c,
41149c55878SDavid Wu 		.bit = 2,
41249c55878SDavid Wu 		.mask = 0x3
41349c55878SDavid Wu 	},
41449c55878SDavid Wu };
41549c55878SDavid Wu 
41649c55878SDavid Wu static  struct rockchip_mux_recalced_data rk3128_mux_recalced_data[] = {
41749c55878SDavid Wu 	{
41849c55878SDavid Wu 		.num = 2,
41949c55878SDavid Wu 		.pin = 20,
42049c55878SDavid Wu 		.reg = 0xe8,
42149c55878SDavid Wu 		.bit = 0,
42249c55878SDavid Wu 		.mask = 0x7
42349c55878SDavid Wu 	}, {
42449c55878SDavid Wu 		.num = 2,
42549c55878SDavid Wu 		.pin = 21,
42649c55878SDavid Wu 		.reg = 0xe8,
42749c55878SDavid Wu 		.bit = 4,
42849c55878SDavid Wu 		.mask = 0x7
42949c55878SDavid Wu 	}, {
43049c55878SDavid Wu 		.num = 2,
43149c55878SDavid Wu 		.pin = 22,
43249c55878SDavid Wu 		.reg = 0xe8,
43349c55878SDavid Wu 		.bit = 8,
43449c55878SDavid Wu 		.mask = 0x7
43549c55878SDavid Wu 	}, {
43649c55878SDavid Wu 		.num = 2,
43749c55878SDavid Wu 		.pin = 23,
43849c55878SDavid Wu 		.reg = 0xe8,
43949c55878SDavid Wu 		.bit = 12,
44049c55878SDavid Wu 		.mask = 0x7
44149c55878SDavid Wu 	}, {
44249c55878SDavid Wu 		.num = 2,
44349c55878SDavid Wu 		.pin = 24,
44449c55878SDavid Wu 		.reg = 0xd4,
44549c55878SDavid Wu 		.bit = 12,
44649c55878SDavid Wu 		.mask = 0x7
44749c55878SDavid Wu 	},
44849c55878SDavid Wu };
44949c55878SDavid Wu 
450b3077611SDavid Wu static struct rockchip_mux_recalced_data rk3308_mux_recalced_data[] = {
451b3077611SDavid Wu 	{
452b3077611SDavid Wu 		.num = 1,
453b3077611SDavid Wu 		.pin = 14,
454b3077611SDavid Wu 		.reg = 0x28,
455b3077611SDavid Wu 		.bit = 12,
456b3077611SDavid Wu 		.mask = 0x7
457b3077611SDavid Wu 	}, {
458b3077611SDavid Wu 		.num = 1,
459b3077611SDavid Wu 		.pin = 15,
460b3077611SDavid Wu 		.reg = 0x2c,
461b3077611SDavid Wu 		.bit = 0,
462b3077611SDavid Wu 		.mask = 0x3
463b3077611SDavid Wu 	}, {
464b3077611SDavid Wu 		.num = 1,
465b3077611SDavid Wu 		.pin = 18,
466b3077611SDavid Wu 		.reg = 0x30,
467b3077611SDavid Wu 		.bit = 4,
468b3077611SDavid Wu 		.mask = 0x7
469b3077611SDavid Wu 	}, {
470b3077611SDavid Wu 		.num = 1,
471b3077611SDavid Wu 		.pin = 19,
472b3077611SDavid Wu 		.reg = 0x30,
473b3077611SDavid Wu 		.bit = 8,
474b3077611SDavid Wu 		.mask = 0x7
475b3077611SDavid Wu 	}, {
476b3077611SDavid Wu 		.num = 1,
477b3077611SDavid Wu 		.pin = 20,
478b3077611SDavid Wu 		.reg = 0x30,
479b3077611SDavid Wu 		.bit = 12,
480b3077611SDavid Wu 		.mask = 0x7
481b3077611SDavid Wu 	}, {
482b3077611SDavid Wu 		.num = 1,
483b3077611SDavid Wu 		.pin = 21,
484b3077611SDavid Wu 		.reg = 0x34,
485b3077611SDavid Wu 		.bit = 0,
486b3077611SDavid Wu 		.mask = 0x7
487b3077611SDavid Wu 	}, {
488b3077611SDavid Wu 		.num = 1,
489b3077611SDavid Wu 		.pin = 22,
490b3077611SDavid Wu 		.reg = 0x34,
491b3077611SDavid Wu 		.bit = 4,
492b3077611SDavid Wu 		.mask = 0x7
493b3077611SDavid Wu 	}, {
494b3077611SDavid Wu 		.num = 1,
495b3077611SDavid Wu 		.pin = 23,
496b3077611SDavid Wu 		.reg = 0x34,
497b3077611SDavid Wu 		.bit = 8,
498b3077611SDavid Wu 		.mask = 0x7
499b3077611SDavid Wu 	}, {
500b3077611SDavid Wu 		.num = 3,
501b3077611SDavid Wu 		.pin = 12,
502b3077611SDavid Wu 		.reg = 0x68,
503b3077611SDavid Wu 		.bit = 8,
504b3077611SDavid Wu 		.mask = 0x7
505b3077611SDavid Wu 	}, {
506b3077611SDavid Wu 		.num = 3,
507b3077611SDavid Wu 		.pin = 13,
508b3077611SDavid Wu 		.reg = 0x68,
509b3077611SDavid Wu 		.bit = 12,
510b3077611SDavid Wu 		.mask = 0x7
511b3077611SDavid Wu 	},
512b3077611SDavid Wu };
513b3077611SDavid Wu 
51449c55878SDavid Wu static struct rockchip_mux_recalced_data rk3328_mux_recalced_data[] = {
51549c55878SDavid Wu 	{
51649c55878SDavid Wu 		.num = 2,
51749c55878SDavid Wu 		.pin = 12,
51849c55878SDavid Wu 		.reg = 0x24,
51949c55878SDavid Wu 		.bit = 8,
52049c55878SDavid Wu 		.mask = 0x3
52149c55878SDavid Wu 	}, {
52249c55878SDavid Wu 		.num = 2,
52349c55878SDavid Wu 		.pin = 15,
52449c55878SDavid Wu 		.reg = 0x28,
52549c55878SDavid Wu 		.bit = 0,
52649c55878SDavid Wu 		.mask = 0x7
52749c55878SDavid Wu 	}, {
52849c55878SDavid Wu 		.num = 2,
52949c55878SDavid Wu 		.pin = 23,
53049c55878SDavid Wu 		.reg = 0x30,
53149c55878SDavid Wu 		.bit = 14,
53249c55878SDavid Wu 		.mask = 0x3
53349c55878SDavid Wu 	},
53449c55878SDavid Wu };
53549c55878SDavid Wu 
53649c55878SDavid Wu static void rockchip_get_recalced_mux(struct rockchip_pin_bank *bank, int pin,
53749c55878SDavid Wu 				      int *reg, u8 *bit, int *mask)
53849c55878SDavid Wu {
53949c55878SDavid Wu 	struct rockchip_pinctrl_priv *priv = bank->priv;
54049c55878SDavid Wu 	struct rockchip_pin_ctrl *ctrl = priv->ctrl;
54149c55878SDavid Wu 	struct rockchip_mux_recalced_data *data;
54249c55878SDavid Wu 	int i;
54349c55878SDavid Wu 
54449c55878SDavid Wu 	for (i = 0; i < ctrl->niomux_recalced; i++) {
54549c55878SDavid Wu 		data = &ctrl->iomux_recalced[i];
54649c55878SDavid Wu 		if (data->num == bank->bank_num &&
54749c55878SDavid Wu 		    data->pin == pin)
54849c55878SDavid Wu 			break;
54949c55878SDavid Wu 	}
55049c55878SDavid Wu 
55149c55878SDavid Wu 	if (i >= ctrl->niomux_recalced)
55249c55878SDavid Wu 		return;
55349c55878SDavid Wu 
55449c55878SDavid Wu 	*reg = data->reg;
55549c55878SDavid Wu 	*mask = data->mask;
55649c55878SDavid Wu 	*bit = data->bit;
55749c55878SDavid Wu }
55849c55878SDavid Wu 
55949c55878SDavid Wu static struct rockchip_mux_route_data px30_mux_route_data[] = {
56049c55878SDavid Wu 	{
56149c55878SDavid Wu 		/* cif-d2m0 */
56249c55878SDavid Wu 		.bank_num = 2,
56349c55878SDavid Wu 		.pin = 0,
56449c55878SDavid Wu 		.func = 1,
56549c55878SDavid Wu 		.route_offset = 0x184,
56649c55878SDavid Wu 		.route_val = BIT(16 + 7),
56749c55878SDavid Wu 	}, {
56849c55878SDavid Wu 		/* cif-d2m1 */
56949c55878SDavid Wu 		.bank_num = 3,
57049c55878SDavid Wu 		.pin = 3,
57149c55878SDavid Wu 		.func = 3,
57249c55878SDavid Wu 		.route_offset = 0x184,
57349c55878SDavid Wu 		.route_val = BIT(16 + 7) | BIT(7),
57449c55878SDavid Wu 	}, {
57549c55878SDavid Wu 		/* pdm-m0 */
57649c55878SDavid Wu 		.bank_num = 3,
57749c55878SDavid Wu 		.pin = 22,
57849c55878SDavid Wu 		.func = 2,
57949c55878SDavid Wu 		.route_offset = 0x184,
58049c55878SDavid Wu 		.route_val = BIT(16 + 8),
58149c55878SDavid Wu 	}, {
58249c55878SDavid Wu 		/* pdm-m1 */
58349c55878SDavid Wu 		.bank_num = 2,
58449c55878SDavid Wu 		.pin = 22,
58549c55878SDavid Wu 		.func = 1,
58649c55878SDavid Wu 		.route_offset = 0x184,
58749c55878SDavid Wu 		.route_val = BIT(16 + 8) | BIT(8),
58849c55878SDavid Wu 	}, {
58949c55878SDavid Wu 		/* uart2-rxm0 */
59049c55878SDavid Wu 		.bank_num = 1,
591793770dfSDavid Wu 		.pin = 27,
59249c55878SDavid Wu 		.func = 2,
59349c55878SDavid Wu 		.route_offset = 0x184,
594793770dfSDavid Wu 		.route_val = BIT(16 + 10),
59549c55878SDavid Wu 	}, {
59649c55878SDavid Wu 		/* uart2-rxm1 */
59749c55878SDavid Wu 		.bank_num = 2,
59849c55878SDavid Wu 		.pin = 14,
59949c55878SDavid Wu 		.func = 2,
60049c55878SDavid Wu 		.route_offset = 0x184,
601793770dfSDavid Wu 		.route_val = BIT(16 + 10) | BIT(10),
60249c55878SDavid Wu 	}, {
60349c55878SDavid Wu 		/* uart3-rxm0 */
60449c55878SDavid Wu 		.bank_num = 0,
60549c55878SDavid Wu 		.pin = 17,
60649c55878SDavid Wu 		.func = 2,
60749c55878SDavid Wu 		.route_offset = 0x184,
608793770dfSDavid Wu 		.route_val = BIT(16 + 9),
60949c55878SDavid Wu 	}, {
61049c55878SDavid Wu 		/* uart3-rxm1 */
61149c55878SDavid Wu 		.bank_num = 1,
612793770dfSDavid Wu 		.pin = 15,
61349c55878SDavid Wu 		.func = 2,
61449c55878SDavid Wu 		.route_offset = 0x184,
615793770dfSDavid Wu 		.route_val = BIT(16 + 9) | BIT(9),
61649c55878SDavid Wu 	},
61749c55878SDavid Wu };
61849c55878SDavid Wu 
61949c55878SDavid Wu static struct rockchip_mux_route_data rk3128_mux_route_data[] = {
62049c55878SDavid Wu 	{
62149c55878SDavid Wu 		/* spi-0 */
62249c55878SDavid Wu 		.bank_num = 1,
62349c55878SDavid Wu 		.pin = 10,
62449c55878SDavid Wu 		.func = 1,
62549c55878SDavid Wu 		.route_offset = 0x144,
62649c55878SDavid Wu 		.route_val = BIT(16 + 3) | BIT(16 + 4),
62749c55878SDavid Wu 	}, {
62849c55878SDavid Wu 		/* spi-1 */
62949c55878SDavid Wu 		.bank_num = 1,
63049c55878SDavid Wu 		.pin = 27,
63149c55878SDavid Wu 		.func = 3,
63249c55878SDavid Wu 		.route_offset = 0x144,
63349c55878SDavid Wu 		.route_val = BIT(16 + 3) | BIT(16 + 4) | BIT(3),
63449c55878SDavid Wu 	}, {
63549c55878SDavid Wu 		/* spi-2 */
63649c55878SDavid Wu 		.bank_num = 0,
63749c55878SDavid Wu 		.pin = 13,
63849c55878SDavid Wu 		.func = 2,
63949c55878SDavid Wu 		.route_offset = 0x144,
64049c55878SDavid Wu 		.route_val = BIT(16 + 3) | BIT(16 + 4) | BIT(4),
64149c55878SDavid Wu 	}, {
64249c55878SDavid Wu 		/* i2s-0 */
64349c55878SDavid Wu 		.bank_num = 1,
64449c55878SDavid Wu 		.pin = 5,
64549c55878SDavid Wu 		.func = 1,
64649c55878SDavid Wu 		.route_offset = 0x144,
64749c55878SDavid Wu 		.route_val = BIT(16 + 5),
64849c55878SDavid Wu 	}, {
64949c55878SDavid Wu 		/* i2s-1 */
65049c55878SDavid Wu 		.bank_num = 0,
65149c55878SDavid Wu 		.pin = 14,
65249c55878SDavid Wu 		.func = 1,
65349c55878SDavid Wu 		.route_offset = 0x144,
65449c55878SDavid Wu 		.route_val = BIT(16 + 5) | BIT(5),
65549c55878SDavid Wu 	}, {
65649c55878SDavid Wu 		/* emmc-0 */
65749c55878SDavid Wu 		.bank_num = 1,
65849c55878SDavid Wu 		.pin = 22,
65949c55878SDavid Wu 		.func = 2,
66049c55878SDavid Wu 		.route_offset = 0x144,
66149c55878SDavid Wu 		.route_val = BIT(16 + 6),
66249c55878SDavid Wu 	}, {
66349c55878SDavid Wu 		/* emmc-1 */
66449c55878SDavid Wu 		.bank_num = 2,
66549c55878SDavid Wu 		.pin = 4,
66649c55878SDavid Wu 		.func = 2,
66749c55878SDavid Wu 		.route_offset = 0x144,
66849c55878SDavid Wu 		.route_val = BIT(16 + 6) | BIT(6),
66949c55878SDavid Wu 	},
67049c55878SDavid Wu };
67149c55878SDavid Wu 
67249c55878SDavid Wu static struct rockchip_mux_route_data rk3228_mux_route_data[] = {
67349c55878SDavid Wu 	{
67449c55878SDavid Wu 		/* pwm0-0 */
67549c55878SDavid Wu 		.bank_num = 0,
67649c55878SDavid Wu 		.pin = 26,
67749c55878SDavid Wu 		.func = 1,
67849c55878SDavid Wu 		.route_offset = 0x50,
67949c55878SDavid Wu 		.route_val = BIT(16),
68049c55878SDavid Wu 	}, {
68149c55878SDavid Wu 		/* pwm0-1 */
68249c55878SDavid Wu 		.bank_num = 3,
68349c55878SDavid Wu 		.pin = 21,
68449c55878SDavid Wu 		.func = 1,
68549c55878SDavid Wu 		.route_offset = 0x50,
68649c55878SDavid Wu 		.route_val = BIT(16) | BIT(0),
68749c55878SDavid Wu 	}, {
68849c55878SDavid Wu 		/* pwm1-0 */
68949c55878SDavid Wu 		.bank_num = 0,
69049c55878SDavid Wu 		.pin = 27,
69149c55878SDavid Wu 		.func = 1,
69249c55878SDavid Wu 		.route_offset = 0x50,
69349c55878SDavid Wu 		.route_val = BIT(16 + 1),
69449c55878SDavid Wu 	}, {
69549c55878SDavid Wu 		/* pwm1-1 */
69649c55878SDavid Wu 		.bank_num = 0,
69749c55878SDavid Wu 		.pin = 30,
69849c55878SDavid Wu 		.func = 2,
69949c55878SDavid Wu 		.route_offset = 0x50,
70049c55878SDavid Wu 		.route_val = BIT(16 + 1) | BIT(1),
70149c55878SDavid Wu 	}, {
70249c55878SDavid Wu 		/* pwm2-0 */
70349c55878SDavid Wu 		.bank_num = 0,
70449c55878SDavid Wu 		.pin = 28,
70549c55878SDavid Wu 		.func = 1,
70649c55878SDavid Wu 		.route_offset = 0x50,
70749c55878SDavid Wu 		.route_val = BIT(16 + 2),
70849c55878SDavid Wu 	}, {
70949c55878SDavid Wu 		/* pwm2-1 */
71049c55878SDavid Wu 		.bank_num = 1,
71149c55878SDavid Wu 		.pin = 12,
71249c55878SDavid Wu 		.func = 2,
71349c55878SDavid Wu 		.route_offset = 0x50,
71449c55878SDavid Wu 		.route_val = BIT(16 + 2) | BIT(2),
71549c55878SDavid Wu 	}, {
71649c55878SDavid Wu 		/* pwm3-0 */
71749c55878SDavid Wu 		.bank_num = 3,
71849c55878SDavid Wu 		.pin = 26,
71949c55878SDavid Wu 		.func = 1,
72049c55878SDavid Wu 		.route_offset = 0x50,
72149c55878SDavid Wu 		.route_val = BIT(16 + 3),
72249c55878SDavid Wu 	}, {
72349c55878SDavid Wu 		/* pwm3-1 */
72449c55878SDavid Wu 		.bank_num = 1,
72549c55878SDavid Wu 		.pin = 11,
72649c55878SDavid Wu 		.func = 2,
72749c55878SDavid Wu 		.route_offset = 0x50,
72849c55878SDavid Wu 		.route_val = BIT(16 + 3) | BIT(3),
72949c55878SDavid Wu 	}, {
73049c55878SDavid Wu 		/* sdio-0_d0 */
73149c55878SDavid Wu 		.bank_num = 1,
73249c55878SDavid Wu 		.pin = 1,
73349c55878SDavid Wu 		.func = 1,
73449c55878SDavid Wu 		.route_offset = 0x50,
73549c55878SDavid Wu 		.route_val = BIT(16 + 4),
73649c55878SDavid Wu 	}, {
73749c55878SDavid Wu 		/* sdio-1_d0 */
73849c55878SDavid Wu 		.bank_num = 3,
73949c55878SDavid Wu 		.pin = 2,
74049c55878SDavid Wu 		.func = 1,
74149c55878SDavid Wu 		.route_offset = 0x50,
74249c55878SDavid Wu 		.route_val = BIT(16 + 4) | BIT(4),
74349c55878SDavid Wu 	}, {
74449c55878SDavid Wu 		/* spi-0_rx */
74549c55878SDavid Wu 		.bank_num = 0,
74649c55878SDavid Wu 		.pin = 13,
74749c55878SDavid Wu 		.func = 2,
74849c55878SDavid Wu 		.route_offset = 0x50,
74949c55878SDavid Wu 		.route_val = BIT(16 + 5),
75049c55878SDavid Wu 	}, {
75149c55878SDavid Wu 		/* spi-1_rx */
75249c55878SDavid Wu 		.bank_num = 2,
75349c55878SDavid Wu 		.pin = 0,
75449c55878SDavid Wu 		.func = 2,
75549c55878SDavid Wu 		.route_offset = 0x50,
75649c55878SDavid Wu 		.route_val = BIT(16 + 5) | BIT(5),
75749c55878SDavid Wu 	}, {
75849c55878SDavid Wu 		/* emmc-0_cmd */
75949c55878SDavid Wu 		.bank_num = 1,
76049c55878SDavid Wu 		.pin = 22,
76149c55878SDavid Wu 		.func = 2,
76249c55878SDavid Wu 		.route_offset = 0x50,
76349c55878SDavid Wu 		.route_val = BIT(16 + 7),
76449c55878SDavid Wu 	}, {
76549c55878SDavid Wu 		/* emmc-1_cmd */
76649c55878SDavid Wu 		.bank_num = 2,
76749c55878SDavid Wu 		.pin = 4,
76849c55878SDavid Wu 		.func = 2,
76949c55878SDavid Wu 		.route_offset = 0x50,
77049c55878SDavid Wu 		.route_val = BIT(16 + 7) | BIT(7),
77149c55878SDavid Wu 	}, {
77249c55878SDavid Wu 		/* uart2-0_rx */
77349c55878SDavid Wu 		.bank_num = 1,
77449c55878SDavid Wu 		.pin = 19,
77549c55878SDavid Wu 		.func = 2,
77649c55878SDavid Wu 		.route_offset = 0x50,
77749c55878SDavid Wu 		.route_val = BIT(16 + 8),
77849c55878SDavid Wu 	}, {
77949c55878SDavid Wu 		/* uart2-1_rx */
78049c55878SDavid Wu 		.bank_num = 1,
78149c55878SDavid Wu 		.pin = 10,
78249c55878SDavid Wu 		.func = 2,
78349c55878SDavid Wu 		.route_offset = 0x50,
78449c55878SDavid Wu 		.route_val = BIT(16 + 8) | BIT(8),
78549c55878SDavid Wu 	}, {
78649c55878SDavid Wu 		/* uart1-0_rx */
78749c55878SDavid Wu 		.bank_num = 1,
78849c55878SDavid Wu 		.pin = 10,
78949c55878SDavid Wu 		.func = 1,
79049c55878SDavid Wu 		.route_offset = 0x50,
79149c55878SDavid Wu 		.route_val = BIT(16 + 11),
79249c55878SDavid Wu 	}, {
79349c55878SDavid Wu 		/* uart1-1_rx */
79449c55878SDavid Wu 		.bank_num = 3,
79549c55878SDavid Wu 		.pin = 13,
79649c55878SDavid Wu 		.func = 1,
79749c55878SDavid Wu 		.route_offset = 0x50,
79849c55878SDavid Wu 		.route_val = BIT(16 + 11) | BIT(11),
79949c55878SDavid Wu 	},
80049c55878SDavid Wu };
80149c55878SDavid Wu 
80249c55878SDavid Wu static struct rockchip_mux_route_data rk3288_mux_route_data[] = {
80349c55878SDavid Wu 	{
80449c55878SDavid Wu 		/* edphdmi_cecinoutt1 */
80549c55878SDavid Wu 		.bank_num = 7,
80649c55878SDavid Wu 		.pin = 16,
80749c55878SDavid Wu 		.func = 2,
80849c55878SDavid Wu 		.route_offset = 0x264,
80949c55878SDavid Wu 		.route_val = BIT(16 + 12) | BIT(12),
81049c55878SDavid Wu 	}, {
81149c55878SDavid Wu 		/* edphdmi_cecinout */
81249c55878SDavid Wu 		.bank_num = 7,
81349c55878SDavid Wu 		.pin = 23,
81449c55878SDavid Wu 		.func = 4,
81549c55878SDavid Wu 		.route_offset = 0x264,
81649c55878SDavid Wu 		.route_val = BIT(16 + 12),
81749c55878SDavid Wu 	},
81849c55878SDavid Wu };
81949c55878SDavid Wu 
820b3077611SDavid Wu static struct rockchip_mux_route_data rk3308_mux_route_data[] = {
821b3077611SDavid Wu 	{
822b3077611SDavid Wu 		/* uart2_rxm0 */
823b3077611SDavid Wu 		.bank_num = 1,
824b3077611SDavid Wu 		.pin = 22,
825b3077611SDavid Wu 		.func = 2,
826b3077611SDavid Wu 		.route_offset = 0x314,
827b3077611SDavid Wu 		.route_val = BIT(16 + 2) | BIT(16 + 3),
828b3077611SDavid Wu 	}, {
829b3077611SDavid Wu 		/* uart2_rxm1 */
830b3077611SDavid Wu 		.bank_num = 4,
831b3077611SDavid Wu 		.pin = 26,
832b3077611SDavid Wu 		.func = 2,
833b3077611SDavid Wu 		.route_offset = 0x314,
834b3077611SDavid Wu 		.route_val = BIT(16 + 2) | BIT(16 + 3) | BIT(2),
835b3077611SDavid Wu 	}, {
836b3077611SDavid Wu 		/* i2c3_sdam0 */
837b3077611SDavid Wu 		.bank_num = 0,
838b3077611SDavid Wu 		.pin = 23,
839b3077611SDavid Wu 		.func = 2,
840b3077611SDavid Wu 		.route_offset = 0x314,
841b3077611SDavid Wu 		.route_val = BIT(16 + 4),
842b3077611SDavid Wu 	}, {
843b3077611SDavid Wu 		/* i2c3_sdam1 */
844b3077611SDavid Wu 		.bank_num = 3,
845b3077611SDavid Wu 		.pin = 12,
846b3077611SDavid Wu 		.func = 2,
847b3077611SDavid Wu 		.route_offset = 0x314,
848b3077611SDavid Wu 		.route_val =  BIT(16 + 4) | BIT(4),
849b3077611SDavid Wu 	},
850b3077611SDavid Wu };
851b3077611SDavid Wu 
85249c55878SDavid Wu static struct rockchip_mux_route_data rk3328_mux_route_data[] = {
85349c55878SDavid Wu 	{
85449c55878SDavid Wu 		/* uart2dbg_rxm0 */
85549c55878SDavid Wu 		.bank_num = 1,
85649c55878SDavid Wu 		.pin = 1,
85749c55878SDavid Wu 		.func = 2,
85849c55878SDavid Wu 		.route_offset = 0x50,
85949c55878SDavid Wu 		.route_val = BIT(16) | BIT(16 + 1),
86049c55878SDavid Wu 	}, {
86149c55878SDavid Wu 		/* uart2dbg_rxm1 */
86249c55878SDavid Wu 		.bank_num = 2,
86349c55878SDavid Wu 		.pin = 1,
86449c55878SDavid Wu 		.func = 1,
86549c55878SDavid Wu 		.route_offset = 0x50,
86649c55878SDavid Wu 		.route_val = BIT(16) | BIT(16 + 1) | BIT(0),
86749c55878SDavid Wu 	}, {
86849c55878SDavid Wu 		/* gmac-m1_rxd0 */
86949c55878SDavid Wu 		.bank_num = 1,
87049c55878SDavid Wu 		.pin = 11,
87149c55878SDavid Wu 		.func = 2,
87249c55878SDavid Wu 		.route_offset = 0x50,
87349c55878SDavid Wu 		.route_val = BIT(16 + 2) | BIT(2),
87449c55878SDavid Wu 	}, {
87549c55878SDavid Wu 		/* gmac-m1-optimized_rxd3 */
87649c55878SDavid Wu 		.bank_num = 1,
87749c55878SDavid Wu 		.pin = 14,
87849c55878SDavid Wu 		.func = 2,
87949c55878SDavid Wu 		.route_offset = 0x50,
88049c55878SDavid Wu 		.route_val = BIT(16 + 10) | BIT(10),
88149c55878SDavid Wu 	}, {
88249c55878SDavid Wu 		/* pdm_sdi0m0 */
88349c55878SDavid Wu 		.bank_num = 2,
88449c55878SDavid Wu 		.pin = 19,
88549c55878SDavid Wu 		.func = 2,
88649c55878SDavid Wu 		.route_offset = 0x50,
88749c55878SDavid Wu 		.route_val = BIT(16 + 3),
88849c55878SDavid Wu 	}, {
88949c55878SDavid Wu 		/* pdm_sdi0m1 */
89049c55878SDavid Wu 		.bank_num = 1,
89149c55878SDavid Wu 		.pin = 23,
89249c55878SDavid Wu 		.func = 3,
89349c55878SDavid Wu 		.route_offset = 0x50,
89449c55878SDavid Wu 		.route_val =  BIT(16 + 3) | BIT(3),
89549c55878SDavid Wu 	}, {
89649c55878SDavid Wu 		/* spi_rxdm2 */
89749c55878SDavid Wu 		.bank_num = 3,
89849c55878SDavid Wu 		.pin = 2,
89949c55878SDavid Wu 		.func = 4,
90049c55878SDavid Wu 		.route_offset = 0x50,
90149c55878SDavid Wu 		.route_val =  BIT(16 + 4) | BIT(16 + 5) | BIT(5),
90249c55878SDavid Wu 	}, {
90349c55878SDavid Wu 		/* i2s2_sdim0 */
90449c55878SDavid Wu 		.bank_num = 1,
90549c55878SDavid Wu 		.pin = 24,
90649c55878SDavid Wu 		.func = 1,
90749c55878SDavid Wu 		.route_offset = 0x50,
90849c55878SDavid Wu 		.route_val = BIT(16 + 6),
90949c55878SDavid Wu 	}, {
91049c55878SDavid Wu 		/* i2s2_sdim1 */
91149c55878SDavid Wu 		.bank_num = 3,
91249c55878SDavid Wu 		.pin = 2,
91349c55878SDavid Wu 		.func = 6,
91449c55878SDavid Wu 		.route_offset = 0x50,
91549c55878SDavid Wu 		.route_val =  BIT(16 + 6) | BIT(6),
91649c55878SDavid Wu 	}, {
91749c55878SDavid Wu 		/* card_iom1 */
91849c55878SDavid Wu 		.bank_num = 2,
91949c55878SDavid Wu 		.pin = 22,
92049c55878SDavid Wu 		.func = 3,
92149c55878SDavid Wu 		.route_offset = 0x50,
92249c55878SDavid Wu 		.route_val =  BIT(16 + 7) | BIT(7),
92349c55878SDavid Wu 	}, {
92449c55878SDavid Wu 		/* tsp_d5m1 */
92549c55878SDavid Wu 		.bank_num = 2,
92649c55878SDavid Wu 		.pin = 16,
92749c55878SDavid Wu 		.func = 3,
92849c55878SDavid Wu 		.route_offset = 0x50,
92949c55878SDavid Wu 		.route_val =  BIT(16 + 8) | BIT(8),
93049c55878SDavid Wu 	}, {
93149c55878SDavid Wu 		/* cif_data5m1 */
93249c55878SDavid Wu 		.bank_num = 2,
93349c55878SDavid Wu 		.pin = 16,
93449c55878SDavid Wu 		.func = 4,
93549c55878SDavid Wu 		.route_offset = 0x50,
93649c55878SDavid Wu 		.route_val =  BIT(16 + 9) | BIT(9),
93749c55878SDavid Wu 	},
93849c55878SDavid Wu };
93949c55878SDavid Wu 
94049c55878SDavid Wu static struct rockchip_mux_route_data rk3399_mux_route_data[] = {
94149c55878SDavid Wu 	{
94249c55878SDavid Wu 		/* uart2dbga_rx */
94349c55878SDavid Wu 		.bank_num = 4,
94449c55878SDavid Wu 		.pin = 8,
94549c55878SDavid Wu 		.func = 2,
94649c55878SDavid Wu 		.route_offset = 0xe21c,
94749c55878SDavid Wu 		.route_val = BIT(16 + 10) | BIT(16 + 11),
94849c55878SDavid Wu 	}, {
94949c55878SDavid Wu 		/* uart2dbgb_rx */
95049c55878SDavid Wu 		.bank_num = 4,
95149c55878SDavid Wu 		.pin = 16,
95249c55878SDavid Wu 		.func = 2,
95349c55878SDavid Wu 		.route_offset = 0xe21c,
95449c55878SDavid Wu 		.route_val = BIT(16 + 10) | BIT(16 + 11) | BIT(10),
95549c55878SDavid Wu 	}, {
95649c55878SDavid Wu 		/* uart2dbgc_rx */
95749c55878SDavid Wu 		.bank_num = 4,
95849c55878SDavid Wu 		.pin = 19,
95949c55878SDavid Wu 		.func = 1,
96049c55878SDavid Wu 		.route_offset = 0xe21c,
96149c55878SDavid Wu 		.route_val = BIT(16 + 10) | BIT(16 + 11) | BIT(11),
96249c55878SDavid Wu 	}, {
96349c55878SDavid Wu 		/* pcie_clkreqn */
96449c55878SDavid Wu 		.bank_num = 2,
96549c55878SDavid Wu 		.pin = 26,
96649c55878SDavid Wu 		.func = 2,
96749c55878SDavid Wu 		.route_offset = 0xe21c,
96849c55878SDavid Wu 		.route_val = BIT(16 + 14),
96949c55878SDavid Wu 	}, {
97049c55878SDavid Wu 		/* pcie_clkreqnb */
97149c55878SDavid Wu 		.bank_num = 4,
97249c55878SDavid Wu 		.pin = 24,
97349c55878SDavid Wu 		.func = 1,
97449c55878SDavid Wu 		.route_offset = 0xe21c,
97549c55878SDavid Wu 		.route_val = BIT(16 + 14) | BIT(14),
97649c55878SDavid Wu 	},
97749c55878SDavid Wu };
97849c55878SDavid Wu 
97949c55878SDavid Wu static bool rockchip_get_mux_route(struct rockchip_pin_bank *bank, int pin,
98049c55878SDavid Wu 				   int mux, u32 *reg, u32 *value)
98149c55878SDavid Wu {
98249c55878SDavid Wu 	struct rockchip_pinctrl_priv *priv = bank->priv;
98349c55878SDavid Wu 	struct rockchip_pin_ctrl *ctrl = priv->ctrl;
98449c55878SDavid Wu 	struct rockchip_mux_route_data *data;
98549c55878SDavid Wu 	int i;
98649c55878SDavid Wu 
98749c55878SDavid Wu 	for (i = 0; i < ctrl->niomux_routes; i++) {
98849c55878SDavid Wu 		data = &ctrl->iomux_routes[i];
98949c55878SDavid Wu 		if ((data->bank_num == bank->bank_num) &&
99049c55878SDavid Wu 		    (data->pin == pin) && (data->func == mux))
99149c55878SDavid Wu 			break;
99249c55878SDavid Wu 	}
99349c55878SDavid Wu 
99449c55878SDavid Wu 	if (i >= ctrl->niomux_routes)
99549c55878SDavid Wu 		return false;
99649c55878SDavid Wu 
99749c55878SDavid Wu 	*reg = data->route_offset;
99849c55878SDavid Wu 	*value = data->route_val;
99949c55878SDavid Wu 
100049c55878SDavid Wu 	return true;
100149c55878SDavid Wu }
100249c55878SDavid Wu 
100349c55878SDavid Wu static int rockchip_get_mux(struct rockchip_pin_bank *bank, int pin)
100449c55878SDavid Wu {
100549c55878SDavid Wu 	struct rockchip_pinctrl_priv *priv = bank->priv;
100649c55878SDavid Wu 	int iomux_num = (pin / 8);
100749c55878SDavid Wu 	struct regmap *regmap;
100849c55878SDavid Wu 	unsigned int val;
100949c55878SDavid Wu 	int reg, ret, mask, mux_type;
101049c55878SDavid Wu 	u8 bit;
101149c55878SDavid Wu 
101249c55878SDavid Wu 	if (iomux_num > 3)
101349c55878SDavid Wu 		return -EINVAL;
101449c55878SDavid Wu 
101549c55878SDavid Wu 	if (bank->iomux[iomux_num].type & IOMUX_UNROUTED) {
101649c55878SDavid Wu 		debug("pin %d is unrouted\n", pin);
101749c55878SDavid Wu 		return -EINVAL;
101849c55878SDavid Wu 	}
101949c55878SDavid Wu 
102049c55878SDavid Wu 	if (bank->iomux[iomux_num].type & IOMUX_GPIO_ONLY)
102149c55878SDavid Wu 		return RK_FUNC_GPIO;
102249c55878SDavid Wu 
102349c55878SDavid Wu 	regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU)
102449c55878SDavid Wu 				? priv->regmap_pmu : priv->regmap_base;
102549c55878SDavid Wu 
102649c55878SDavid Wu 	/* get basic quadrupel of mux registers and the correct reg inside */
102749c55878SDavid Wu 	mux_type = bank->iomux[iomux_num].type;
102849c55878SDavid Wu 	reg = bank->iomux[iomux_num].offset;
102949c55878SDavid Wu 	if (mux_type & IOMUX_WIDTH_4BIT) {
103049c55878SDavid Wu 		if ((pin % 8) >= 4)
103149c55878SDavid Wu 			reg += 0x4;
103249c55878SDavid Wu 		bit = (pin % 4) * 4;
103349c55878SDavid Wu 		mask = 0xf;
103449c55878SDavid Wu 	} else if (mux_type & IOMUX_WIDTH_3BIT) {
103549c55878SDavid Wu 		if ((pin % 8) >= 5)
103649c55878SDavid Wu 			reg += 0x4;
103749c55878SDavid Wu 		bit = (pin % 8 % 5) * 3;
103849c55878SDavid Wu 		mask = 0x7;
103949c55878SDavid Wu 	} else {
104049c55878SDavid Wu 		bit = (pin % 8) * 2;
104149c55878SDavid Wu 		mask = 0x3;
104249c55878SDavid Wu 	}
104349c55878SDavid Wu 
104449c55878SDavid Wu 	if (bank->recalced_mask & BIT(pin))
104549c55878SDavid Wu 		rockchip_get_recalced_mux(bank, pin, &reg, &bit, &mask);
104649c55878SDavid Wu 
104749c55878SDavid Wu 	ret = regmap_read(regmap, reg, &val);
104849c55878SDavid Wu 	if (ret)
104949c55878SDavid Wu 		return ret;
105049c55878SDavid Wu 
105149c55878SDavid Wu 	return ((val >> bit) & mask);
105249c55878SDavid Wu }
105349c55878SDavid Wu 
105449c55878SDavid Wu static int rockchip_pinctrl_get_gpio_mux(struct udevice *dev, int banknum,
105549c55878SDavid Wu 					 int index)
105649c55878SDavid Wu {	struct rockchip_pinctrl_priv *priv = dev_get_priv(dev);
105749c55878SDavid Wu 	struct rockchip_pin_ctrl *ctrl = priv->ctrl;
105849c55878SDavid Wu 
105949c55878SDavid Wu 	return rockchip_get_mux(&ctrl->pin_banks[banknum], index);
106049c55878SDavid Wu }
106149c55878SDavid Wu 
106249c55878SDavid Wu static int rockchip_verify_mux(struct rockchip_pin_bank *bank,
106349c55878SDavid Wu 			       int pin, int mux)
106449c55878SDavid Wu {
106549c55878SDavid Wu 	int iomux_num = (pin / 8);
106649c55878SDavid Wu 
106749c55878SDavid Wu 	if (iomux_num > 3)
106849c55878SDavid Wu 		return -EINVAL;
106949c55878SDavid Wu 
107049c55878SDavid Wu 	if (bank->iomux[iomux_num].type & IOMUX_UNROUTED) {
107149c55878SDavid Wu 		debug("pin %d is unrouted\n", pin);
107249c55878SDavid Wu 		return -EINVAL;
107349c55878SDavid Wu 	}
107449c55878SDavid Wu 
107549c55878SDavid Wu 	if (bank->iomux[iomux_num].type & IOMUX_GPIO_ONLY) {
107649c55878SDavid Wu 		if (mux != IOMUX_GPIO_ONLY) {
107749c55878SDavid Wu 			debug("pin %d only supports a gpio mux\n", pin);
107849c55878SDavid Wu 			return -ENOTSUPP;
107949c55878SDavid Wu 		}
108049c55878SDavid Wu 	}
108149c55878SDavid Wu 
108249c55878SDavid Wu 	return 0;
108349c55878SDavid Wu }
108449c55878SDavid Wu 
108549c55878SDavid Wu /*
108649c55878SDavid Wu  * Set a new mux function for a pin.
108749c55878SDavid Wu  *
108849c55878SDavid Wu  * The register is divided into the upper and lower 16 bit. When changing
108949c55878SDavid Wu  * a value, the previous register value is not read and changed. Instead
109049c55878SDavid Wu  * it seems the changed bits are marked in the upper 16 bit, while the
109149c55878SDavid Wu  * changed value gets set in the same offset in the lower 16 bit.
109249c55878SDavid Wu  * All pin settings seem to be 2 bit wide in both the upper and lower
109349c55878SDavid Wu  * parts.
109449c55878SDavid Wu  * @bank: pin bank to change
109549c55878SDavid Wu  * @pin: pin to change
109649c55878SDavid Wu  * @mux: new mux function to set
109749c55878SDavid Wu  */
109849c55878SDavid Wu static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
109949c55878SDavid Wu {
110049c55878SDavid Wu 	struct rockchip_pinctrl_priv *priv = bank->priv;
110149c55878SDavid Wu 	int iomux_num = (pin / 8);
110249c55878SDavid Wu 	struct regmap *regmap;
110349c55878SDavid Wu 	int reg, ret, mask, mux_type;
110449c55878SDavid Wu 	u8 bit;
110549c55878SDavid Wu 	u32 data, route_reg, route_val;
110649c55878SDavid Wu 
110749c55878SDavid Wu 	ret = rockchip_verify_mux(bank, pin, mux);
110849c55878SDavid Wu 	if (ret < 0)
110949c55878SDavid Wu 		return ret;
111049c55878SDavid Wu 
111149c55878SDavid Wu 	if (bank->iomux[iomux_num].type & IOMUX_GPIO_ONLY)
111249c55878SDavid Wu 		return 0;
111349c55878SDavid Wu 
111449c55878SDavid Wu 	debug("setting mux of GPIO%d-%d to %d\n", bank->bank_num, pin, mux);
111549c55878SDavid Wu 
111649c55878SDavid Wu 	regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU)
111749c55878SDavid Wu 				? priv->regmap_pmu : priv->regmap_base;
111849c55878SDavid Wu 
111949c55878SDavid Wu 	/* get basic quadrupel of mux registers and the correct reg inside */
112049c55878SDavid Wu 	mux_type = bank->iomux[iomux_num].type;
112149c55878SDavid Wu 	reg = bank->iomux[iomux_num].offset;
112249c55878SDavid Wu 	if (mux_type & IOMUX_WIDTH_4BIT) {
112349c55878SDavid Wu 		if ((pin % 8) >= 4)
112449c55878SDavid Wu 			reg += 0x4;
112549c55878SDavid Wu 		bit = (pin % 4) * 4;
112649c55878SDavid Wu 		mask = 0xf;
112749c55878SDavid Wu 	} else if (mux_type & IOMUX_WIDTH_3BIT) {
112849c55878SDavid Wu 		if ((pin % 8) >= 5)
112949c55878SDavid Wu 			reg += 0x4;
113049c55878SDavid Wu 		bit = (pin % 8 % 5) * 3;
113149c55878SDavid Wu 		mask = 0x7;
113249c55878SDavid Wu 	} else {
113349c55878SDavid Wu 		bit = (pin % 8) * 2;
113449c55878SDavid Wu 		mask = 0x3;
113549c55878SDavid Wu 	}
113649c55878SDavid Wu 
113749c55878SDavid Wu 	if (bank->recalced_mask & BIT(pin))
113849c55878SDavid Wu 		rockchip_get_recalced_mux(bank, pin, &reg, &bit, &mask);
113949c55878SDavid Wu 
114049c55878SDavid Wu 	if (bank->route_mask & BIT(pin)) {
114149c55878SDavid Wu 		if (rockchip_get_mux_route(bank, pin, mux, &route_reg,
114249c55878SDavid Wu 					   &route_val)) {
114349c55878SDavid Wu 			ret = regmap_write(regmap, route_reg, route_val);
114449c55878SDavid Wu 			if (ret)
114549c55878SDavid Wu 				return ret;
114649c55878SDavid Wu 		}
114749c55878SDavid Wu 	}
114849c55878SDavid Wu 
11494bafc2daSDavid Wu 	if (mux_type & IOMUX_WRITABLE_32BIT) {
11508bf1bc66SDavid Wu 		regmap_read(regmap, reg, &data);
11514bafc2daSDavid Wu 		data &= ~(mask << bit);
11524bafc2daSDavid Wu 	} else {
115349c55878SDavid Wu 		data = (mask << (bit + 16));
11544bafc2daSDavid Wu 	}
11558bf1bc66SDavid Wu 
115649c55878SDavid Wu 	data |= (mux & mask) << bit;
115749c55878SDavid Wu 	ret = regmap_write(regmap, reg, data);
115849c55878SDavid Wu 
115949c55878SDavid Wu 	return ret;
116049c55878SDavid Wu }
116149c55878SDavid Wu 
116249c55878SDavid Wu #define PX30_PULL_PMU_OFFSET		0x10
116349c55878SDavid Wu #define PX30_PULL_GRF_OFFSET		0x60
116449c55878SDavid Wu #define PX30_PULL_BITS_PER_PIN		2
116549c55878SDavid Wu #define PX30_PULL_PINS_PER_REG		8
116649c55878SDavid Wu #define PX30_PULL_BANK_STRIDE		16
116749c55878SDavid Wu 
116849c55878SDavid Wu static void px30_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
116949c55878SDavid Wu 				       int pin_num, struct regmap **regmap,
117049c55878SDavid Wu 				       int *reg, u8 *bit)
117149c55878SDavid Wu {
117249c55878SDavid Wu 	struct rockchip_pinctrl_priv *priv = bank->priv;
117349c55878SDavid Wu 
117449c55878SDavid Wu 	/* The first 32 pins of the first bank are located in PMU */
117549c55878SDavid Wu 	if (bank->bank_num == 0) {
117649c55878SDavid Wu 		*regmap = priv->regmap_pmu;
117749c55878SDavid Wu 		*reg = PX30_PULL_PMU_OFFSET;
117849c55878SDavid Wu 	} else {
117949c55878SDavid Wu 		*regmap = priv->regmap_base;
118049c55878SDavid Wu 		*reg = PX30_PULL_GRF_OFFSET;
118149c55878SDavid Wu 
118249c55878SDavid Wu 		/* correct the offset, as we're starting with the 2nd bank */
118349c55878SDavid Wu 		*reg -= 0x10;
118449c55878SDavid Wu 		*reg += bank->bank_num * PX30_PULL_BANK_STRIDE;
118549c55878SDavid Wu 	}
118649c55878SDavid Wu 
118749c55878SDavid Wu 	*reg += ((pin_num / PX30_PULL_PINS_PER_REG) * 4);
118849c55878SDavid Wu 	*bit = (pin_num % PX30_PULL_PINS_PER_REG);
118949c55878SDavid Wu 	*bit *= PX30_PULL_BITS_PER_PIN;
119049c55878SDavid Wu }
119149c55878SDavid Wu 
119249c55878SDavid Wu #define PX30_DRV_PMU_OFFSET		0x20
119349c55878SDavid Wu #define PX30_DRV_GRF_OFFSET		0xf0
119449c55878SDavid Wu #define PX30_DRV_BITS_PER_PIN		2
119549c55878SDavid Wu #define PX30_DRV_PINS_PER_REG		8
119649c55878SDavid Wu #define PX30_DRV_BANK_STRIDE		16
119749c55878SDavid Wu 
119849c55878SDavid Wu static void px30_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
119949c55878SDavid Wu 				      int pin_num, struct regmap **regmap,
120049c55878SDavid Wu 				      int *reg, u8 *bit)
120149c55878SDavid Wu {
120249c55878SDavid Wu 	struct rockchip_pinctrl_priv *priv = bank->priv;
120349c55878SDavid Wu 
120449c55878SDavid Wu 	/* The first 32 pins of the first bank are located in PMU */
120549c55878SDavid Wu 	if (bank->bank_num == 0) {
120649c55878SDavid Wu 		*regmap = priv->regmap_pmu;
120749c55878SDavid Wu 		*reg = PX30_DRV_PMU_OFFSET;
120849c55878SDavid Wu 	} else {
120949c55878SDavid Wu 		*regmap = priv->regmap_base;
121049c55878SDavid Wu 		*reg = PX30_DRV_GRF_OFFSET;
121149c55878SDavid Wu 
121249c55878SDavid Wu 		/* correct the offset, as we're starting with the 2nd bank */
121349c55878SDavid Wu 		*reg -= 0x10;
121449c55878SDavid Wu 		*reg += bank->bank_num * PX30_DRV_BANK_STRIDE;
121549c55878SDavid Wu 	}
121649c55878SDavid Wu 
121749c55878SDavid Wu 	*reg += ((pin_num / PX30_DRV_PINS_PER_REG) * 4);
121849c55878SDavid Wu 	*bit = (pin_num % PX30_DRV_PINS_PER_REG);
121949c55878SDavid Wu 	*bit *= PX30_DRV_BITS_PER_PIN;
122049c55878SDavid Wu }
122149c55878SDavid Wu 
122249c55878SDavid Wu #define PX30_SCHMITT_PMU_OFFSET			0x38
122349c55878SDavid Wu #define PX30_SCHMITT_GRF_OFFSET			0xc0
122449c55878SDavid Wu #define PX30_SCHMITT_PINS_PER_PMU_REG		16
122549c55878SDavid Wu #define PX30_SCHMITT_BANK_STRIDE		16
122649c55878SDavid Wu #define PX30_SCHMITT_PINS_PER_GRF_REG		8
122749c55878SDavid Wu 
122849c55878SDavid Wu static int px30_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank,
122949c55878SDavid Wu 					 int pin_num,
123049c55878SDavid Wu 					 struct regmap **regmap,
123149c55878SDavid Wu 					 int *reg, u8 *bit)
123249c55878SDavid Wu {
123349c55878SDavid Wu 	struct rockchip_pinctrl_priv *priv = bank->priv;
123449c55878SDavid Wu 	int pins_per_reg;
123549c55878SDavid Wu 
123649c55878SDavid Wu 	if (bank->bank_num == 0) {
123749c55878SDavid Wu 		*regmap = priv->regmap_pmu;
123849c55878SDavid Wu 		*reg = PX30_SCHMITT_PMU_OFFSET;
123949c55878SDavid Wu 		pins_per_reg = PX30_SCHMITT_PINS_PER_PMU_REG;
124049c55878SDavid Wu 	} else {
124149c55878SDavid Wu 		*regmap = priv->regmap_base;
124249c55878SDavid Wu 		*reg = PX30_SCHMITT_GRF_OFFSET;
124349c55878SDavid Wu 		pins_per_reg = PX30_SCHMITT_PINS_PER_GRF_REG;
124449c55878SDavid Wu 		*reg += (bank->bank_num - 1) * PX30_SCHMITT_BANK_STRIDE;
124549c55878SDavid Wu 	}
124649c55878SDavid Wu 	*reg += ((pin_num / pins_per_reg) * 4);
124749c55878SDavid Wu 	*bit = pin_num % pins_per_reg;
124849c55878SDavid Wu 
124949c55878SDavid Wu 	return 0;
125049c55878SDavid Wu }
125149c55878SDavid Wu 
125249c55878SDavid Wu #define RV1108_PULL_PMU_OFFSET		0x10
125349c55878SDavid Wu #define RV1108_PULL_OFFSET		0x110
125449c55878SDavid Wu #define RV1108_PULL_PINS_PER_REG	8
125549c55878SDavid Wu #define RV1108_PULL_BITS_PER_PIN	2
125649c55878SDavid Wu #define RV1108_PULL_BANK_STRIDE		16
125749c55878SDavid Wu 
125849c55878SDavid Wu static void rv1108_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
125949c55878SDavid Wu 					 int pin_num, struct regmap **regmap,
126049c55878SDavid Wu 					 int *reg, u8 *bit)
126149c55878SDavid Wu {
126249c55878SDavid Wu 	struct rockchip_pinctrl_priv *priv = bank->priv;
126349c55878SDavid Wu 
126449c55878SDavid Wu 	/* The first 24 pins of the first bank are located in PMU */
126549c55878SDavid Wu 	if (bank->bank_num == 0) {
126649c55878SDavid Wu 		*regmap = priv->regmap_pmu;
126749c55878SDavid Wu 		*reg = RV1108_PULL_PMU_OFFSET;
126849c55878SDavid Wu 	} else {
126949c55878SDavid Wu 		*reg = RV1108_PULL_OFFSET;
127049c55878SDavid Wu 		*regmap = priv->regmap_base;
127149c55878SDavid Wu 		/* correct the offset, as we're starting with the 2nd bank */
127249c55878SDavid Wu 		*reg -= 0x10;
127349c55878SDavid Wu 		*reg += bank->bank_num * RV1108_PULL_BANK_STRIDE;
127449c55878SDavid Wu 	}
127549c55878SDavid Wu 
127649c55878SDavid Wu 	*reg += ((pin_num / RV1108_PULL_PINS_PER_REG) * 4);
127749c55878SDavid Wu 	*bit = (pin_num % RV1108_PULL_PINS_PER_REG);
127849c55878SDavid Wu 	*bit *= RV1108_PULL_BITS_PER_PIN;
127949c55878SDavid Wu }
128049c55878SDavid Wu 
128149c55878SDavid Wu #define RV1108_DRV_PMU_OFFSET		0x20
128249c55878SDavid Wu #define RV1108_DRV_GRF_OFFSET		0x210
128349c55878SDavid Wu #define RV1108_DRV_BITS_PER_PIN		2
128449c55878SDavid Wu #define RV1108_DRV_PINS_PER_REG		8
128549c55878SDavid Wu #define RV1108_DRV_BANK_STRIDE		16
128649c55878SDavid Wu 
128749c55878SDavid Wu static void rv1108_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
128849c55878SDavid Wu 					int pin_num, struct regmap **regmap,
128949c55878SDavid Wu 					int *reg, u8 *bit)
129049c55878SDavid Wu {
129149c55878SDavid Wu 	struct rockchip_pinctrl_priv *priv = bank->priv;
129249c55878SDavid Wu 
129349c55878SDavid Wu 	/* The first 24 pins of the first bank are located in PMU */
129449c55878SDavid Wu 	if (bank->bank_num == 0) {
129549c55878SDavid Wu 		*regmap = priv->regmap_pmu;
129649c55878SDavid Wu 		*reg = RV1108_DRV_PMU_OFFSET;
129749c55878SDavid Wu 	} else {
129849c55878SDavid Wu 		*regmap = priv->regmap_base;
129949c55878SDavid Wu 		*reg = RV1108_DRV_GRF_OFFSET;
130049c55878SDavid Wu 
130149c55878SDavid Wu 		/* correct the offset, as we're starting with the 2nd bank */
130249c55878SDavid Wu 		*reg -= 0x10;
130349c55878SDavid Wu 		*reg += bank->bank_num * RV1108_DRV_BANK_STRIDE;
130449c55878SDavid Wu 	}
130549c55878SDavid Wu 
130649c55878SDavid Wu 	*reg += ((pin_num / RV1108_DRV_PINS_PER_REG) * 4);
130749c55878SDavid Wu 	*bit = pin_num % RV1108_DRV_PINS_PER_REG;
130849c55878SDavid Wu 	*bit *= RV1108_DRV_BITS_PER_PIN;
130949c55878SDavid Wu }
131049c55878SDavid Wu 
131149c55878SDavid Wu #define RV1108_SCHMITT_PMU_OFFSET		0x30
131249c55878SDavid Wu #define RV1108_SCHMITT_GRF_OFFSET		0x388
131349c55878SDavid Wu #define RV1108_SCHMITT_BANK_STRIDE		8
131449c55878SDavid Wu #define RV1108_SCHMITT_PINS_PER_GRF_REG		16
131549c55878SDavid Wu #define RV1108_SCHMITT_PINS_PER_PMU_REG		8
131649c55878SDavid Wu 
131749c55878SDavid Wu static int rv1108_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank,
131849c55878SDavid Wu 					   int pin_num,
131949c55878SDavid Wu 					   struct regmap **regmap,
132049c55878SDavid Wu 					   int *reg, u8 *bit)
132149c55878SDavid Wu {
132249c55878SDavid Wu 	struct rockchip_pinctrl_priv *priv = bank->priv;
132349c55878SDavid Wu 	int pins_per_reg;
132449c55878SDavid Wu 
132549c55878SDavid Wu 	if (bank->bank_num == 0) {
132649c55878SDavid Wu 		*regmap = priv->regmap_pmu;
132749c55878SDavid Wu 		*reg = RV1108_SCHMITT_PMU_OFFSET;
132849c55878SDavid Wu 		pins_per_reg = RV1108_SCHMITT_PINS_PER_PMU_REG;
132949c55878SDavid Wu 	} else {
133049c55878SDavid Wu 		*regmap = priv->regmap_base;
133149c55878SDavid Wu 		*reg = RV1108_SCHMITT_GRF_OFFSET;
133249c55878SDavid Wu 		pins_per_reg = RV1108_SCHMITT_PINS_PER_GRF_REG;
133349c55878SDavid Wu 		*reg += (bank->bank_num  - 1) * RV1108_SCHMITT_BANK_STRIDE;
133449c55878SDavid Wu 	}
133549c55878SDavid Wu 	*reg += ((pin_num / pins_per_reg) * 4);
133649c55878SDavid Wu 	*bit = pin_num % pins_per_reg;
133749c55878SDavid Wu 
133849c55878SDavid Wu 	return 0;
133949c55878SDavid Wu }
134049c55878SDavid Wu 
134149c55878SDavid Wu #define RK2928_PULL_OFFSET		0x118
134249c55878SDavid Wu #define RK2928_PULL_PINS_PER_REG	16
134349c55878SDavid Wu #define RK2928_PULL_BANK_STRIDE		8
134449c55878SDavid Wu 
134549c55878SDavid Wu static void rk2928_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
134649c55878SDavid Wu 					 int pin_num, struct regmap **regmap,
134749c55878SDavid Wu 					 int *reg, u8 *bit)
134849c55878SDavid Wu {
134949c55878SDavid Wu 	struct rockchip_pinctrl_priv *priv = bank->priv;
135049c55878SDavid Wu 
135149c55878SDavid Wu 	*regmap = priv->regmap_base;
135249c55878SDavid Wu 	*reg = RK2928_PULL_OFFSET;
135349c55878SDavid Wu 	*reg += bank->bank_num * RK2928_PULL_BANK_STRIDE;
135449c55878SDavid Wu 	*reg += (pin_num / RK2928_PULL_PINS_PER_REG) * 4;
135549c55878SDavid Wu 
135649c55878SDavid Wu 	*bit = pin_num % RK2928_PULL_PINS_PER_REG;
135749c55878SDavid Wu };
135849c55878SDavid Wu 
135949c55878SDavid Wu #define RK3128_PULL_OFFSET	0x118
136049c55878SDavid Wu 
136149c55878SDavid Wu static void rk3128_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
136249c55878SDavid Wu 					 int pin_num, struct regmap **regmap,
136349c55878SDavid Wu 					 int *reg, u8 *bit)
136449c55878SDavid Wu {
136549c55878SDavid Wu 	struct rockchip_pinctrl_priv *priv = bank->priv;
136649c55878SDavid Wu 
136749c55878SDavid Wu 	*regmap = priv->regmap_base;
136849c55878SDavid Wu 	*reg = RK3128_PULL_OFFSET;
136949c55878SDavid Wu 	*reg += bank->bank_num * RK2928_PULL_BANK_STRIDE;
137049c55878SDavid Wu 	*reg += ((pin_num / RK2928_PULL_PINS_PER_REG) * 4);
137149c55878SDavid Wu 
137249c55878SDavid Wu 	*bit = pin_num % RK2928_PULL_PINS_PER_REG;
137349c55878SDavid Wu }
137449c55878SDavid Wu 
137549c55878SDavid Wu #define RK3188_PULL_OFFSET		0x164
137649c55878SDavid Wu #define RK3188_PULL_BITS_PER_PIN	2
137749c55878SDavid Wu #define RK3188_PULL_PINS_PER_REG	8
137849c55878SDavid Wu #define RK3188_PULL_BANK_STRIDE		16
137949c55878SDavid Wu #define RK3188_PULL_PMU_OFFSET		0x64
138049c55878SDavid Wu 
138149c55878SDavid Wu static void rk3188_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
138249c55878SDavid Wu 					 int pin_num, struct regmap **regmap,
138349c55878SDavid Wu 					 int *reg, u8 *bit)
138449c55878SDavid Wu {
138549c55878SDavid Wu 	struct rockchip_pinctrl_priv *priv = bank->priv;
138649c55878SDavid Wu 
138749c55878SDavid Wu 	/* The first 12 pins of the first bank are located elsewhere */
138849c55878SDavid Wu 	if (bank->bank_num == 0 && pin_num < 12) {
138949c55878SDavid Wu 		*regmap = priv->regmap_pmu;
139049c55878SDavid Wu 		*reg = RK3188_PULL_PMU_OFFSET;
139149c55878SDavid Wu 
139249c55878SDavid Wu 		*reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4);
139349c55878SDavid Wu 		*bit = pin_num % RK3188_PULL_PINS_PER_REG;
139449c55878SDavid Wu 		*bit *= RK3188_PULL_BITS_PER_PIN;
139549c55878SDavid Wu 	} else {
139649c55878SDavid Wu 		*regmap = priv->regmap_base;
139749c55878SDavid Wu 		*reg = RK3188_PULL_OFFSET;
139849c55878SDavid Wu 
139949c55878SDavid Wu 		/* correct the offset, as it is the 2nd pull register */
140049c55878SDavid Wu 		*reg -= 4;
140149c55878SDavid Wu 		*reg += bank->bank_num * RK3188_PULL_BANK_STRIDE;
140249c55878SDavid Wu 		*reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4);
140349c55878SDavid Wu 
140449c55878SDavid Wu 		/*
140549c55878SDavid Wu 		 * The bits in these registers have an inverse ordering
140649c55878SDavid Wu 		 * with the lowest pin being in bits 15:14 and the highest
140749c55878SDavid Wu 		 * pin in bits 1:0
140849c55878SDavid Wu 		 */
140949c55878SDavid Wu 		*bit = 7 - (pin_num % RK3188_PULL_PINS_PER_REG);
141049c55878SDavid Wu 		*bit *= RK3188_PULL_BITS_PER_PIN;
141149c55878SDavid Wu 	}
141249c55878SDavid Wu }
141349c55878SDavid Wu 
141449c55878SDavid Wu #define RK3288_PULL_OFFSET		0x140
141549c55878SDavid Wu static void rk3288_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
141649c55878SDavid Wu 					 int pin_num, struct regmap **regmap,
141749c55878SDavid Wu 					 int *reg, u8 *bit)
141849c55878SDavid Wu {
141949c55878SDavid Wu 	struct rockchip_pinctrl_priv *priv = bank->priv;
142049c55878SDavid Wu 
142149c55878SDavid Wu 	/* The first 24 pins of the first bank are located in PMU */
142249c55878SDavid Wu 	if (bank->bank_num == 0) {
142349c55878SDavid Wu 		*regmap = priv->regmap_pmu;
142449c55878SDavid Wu 		*reg = RK3188_PULL_PMU_OFFSET;
142549c55878SDavid Wu 
142649c55878SDavid Wu 		*reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4);
142749c55878SDavid Wu 		*bit = pin_num % RK3188_PULL_PINS_PER_REG;
142849c55878SDavid Wu 		*bit *= RK3188_PULL_BITS_PER_PIN;
142949c55878SDavid Wu 	} else {
143049c55878SDavid Wu 		*regmap = priv->regmap_base;
143149c55878SDavid Wu 		*reg = RK3288_PULL_OFFSET;
143249c55878SDavid Wu 
143349c55878SDavid Wu 		/* correct the offset, as we're starting with the 2nd bank */
143449c55878SDavid Wu 		*reg -= 0x10;
143549c55878SDavid Wu 		*reg += bank->bank_num * RK3188_PULL_BANK_STRIDE;
143649c55878SDavid Wu 		*reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4);
143749c55878SDavid Wu 
143849c55878SDavid Wu 		*bit = (pin_num % RK3188_PULL_PINS_PER_REG);
143949c55878SDavid Wu 		*bit *= RK3188_PULL_BITS_PER_PIN;
144049c55878SDavid Wu 	}
144149c55878SDavid Wu }
144249c55878SDavid Wu 
144349c55878SDavid Wu #define RK3288_DRV_PMU_OFFSET		0x70
144449c55878SDavid Wu #define RK3288_DRV_GRF_OFFSET		0x1c0
144549c55878SDavid Wu #define RK3288_DRV_BITS_PER_PIN		2
144649c55878SDavid Wu #define RK3288_DRV_PINS_PER_REG		8
144749c55878SDavid Wu #define RK3288_DRV_BANK_STRIDE		16
144849c55878SDavid Wu 
144949c55878SDavid Wu static void rk3288_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
145049c55878SDavid Wu 					int pin_num, struct regmap **regmap,
145149c55878SDavid Wu 					int *reg, u8 *bit)
145249c55878SDavid Wu {
145349c55878SDavid Wu 	struct rockchip_pinctrl_priv *priv = bank->priv;
145449c55878SDavid Wu 
145549c55878SDavid Wu 	/* The first 24 pins of the first bank are located in PMU */
145649c55878SDavid Wu 	if (bank->bank_num == 0) {
145749c55878SDavid Wu 		*regmap = priv->regmap_pmu;
145849c55878SDavid Wu 		*reg = RK3288_DRV_PMU_OFFSET;
145949c55878SDavid Wu 
146049c55878SDavid Wu 		*reg += ((pin_num / RK3288_DRV_PINS_PER_REG) * 4);
146149c55878SDavid Wu 		*bit = pin_num % RK3288_DRV_PINS_PER_REG;
146249c55878SDavid Wu 		*bit *= RK3288_DRV_BITS_PER_PIN;
146349c55878SDavid Wu 	} else {
146449c55878SDavid Wu 		*regmap = priv->regmap_base;
146549c55878SDavid Wu 		*reg = RK3288_DRV_GRF_OFFSET;
146649c55878SDavid Wu 
146749c55878SDavid Wu 		/* correct the offset, as we're starting with the 2nd bank */
146849c55878SDavid Wu 		*reg -= 0x10;
146949c55878SDavid Wu 		*reg += bank->bank_num * RK3288_DRV_BANK_STRIDE;
147049c55878SDavid Wu 		*reg += ((pin_num / RK3288_DRV_PINS_PER_REG) * 4);
147149c55878SDavid Wu 
147249c55878SDavid Wu 		*bit = (pin_num % RK3288_DRV_PINS_PER_REG);
147349c55878SDavid Wu 		*bit *= RK3288_DRV_BITS_PER_PIN;
147449c55878SDavid Wu 	}
147549c55878SDavid Wu }
147649c55878SDavid Wu 
147749c55878SDavid Wu #define RK3228_PULL_OFFSET		0x100
147849c55878SDavid Wu 
147949c55878SDavid Wu static void rk3228_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
148049c55878SDavid Wu 					 int pin_num, struct regmap **regmap,
148149c55878SDavid Wu 					 int *reg, u8 *bit)
148249c55878SDavid Wu {
148349c55878SDavid Wu 	struct rockchip_pinctrl_priv *priv = bank->priv;
148449c55878SDavid Wu 
148549c55878SDavid Wu 	*regmap = priv->regmap_base;
148649c55878SDavid Wu 	*reg = RK3228_PULL_OFFSET;
148749c55878SDavid Wu 	*reg += bank->bank_num * RK3188_PULL_BANK_STRIDE;
148849c55878SDavid Wu 	*reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4);
148949c55878SDavid Wu 
149049c55878SDavid Wu 	*bit = (pin_num % RK3188_PULL_PINS_PER_REG);
149149c55878SDavid Wu 	*bit *= RK3188_PULL_BITS_PER_PIN;
149249c55878SDavid Wu }
149349c55878SDavid Wu 
149449c55878SDavid Wu #define RK3228_DRV_GRF_OFFSET		0x200
149549c55878SDavid Wu 
149649c55878SDavid Wu static void rk3228_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
149749c55878SDavid Wu 					int pin_num, struct regmap **regmap,
149849c55878SDavid Wu 					int *reg, u8 *bit)
149949c55878SDavid Wu {
150049c55878SDavid Wu 	struct rockchip_pinctrl_priv *priv = bank->priv;
150149c55878SDavid Wu 
150249c55878SDavid Wu 	*regmap = priv->regmap_base;
150349c55878SDavid Wu 	*reg = RK3228_DRV_GRF_OFFSET;
150449c55878SDavid Wu 	*reg += bank->bank_num * RK3288_DRV_BANK_STRIDE;
150549c55878SDavid Wu 	*reg += ((pin_num / RK3288_DRV_PINS_PER_REG) * 4);
150649c55878SDavid Wu 
150749c55878SDavid Wu 	*bit = (pin_num % RK3288_DRV_PINS_PER_REG);
150849c55878SDavid Wu 	*bit *= RK3288_DRV_BITS_PER_PIN;
150949c55878SDavid Wu }
151049c55878SDavid Wu 
1511b3077611SDavid Wu #define RK3308_PULL_OFFSET		0xa0
1512b3077611SDavid Wu 
1513b3077611SDavid Wu static void rk3308_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
1514b3077611SDavid Wu 					 int pin_num, struct regmap **regmap,
1515b3077611SDavid Wu 					 int *reg, u8 *bit)
1516b3077611SDavid Wu {
1517b3077611SDavid Wu 	struct rockchip_pinctrl_priv *priv = bank->priv;
1518b3077611SDavid Wu 
1519b3077611SDavid Wu 	*regmap = priv->regmap_base;
1520b3077611SDavid Wu 	*reg = RK3308_PULL_OFFSET;
1521b3077611SDavid Wu 	*reg += bank->bank_num * RK3188_PULL_BANK_STRIDE;
1522b3077611SDavid Wu 	*reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4);
1523b3077611SDavid Wu 
1524b3077611SDavid Wu 	*bit = (pin_num % RK3188_PULL_PINS_PER_REG);
1525b3077611SDavid Wu 	*bit *= RK3188_PULL_BITS_PER_PIN;
1526b3077611SDavid Wu }
1527b3077611SDavid Wu 
1528b3077611SDavid Wu #define RK3308_DRV_GRF_OFFSET		0x100
1529b3077611SDavid Wu 
1530b3077611SDavid Wu static void rk3308_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
1531b3077611SDavid Wu 					int pin_num, struct regmap **regmap,
1532b3077611SDavid Wu 					int *reg, u8 *bit)
1533b3077611SDavid Wu {
1534b3077611SDavid Wu 	struct rockchip_pinctrl_priv *priv = bank->priv;
1535b3077611SDavid Wu 
1536b3077611SDavid Wu 	*regmap = priv->regmap_base;
1537b3077611SDavid Wu 	*reg = RK3308_DRV_GRF_OFFSET;
1538b3077611SDavid Wu 	*reg += bank->bank_num * RK3288_DRV_BANK_STRIDE;
1539b3077611SDavid Wu 	*reg += ((pin_num / RK3288_DRV_PINS_PER_REG) * 4);
1540b3077611SDavid Wu 
1541b3077611SDavid Wu 	*bit = (pin_num % RK3288_DRV_PINS_PER_REG);
1542b3077611SDavid Wu 	*bit *= RK3288_DRV_BITS_PER_PIN;
1543b3077611SDavid Wu }
1544b3077611SDavid Wu 
1545b3077611SDavid Wu #define RK3308_SCHMITT_PINS_PER_REG	8
1546b3077611SDavid Wu #define RK3308_SCHMITT_BANK_STRIDE	16
1547b3077611SDavid Wu #define RK3308_SCHMITT_GRF_OFFSET	0x1a0
1548b3077611SDavid Wu 
1549b3077611SDavid Wu static int rk3308_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank,
1550b3077611SDavid Wu 					   int pin_num,
1551b3077611SDavid Wu 					   struct regmap **regmap,
1552b3077611SDavid Wu 					   int *reg, u8 *bit)
1553b3077611SDavid Wu {
1554b3077611SDavid Wu 	struct rockchip_pinctrl_priv *priv = bank->priv;
1555b3077611SDavid Wu 
1556b3077611SDavid Wu 	*regmap = priv->regmap_base;
1557b3077611SDavid Wu 	*reg = RK3308_SCHMITT_GRF_OFFSET;
1558b3077611SDavid Wu 
1559b3077611SDavid Wu 	*reg += bank->bank_num * RK3308_SCHMITT_BANK_STRIDE;
1560b3077611SDavid Wu 	*reg += ((pin_num / RK3308_SCHMITT_PINS_PER_REG) * 4);
1561b3077611SDavid Wu 	*bit = pin_num % RK3308_SCHMITT_PINS_PER_REG;
1562b3077611SDavid Wu 
1563b3077611SDavid Wu 	return 0;
1564b3077611SDavid Wu }
1565b3077611SDavid Wu 
156649c55878SDavid Wu #define RK3368_PULL_GRF_OFFSET		0x100
156749c55878SDavid Wu #define RK3368_PULL_PMU_OFFSET		0x10
156849c55878SDavid Wu 
156949c55878SDavid Wu static void rk3368_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
157049c55878SDavid Wu 					 int pin_num, struct regmap **regmap,
157149c55878SDavid Wu 					 int *reg, u8 *bit)
157249c55878SDavid Wu {
157349c55878SDavid Wu 	struct rockchip_pinctrl_priv *priv = bank->priv;
157449c55878SDavid Wu 
157549c55878SDavid Wu 	/* The first 32 pins of the first bank are located in PMU */
157649c55878SDavid Wu 	if (bank->bank_num == 0) {
157749c55878SDavid Wu 		*regmap = priv->regmap_pmu;
157849c55878SDavid Wu 		*reg = RK3368_PULL_PMU_OFFSET;
157949c55878SDavid Wu 
158049c55878SDavid Wu 		*reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4);
158149c55878SDavid Wu 		*bit = pin_num % RK3188_PULL_PINS_PER_REG;
158249c55878SDavid Wu 		*bit *= RK3188_PULL_BITS_PER_PIN;
158349c55878SDavid Wu 	} else {
158449c55878SDavid Wu 		*regmap = priv->regmap_base;
158549c55878SDavid Wu 		*reg = RK3368_PULL_GRF_OFFSET;
158649c55878SDavid Wu 
158749c55878SDavid Wu 		/* correct the offset, as we're starting with the 2nd bank */
158849c55878SDavid Wu 		*reg -= 0x10;
158949c55878SDavid Wu 		*reg += bank->bank_num * RK3188_PULL_BANK_STRIDE;
159049c55878SDavid Wu 		*reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4);
159149c55878SDavid Wu 
159249c55878SDavid Wu 		*bit = (pin_num % RK3188_PULL_PINS_PER_REG);
159349c55878SDavid Wu 		*bit *= RK3188_PULL_BITS_PER_PIN;
159449c55878SDavid Wu 	}
159549c55878SDavid Wu }
159649c55878SDavid Wu 
159749c55878SDavid Wu #define RK3368_DRV_PMU_OFFSET		0x20
159849c55878SDavid Wu #define RK3368_DRV_GRF_OFFSET		0x200
159949c55878SDavid Wu 
160049c55878SDavid Wu static void rk3368_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
160149c55878SDavid Wu 					int pin_num, struct regmap **regmap,
160249c55878SDavid Wu 					int *reg, u8 *bit)
160349c55878SDavid Wu {
160449c55878SDavid Wu 	struct rockchip_pinctrl_priv *priv = bank->priv;
160549c55878SDavid Wu 
160649c55878SDavid Wu 	/* The first 32 pins of the first bank are located in PMU */
160749c55878SDavid Wu 	if (bank->bank_num == 0) {
160849c55878SDavid Wu 		*regmap = priv->regmap_pmu;
160949c55878SDavid Wu 		*reg = RK3368_DRV_PMU_OFFSET;
161049c55878SDavid Wu 
161149c55878SDavid Wu 		*reg += ((pin_num / RK3288_DRV_PINS_PER_REG) * 4);
161249c55878SDavid Wu 		*bit = pin_num % RK3288_DRV_PINS_PER_REG;
161349c55878SDavid Wu 		*bit *= RK3288_DRV_BITS_PER_PIN;
161449c55878SDavid Wu 	} else {
161549c55878SDavid Wu 		*regmap = priv->regmap_base;
161649c55878SDavid Wu 		*reg = RK3368_DRV_GRF_OFFSET;
161749c55878SDavid Wu 
161849c55878SDavid Wu 		/* correct the offset, as we're starting with the 2nd bank */
161949c55878SDavid Wu 		*reg -= 0x10;
162049c55878SDavid Wu 		*reg += bank->bank_num * RK3288_DRV_BANK_STRIDE;
162149c55878SDavid Wu 		*reg += ((pin_num / RK3288_DRV_PINS_PER_REG) * 4);
162249c55878SDavid Wu 
162349c55878SDavid Wu 		*bit = (pin_num % RK3288_DRV_PINS_PER_REG);
162449c55878SDavid Wu 		*bit *= RK3288_DRV_BITS_PER_PIN;
162549c55878SDavid Wu 	}
162649c55878SDavid Wu }
162749c55878SDavid Wu 
162849c55878SDavid Wu #define RK3399_PULL_GRF_OFFSET		0xe040
162949c55878SDavid Wu #define RK3399_PULL_PMU_OFFSET		0x40
163049c55878SDavid Wu #define RK3399_DRV_3BITS_PER_PIN	3
163149c55878SDavid Wu 
163249c55878SDavid Wu static void rk3399_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
163349c55878SDavid Wu 					 int pin_num, struct regmap **regmap,
163449c55878SDavid Wu 					 int *reg, u8 *bit)
163549c55878SDavid Wu {
163649c55878SDavid Wu 	struct rockchip_pinctrl_priv *priv = bank->priv;
163749c55878SDavid Wu 
163849c55878SDavid Wu 	/* The bank0:16 and bank1:32 pins are located in PMU */
163949c55878SDavid Wu 	if ((bank->bank_num == 0) || (bank->bank_num == 1)) {
164049c55878SDavid Wu 		*regmap = priv->regmap_pmu;
164149c55878SDavid Wu 		*reg = RK3399_PULL_PMU_OFFSET;
164249c55878SDavid Wu 
164349c55878SDavid Wu 		*reg += bank->bank_num * RK3188_PULL_BANK_STRIDE;
164449c55878SDavid Wu 
164549c55878SDavid Wu 		*reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4);
164649c55878SDavid Wu 		*bit = pin_num % RK3188_PULL_PINS_PER_REG;
164749c55878SDavid Wu 		*bit *= RK3188_PULL_BITS_PER_PIN;
164849c55878SDavid Wu 	} else {
164949c55878SDavid Wu 		*regmap = priv->regmap_base;
165049c55878SDavid Wu 		*reg = RK3399_PULL_GRF_OFFSET;
165149c55878SDavid Wu 
165249c55878SDavid Wu 		/* correct the offset, as we're starting with the 3rd bank */
165349c55878SDavid Wu 		*reg -= 0x20;
165449c55878SDavid Wu 		*reg += bank->bank_num * RK3188_PULL_BANK_STRIDE;
165549c55878SDavid Wu 		*reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4);
165649c55878SDavid Wu 
165749c55878SDavid Wu 		*bit = (pin_num % RK3188_PULL_PINS_PER_REG);
165849c55878SDavid Wu 		*bit *= RK3188_PULL_BITS_PER_PIN;
165949c55878SDavid Wu 	}
166049c55878SDavid Wu }
166149c55878SDavid Wu 
166249c55878SDavid Wu static void rk3399_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
166349c55878SDavid Wu 					int pin_num, struct regmap **regmap,
166449c55878SDavid Wu 					int *reg, u8 *bit)
166549c55878SDavid Wu {
166649c55878SDavid Wu 	struct rockchip_pinctrl_priv *priv = bank->priv;
166749c55878SDavid Wu 	int drv_num = (pin_num / 8);
166849c55878SDavid Wu 
166949c55878SDavid Wu 	/*  The bank0:16 and bank1:32 pins are located in PMU */
167049c55878SDavid Wu 	if ((bank->bank_num == 0) || (bank->bank_num == 1))
167149c55878SDavid Wu 		*regmap = priv->regmap_pmu;
167249c55878SDavid Wu 	else
167349c55878SDavid Wu 		*regmap = priv->regmap_base;
167449c55878SDavid Wu 
167549c55878SDavid Wu 	*reg = bank->drv[drv_num].offset;
167649c55878SDavid Wu 	if ((bank->drv[drv_num].drv_type == DRV_TYPE_IO_1V8_3V0_AUTO) ||
167749c55878SDavid Wu 	    (bank->drv[drv_num].drv_type == DRV_TYPE_IO_3V3_ONLY))
167849c55878SDavid Wu 		*bit = (pin_num % 8) * 3;
167949c55878SDavid Wu 	else
168049c55878SDavid Wu 		*bit = (pin_num % 8) * 2;
168149c55878SDavid Wu }
168249c55878SDavid Wu 
168349c55878SDavid Wu static int rockchip_perpin_drv_list[DRV_TYPE_MAX][8] = {
168449c55878SDavid Wu 	{ 2, 4, 8, 12, -1, -1, -1, -1 },
168549c55878SDavid Wu 	{ 3, 6, 9, 12, -1, -1, -1, -1 },
168649c55878SDavid Wu 	{ 5, 10, 15, 20, -1, -1, -1, -1 },
168749c55878SDavid Wu 	{ 4, 6, 8, 10, 12, 14, 16, 18 },
168849c55878SDavid Wu 	{ 4, 7, 10, 13, 16, 19, 22, 26 }
168949c55878SDavid Wu };
169049c55878SDavid Wu 
169149c55878SDavid Wu static int rockchip_set_drive_perpin(struct rockchip_pin_bank *bank,
169249c55878SDavid Wu 				     int pin_num, int strength)
169349c55878SDavid Wu {
169449c55878SDavid Wu 	struct rockchip_pinctrl_priv *priv = bank->priv;
169549c55878SDavid Wu 	struct rockchip_pin_ctrl *ctrl = priv->ctrl;
169649c55878SDavid Wu 	struct regmap *regmap;
169749c55878SDavid Wu 	int reg, ret, i;
169849c55878SDavid Wu 	u32 data, rmask_bits, temp;
169949c55878SDavid Wu 	u8 bit;
1700*55a89bc6SDavid Wu 	int drv_type = bank->drv[pin_num / 8].drv_type & DRV_TYPE_IO_MASK;
170149c55878SDavid Wu 
170249c55878SDavid Wu 	debug("setting drive of GPIO%d-%d to %d\n", bank->bank_num,
170349c55878SDavid Wu 	      pin_num, strength);
170449c55878SDavid Wu 
170549c55878SDavid Wu 	ctrl->drv_calc_reg(bank, pin_num, &regmap, &reg, &bit);
170649c55878SDavid Wu 
170749c55878SDavid Wu 	ret = -EINVAL;
170849c55878SDavid Wu 	for (i = 0; i < ARRAY_SIZE(rockchip_perpin_drv_list[drv_type]); i++) {
170949c55878SDavid Wu 		if (rockchip_perpin_drv_list[drv_type][i] == strength) {
171049c55878SDavid Wu 			ret = i;
171149c55878SDavid Wu 			break;
171249c55878SDavid Wu 		} else if (rockchip_perpin_drv_list[drv_type][i] < 0) {
171349c55878SDavid Wu 			ret = rockchip_perpin_drv_list[drv_type][i];
171449c55878SDavid Wu 			break;
171549c55878SDavid Wu 		}
171649c55878SDavid Wu 	}
171749c55878SDavid Wu 
171849c55878SDavid Wu 	if (ret < 0) {
171949c55878SDavid Wu 		debug("unsupported driver strength %d\n", strength);
172049c55878SDavid Wu 		return ret;
172149c55878SDavid Wu 	}
172249c55878SDavid Wu 
172349c55878SDavid Wu 	switch (drv_type) {
172449c55878SDavid Wu 	case DRV_TYPE_IO_1V8_3V0_AUTO:
172549c55878SDavid Wu 	case DRV_TYPE_IO_3V3_ONLY:
172649c55878SDavid Wu 		rmask_bits = RK3399_DRV_3BITS_PER_PIN;
172749c55878SDavid Wu 		switch (bit) {
172849c55878SDavid Wu 		case 0 ... 12:
172949c55878SDavid Wu 			/* regular case, nothing to do */
173049c55878SDavid Wu 			break;
173149c55878SDavid Wu 		case 15:
173249c55878SDavid Wu 			/*
173349c55878SDavid Wu 			 * drive-strength offset is special, as it is spread
173449c55878SDavid Wu 			 * over 2 registers, the bit data[15] contains bit 0
173549c55878SDavid Wu 			 * of the value while temp[1:0] contains bits 2 and 1
173649c55878SDavid Wu 			 */
173749c55878SDavid Wu 			data = (ret & 0x1) << 15;
173849c55878SDavid Wu 			temp = (ret >> 0x1) & 0x3;
173949c55878SDavid Wu 
174049c55878SDavid Wu 			data |= BIT(31);
174149c55878SDavid Wu 			ret = regmap_write(regmap, reg, data);
174249c55878SDavid Wu 			if (ret)
174349c55878SDavid Wu 				return ret;
174449c55878SDavid Wu 
174549c55878SDavid Wu 			temp |= (0x3 << 16);
174649c55878SDavid Wu 			reg += 0x4;
174749c55878SDavid Wu 			ret = regmap_write(regmap, reg, temp);
174849c55878SDavid Wu 
174949c55878SDavid Wu 			return ret;
175049c55878SDavid Wu 		case 18 ... 21:
175149c55878SDavid Wu 			/* setting fully enclosed in the second register */
175249c55878SDavid Wu 			reg += 4;
175349c55878SDavid Wu 			bit -= 16;
175449c55878SDavid Wu 			break;
175549c55878SDavid Wu 		default:
175649c55878SDavid Wu 			debug("unsupported bit: %d for pinctrl drive type: %d\n",
175749c55878SDavid Wu 			      bit, drv_type);
175849c55878SDavid Wu 			return -EINVAL;
175949c55878SDavid Wu 		}
176049c55878SDavid Wu 		break;
176149c55878SDavid Wu 	case DRV_TYPE_IO_DEFAULT:
176249c55878SDavid Wu 	case DRV_TYPE_IO_1V8_OR_3V0:
176349c55878SDavid Wu 	case DRV_TYPE_IO_1V8_ONLY:
176449c55878SDavid Wu 		rmask_bits = RK3288_DRV_BITS_PER_PIN;
176549c55878SDavid Wu 		break;
176649c55878SDavid Wu 	default:
176749c55878SDavid Wu 		debug("unsupported pinctrl drive type: %d\n",
176849c55878SDavid Wu 		      drv_type);
176949c55878SDavid Wu 		return -EINVAL;
177049c55878SDavid Wu 	}
177149c55878SDavid Wu 
1772*55a89bc6SDavid Wu 	if (bank->drv[pin_num / 8].drv_type & DRV_TYPE_WRITABLE_32BIT) {
1773*55a89bc6SDavid Wu 		regmap_read(regmap, reg, &data);
1774*55a89bc6SDavid Wu 		data &= ~(((1 << rmask_bits) - 1) << bit);
1775*55a89bc6SDavid Wu 	} else {
177649c55878SDavid Wu 		/* enable the write to the equivalent lower bits */
177749c55878SDavid Wu 		data = ((1 << rmask_bits) - 1) << (bit + 16);
1778*55a89bc6SDavid Wu 	}
177949c55878SDavid Wu 
1780*55a89bc6SDavid Wu 	data |= (ret << bit);
178149c55878SDavid Wu 	ret = regmap_write(regmap, reg, data);
178249c55878SDavid Wu 	return ret;
178349c55878SDavid Wu }
178449c55878SDavid Wu 
178549c55878SDavid Wu static int rockchip_pull_list[PULL_TYPE_MAX][4] = {
178649c55878SDavid Wu 	{
178749c55878SDavid Wu 		PIN_CONFIG_BIAS_DISABLE,
178849c55878SDavid Wu 		PIN_CONFIG_BIAS_PULL_UP,
178949c55878SDavid Wu 		PIN_CONFIG_BIAS_PULL_DOWN,
179049c55878SDavid Wu 		PIN_CONFIG_BIAS_BUS_HOLD
179149c55878SDavid Wu 	},
179249c55878SDavid Wu 	{
179349c55878SDavid Wu 		PIN_CONFIG_BIAS_DISABLE,
179449c55878SDavid Wu 		PIN_CONFIG_BIAS_PULL_DOWN,
179549c55878SDavid Wu 		PIN_CONFIG_BIAS_DISABLE,
179649c55878SDavid Wu 		PIN_CONFIG_BIAS_PULL_UP
179749c55878SDavid Wu 	},
179849c55878SDavid Wu };
179949c55878SDavid Wu 
180049c55878SDavid Wu static int rockchip_set_pull(struct rockchip_pin_bank *bank,
180149c55878SDavid Wu 			     int pin_num, int pull)
180249c55878SDavid Wu {
180349c55878SDavid Wu 	struct rockchip_pinctrl_priv *priv = bank->priv;
180449c55878SDavid Wu 	struct rockchip_pin_ctrl *ctrl = priv->ctrl;
180549c55878SDavid Wu 	struct regmap *regmap;
180649c55878SDavid Wu 	int reg, ret, i, pull_type;
180749c55878SDavid Wu 	u8 bit;
180849c55878SDavid Wu 	u32 data;
180949c55878SDavid Wu 
181049c55878SDavid Wu 	debug("setting pull of GPIO%d-%d to %d\n", bank->bank_num,
181149c55878SDavid Wu 	      pin_num, pull);
181249c55878SDavid Wu 
181349c55878SDavid Wu 	/* rk3066b does support any pulls */
181449c55878SDavid Wu 	if (ctrl->type == RK3066B)
181549c55878SDavid Wu 		return pull ? -EINVAL : 0;
181649c55878SDavid Wu 
181749c55878SDavid Wu 	ctrl->pull_calc_reg(bank, pin_num, &regmap, &reg, &bit);
181849c55878SDavid Wu 
181949c55878SDavid Wu 	switch (ctrl->type) {
182049c55878SDavid Wu 	case RK2928:
182149c55878SDavid Wu 	case RK3128:
182249c55878SDavid Wu 		data = BIT(bit + 16);
182349c55878SDavid Wu 		if (pull == PIN_CONFIG_BIAS_DISABLE)
182449c55878SDavid Wu 			data |= BIT(bit);
182549c55878SDavid Wu 		ret = regmap_write(regmap, reg, data);
182649c55878SDavid Wu 		break;
182749c55878SDavid Wu 	case PX30:
182849c55878SDavid Wu 	case RV1108:
182949c55878SDavid Wu 	case RK3188:
183049c55878SDavid Wu 	case RK3288:
1831b3077611SDavid Wu 	case RK3308:
183249c55878SDavid Wu 	case RK3368:
183349c55878SDavid Wu 	case RK3399:
1834*55a89bc6SDavid Wu 		pull_type = bank->pull_type[pin_num / 8] & PULL_TYPE_IO_MASK;
183549c55878SDavid Wu 		ret = -EINVAL;
183649c55878SDavid Wu 		for (i = 0; i < ARRAY_SIZE(rockchip_pull_list[pull_type]);
183749c55878SDavid Wu 			i++) {
183849c55878SDavid Wu 			if (rockchip_pull_list[pull_type][i] == pull) {
183949c55878SDavid Wu 				ret = i;
184049c55878SDavid Wu 				break;
184149c55878SDavid Wu 			}
184249c55878SDavid Wu 		}
184349c55878SDavid Wu 
184449c55878SDavid Wu 		if (ret < 0) {
184549c55878SDavid Wu 			debug("unsupported pull setting %d\n", pull);
184649c55878SDavid Wu 			return ret;
184749c55878SDavid Wu 		}
184849c55878SDavid Wu 
1849*55a89bc6SDavid Wu 		if (bank->pull_type[pin_num / 8] & PULL_TYPE_WRITABLE_32BIT) {
1850*55a89bc6SDavid Wu 			regmap_read(regmap, reg, &data);
1851*55a89bc6SDavid Wu 			data &= ~(((1 << RK3188_PULL_BITS_PER_PIN) - 1) << bit);
1852*55a89bc6SDavid Wu 		} else {
185349c55878SDavid Wu 			/* enable the write to the equivalent lower bits */
185449c55878SDavid Wu 			data = ((1 << RK3188_PULL_BITS_PER_PIN) - 1) << (bit + 16);
1855*55a89bc6SDavid Wu 		}
185649c55878SDavid Wu 
1857*55a89bc6SDavid Wu 		data |= (ret << bit);
185849c55878SDavid Wu 		ret = regmap_write(regmap, reg, data);
185949c55878SDavid Wu 		break;
186049c55878SDavid Wu 	default:
186149c55878SDavid Wu 		debug("unsupported pinctrl type\n");
186249c55878SDavid Wu 		return -EINVAL;
186349c55878SDavid Wu 	}
186449c55878SDavid Wu 
186549c55878SDavid Wu 	return ret;
186649c55878SDavid Wu }
186749c55878SDavid Wu 
186849c55878SDavid Wu #define RK3328_SCHMITT_BITS_PER_PIN		1
186949c55878SDavid Wu #define RK3328_SCHMITT_PINS_PER_REG		16
187049c55878SDavid Wu #define RK3328_SCHMITT_BANK_STRIDE		8
187149c55878SDavid Wu #define RK3328_SCHMITT_GRF_OFFSET		0x380
187249c55878SDavid Wu 
187349c55878SDavid Wu static int rk3328_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank,
187449c55878SDavid Wu 					   int pin_num,
187549c55878SDavid Wu 					   struct regmap **regmap,
187649c55878SDavid Wu 					   int *reg, u8 *bit)
187749c55878SDavid Wu {
187849c55878SDavid Wu 	struct rockchip_pinctrl_priv *priv = bank->priv;
187949c55878SDavid Wu 
188049c55878SDavid Wu 	*regmap = priv->regmap_base;
188149c55878SDavid Wu 	*reg = RK3328_SCHMITT_GRF_OFFSET;
188249c55878SDavid Wu 
188349c55878SDavid Wu 	*reg += bank->bank_num * RK3328_SCHMITT_BANK_STRIDE;
188449c55878SDavid Wu 	*reg += ((pin_num / RK3328_SCHMITT_PINS_PER_REG) * 4);
188549c55878SDavid Wu 	*bit = pin_num % RK3328_SCHMITT_PINS_PER_REG;
188649c55878SDavid Wu 
188749c55878SDavid Wu 	return 0;
188849c55878SDavid Wu }
188949c55878SDavid Wu 
189049c55878SDavid Wu static int rockchip_set_schmitt(struct rockchip_pin_bank *bank,
189149c55878SDavid Wu 				int pin_num, int enable)
189249c55878SDavid Wu {
189349c55878SDavid Wu 	struct rockchip_pinctrl_priv *priv = bank->priv;
189449c55878SDavid Wu 	struct rockchip_pin_ctrl *ctrl = priv->ctrl;
189549c55878SDavid Wu 	struct regmap *regmap;
189649c55878SDavid Wu 	int reg, ret;
189749c55878SDavid Wu 	u8 bit;
189849c55878SDavid Wu 	u32 data;
189949c55878SDavid Wu 
190049c55878SDavid Wu 	debug("setting input schmitt of GPIO%d-%d to %d\n", bank->bank_num,
190149c55878SDavid Wu 	      pin_num, enable);
190249c55878SDavid Wu 
190349c55878SDavid Wu 	ret = ctrl->schmitt_calc_reg(bank, pin_num, &regmap, &reg, &bit);
190449c55878SDavid Wu 	if (ret)
190549c55878SDavid Wu 		return ret;
190649c55878SDavid Wu 
190749c55878SDavid Wu 	/* enable the write to the equivalent lower bits */
190849c55878SDavid Wu 	data = BIT(bit + 16) | (enable << bit);
190949c55878SDavid Wu 
191049c55878SDavid Wu 	return regmap_write(regmap, reg, data);
191149c55878SDavid Wu }
191249c55878SDavid Wu 
191349c55878SDavid Wu /*
191449c55878SDavid Wu  * Pinconf_ops handling
191549c55878SDavid Wu  */
191649c55878SDavid Wu static bool rockchip_pinconf_pull_valid(struct rockchip_pin_ctrl *ctrl,
191749c55878SDavid Wu 					unsigned int pull)
191849c55878SDavid Wu {
191949c55878SDavid Wu 	switch (ctrl->type) {
192049c55878SDavid Wu 	case RK2928:
192149c55878SDavid Wu 	case RK3128:
192249c55878SDavid Wu 		return (pull == PIN_CONFIG_BIAS_PULL_PIN_DEFAULT ||
192349c55878SDavid Wu 			pull == PIN_CONFIG_BIAS_DISABLE);
192449c55878SDavid Wu 	case RK3066B:
192549c55878SDavid Wu 		return pull ? false : true;
192649c55878SDavid Wu 	case PX30:
192749c55878SDavid Wu 	case RV1108:
192849c55878SDavid Wu 	case RK3188:
192949c55878SDavid Wu 	case RK3288:
1930b3077611SDavid Wu 	case RK3308:
193149c55878SDavid Wu 	case RK3368:
193249c55878SDavid Wu 	case RK3399:
193349c55878SDavid Wu 		return (pull != PIN_CONFIG_BIAS_PULL_PIN_DEFAULT);
193449c55878SDavid Wu 	}
193549c55878SDavid Wu 
193649c55878SDavid Wu 	return false;
193749c55878SDavid Wu }
193849c55878SDavid Wu 
193949c55878SDavid Wu /* set the pin config settings for a specified pin */
194049c55878SDavid Wu static int rockchip_pinconf_set(struct rockchip_pin_bank *bank,
194149c55878SDavid Wu 				u32 pin, u32 param, u32 arg)
194249c55878SDavid Wu {
194349c55878SDavid Wu 	struct rockchip_pinctrl_priv *priv = bank->priv;
194449c55878SDavid Wu 	struct rockchip_pin_ctrl *ctrl = priv->ctrl;
194549c55878SDavid Wu 	int rc;
194649c55878SDavid Wu 
194749c55878SDavid Wu 	switch (param) {
194849c55878SDavid Wu 	case PIN_CONFIG_BIAS_DISABLE:
194949c55878SDavid Wu 		rc =  rockchip_set_pull(bank, pin, param);
195049c55878SDavid Wu 		if (rc)
195149c55878SDavid Wu 			return rc;
195249c55878SDavid Wu 		break;
195349c55878SDavid Wu 
195449c55878SDavid Wu 	case PIN_CONFIG_BIAS_PULL_UP:
195549c55878SDavid Wu 	case PIN_CONFIG_BIAS_PULL_DOWN:
195649c55878SDavid Wu 	case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT:
195749c55878SDavid Wu 	case PIN_CONFIG_BIAS_BUS_HOLD:
195849c55878SDavid Wu 		if (!rockchip_pinconf_pull_valid(ctrl, param))
195949c55878SDavid Wu 			return -ENOTSUPP;
196049c55878SDavid Wu 
196149c55878SDavid Wu 		if (!arg)
196249c55878SDavid Wu 			return -EINVAL;
196349c55878SDavid Wu 
196449c55878SDavid Wu 		rc = rockchip_set_pull(bank, pin, param);
196549c55878SDavid Wu 		if (rc)
196649c55878SDavid Wu 			return rc;
196749c55878SDavid Wu 		break;
196849c55878SDavid Wu 
196949c55878SDavid Wu 	case PIN_CONFIG_DRIVE_STRENGTH:
197049c55878SDavid Wu 		if (!ctrl->drv_calc_reg)
197149c55878SDavid Wu 			return -ENOTSUPP;
197249c55878SDavid Wu 
197349c55878SDavid Wu 		rc = rockchip_set_drive_perpin(bank, pin, arg);
197449c55878SDavid Wu 		if (rc < 0)
197549c55878SDavid Wu 			return rc;
197649c55878SDavid Wu 		break;
197749c55878SDavid Wu 
197849c55878SDavid Wu 	case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
197949c55878SDavid Wu 		if (!ctrl->schmitt_calc_reg)
198049c55878SDavid Wu 			return -ENOTSUPP;
198149c55878SDavid Wu 
198249c55878SDavid Wu 		rc = rockchip_set_schmitt(bank, pin, arg);
198349c55878SDavid Wu 		if (rc < 0)
198449c55878SDavid Wu 			return rc;
198549c55878SDavid Wu 		break;
198649c55878SDavid Wu 
198749c55878SDavid Wu 	default:
198849c55878SDavid Wu 		break;
198949c55878SDavid Wu 	}
199049c55878SDavid Wu 
199149c55878SDavid Wu 	return 0;
199249c55878SDavid Wu }
199349c55878SDavid Wu 
199449c55878SDavid Wu static const struct pinconf_param rockchip_conf_params[] = {
199549c55878SDavid Wu 	{ "bias-disable", PIN_CONFIG_BIAS_DISABLE, 0 },
199649c55878SDavid Wu 	{ "bias-bus-hold", PIN_CONFIG_BIAS_BUS_HOLD, 0 },
199749c55878SDavid Wu 	{ "bias-pull-up", PIN_CONFIG_BIAS_PULL_UP, 1 },
199849c55878SDavid Wu 	{ "bias-pull-down", PIN_CONFIG_BIAS_PULL_DOWN, 1 },
199949c55878SDavid Wu 	{ "drive-strength", PIN_CONFIG_DRIVE_STRENGTH, 0 },
200049c55878SDavid Wu 	{ "input-enable", PIN_CONFIG_INPUT_ENABLE, 1 },
200149c55878SDavid Wu 	{ "input-disable", PIN_CONFIG_INPUT_ENABLE, 0 },
200249c55878SDavid Wu 	{ "input-schmitt-disable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 0 },
200349c55878SDavid Wu 	{ "input-schmitt-enable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 1 },
200449c55878SDavid Wu };
200549c55878SDavid Wu 
200649c55878SDavid Wu static int rockchip_pinconf_prop_name_to_param(const char *property,
200749c55878SDavid Wu 					       u32 *default_value)
200849c55878SDavid Wu {
200949c55878SDavid Wu 	const struct pinconf_param *p, *end;
201049c55878SDavid Wu 
201149c55878SDavid Wu 	p = rockchip_conf_params;
201249c55878SDavid Wu 	end = p + sizeof(rockchip_conf_params) / sizeof(struct pinconf_param);
201349c55878SDavid Wu 
201449c55878SDavid Wu 	/* See if this pctldev supports this parameter */
201549c55878SDavid Wu 	for (; p < end; p++) {
201649c55878SDavid Wu 		if (!strcmp(property, p->property)) {
201749c55878SDavid Wu 			*default_value = p->default_value;
201849c55878SDavid Wu 			return p->param;
201949c55878SDavid Wu 		}
202049c55878SDavid Wu 	}
202149c55878SDavid Wu 
202249c55878SDavid Wu 	*default_value = 0;
202349c55878SDavid Wu 	return -EPERM;
202449c55878SDavid Wu }
202549c55878SDavid Wu 
202649c55878SDavid Wu static int rockchip_pinctrl_set_state(struct udevice *dev,
202749c55878SDavid Wu 				      struct udevice *config)
202849c55878SDavid Wu {
202949c55878SDavid Wu 	struct rockchip_pinctrl_priv *priv = dev_get_priv(dev);
203049c55878SDavid Wu 	struct rockchip_pin_ctrl *ctrl = priv->ctrl;
203149c55878SDavid Wu 	u32 cells[MAX_ROCKCHIP_PINS_ENTRIES * 4];
203249c55878SDavid Wu 	u32 bank, pin, mux, conf, arg, default_val;
203349c55878SDavid Wu 	int ret, count, i;
203449c55878SDavid Wu 	const char *prop_name;
203549c55878SDavid Wu 	const void *value;
20362208cfa9SKever Yang 	int prop_len, param;
20372208cfa9SKever Yang 	const u32 *data;
20382208cfa9SKever Yang 	ofnode node;
20392208cfa9SKever Yang #ifdef CONFIG_OF_LIVE
20402208cfa9SKever Yang 	const struct device_node *np;
20412208cfa9SKever Yang 	struct property *pp;
20422208cfa9SKever Yang #else
20432208cfa9SKever Yang 	int property_offset, pcfg_node;
20442208cfa9SKever Yang 	const void *blob = gd->fdt_blob;
20452208cfa9SKever Yang #endif
20462208cfa9SKever Yang 	data = dev_read_prop(config, "rockchip,pins", &count);
204749c55878SDavid Wu 	if (count < 0) {
204887f0ac57SDavid Wu 		debug("%s: bad array size %d\n", __func__, count);
204949c55878SDavid Wu 		return -EINVAL;
205049c55878SDavid Wu 	}
205149c55878SDavid Wu 
205287f0ac57SDavid Wu 	count /= sizeof(u32);
205349c55878SDavid Wu 	if (count > MAX_ROCKCHIP_PINS_ENTRIES * 4) {
205449c55878SDavid Wu 		debug("%s: unsupported pins array count %d\n",
205549c55878SDavid Wu 		      __func__, count);
205649c55878SDavid Wu 		return -EINVAL;
205749c55878SDavid Wu 	}
205849c55878SDavid Wu 
205987f0ac57SDavid Wu 	for (i = 0; i < count; i++)
206087f0ac57SDavid Wu 		cells[i] = fdt32_to_cpu(data[i]);
206187f0ac57SDavid Wu 
206249c55878SDavid Wu 	for (i = 0; i < (count >> 2); i++) {
206349c55878SDavid Wu 		bank = cells[4 * i + 0];
206449c55878SDavid Wu 		pin = cells[4 * i + 1];
206549c55878SDavid Wu 		mux = cells[4 * i + 2];
206649c55878SDavid Wu 		conf = cells[4 * i + 3];
206749c55878SDavid Wu 
206849c55878SDavid Wu 		ret = rockchip_verify_config(dev, bank, pin);
206949c55878SDavid Wu 		if (ret)
207049c55878SDavid Wu 			return ret;
207149c55878SDavid Wu 
207249c55878SDavid Wu 		ret = rockchip_set_mux(&ctrl->pin_banks[bank], pin, mux);
207349c55878SDavid Wu 		if (ret)
207449c55878SDavid Wu 			return ret;
207549c55878SDavid Wu 
20762208cfa9SKever Yang 		node = ofnode_get_by_phandle(conf);
20772208cfa9SKever Yang 		if (!ofnode_valid(node))
207849c55878SDavid Wu 			return -ENODEV;
20792208cfa9SKever Yang #ifdef CONFIG_OF_LIVE
20802208cfa9SKever Yang 		np = ofnode_to_np(node);
20812208cfa9SKever Yang 		for (pp = np->properties; pp; pp = pp->next) {
20822208cfa9SKever Yang 			prop_name = pp->name;
20832208cfa9SKever Yang 			prop_len = pp->length;
20842208cfa9SKever Yang 			value = pp->value;
20852208cfa9SKever Yang #else
20862208cfa9SKever Yang 		pcfg_node = ofnode_to_offset(node);
208749c55878SDavid Wu 		fdt_for_each_property_offset(property_offset, blob, pcfg_node) {
208849c55878SDavid Wu 			value = fdt_getprop_by_offset(blob, property_offset,
208949c55878SDavid Wu 						      &prop_name, &prop_len);
209049c55878SDavid Wu 			if (!value)
209149c55878SDavid Wu 				return -ENOENT;
20922208cfa9SKever Yang #endif
209349c55878SDavid Wu 			param = rockchip_pinconf_prop_name_to_param(prop_name,
209449c55878SDavid Wu 								    &default_val);
209549c55878SDavid Wu 			if (param < 0)
209649c55878SDavid Wu 				break;
209749c55878SDavid Wu 
209849c55878SDavid Wu 			if (prop_len >= sizeof(fdt32_t))
209949c55878SDavid Wu 				arg = fdt32_to_cpu(*(fdt32_t *)value);
210049c55878SDavid Wu 			else
210149c55878SDavid Wu 				arg = default_val;
210249c55878SDavid Wu 
210349c55878SDavid Wu 			ret = rockchip_pinconf_set(&ctrl->pin_banks[bank], pin,
210449c55878SDavid Wu 						   param, arg);
210549c55878SDavid Wu 			if (ret) {
210649c55878SDavid Wu 				debug("%s: rockchip_pinconf_set fail: %d\n",
210749c55878SDavid Wu 				      __func__, ret);
210849c55878SDavid Wu 				return ret;
210949c55878SDavid Wu 			}
211049c55878SDavid Wu 		}
211149c55878SDavid Wu 	}
211249c55878SDavid Wu 
211349c55878SDavid Wu 	return 0;
211449c55878SDavid Wu }
211549c55878SDavid Wu 
211649c55878SDavid Wu static struct pinctrl_ops rockchip_pinctrl_ops = {
211749c55878SDavid Wu 	.set_state			= rockchip_pinctrl_set_state,
211849c55878SDavid Wu 	.get_gpio_mux			= rockchip_pinctrl_get_gpio_mux,
211949c55878SDavid Wu };
212049c55878SDavid Wu 
212149c55878SDavid Wu /* retrieve the soc specific data */
212249c55878SDavid Wu static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data(struct udevice *dev)
212349c55878SDavid Wu {
212449c55878SDavid Wu 	struct rockchip_pinctrl_priv *priv = dev_get_priv(dev);
212549c55878SDavid Wu 	struct rockchip_pin_ctrl *ctrl =
212649c55878SDavid Wu 			(struct rockchip_pin_ctrl *)dev_get_driver_data(dev);
212749c55878SDavid Wu 	struct rockchip_pin_bank *bank;
212849c55878SDavid Wu 	int grf_offs, pmu_offs, drv_grf_offs, drv_pmu_offs, i, j;
212949c55878SDavid Wu 
213049c55878SDavid Wu 	grf_offs = ctrl->grf_mux_offset;
213149c55878SDavid Wu 	pmu_offs = ctrl->pmu_mux_offset;
213249c55878SDavid Wu 	drv_pmu_offs = ctrl->pmu_drv_offset;
213349c55878SDavid Wu 	drv_grf_offs = ctrl->grf_drv_offset;
213449c55878SDavid Wu 	bank = ctrl->pin_banks;
213549c55878SDavid Wu 
213649c55878SDavid Wu 	for (i = 0; i < ctrl->nr_banks; ++i, ++bank) {
213749c55878SDavid Wu 		int bank_pins = 0;
213849c55878SDavid Wu 
213949c55878SDavid Wu 		bank->priv = priv;
214049c55878SDavid Wu 		bank->pin_base = ctrl->nr_pins;
214149c55878SDavid Wu 		ctrl->nr_pins += bank->nr_pins;
214249c55878SDavid Wu 
214349c55878SDavid Wu 		/* calculate iomux and drv offsets */
214449c55878SDavid Wu 		for (j = 0; j < 4; j++) {
214549c55878SDavid Wu 			struct rockchip_iomux *iom = &bank->iomux[j];
214649c55878SDavid Wu 			struct rockchip_drv *drv = &bank->drv[j];
214749c55878SDavid Wu 			int inc;
214849c55878SDavid Wu 
214949c55878SDavid Wu 			if (bank_pins >= bank->nr_pins)
215049c55878SDavid Wu 				break;
215149c55878SDavid Wu 
215249c55878SDavid Wu 			/* preset iomux offset value, set new start value */
215349c55878SDavid Wu 			if (iom->offset >= 0) {
215449c55878SDavid Wu 				if (iom->type & IOMUX_SOURCE_PMU)
215549c55878SDavid Wu 					pmu_offs = iom->offset;
215649c55878SDavid Wu 				else
215749c55878SDavid Wu 					grf_offs = iom->offset;
215849c55878SDavid Wu 			} else { /* set current iomux offset */
215949c55878SDavid Wu 				iom->offset = (iom->type & IOMUX_SOURCE_PMU) ?
216049c55878SDavid Wu 							pmu_offs : grf_offs;
216149c55878SDavid Wu 			}
216249c55878SDavid Wu 
216349c55878SDavid Wu 			/* preset drv offset value, set new start value */
216449c55878SDavid Wu 			if (drv->offset >= 0) {
216549c55878SDavid Wu 				if (iom->type & IOMUX_SOURCE_PMU)
216649c55878SDavid Wu 					drv_pmu_offs = drv->offset;
216749c55878SDavid Wu 				else
216849c55878SDavid Wu 					drv_grf_offs = drv->offset;
216949c55878SDavid Wu 			} else { /* set current drv offset */
217049c55878SDavid Wu 				drv->offset = (iom->type & IOMUX_SOURCE_PMU) ?
217149c55878SDavid Wu 						drv_pmu_offs : drv_grf_offs;
217249c55878SDavid Wu 			}
217349c55878SDavid Wu 
217449c55878SDavid Wu 			debug("bank %d, iomux %d has iom_offset 0x%x drv_offset 0x%x\n",
217549c55878SDavid Wu 			      i, j, iom->offset, drv->offset);
217649c55878SDavid Wu 
217749c55878SDavid Wu 			/*
217849c55878SDavid Wu 			 * Increase offset according to iomux width.
217949c55878SDavid Wu 			 * 4bit iomux'es are spread over two registers.
218049c55878SDavid Wu 			 */
218149c55878SDavid Wu 			inc = (iom->type & (IOMUX_WIDTH_4BIT |
218288a1f7ffSDavid Wu 					    IOMUX_WIDTH_3BIT |
218388a1f7ffSDavid Wu 					    IOMUX_8WIDTH_2BIT)) ? 8 : 4;
218449c55878SDavid Wu 			if (iom->type & IOMUX_SOURCE_PMU)
218549c55878SDavid Wu 				pmu_offs += inc;
218649c55878SDavid Wu 			else
218749c55878SDavid Wu 				grf_offs += inc;
218849c55878SDavid Wu 
218949c55878SDavid Wu 			/*
219049c55878SDavid Wu 			 * Increase offset according to drv width.
219149c55878SDavid Wu 			 * 3bit drive-strenth'es are spread over two registers.
219249c55878SDavid Wu 			 */
219349c55878SDavid Wu 			if ((drv->drv_type == DRV_TYPE_IO_1V8_3V0_AUTO) ||
219449c55878SDavid Wu 			    (drv->drv_type == DRV_TYPE_IO_3V3_ONLY))
219549c55878SDavid Wu 				inc = 8;
219649c55878SDavid Wu 			else
219749c55878SDavid Wu 				inc = 4;
219849c55878SDavid Wu 
219949c55878SDavid Wu 			if (iom->type & IOMUX_SOURCE_PMU)
220049c55878SDavid Wu 				drv_pmu_offs += inc;
220149c55878SDavid Wu 			else
220249c55878SDavid Wu 				drv_grf_offs += inc;
220349c55878SDavid Wu 
220449c55878SDavid Wu 			bank_pins += 8;
220549c55878SDavid Wu 		}
220649c55878SDavid Wu 
220749c55878SDavid Wu 		/* calculate the per-bank recalced_mask */
220849c55878SDavid Wu 		for (j = 0; j < ctrl->niomux_recalced; j++) {
220949c55878SDavid Wu 			int pin = 0;
221049c55878SDavid Wu 
221149c55878SDavid Wu 			if (ctrl->iomux_recalced[j].num == bank->bank_num) {
221249c55878SDavid Wu 				pin = ctrl->iomux_recalced[j].pin;
221349c55878SDavid Wu 				bank->recalced_mask |= BIT(pin);
221449c55878SDavid Wu 			}
221549c55878SDavid Wu 		}
221649c55878SDavid Wu 
221749c55878SDavid Wu 		/* calculate the per-bank route_mask */
221849c55878SDavid Wu 		for (j = 0; j < ctrl->niomux_routes; j++) {
221949c55878SDavid Wu 			int pin = 0;
222049c55878SDavid Wu 
222149c55878SDavid Wu 			if (ctrl->iomux_routes[j].bank_num == bank->bank_num) {
222249c55878SDavid Wu 				pin = ctrl->iomux_routes[j].pin;
222349c55878SDavid Wu 				bank->route_mask |= BIT(pin);
222449c55878SDavid Wu 			}
222549c55878SDavid Wu 		}
222649c55878SDavid Wu 	}
222749c55878SDavid Wu 
222849c55878SDavid Wu 	return ctrl;
222949c55878SDavid Wu }
223049c55878SDavid Wu 
223149c55878SDavid Wu static int rockchip_pinctrl_probe(struct udevice *dev)
223249c55878SDavid Wu {
223349c55878SDavid Wu 	struct rockchip_pinctrl_priv *priv = dev_get_priv(dev);
223449c55878SDavid Wu 	struct rockchip_pin_ctrl *ctrl;
223549c55878SDavid Wu 	struct udevice *syscon;
223649c55878SDavid Wu 	struct regmap *regmap;
223749c55878SDavid Wu 	int ret = 0;
223849c55878SDavid Wu 
223949c55878SDavid Wu 	/* get rockchip grf syscon phandle */
224049c55878SDavid Wu 	ret = uclass_get_device_by_phandle(UCLASS_SYSCON, dev, "rockchip,grf",
224149c55878SDavid Wu 					   &syscon);
224249c55878SDavid Wu 	if (ret) {
224349c55878SDavid Wu 		debug("unable to find rockchip,grf syscon device (%d)\n", ret);
224449c55878SDavid Wu 		return ret;
224549c55878SDavid Wu 	}
224649c55878SDavid Wu 
224749c55878SDavid Wu 	/* get grf-reg base address */
224849c55878SDavid Wu 	regmap = syscon_get_regmap(syscon);
224949c55878SDavid Wu 	if (!regmap) {
225049c55878SDavid Wu 		debug("unable to find rockchip grf regmap\n");
225149c55878SDavid Wu 		return -ENODEV;
225249c55878SDavid Wu 	}
225349c55878SDavid Wu 	priv->regmap_base = regmap;
225449c55878SDavid Wu 
225549c55878SDavid Wu 	/* option: get pmu-reg base address */
225649c55878SDavid Wu 	ret = uclass_get_device_by_phandle(UCLASS_SYSCON, dev, "rockchip,pmu",
225749c55878SDavid Wu 					   &syscon);
225849c55878SDavid Wu 	if (!ret) {
225949c55878SDavid Wu 		/* get pmugrf-reg base address */
226049c55878SDavid Wu 		regmap = syscon_get_regmap(syscon);
226149c55878SDavid Wu 		if (!regmap) {
226249c55878SDavid Wu 			debug("unable to find rockchip pmu regmap\n");
226349c55878SDavid Wu 			return -ENODEV;
226449c55878SDavid Wu 		}
226549c55878SDavid Wu 		priv->regmap_pmu = regmap;
226649c55878SDavid Wu 	}
226749c55878SDavid Wu 
226849c55878SDavid Wu 	ctrl = rockchip_pinctrl_get_soc_data(dev);
226949c55878SDavid Wu 	if (!ctrl) {
227049c55878SDavid Wu 		debug("driver data not available\n");
227149c55878SDavid Wu 		return -EINVAL;
227249c55878SDavid Wu 	}
227349c55878SDavid Wu 
227449c55878SDavid Wu 	priv->ctrl = ctrl;
227549c55878SDavid Wu 	return 0;
227649c55878SDavid Wu }
227749c55878SDavid Wu 
227849c55878SDavid Wu static struct rockchip_pin_bank px30_pin_banks[] = {
227949c55878SDavid Wu 	PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_SOURCE_PMU,
228049c55878SDavid Wu 					     IOMUX_SOURCE_PMU,
228149c55878SDavid Wu 					     IOMUX_SOURCE_PMU,
228249c55878SDavid Wu 					     IOMUX_SOURCE_PMU
228349c55878SDavid Wu 			    ),
228449c55878SDavid Wu 	PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", IOMUX_WIDTH_4BIT,
228549c55878SDavid Wu 					     IOMUX_WIDTH_4BIT,
228649c55878SDavid Wu 					     IOMUX_WIDTH_4BIT,
228749c55878SDavid Wu 					     IOMUX_WIDTH_4BIT
228849c55878SDavid Wu 			    ),
228949c55878SDavid Wu 	PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", IOMUX_WIDTH_4BIT,
229049c55878SDavid Wu 					     IOMUX_WIDTH_4BIT,
229149c55878SDavid Wu 					     IOMUX_WIDTH_4BIT,
229249c55878SDavid Wu 					     IOMUX_WIDTH_4BIT
229349c55878SDavid Wu 			    ),
229449c55878SDavid Wu 	PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", IOMUX_WIDTH_4BIT,
229549c55878SDavid Wu 					     IOMUX_WIDTH_4BIT,
229649c55878SDavid Wu 					     IOMUX_WIDTH_4BIT,
229749c55878SDavid Wu 					     IOMUX_WIDTH_4BIT
229849c55878SDavid Wu 			    ),
229949c55878SDavid Wu };
230049c55878SDavid Wu 
230149c55878SDavid Wu static struct rockchip_pin_ctrl px30_pin_ctrl = {
230249c55878SDavid Wu 		.pin_banks		= px30_pin_banks,
230349c55878SDavid Wu 		.nr_banks		= ARRAY_SIZE(px30_pin_banks),
230449c55878SDavid Wu 		.label			= "PX30-GPIO",
230549c55878SDavid Wu 		.type			= PX30,
230649c55878SDavid Wu 		.grf_mux_offset		= 0x0,
230749c55878SDavid Wu 		.pmu_mux_offset		= 0x0,
230849c55878SDavid Wu 		.iomux_routes		= px30_mux_route_data,
230949c55878SDavid Wu 		.niomux_routes		= ARRAY_SIZE(px30_mux_route_data),
231049c55878SDavid Wu 		.pull_calc_reg		= px30_calc_pull_reg_and_bit,
231149c55878SDavid Wu 		.drv_calc_reg		= px30_calc_drv_reg_and_bit,
231249c55878SDavid Wu 		.schmitt_calc_reg	= px30_calc_schmitt_reg_and_bit,
231349c55878SDavid Wu };
231449c55878SDavid Wu 
231549c55878SDavid Wu static struct rockchip_pin_bank rv1108_pin_banks[] = {
231649c55878SDavid Wu 	PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_SOURCE_PMU,
231749c55878SDavid Wu 					     IOMUX_SOURCE_PMU,
231849c55878SDavid Wu 					     IOMUX_SOURCE_PMU,
231949c55878SDavid Wu 					     IOMUX_SOURCE_PMU),
232049c55878SDavid Wu 	PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", 0, 0, 0, 0),
232149c55878SDavid Wu 	PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", 0, 0, 0, 0),
232249c55878SDavid Wu 	PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", 0, 0, 0, 0),
232349c55878SDavid Wu };
232449c55878SDavid Wu 
232549c55878SDavid Wu static struct rockchip_pin_ctrl rv1108_pin_ctrl = {
232649c55878SDavid Wu 	.pin_banks		= rv1108_pin_banks,
232749c55878SDavid Wu 	.nr_banks		= ARRAY_SIZE(rv1108_pin_banks),
232849c55878SDavid Wu 	.label			= "RV1108-GPIO",
232949c55878SDavid Wu 	.type			= RV1108,
233049c55878SDavid Wu 	.grf_mux_offset		= 0x10,
233149c55878SDavid Wu 	.pmu_mux_offset		= 0x0,
233249c55878SDavid Wu 	.iomux_recalced		= rv1108_mux_recalced_data,
233349c55878SDavid Wu 	.niomux_recalced	= ARRAY_SIZE(rv1108_mux_recalced_data),
233449c55878SDavid Wu 	.pull_calc_reg		= rv1108_calc_pull_reg_and_bit,
233549c55878SDavid Wu 	.drv_calc_reg		= rv1108_calc_drv_reg_and_bit,
233649c55878SDavid Wu 	.schmitt_calc_reg	= rv1108_calc_schmitt_reg_and_bit,
233749c55878SDavid Wu };
233849c55878SDavid Wu 
233949c55878SDavid Wu static struct rockchip_pin_bank rk2928_pin_banks[] = {
234049c55878SDavid Wu 	PIN_BANK(0, 32, "gpio0"),
234149c55878SDavid Wu 	PIN_BANK(1, 32, "gpio1"),
234249c55878SDavid Wu 	PIN_BANK(2, 32, "gpio2"),
234349c55878SDavid Wu 	PIN_BANK(3, 32, "gpio3"),
234449c55878SDavid Wu };
234549c55878SDavid Wu 
234649c55878SDavid Wu static struct rockchip_pin_ctrl rk2928_pin_ctrl = {
234749c55878SDavid Wu 		.pin_banks		= rk2928_pin_banks,
234849c55878SDavid Wu 		.nr_banks		= ARRAY_SIZE(rk2928_pin_banks),
234949c55878SDavid Wu 		.label			= "RK2928-GPIO",
235049c55878SDavid Wu 		.type			= RK2928,
235149c55878SDavid Wu 		.grf_mux_offset		= 0xa8,
235249c55878SDavid Wu 		.pull_calc_reg		= rk2928_calc_pull_reg_and_bit,
235349c55878SDavid Wu };
235449c55878SDavid Wu 
235549c55878SDavid Wu static struct rockchip_pin_bank rk3036_pin_banks[] = {
235649c55878SDavid Wu 	PIN_BANK(0, 32, "gpio0"),
235749c55878SDavid Wu 	PIN_BANK(1, 32, "gpio1"),
235849c55878SDavid Wu 	PIN_BANK(2, 32, "gpio2"),
235949c55878SDavid Wu };
236049c55878SDavid Wu 
236149c55878SDavid Wu static struct rockchip_pin_ctrl rk3036_pin_ctrl = {
236249c55878SDavid Wu 		.pin_banks		= rk3036_pin_banks,
236349c55878SDavid Wu 		.nr_banks		= ARRAY_SIZE(rk3036_pin_banks),
236449c55878SDavid Wu 		.label			= "RK3036-GPIO",
236549c55878SDavid Wu 		.type			= RK2928,
236649c55878SDavid Wu 		.grf_mux_offset		= 0xa8,
236749c55878SDavid Wu 		.pull_calc_reg		= rk2928_calc_pull_reg_and_bit,
236849c55878SDavid Wu };
236949c55878SDavid Wu 
237049c55878SDavid Wu static struct rockchip_pin_bank rk3066a_pin_banks[] = {
237149c55878SDavid Wu 	PIN_BANK(0, 32, "gpio0"),
237249c55878SDavid Wu 	PIN_BANK(1, 32, "gpio1"),
237349c55878SDavid Wu 	PIN_BANK(2, 32, "gpio2"),
237449c55878SDavid Wu 	PIN_BANK(3, 32, "gpio3"),
237549c55878SDavid Wu 	PIN_BANK(4, 32, "gpio4"),
237649c55878SDavid Wu 	PIN_BANK(6, 16, "gpio6"),
237749c55878SDavid Wu };
237849c55878SDavid Wu 
237949c55878SDavid Wu static struct rockchip_pin_ctrl rk3066a_pin_ctrl = {
238049c55878SDavid Wu 		.pin_banks		= rk3066a_pin_banks,
238149c55878SDavid Wu 		.nr_banks		= ARRAY_SIZE(rk3066a_pin_banks),
238249c55878SDavid Wu 		.label			= "RK3066a-GPIO",
238349c55878SDavid Wu 		.type			= RK2928,
238449c55878SDavid Wu 		.grf_mux_offset		= 0xa8,
238549c55878SDavid Wu 		.pull_calc_reg		= rk2928_calc_pull_reg_and_bit,
238649c55878SDavid Wu };
238749c55878SDavid Wu 
238849c55878SDavid Wu static struct rockchip_pin_bank rk3066b_pin_banks[] = {
238949c55878SDavid Wu 	PIN_BANK(0, 32, "gpio0"),
239049c55878SDavid Wu 	PIN_BANK(1, 32, "gpio1"),
239149c55878SDavid Wu 	PIN_BANK(2, 32, "gpio2"),
239249c55878SDavid Wu 	PIN_BANK(3, 32, "gpio3"),
239349c55878SDavid Wu };
239449c55878SDavid Wu 
239549c55878SDavid Wu static struct rockchip_pin_ctrl rk3066b_pin_ctrl = {
239649c55878SDavid Wu 		.pin_banks	= rk3066b_pin_banks,
239749c55878SDavid Wu 		.nr_banks	= ARRAY_SIZE(rk3066b_pin_banks),
239849c55878SDavid Wu 		.label		= "RK3066b-GPIO",
239949c55878SDavid Wu 		.type		= RK3066B,
240049c55878SDavid Wu 		.grf_mux_offset	= 0x60,
240149c55878SDavid Wu };
240249c55878SDavid Wu 
240349c55878SDavid Wu static struct rockchip_pin_bank rk3128_pin_banks[] = {
240449c55878SDavid Wu 	PIN_BANK(0, 32, "gpio0"),
240549c55878SDavid Wu 	PIN_BANK(1, 32, "gpio1"),
240649c55878SDavid Wu 	PIN_BANK(2, 32, "gpio2"),
240749c55878SDavid Wu 	PIN_BANK(3, 32, "gpio3"),
240849c55878SDavid Wu };
240949c55878SDavid Wu 
241049c55878SDavid Wu static struct rockchip_pin_ctrl rk3128_pin_ctrl = {
241149c55878SDavid Wu 		.pin_banks		= rk3128_pin_banks,
241249c55878SDavid Wu 		.nr_banks		= ARRAY_SIZE(rk3128_pin_banks),
241349c55878SDavid Wu 		.label			= "RK3128-GPIO",
241449c55878SDavid Wu 		.type			= RK3128,
241549c55878SDavid Wu 		.grf_mux_offset		= 0xa8,
241649c55878SDavid Wu 		.iomux_recalced		= rk3128_mux_recalced_data,
241749c55878SDavid Wu 		.niomux_recalced	= ARRAY_SIZE(rk3128_mux_recalced_data),
241849c55878SDavid Wu 		.iomux_routes		= rk3128_mux_route_data,
241949c55878SDavid Wu 		.niomux_routes		= ARRAY_SIZE(rk3128_mux_route_data),
242049c55878SDavid Wu 		.pull_calc_reg		= rk3128_calc_pull_reg_and_bit,
242149c55878SDavid Wu };
242249c55878SDavid Wu 
242349c55878SDavid Wu static struct rockchip_pin_bank rk3188_pin_banks[] = {
242449c55878SDavid Wu 	PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_GPIO_ONLY, 0, 0, 0),
242549c55878SDavid Wu 	PIN_BANK(1, 32, "gpio1"),
242649c55878SDavid Wu 	PIN_BANK(2, 32, "gpio2"),
242749c55878SDavid Wu 	PIN_BANK(3, 32, "gpio3"),
242849c55878SDavid Wu };
242949c55878SDavid Wu 
243049c55878SDavid Wu static struct rockchip_pin_ctrl rk3188_pin_ctrl = {
243149c55878SDavid Wu 		.pin_banks		= rk3188_pin_banks,
243249c55878SDavid Wu 		.nr_banks		= ARRAY_SIZE(rk3188_pin_banks),
243349c55878SDavid Wu 		.label			= "RK3188-GPIO",
243449c55878SDavid Wu 		.type			= RK3188,
243549c55878SDavid Wu 		.grf_mux_offset		= 0x60,
243649c55878SDavid Wu 		.pull_calc_reg		= rk3188_calc_pull_reg_and_bit,
243749c55878SDavid Wu };
243849c55878SDavid Wu 
243949c55878SDavid Wu static struct rockchip_pin_bank rk3228_pin_banks[] = {
244049c55878SDavid Wu 	PIN_BANK(0, 32, "gpio0"),
244149c55878SDavid Wu 	PIN_BANK(1, 32, "gpio1"),
244249c55878SDavid Wu 	PIN_BANK(2, 32, "gpio2"),
244349c55878SDavid Wu 	PIN_BANK(3, 32, "gpio3"),
244449c55878SDavid Wu };
244549c55878SDavid Wu 
244649c55878SDavid Wu static struct rockchip_pin_ctrl rk3228_pin_ctrl = {
244749c55878SDavid Wu 		.pin_banks		= rk3228_pin_banks,
244849c55878SDavid Wu 		.nr_banks		= ARRAY_SIZE(rk3228_pin_banks),
244949c55878SDavid Wu 		.label			= "RK3228-GPIO",
245049c55878SDavid Wu 		.type			= RK3288,
245149c55878SDavid Wu 		.grf_mux_offset		= 0x0,
245249c55878SDavid Wu 		.iomux_routes		= rk3228_mux_route_data,
245349c55878SDavid Wu 		.niomux_routes		= ARRAY_SIZE(rk3228_mux_route_data),
245449c55878SDavid Wu 		.pull_calc_reg		= rk3228_calc_pull_reg_and_bit,
245549c55878SDavid Wu 		.drv_calc_reg		= rk3228_calc_drv_reg_and_bit,
245649c55878SDavid Wu };
245749c55878SDavid Wu 
245849c55878SDavid Wu static struct rockchip_pin_bank rk3288_pin_banks[] = {
2459*55a89bc6SDavid Wu 	PIN_BANK_IOMUX_DRV_PULL_FLAGS(0, 24, "gpio0",
24604bafc2daSDavid Wu 				      IOMUX_SOURCE_PMU | IOMUX_WRITABLE_32BIT,
24614bafc2daSDavid Wu 				      IOMUX_SOURCE_PMU | IOMUX_WRITABLE_32BIT,
2462*55a89bc6SDavid Wu 				      IOMUX_SOURCE_PMU | IOMUX_WRITABLE_32BIT,
2463*55a89bc6SDavid Wu 				      IOMUX_UNROUTED,
2464*55a89bc6SDavid Wu 				      DRV_TYPE_WRITABLE_32BIT,
2465*55a89bc6SDavid Wu 				      DRV_TYPE_WRITABLE_32BIT,
2466*55a89bc6SDavid Wu 				      DRV_TYPE_WRITABLE_32BIT,
2467*55a89bc6SDavid Wu 				      0,
2468*55a89bc6SDavid Wu 				      PULL_TYPE_WRITABLE_32BIT,
2469*55a89bc6SDavid Wu 				      PULL_TYPE_WRITABLE_32BIT,
2470*55a89bc6SDavid Wu 				      PULL_TYPE_WRITABLE_32BIT,
2471*55a89bc6SDavid Wu 				      0
247249c55878SDavid Wu 			    ),
247349c55878SDavid Wu 	PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", IOMUX_UNROUTED,
247449c55878SDavid Wu 					     IOMUX_UNROUTED,
247549c55878SDavid Wu 					     IOMUX_UNROUTED,
247649c55878SDavid Wu 					     0
247749c55878SDavid Wu 			    ),
247849c55878SDavid Wu 	PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", 0, 0, 0, IOMUX_UNROUTED),
247949c55878SDavid Wu 	PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", 0, 0, 0, IOMUX_WIDTH_4BIT),
248049c55878SDavid Wu 	PIN_BANK_IOMUX_FLAGS(4, 32, "gpio4", IOMUX_WIDTH_4BIT,
248149c55878SDavid Wu 					     IOMUX_WIDTH_4BIT,
248249c55878SDavid Wu 					     0,
248349c55878SDavid Wu 					     0
248449c55878SDavid Wu 			    ),
248549c55878SDavid Wu 	PIN_BANK_IOMUX_FLAGS(5, 32, "gpio5", IOMUX_UNROUTED,
248649c55878SDavid Wu 					     0,
248749c55878SDavid Wu 					     0,
248849c55878SDavid Wu 					     IOMUX_UNROUTED
248949c55878SDavid Wu 			    ),
249049c55878SDavid Wu 	PIN_BANK_IOMUX_FLAGS(6, 32, "gpio6", 0, 0, 0, IOMUX_UNROUTED),
249149c55878SDavid Wu 	PIN_BANK_IOMUX_FLAGS(7, 32, "gpio7", 0,
249249c55878SDavid Wu 					     0,
249349c55878SDavid Wu 					     IOMUX_WIDTH_4BIT,
249449c55878SDavid Wu 					     IOMUX_UNROUTED
249549c55878SDavid Wu 			    ),
249649c55878SDavid Wu 	PIN_BANK(8, 16, "gpio8"),
249749c55878SDavid Wu };
249849c55878SDavid Wu 
249949c55878SDavid Wu static struct rockchip_pin_ctrl rk3288_pin_ctrl = {
250049c55878SDavid Wu 		.pin_banks		= rk3288_pin_banks,
250149c55878SDavid Wu 		.nr_banks		= ARRAY_SIZE(rk3288_pin_banks),
250249c55878SDavid Wu 		.label			= "RK3288-GPIO",
250349c55878SDavid Wu 		.type			= RK3288,
250449c55878SDavid Wu 		.grf_mux_offset		= 0x0,
250549c55878SDavid Wu 		.pmu_mux_offset		= 0x84,
250649c55878SDavid Wu 		.iomux_routes		= rk3288_mux_route_data,
250749c55878SDavid Wu 		.niomux_routes		= ARRAY_SIZE(rk3288_mux_route_data),
250849c55878SDavid Wu 		.pull_calc_reg		= rk3288_calc_pull_reg_and_bit,
250949c55878SDavid Wu 		.drv_calc_reg		= rk3288_calc_drv_reg_and_bit,
251049c55878SDavid Wu };
251149c55878SDavid Wu 
2512b3077611SDavid Wu static struct rockchip_pin_bank rk3308_pin_banks[] = {
2513b3077611SDavid Wu 	PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_8WIDTH_2BIT,
2514b3077611SDavid Wu 					     IOMUX_8WIDTH_2BIT,
2515b3077611SDavid Wu 					     IOMUX_8WIDTH_2BIT,
2516b3077611SDavid Wu 					     IOMUX_8WIDTH_2BIT),
2517b3077611SDavid Wu 	PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", IOMUX_8WIDTH_2BIT,
2518b3077611SDavid Wu 					     IOMUX_8WIDTH_2BIT,
2519b3077611SDavid Wu 					     IOMUX_8WIDTH_2BIT,
2520b3077611SDavid Wu 					     IOMUX_8WIDTH_2BIT),
2521b3077611SDavid Wu 	PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", IOMUX_8WIDTH_2BIT,
2522b3077611SDavid Wu 					     IOMUX_8WIDTH_2BIT,
2523b3077611SDavid Wu 					     IOMUX_8WIDTH_2BIT,
2524b3077611SDavid Wu 					     IOMUX_8WIDTH_2BIT),
2525b3077611SDavid Wu 	PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", IOMUX_8WIDTH_2BIT,
2526b3077611SDavid Wu 					     IOMUX_8WIDTH_2BIT,
2527b3077611SDavid Wu 					     IOMUX_8WIDTH_2BIT,
2528b3077611SDavid Wu 					     IOMUX_8WIDTH_2BIT),
2529b3077611SDavid Wu 	PIN_BANK_IOMUX_FLAGS(4, 32, "gpio4", IOMUX_8WIDTH_2BIT,
2530b3077611SDavid Wu 					     IOMUX_8WIDTH_2BIT,
2531b3077611SDavid Wu 					     IOMUX_8WIDTH_2BIT,
2532b3077611SDavid Wu 					     IOMUX_8WIDTH_2BIT),
2533b3077611SDavid Wu };
2534b3077611SDavid Wu 
2535b3077611SDavid Wu static struct rockchip_pin_ctrl rk3308_pin_ctrl = {
2536b3077611SDavid Wu 		.pin_banks		= rk3308_pin_banks,
2537b3077611SDavid Wu 		.nr_banks		= ARRAY_SIZE(rk3308_pin_banks),
2538b3077611SDavid Wu 		.label			= "RK3308-GPIO",
2539b3077611SDavid Wu 		.type			= RK3308,
2540b3077611SDavid Wu 		.grf_mux_offset		= 0x0,
2541b3077611SDavid Wu 		.iomux_recalced		= rk3308_mux_recalced_data,
2542b3077611SDavid Wu 		.niomux_recalced	= ARRAY_SIZE(rk3308_mux_recalced_data),
2543b3077611SDavid Wu 		.iomux_routes		= rk3308_mux_route_data,
2544b3077611SDavid Wu 		.niomux_routes		= ARRAY_SIZE(rk3308_mux_route_data),
2545b3077611SDavid Wu 		.pull_calc_reg		= rk3308_calc_pull_reg_and_bit,
2546b3077611SDavid Wu 		.drv_calc_reg		= rk3308_calc_drv_reg_and_bit,
2547b3077611SDavid Wu 		.schmitt_calc_reg	= rk3308_calc_schmitt_reg_and_bit,
2548b3077611SDavid Wu };
2549b3077611SDavid Wu 
255049c55878SDavid Wu static struct rockchip_pin_bank rk3328_pin_banks[] = {
255149c55878SDavid Wu 	PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", 0, 0, 0, 0),
255249c55878SDavid Wu 	PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", 0, 0, 0, 0),
255349c55878SDavid Wu 	PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", 0,
255449c55878SDavid Wu 			     IOMUX_WIDTH_3BIT,
255549c55878SDavid Wu 			     IOMUX_WIDTH_3BIT,
255649c55878SDavid Wu 			     0),
255749c55878SDavid Wu 	PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3",
255849c55878SDavid Wu 			     IOMUX_WIDTH_3BIT,
255949c55878SDavid Wu 			     IOMUX_WIDTH_3BIT,
256049c55878SDavid Wu 			     0,
256149c55878SDavid Wu 			     0),
256249c55878SDavid Wu };
256349c55878SDavid Wu 
256449c55878SDavid Wu static struct rockchip_pin_ctrl rk3328_pin_ctrl = {
256549c55878SDavid Wu 		.pin_banks		= rk3328_pin_banks,
256649c55878SDavid Wu 		.nr_banks		= ARRAY_SIZE(rk3328_pin_banks),
256749c55878SDavid Wu 		.label			= "RK3328-GPIO",
256849c55878SDavid Wu 		.type			= RK3288,
256949c55878SDavid Wu 		.grf_mux_offset		= 0x0,
257049c55878SDavid Wu 		.iomux_recalced		= rk3328_mux_recalced_data,
257149c55878SDavid Wu 		.niomux_recalced	= ARRAY_SIZE(rk3328_mux_recalced_data),
257249c55878SDavid Wu 		.iomux_routes		= rk3328_mux_route_data,
257349c55878SDavid Wu 		.niomux_routes		= ARRAY_SIZE(rk3328_mux_route_data),
257449c55878SDavid Wu 		.pull_calc_reg		= rk3228_calc_pull_reg_and_bit,
257549c55878SDavid Wu 		.drv_calc_reg		= rk3228_calc_drv_reg_and_bit,
257649c55878SDavid Wu 		.schmitt_calc_reg	= rk3328_calc_schmitt_reg_and_bit,
257749c55878SDavid Wu };
257849c55878SDavid Wu 
257949c55878SDavid Wu static struct rockchip_pin_bank rk3368_pin_banks[] = {
258049c55878SDavid Wu 	PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_SOURCE_PMU,
258149c55878SDavid Wu 					     IOMUX_SOURCE_PMU,
258249c55878SDavid Wu 					     IOMUX_SOURCE_PMU,
258349c55878SDavid Wu 					     IOMUX_SOURCE_PMU
258449c55878SDavid Wu 			    ),
258549c55878SDavid Wu 	PIN_BANK(1, 32, "gpio1"),
258649c55878SDavid Wu 	PIN_BANK(2, 32, "gpio2"),
258749c55878SDavid Wu 	PIN_BANK(3, 32, "gpio3"),
258849c55878SDavid Wu };
258949c55878SDavid Wu 
259049c55878SDavid Wu static struct rockchip_pin_ctrl rk3368_pin_ctrl = {
259149c55878SDavid Wu 		.pin_banks		= rk3368_pin_banks,
259249c55878SDavid Wu 		.nr_banks		= ARRAY_SIZE(rk3368_pin_banks),
259349c55878SDavid Wu 		.label			= "RK3368-GPIO",
259449c55878SDavid Wu 		.type			= RK3368,
259549c55878SDavid Wu 		.grf_mux_offset		= 0x0,
259649c55878SDavid Wu 		.pmu_mux_offset		= 0x0,
259749c55878SDavid Wu 		.pull_calc_reg		= rk3368_calc_pull_reg_and_bit,
259849c55878SDavid Wu 		.drv_calc_reg		= rk3368_calc_drv_reg_and_bit,
259949c55878SDavid Wu };
260049c55878SDavid Wu 
260149c55878SDavid Wu static struct rockchip_pin_bank rk3399_pin_banks[] = {
260249c55878SDavid Wu 	PIN_BANK_IOMUX_FLAGS_DRV_FLAGS_OFFSET_PULL_FLAGS(0, 32, "gpio0",
260349c55878SDavid Wu 							 IOMUX_SOURCE_PMU,
260449c55878SDavid Wu 							 IOMUX_SOURCE_PMU,
260549c55878SDavid Wu 							 IOMUX_SOURCE_PMU,
260649c55878SDavid Wu 							 IOMUX_SOURCE_PMU,
260749c55878SDavid Wu 							 DRV_TYPE_IO_1V8_ONLY,
260849c55878SDavid Wu 							 DRV_TYPE_IO_1V8_ONLY,
260949c55878SDavid Wu 							 DRV_TYPE_IO_DEFAULT,
261049c55878SDavid Wu 							 DRV_TYPE_IO_DEFAULT,
261149c55878SDavid Wu 							 0x80,
261249c55878SDavid Wu 							 0x88,
261349c55878SDavid Wu 							 -1,
261449c55878SDavid Wu 							 -1,
261549c55878SDavid Wu 							 PULL_TYPE_IO_1V8_ONLY,
261649c55878SDavid Wu 							 PULL_TYPE_IO_1V8_ONLY,
261749c55878SDavid Wu 							 PULL_TYPE_IO_DEFAULT,
261849c55878SDavid Wu 							 PULL_TYPE_IO_DEFAULT
261949c55878SDavid Wu 							),
262049c55878SDavid Wu 	PIN_BANK_IOMUX_DRV_FLAGS_OFFSET(1, 32, "gpio1", IOMUX_SOURCE_PMU,
262149c55878SDavid Wu 					IOMUX_SOURCE_PMU,
262249c55878SDavid Wu 					IOMUX_SOURCE_PMU,
262349c55878SDavid Wu 					IOMUX_SOURCE_PMU,
262449c55878SDavid Wu 					DRV_TYPE_IO_1V8_OR_3V0,
262549c55878SDavid Wu 					DRV_TYPE_IO_1V8_OR_3V0,
262649c55878SDavid Wu 					DRV_TYPE_IO_1V8_OR_3V0,
262749c55878SDavid Wu 					DRV_TYPE_IO_1V8_OR_3V0,
262849c55878SDavid Wu 					0xa0,
262949c55878SDavid Wu 					0xa8,
263049c55878SDavid Wu 					0xb0,
263149c55878SDavid Wu 					0xb8
263249c55878SDavid Wu 					),
263349c55878SDavid Wu 	PIN_BANK_DRV_FLAGS_PULL_FLAGS(2, 32, "gpio2", DRV_TYPE_IO_1V8_OR_3V0,
263449c55878SDavid Wu 				      DRV_TYPE_IO_1V8_OR_3V0,
263549c55878SDavid Wu 				      DRV_TYPE_IO_1V8_ONLY,
263649c55878SDavid Wu 				      DRV_TYPE_IO_1V8_ONLY,
263749c55878SDavid Wu 				      PULL_TYPE_IO_DEFAULT,
263849c55878SDavid Wu 				      PULL_TYPE_IO_DEFAULT,
263949c55878SDavid Wu 				      PULL_TYPE_IO_1V8_ONLY,
264049c55878SDavid Wu 				      PULL_TYPE_IO_1V8_ONLY
264149c55878SDavid Wu 				      ),
264249c55878SDavid Wu 	PIN_BANK_DRV_FLAGS(3, 32, "gpio3", DRV_TYPE_IO_3V3_ONLY,
264349c55878SDavid Wu 			   DRV_TYPE_IO_3V3_ONLY,
264449c55878SDavid Wu 			   DRV_TYPE_IO_3V3_ONLY,
264549c55878SDavid Wu 			   DRV_TYPE_IO_1V8_OR_3V0
264649c55878SDavid Wu 			   ),
264749c55878SDavid Wu 	PIN_BANK_DRV_FLAGS(4, 32, "gpio4", DRV_TYPE_IO_1V8_OR_3V0,
264849c55878SDavid Wu 			   DRV_TYPE_IO_1V8_3V0_AUTO,
264949c55878SDavid Wu 			   DRV_TYPE_IO_1V8_OR_3V0,
265049c55878SDavid Wu 			   DRV_TYPE_IO_1V8_OR_3V0
265149c55878SDavid Wu 			   ),
265249c55878SDavid Wu };
265349c55878SDavid Wu 
265449c55878SDavid Wu static struct rockchip_pin_ctrl rk3399_pin_ctrl = {
265549c55878SDavid Wu 		.pin_banks		= rk3399_pin_banks,
265649c55878SDavid Wu 		.nr_banks		= ARRAY_SIZE(rk3399_pin_banks),
265749c55878SDavid Wu 		.label			= "RK3399-GPIO",
265849c55878SDavid Wu 		.type			= RK3399,
265949c55878SDavid Wu 		.grf_mux_offset		= 0xe000,
266049c55878SDavid Wu 		.pmu_mux_offset		= 0x0,
266149c55878SDavid Wu 		.grf_drv_offset		= 0xe100,
266249c55878SDavid Wu 		.pmu_drv_offset		= 0x80,
266349c55878SDavid Wu 		.iomux_routes		= rk3399_mux_route_data,
266449c55878SDavid Wu 		.niomux_routes		= ARRAY_SIZE(rk3399_mux_route_data),
266549c55878SDavid Wu 		.pull_calc_reg		= rk3399_calc_pull_reg_and_bit,
266649c55878SDavid Wu 		.drv_calc_reg		= rk3399_calc_drv_reg_and_bit,
266749c55878SDavid Wu };
266849c55878SDavid Wu 
266949c55878SDavid Wu static const struct udevice_id rockchip_pinctrl_dt_match[] = {
267049c55878SDavid Wu 	{ .compatible = "rockchip,px30-pinctrl",
267149c55878SDavid Wu 		.data = (ulong)&px30_pin_ctrl },
267249c55878SDavid Wu 	{ .compatible = "rockchip,rv1108-pinctrl",
267349c55878SDavid Wu 		.data = (ulong)&rv1108_pin_ctrl },
267449c55878SDavid Wu 	{ .compatible = "rockchip,rk2928-pinctrl",
267549c55878SDavid Wu 		.data = (ulong)&rk2928_pin_ctrl },
267649c55878SDavid Wu 	{ .compatible = "rockchip,rk3036-pinctrl",
267749c55878SDavid Wu 		.data = (ulong)&rk3036_pin_ctrl },
267849c55878SDavid Wu 	{ .compatible = "rockchip,rk3066a-pinctrl",
267949c55878SDavid Wu 		.data = (ulong)&rk3066a_pin_ctrl },
268049c55878SDavid Wu 	{ .compatible = "rockchip,rk3066b-pinctrl",
268149c55878SDavid Wu 		.data = (ulong)&rk3066b_pin_ctrl },
268249c55878SDavid Wu 	{ .compatible = "rockchip,rk3128-pinctrl",
268349c55878SDavid Wu 		.data = (ulong)&rk3128_pin_ctrl },
268449c55878SDavid Wu 	{ .compatible = "rockchip,rk3188-pinctrl",
268549c55878SDavid Wu 		.data = (ulong)&rk3188_pin_ctrl },
268649c55878SDavid Wu 	{ .compatible = "rockchip,rk3228-pinctrl",
268749c55878SDavid Wu 		.data = (ulong)&rk3228_pin_ctrl },
268849c55878SDavid Wu 	{ .compatible = "rockchip,rk3288-pinctrl",
268949c55878SDavid Wu 		.data = (ulong)&rk3288_pin_ctrl },
2690b3077611SDavid Wu 	{ .compatible = "rockchip,rk3308-pinctrl",
2691b3077611SDavid Wu 		.data = (ulong)&rk3308_pin_ctrl },
269249c55878SDavid Wu 	{ .compatible = "rockchip,rk3328-pinctrl",
269349c55878SDavid Wu 		.data = (ulong)&rk3328_pin_ctrl },
269449c55878SDavid Wu 	{ .compatible = "rockchip,rk3368-pinctrl",
269549c55878SDavid Wu 		.data = (ulong)&rk3368_pin_ctrl },
269649c55878SDavid Wu 	{ .compatible = "rockchip,rk3399-pinctrl",
269749c55878SDavid Wu 		.data = (ulong)&rk3399_pin_ctrl },
269849c55878SDavid Wu 	{},
269949c55878SDavid Wu };
270049c55878SDavid Wu 
270149c55878SDavid Wu U_BOOT_DRIVER(pinctrl_rockchip) = {
270249c55878SDavid Wu 	.name		= "rockchip_pinctrl",
270349c55878SDavid Wu 	.id		= UCLASS_PINCTRL,
270449c55878SDavid Wu 	.of_match	= rockchip_pinctrl_dt_match,
270549c55878SDavid Wu 	.priv_auto_alloc_size = sizeof(struct rockchip_pinctrl_priv),
270649c55878SDavid Wu 	.ops		= &rockchip_pinctrl_ops,
270749c55878SDavid Wu #if !CONFIG_IS_ENABLED(OF_PLATDATA)
270849c55878SDavid Wu 	.bind		= dm_scan_fdt_dev,
270949c55878SDavid Wu #endif
271049c55878SDavid Wu 	.probe		= rockchip_pinctrl_probe,
271149c55878SDavid Wu };
2712