xref: /rk3399_rockchip-uboot/drivers/pinctrl/pinctrl-rockchip.c (revision 4bafc2da2ded5e0dcfd8c097a501e301c8eeea9f)
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)
40*4bafc2daSDavid 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 
5349c55878SDavid Wu /**
5449c55878SDavid Wu  * enum type index corresponding to rockchip_perpin_drv_list arrays index.
5549c55878SDavid Wu  */
5649c55878SDavid Wu enum rockchip_pin_drv_type {
5749c55878SDavid Wu 	DRV_TYPE_IO_DEFAULT = 0,
5849c55878SDavid Wu 	DRV_TYPE_IO_1V8_OR_3V0,
5949c55878SDavid Wu 	DRV_TYPE_IO_1V8_ONLY,
6049c55878SDavid Wu 	DRV_TYPE_IO_1V8_3V0_AUTO,
6149c55878SDavid Wu 	DRV_TYPE_IO_3V3_ONLY,
6249c55878SDavid Wu 	DRV_TYPE_MAX
6349c55878SDavid Wu };
6449c55878SDavid Wu 
6549c55878SDavid Wu /**
6649c55878SDavid Wu  * enum type index corresponding to rockchip_pull_list arrays index.
6749c55878SDavid Wu  */
6849c55878SDavid Wu enum rockchip_pin_pull_type {
6949c55878SDavid Wu 	PULL_TYPE_IO_DEFAULT = 0,
7049c55878SDavid Wu 	PULL_TYPE_IO_1V8_ONLY,
7149c55878SDavid Wu 	PULL_TYPE_MAX
7249c55878SDavid Wu };
7349c55878SDavid Wu 
7449c55878SDavid Wu /**
7549c55878SDavid Wu  * @drv_type: drive strength variant using rockchip_perpin_drv_type
7649c55878SDavid Wu  * @offset: if initialized to -1 it will be autocalculated, by specifying
7749c55878SDavid Wu  *	    an initial offset value the relevant source offset can be reset
7849c55878SDavid Wu  *	    to a new value for autocalculating the following drive strength
7949c55878SDavid Wu  *	    registers. if used chips own cal_drv func instead to calculate
8049c55878SDavid Wu  *	    registers offset, the variant could be ignored.
8149c55878SDavid Wu  */
8249c55878SDavid Wu struct rockchip_drv {
8349c55878SDavid Wu 	enum rockchip_pin_drv_type	drv_type;
8449c55878SDavid Wu 	int				offset;
8549c55878SDavid Wu };
8649c55878SDavid Wu 
8749c55878SDavid Wu /**
8849c55878SDavid Wu  * @priv: common pinctrl private basedata
8949c55878SDavid Wu  * @pin_base: first pin number
9049c55878SDavid Wu  * @nr_pins: number of pins in this bank
9149c55878SDavid Wu  * @name: name of the bank
9249c55878SDavid Wu  * @bank_num: number of the bank, to account for holes
9349c55878SDavid Wu  * @iomux: array describing the 4 iomux sources of the bank
9449c55878SDavid Wu  * @drv: array describing the 4 drive strength sources of the bank
9549c55878SDavid Wu  * @pull_type: array describing the 4 pull type sources of the bank
9649c55878SDavid Wu  * @recalced_mask: bits describing the mux recalced pins of per bank
9749c55878SDavid Wu  * @route_mask: bits describing the routing pins of per bank
9849c55878SDavid Wu  */
9949c55878SDavid Wu struct rockchip_pin_bank {
10049c55878SDavid Wu 	struct rockchip_pinctrl_priv	*priv;
10149c55878SDavid Wu 	u32				pin_base;
10249c55878SDavid Wu 	u8				nr_pins;
10349c55878SDavid Wu 	char				*name;
10449c55878SDavid Wu 	u8				bank_num;
10549c55878SDavid Wu 	struct rockchip_iomux		iomux[4];
10649c55878SDavid Wu 	struct rockchip_drv		drv[4];
10749c55878SDavid Wu 	enum rockchip_pin_pull_type	pull_type[4];
10849c55878SDavid Wu 	u32				recalced_mask;
10949c55878SDavid Wu 	u32				route_mask;
11049c55878SDavid Wu };
11149c55878SDavid Wu 
11249c55878SDavid Wu #define PIN_BANK(id, pins, label)			\
11349c55878SDavid Wu 	{						\
11449c55878SDavid Wu 		.bank_num	= id,			\
11549c55878SDavid Wu 		.nr_pins	= pins,			\
11649c55878SDavid Wu 		.name		= label,		\
11749c55878SDavid Wu 		.iomux		= {			\
11849c55878SDavid Wu 			{ .offset = -1 },		\
11949c55878SDavid Wu 			{ .offset = -1 },		\
12049c55878SDavid Wu 			{ .offset = -1 },		\
12149c55878SDavid Wu 			{ .offset = -1 },		\
12249c55878SDavid Wu 		},					\
12349c55878SDavid Wu 	}
12449c55878SDavid Wu 
12549c55878SDavid Wu #define PIN_BANK_IOMUX_FLAGS(id, pins, label, iom0, iom1, iom2, iom3)	\
12649c55878SDavid Wu 	{								\
12749c55878SDavid Wu 		.bank_num	= id,					\
12849c55878SDavid Wu 		.nr_pins	= pins,					\
12949c55878SDavid Wu 		.name		= label,				\
13049c55878SDavid Wu 		.iomux		= {					\
13149c55878SDavid Wu 			{ .type = iom0, .offset = -1 },			\
13249c55878SDavid Wu 			{ .type = iom1, .offset = -1 },			\
13349c55878SDavid Wu 			{ .type = iom2, .offset = -1 },			\
13449c55878SDavid Wu 			{ .type = iom3, .offset = -1 },			\
13549c55878SDavid Wu 		},							\
13649c55878SDavid Wu 	}
13749c55878SDavid Wu 
13849c55878SDavid Wu #define PIN_BANK_DRV_FLAGS(id, pins, label, type0, type1, type2, type3) \
13949c55878SDavid Wu 	{								\
14049c55878SDavid Wu 		.bank_num	= id,					\
14149c55878SDavid Wu 		.nr_pins	= pins,					\
14249c55878SDavid Wu 		.name		= label,				\
14349c55878SDavid Wu 		.iomux		= {					\
14449c55878SDavid Wu 			{ .offset = -1 },				\
14549c55878SDavid Wu 			{ .offset = -1 },				\
14649c55878SDavid Wu 			{ .offset = -1 },				\
14749c55878SDavid Wu 			{ .offset = -1 },				\
14849c55878SDavid Wu 		},							\
14949c55878SDavid Wu 		.drv		= {					\
15049c55878SDavid Wu 			{ .drv_type = type0, .offset = -1 },		\
15149c55878SDavid Wu 			{ .drv_type = type1, .offset = -1 },		\
15249c55878SDavid Wu 			{ .drv_type = type2, .offset = -1 },		\
15349c55878SDavid Wu 			{ .drv_type = type3, .offset = -1 },		\
15449c55878SDavid Wu 		},							\
15549c55878SDavid Wu 	}
15649c55878SDavid Wu 
15749c55878SDavid Wu #define PIN_BANK_DRV_FLAGS_PULL_FLAGS(id, pins, label, drv0, drv1,	\
15849c55878SDavid Wu 				      drv2, drv3, pull0, pull1,		\
15949c55878SDavid Wu 				      pull2, pull3)			\
16049c55878SDavid Wu 	{								\
16149c55878SDavid Wu 		.bank_num	= id,					\
16249c55878SDavid Wu 		.nr_pins	= pins,					\
16349c55878SDavid Wu 		.name		= label,				\
16449c55878SDavid Wu 		.iomux		= {					\
16549c55878SDavid Wu 			{ .offset = -1 },				\
16649c55878SDavid Wu 			{ .offset = -1 },				\
16749c55878SDavid Wu 			{ .offset = -1 },				\
16849c55878SDavid Wu 			{ .offset = -1 },				\
16949c55878SDavid Wu 		},							\
17049c55878SDavid Wu 		.drv		= {					\
17149c55878SDavid Wu 			{ .drv_type = drv0, .offset = -1 },		\
17249c55878SDavid Wu 			{ .drv_type = drv1, .offset = -1 },		\
17349c55878SDavid Wu 			{ .drv_type = drv2, .offset = -1 },		\
17449c55878SDavid Wu 			{ .drv_type = drv3, .offset = -1 },		\
17549c55878SDavid Wu 		},							\
17649c55878SDavid Wu 		.pull_type[0] = pull0,					\
17749c55878SDavid Wu 		.pull_type[1] = pull1,					\
17849c55878SDavid Wu 		.pull_type[2] = pull2,					\
17949c55878SDavid Wu 		.pull_type[3] = pull3,					\
18049c55878SDavid Wu 	}
18149c55878SDavid Wu 
18249c55878SDavid Wu #define PIN_BANK_IOMUX_DRV_FLAGS_OFFSET(id, pins, label, iom0, iom1,	\
18349c55878SDavid Wu 					iom2, iom3, drv0, drv1, drv2,	\
18449c55878SDavid Wu 					drv3, offset0, offset1,		\
18549c55878SDavid Wu 					offset2, offset3)		\
18649c55878SDavid Wu 	{								\
18749c55878SDavid Wu 		.bank_num	= id,					\
18849c55878SDavid Wu 		.nr_pins	= pins,					\
18949c55878SDavid Wu 		.name		= label,				\
19049c55878SDavid Wu 		.iomux		= {					\
19149c55878SDavid Wu 			{ .type = iom0, .offset = -1 },			\
19249c55878SDavid Wu 			{ .type = iom1, .offset = -1 },			\
19349c55878SDavid Wu 			{ .type = iom2, .offset = -1 },			\
19449c55878SDavid Wu 			{ .type = iom3, .offset = -1 },			\
19549c55878SDavid Wu 		},							\
19649c55878SDavid Wu 		.drv		= {					\
19749c55878SDavid Wu 			{ .drv_type = drv0, .offset = offset0 },	\
19849c55878SDavid Wu 			{ .drv_type = drv1, .offset = offset1 },	\
19949c55878SDavid Wu 			{ .drv_type = drv2, .offset = offset2 },	\
20049c55878SDavid Wu 			{ .drv_type = drv3, .offset = offset3 },	\
20149c55878SDavid Wu 		},							\
20249c55878SDavid Wu 	}
20349c55878SDavid Wu 
20449c55878SDavid Wu #define PIN_BANK_IOMUX_FLAGS_DRV_FLAGS_OFFSET_PULL_FLAGS(id, pins,	\
20549c55878SDavid Wu 					      label, iom0, iom1, iom2,  \
20649c55878SDavid Wu 					      iom3, drv0, drv1, drv2,   \
20749c55878SDavid Wu 					      drv3, offset0, offset1,   \
20849c55878SDavid Wu 					      offset2, offset3, pull0,  \
20949c55878SDavid Wu 					      pull1, pull2, pull3)	\
21049c55878SDavid Wu 	{								\
21149c55878SDavid Wu 		.bank_num	= id,					\
21249c55878SDavid Wu 		.nr_pins	= pins,					\
21349c55878SDavid Wu 		.name		= label,				\
21449c55878SDavid Wu 		.iomux		= {					\
21549c55878SDavid Wu 			{ .type = iom0, .offset = -1 },			\
21649c55878SDavid Wu 			{ .type = iom1, .offset = -1 },			\
21749c55878SDavid Wu 			{ .type = iom2, .offset = -1 },			\
21849c55878SDavid Wu 			{ .type = iom3, .offset = -1 },			\
21949c55878SDavid Wu 		},							\
22049c55878SDavid Wu 		.drv		= {					\
22149c55878SDavid Wu 			{ .drv_type = drv0, .offset = offset0 },	\
22249c55878SDavid Wu 			{ .drv_type = drv1, .offset = offset1 },	\
22349c55878SDavid Wu 			{ .drv_type = drv2, .offset = offset2 },	\
22449c55878SDavid Wu 			{ .drv_type = drv3, .offset = offset3 },	\
22549c55878SDavid Wu 		},							\
22649c55878SDavid Wu 		.pull_type[0] = pull0,					\
22749c55878SDavid Wu 		.pull_type[1] = pull1,					\
22849c55878SDavid Wu 		.pull_type[2] = pull2,					\
22949c55878SDavid Wu 		.pull_type[3] = pull3,					\
23049c55878SDavid Wu 	}
23149c55878SDavid Wu 
23249c55878SDavid Wu /**
23349c55878SDavid Wu  * struct rockchip_mux_recalced_data: represent a pin iomux data.
23449c55878SDavid Wu  * @num: bank number.
23549c55878SDavid Wu  * @pin: pin number.
23649c55878SDavid Wu  * @bit: index at register.
23749c55878SDavid Wu  * @reg: register offset.
23849c55878SDavid Wu  * @mask: mask bit
23949c55878SDavid Wu  */
24049c55878SDavid Wu struct rockchip_mux_recalced_data {
24149c55878SDavid Wu 	u8 num;
24249c55878SDavid Wu 	u8 pin;
24349c55878SDavid Wu 	u32 reg;
24449c55878SDavid Wu 	u8 bit;
24549c55878SDavid Wu 	u8 mask;
24649c55878SDavid Wu };
24749c55878SDavid Wu 
24849c55878SDavid Wu /**
24949c55878SDavid Wu  * struct rockchip_mux_recalced_data: represent a pin iomux data.
25049c55878SDavid Wu  * @bank_num: bank number.
25149c55878SDavid Wu  * @pin: index at register or used to calc index.
25249c55878SDavid Wu  * @func: the min pin.
25349c55878SDavid Wu  * @route_offset: the max pin.
25449c55878SDavid Wu  * @route_val: the register offset.
25549c55878SDavid Wu  */
25649c55878SDavid Wu struct rockchip_mux_route_data {
25749c55878SDavid Wu 	u8 bank_num;
25849c55878SDavid Wu 	u8 pin;
25949c55878SDavid Wu 	u8 func;
26049c55878SDavid Wu 	u32 route_offset;
26149c55878SDavid Wu 	u32 route_val;
26249c55878SDavid Wu };
26349c55878SDavid Wu 
26449c55878SDavid Wu /**
26549c55878SDavid Wu  */
26649c55878SDavid Wu struct rockchip_pin_ctrl {
26749c55878SDavid Wu 	struct rockchip_pin_bank	*pin_banks;
26849c55878SDavid Wu 	u32				nr_banks;
26949c55878SDavid Wu 	u32				nr_pins;
27049c55878SDavid Wu 	char				*label;
27149c55878SDavid Wu 	enum rockchip_pinctrl_type	type;
27249c55878SDavid Wu 	int				grf_mux_offset;
27349c55878SDavid Wu 	int				pmu_mux_offset;
27449c55878SDavid Wu 	int				grf_drv_offset;
27549c55878SDavid Wu 	int				pmu_drv_offset;
27649c55878SDavid Wu 	struct rockchip_mux_recalced_data *iomux_recalced;
27749c55878SDavid Wu 	u32				niomux_recalced;
27849c55878SDavid Wu 	struct rockchip_mux_route_data *iomux_routes;
27949c55878SDavid Wu 	u32				niomux_routes;
28049c55878SDavid Wu 
28149c55878SDavid Wu 	void	(*pull_calc_reg)(struct rockchip_pin_bank *bank,
28249c55878SDavid Wu 				 int pin_num, struct regmap **regmap,
28349c55878SDavid Wu 				 int *reg, u8 *bit);
28449c55878SDavid Wu 	void	(*drv_calc_reg)(struct rockchip_pin_bank *bank,
28549c55878SDavid Wu 				int pin_num, struct regmap **regmap,
28649c55878SDavid Wu 				int *reg, u8 *bit);
28749c55878SDavid Wu 	int	(*schmitt_calc_reg)(struct rockchip_pin_bank *bank,
28849c55878SDavid Wu 				    int pin_num, struct regmap **regmap,
28949c55878SDavid Wu 				    int *reg, u8 *bit);
29049c55878SDavid Wu };
29149c55878SDavid Wu 
29249c55878SDavid Wu /**
29349c55878SDavid Wu  */
29449c55878SDavid Wu struct rockchip_pinctrl_priv {
29549c55878SDavid Wu 	struct rockchip_pin_ctrl	*ctrl;
29649c55878SDavid Wu 	struct regmap			*regmap_base;
29749c55878SDavid Wu 	struct regmap			*regmap_pmu;
29849c55878SDavid Wu 
29949c55878SDavid Wu };
30049c55878SDavid Wu 
30149c55878SDavid Wu static int rockchip_verify_config(struct udevice *dev, u32 bank, u32 pin)
30249c55878SDavid Wu {
30349c55878SDavid Wu 	struct rockchip_pinctrl_priv *priv = dev_get_priv(dev);
30449c55878SDavid Wu 	struct rockchip_pin_ctrl *ctrl = priv->ctrl;
30549c55878SDavid Wu 
30649c55878SDavid Wu 	if (bank >= ctrl->nr_banks) {
30749c55878SDavid Wu 		debug("pin conf bank %d >= nbanks %d\n", bank, ctrl->nr_banks);
30849c55878SDavid Wu 		return -EINVAL;
30949c55878SDavid Wu 	}
31049c55878SDavid Wu 
31149c55878SDavid Wu 	if (pin >= MAX_ROCKCHIP_GPIO_PER_BANK) {
31249c55878SDavid Wu 		debug("pin conf pin %d >= %d\n", pin,
31349c55878SDavid Wu 		      MAX_ROCKCHIP_GPIO_PER_BANK);
31449c55878SDavid Wu 		return -EINVAL;
31549c55878SDavid Wu 	}
31649c55878SDavid Wu 
31749c55878SDavid Wu 	return 0;
31849c55878SDavid Wu }
31949c55878SDavid Wu 
32049c55878SDavid Wu static struct rockchip_mux_recalced_data rv1108_mux_recalced_data[] = {
32149c55878SDavid Wu 	{
32249c55878SDavid Wu 		.num = 1,
32349c55878SDavid Wu 		.pin = 0,
32449c55878SDavid Wu 		.reg = 0x418,
32549c55878SDavid Wu 		.bit = 0,
32649c55878SDavid Wu 		.mask = 0x3
32749c55878SDavid Wu 	}, {
32849c55878SDavid Wu 		.num = 1,
32949c55878SDavid Wu 		.pin = 1,
33049c55878SDavid Wu 		.reg = 0x418,
33149c55878SDavid Wu 		.bit = 2,
33249c55878SDavid Wu 		.mask = 0x3
33349c55878SDavid Wu 	}, {
33449c55878SDavid Wu 		.num = 1,
33549c55878SDavid Wu 		.pin = 2,
33649c55878SDavid Wu 		.reg = 0x418,
33749c55878SDavid Wu 		.bit = 4,
33849c55878SDavid Wu 		.mask = 0x3
33949c55878SDavid Wu 	}, {
34049c55878SDavid Wu 		.num = 1,
34149c55878SDavid Wu 		.pin = 3,
34249c55878SDavid Wu 		.reg = 0x418,
34349c55878SDavid Wu 		.bit = 6,
34449c55878SDavid Wu 		.mask = 0x3
34549c55878SDavid Wu 	}, {
34649c55878SDavid Wu 		.num = 1,
34749c55878SDavid Wu 		.pin = 4,
34849c55878SDavid Wu 		.reg = 0x418,
34949c55878SDavid Wu 		.bit = 8,
35049c55878SDavid Wu 		.mask = 0x3
35149c55878SDavid Wu 	}, {
35249c55878SDavid Wu 		.num = 1,
35349c55878SDavid Wu 		.pin = 5,
35449c55878SDavid Wu 		.reg = 0x418,
35549c55878SDavid Wu 		.bit = 10,
35649c55878SDavid Wu 		.mask = 0x3
35749c55878SDavid Wu 	}, {
35849c55878SDavid Wu 		.num = 1,
35949c55878SDavid Wu 		.pin = 6,
36049c55878SDavid Wu 		.reg = 0x418,
36149c55878SDavid Wu 		.bit = 12,
36249c55878SDavid Wu 		.mask = 0x3
36349c55878SDavid Wu 	}, {
36449c55878SDavid Wu 		.num = 1,
36549c55878SDavid Wu 		.pin = 7,
36649c55878SDavid Wu 		.reg = 0x418,
36749c55878SDavid Wu 		.bit = 14,
36849c55878SDavid Wu 		.mask = 0x3
36949c55878SDavid Wu 	}, {
37049c55878SDavid Wu 		.num = 1,
37149c55878SDavid Wu 		.pin = 8,
37249c55878SDavid Wu 		.reg = 0x41c,
37349c55878SDavid Wu 		.bit = 0,
37449c55878SDavid Wu 		.mask = 0x3
37549c55878SDavid Wu 	}, {
37649c55878SDavid Wu 		.num = 1,
37749c55878SDavid Wu 		.pin = 9,
37849c55878SDavid Wu 		.reg = 0x41c,
37949c55878SDavid Wu 		.bit = 2,
38049c55878SDavid Wu 		.mask = 0x3
38149c55878SDavid Wu 	},
38249c55878SDavid Wu };
38349c55878SDavid Wu 
38449c55878SDavid Wu static  struct rockchip_mux_recalced_data rk3128_mux_recalced_data[] = {
38549c55878SDavid Wu 	{
38649c55878SDavid Wu 		.num = 2,
38749c55878SDavid Wu 		.pin = 20,
38849c55878SDavid Wu 		.reg = 0xe8,
38949c55878SDavid Wu 		.bit = 0,
39049c55878SDavid Wu 		.mask = 0x7
39149c55878SDavid Wu 	}, {
39249c55878SDavid Wu 		.num = 2,
39349c55878SDavid Wu 		.pin = 21,
39449c55878SDavid Wu 		.reg = 0xe8,
39549c55878SDavid Wu 		.bit = 4,
39649c55878SDavid Wu 		.mask = 0x7
39749c55878SDavid Wu 	}, {
39849c55878SDavid Wu 		.num = 2,
39949c55878SDavid Wu 		.pin = 22,
40049c55878SDavid Wu 		.reg = 0xe8,
40149c55878SDavid Wu 		.bit = 8,
40249c55878SDavid Wu 		.mask = 0x7
40349c55878SDavid Wu 	}, {
40449c55878SDavid Wu 		.num = 2,
40549c55878SDavid Wu 		.pin = 23,
40649c55878SDavid Wu 		.reg = 0xe8,
40749c55878SDavid Wu 		.bit = 12,
40849c55878SDavid Wu 		.mask = 0x7
40949c55878SDavid Wu 	}, {
41049c55878SDavid Wu 		.num = 2,
41149c55878SDavid Wu 		.pin = 24,
41249c55878SDavid Wu 		.reg = 0xd4,
41349c55878SDavid Wu 		.bit = 12,
41449c55878SDavid Wu 		.mask = 0x7
41549c55878SDavid Wu 	},
41649c55878SDavid Wu };
41749c55878SDavid Wu 
418b3077611SDavid Wu static struct rockchip_mux_recalced_data rk3308_mux_recalced_data[] = {
419b3077611SDavid Wu 	{
420b3077611SDavid Wu 		.num = 1,
421b3077611SDavid Wu 		.pin = 14,
422b3077611SDavid Wu 		.reg = 0x28,
423b3077611SDavid Wu 		.bit = 12,
424b3077611SDavid Wu 		.mask = 0x7
425b3077611SDavid Wu 	}, {
426b3077611SDavid Wu 		.num = 1,
427b3077611SDavid Wu 		.pin = 15,
428b3077611SDavid Wu 		.reg = 0x2c,
429b3077611SDavid Wu 		.bit = 0,
430b3077611SDavid Wu 		.mask = 0x3
431b3077611SDavid Wu 	}, {
432b3077611SDavid Wu 		.num = 1,
433b3077611SDavid Wu 		.pin = 18,
434b3077611SDavid Wu 		.reg = 0x30,
435b3077611SDavid Wu 		.bit = 4,
436b3077611SDavid Wu 		.mask = 0x7
437b3077611SDavid Wu 	}, {
438b3077611SDavid Wu 		.num = 1,
439b3077611SDavid Wu 		.pin = 19,
440b3077611SDavid Wu 		.reg = 0x30,
441b3077611SDavid Wu 		.bit = 8,
442b3077611SDavid Wu 		.mask = 0x7
443b3077611SDavid Wu 	}, {
444b3077611SDavid Wu 		.num = 1,
445b3077611SDavid Wu 		.pin = 20,
446b3077611SDavid Wu 		.reg = 0x30,
447b3077611SDavid Wu 		.bit = 12,
448b3077611SDavid Wu 		.mask = 0x7
449b3077611SDavid Wu 	}, {
450b3077611SDavid Wu 		.num = 1,
451b3077611SDavid Wu 		.pin = 21,
452b3077611SDavid Wu 		.reg = 0x34,
453b3077611SDavid Wu 		.bit = 0,
454b3077611SDavid Wu 		.mask = 0x7
455b3077611SDavid Wu 	}, {
456b3077611SDavid Wu 		.num = 1,
457b3077611SDavid Wu 		.pin = 22,
458b3077611SDavid Wu 		.reg = 0x34,
459b3077611SDavid Wu 		.bit = 4,
460b3077611SDavid Wu 		.mask = 0x7
461b3077611SDavid Wu 	}, {
462b3077611SDavid Wu 		.num = 1,
463b3077611SDavid Wu 		.pin = 23,
464b3077611SDavid Wu 		.reg = 0x34,
465b3077611SDavid Wu 		.bit = 8,
466b3077611SDavid Wu 		.mask = 0x7
467b3077611SDavid Wu 	}, {
468b3077611SDavid Wu 		.num = 3,
469b3077611SDavid Wu 		.pin = 12,
470b3077611SDavid Wu 		.reg = 0x68,
471b3077611SDavid Wu 		.bit = 8,
472b3077611SDavid Wu 		.mask = 0x7
473b3077611SDavid Wu 	}, {
474b3077611SDavid Wu 		.num = 3,
475b3077611SDavid Wu 		.pin = 13,
476b3077611SDavid Wu 		.reg = 0x68,
477b3077611SDavid Wu 		.bit = 12,
478b3077611SDavid Wu 		.mask = 0x7
479b3077611SDavid Wu 	},
480b3077611SDavid Wu };
481b3077611SDavid Wu 
48249c55878SDavid Wu static struct rockchip_mux_recalced_data rk3328_mux_recalced_data[] = {
48349c55878SDavid Wu 	{
48449c55878SDavid Wu 		.num = 2,
48549c55878SDavid Wu 		.pin = 12,
48649c55878SDavid Wu 		.reg = 0x24,
48749c55878SDavid Wu 		.bit = 8,
48849c55878SDavid Wu 		.mask = 0x3
48949c55878SDavid Wu 	}, {
49049c55878SDavid Wu 		.num = 2,
49149c55878SDavid Wu 		.pin = 15,
49249c55878SDavid Wu 		.reg = 0x28,
49349c55878SDavid Wu 		.bit = 0,
49449c55878SDavid Wu 		.mask = 0x7
49549c55878SDavid Wu 	}, {
49649c55878SDavid Wu 		.num = 2,
49749c55878SDavid Wu 		.pin = 23,
49849c55878SDavid Wu 		.reg = 0x30,
49949c55878SDavid Wu 		.bit = 14,
50049c55878SDavid Wu 		.mask = 0x3
50149c55878SDavid Wu 	},
50249c55878SDavid Wu };
50349c55878SDavid Wu 
50449c55878SDavid Wu static void rockchip_get_recalced_mux(struct rockchip_pin_bank *bank, int pin,
50549c55878SDavid Wu 				      int *reg, u8 *bit, int *mask)
50649c55878SDavid Wu {
50749c55878SDavid Wu 	struct rockchip_pinctrl_priv *priv = bank->priv;
50849c55878SDavid Wu 	struct rockchip_pin_ctrl *ctrl = priv->ctrl;
50949c55878SDavid Wu 	struct rockchip_mux_recalced_data *data;
51049c55878SDavid Wu 	int i;
51149c55878SDavid Wu 
51249c55878SDavid Wu 	for (i = 0; i < ctrl->niomux_recalced; i++) {
51349c55878SDavid Wu 		data = &ctrl->iomux_recalced[i];
51449c55878SDavid Wu 		if (data->num == bank->bank_num &&
51549c55878SDavid Wu 		    data->pin == pin)
51649c55878SDavid Wu 			break;
51749c55878SDavid Wu 	}
51849c55878SDavid Wu 
51949c55878SDavid Wu 	if (i >= ctrl->niomux_recalced)
52049c55878SDavid Wu 		return;
52149c55878SDavid Wu 
52249c55878SDavid Wu 	*reg = data->reg;
52349c55878SDavid Wu 	*mask = data->mask;
52449c55878SDavid Wu 	*bit = data->bit;
52549c55878SDavid Wu }
52649c55878SDavid Wu 
52749c55878SDavid Wu static struct rockchip_mux_route_data px30_mux_route_data[] = {
52849c55878SDavid Wu 	{
52949c55878SDavid Wu 		/* cif-d2m0 */
53049c55878SDavid Wu 		.bank_num = 2,
53149c55878SDavid Wu 		.pin = 0,
53249c55878SDavid Wu 		.func = 1,
53349c55878SDavid Wu 		.route_offset = 0x184,
53449c55878SDavid Wu 		.route_val = BIT(16 + 7),
53549c55878SDavid Wu 	}, {
53649c55878SDavid Wu 		/* cif-d2m1 */
53749c55878SDavid Wu 		.bank_num = 3,
53849c55878SDavid Wu 		.pin = 3,
53949c55878SDavid Wu 		.func = 3,
54049c55878SDavid Wu 		.route_offset = 0x184,
54149c55878SDavid Wu 		.route_val = BIT(16 + 7) | BIT(7),
54249c55878SDavid Wu 	}, {
54349c55878SDavid Wu 		/* pdm-m0 */
54449c55878SDavid Wu 		.bank_num = 3,
54549c55878SDavid Wu 		.pin = 22,
54649c55878SDavid Wu 		.func = 2,
54749c55878SDavid Wu 		.route_offset = 0x184,
54849c55878SDavid Wu 		.route_val = BIT(16 + 8),
54949c55878SDavid Wu 	}, {
55049c55878SDavid Wu 		/* pdm-m1 */
55149c55878SDavid Wu 		.bank_num = 2,
55249c55878SDavid Wu 		.pin = 22,
55349c55878SDavid Wu 		.func = 1,
55449c55878SDavid Wu 		.route_offset = 0x184,
55549c55878SDavid Wu 		.route_val = BIT(16 + 8) | BIT(8),
55649c55878SDavid Wu 	}, {
55749c55878SDavid Wu 		/* uart2-rxm0 */
55849c55878SDavid Wu 		.bank_num = 1,
559793770dfSDavid Wu 		.pin = 27,
56049c55878SDavid Wu 		.func = 2,
56149c55878SDavid Wu 		.route_offset = 0x184,
562793770dfSDavid Wu 		.route_val = BIT(16 + 10),
56349c55878SDavid Wu 	}, {
56449c55878SDavid Wu 		/* uart2-rxm1 */
56549c55878SDavid Wu 		.bank_num = 2,
56649c55878SDavid Wu 		.pin = 14,
56749c55878SDavid Wu 		.func = 2,
56849c55878SDavid Wu 		.route_offset = 0x184,
569793770dfSDavid Wu 		.route_val = BIT(16 + 10) | BIT(10),
57049c55878SDavid Wu 	}, {
57149c55878SDavid Wu 		/* uart3-rxm0 */
57249c55878SDavid Wu 		.bank_num = 0,
57349c55878SDavid Wu 		.pin = 17,
57449c55878SDavid Wu 		.func = 2,
57549c55878SDavid Wu 		.route_offset = 0x184,
576793770dfSDavid Wu 		.route_val = BIT(16 + 9),
57749c55878SDavid Wu 	}, {
57849c55878SDavid Wu 		/* uart3-rxm1 */
57949c55878SDavid Wu 		.bank_num = 1,
580793770dfSDavid Wu 		.pin = 15,
58149c55878SDavid Wu 		.func = 2,
58249c55878SDavid Wu 		.route_offset = 0x184,
583793770dfSDavid Wu 		.route_val = BIT(16 + 9) | BIT(9),
58449c55878SDavid Wu 	},
58549c55878SDavid Wu };
58649c55878SDavid Wu 
58749c55878SDavid Wu static struct rockchip_mux_route_data rk3128_mux_route_data[] = {
58849c55878SDavid Wu 	{
58949c55878SDavid Wu 		/* spi-0 */
59049c55878SDavid Wu 		.bank_num = 1,
59149c55878SDavid Wu 		.pin = 10,
59249c55878SDavid Wu 		.func = 1,
59349c55878SDavid Wu 		.route_offset = 0x144,
59449c55878SDavid Wu 		.route_val = BIT(16 + 3) | BIT(16 + 4),
59549c55878SDavid Wu 	}, {
59649c55878SDavid Wu 		/* spi-1 */
59749c55878SDavid Wu 		.bank_num = 1,
59849c55878SDavid Wu 		.pin = 27,
59949c55878SDavid Wu 		.func = 3,
60049c55878SDavid Wu 		.route_offset = 0x144,
60149c55878SDavid Wu 		.route_val = BIT(16 + 3) | BIT(16 + 4) | BIT(3),
60249c55878SDavid Wu 	}, {
60349c55878SDavid Wu 		/* spi-2 */
60449c55878SDavid Wu 		.bank_num = 0,
60549c55878SDavid Wu 		.pin = 13,
60649c55878SDavid Wu 		.func = 2,
60749c55878SDavid Wu 		.route_offset = 0x144,
60849c55878SDavid Wu 		.route_val = BIT(16 + 3) | BIT(16 + 4) | BIT(4),
60949c55878SDavid Wu 	}, {
61049c55878SDavid Wu 		/* i2s-0 */
61149c55878SDavid Wu 		.bank_num = 1,
61249c55878SDavid Wu 		.pin = 5,
61349c55878SDavid Wu 		.func = 1,
61449c55878SDavid Wu 		.route_offset = 0x144,
61549c55878SDavid Wu 		.route_val = BIT(16 + 5),
61649c55878SDavid Wu 	}, {
61749c55878SDavid Wu 		/* i2s-1 */
61849c55878SDavid Wu 		.bank_num = 0,
61949c55878SDavid Wu 		.pin = 14,
62049c55878SDavid Wu 		.func = 1,
62149c55878SDavid Wu 		.route_offset = 0x144,
62249c55878SDavid Wu 		.route_val = BIT(16 + 5) | BIT(5),
62349c55878SDavid Wu 	}, {
62449c55878SDavid Wu 		/* emmc-0 */
62549c55878SDavid Wu 		.bank_num = 1,
62649c55878SDavid Wu 		.pin = 22,
62749c55878SDavid Wu 		.func = 2,
62849c55878SDavid Wu 		.route_offset = 0x144,
62949c55878SDavid Wu 		.route_val = BIT(16 + 6),
63049c55878SDavid Wu 	}, {
63149c55878SDavid Wu 		/* emmc-1 */
63249c55878SDavid Wu 		.bank_num = 2,
63349c55878SDavid Wu 		.pin = 4,
63449c55878SDavid Wu 		.func = 2,
63549c55878SDavid Wu 		.route_offset = 0x144,
63649c55878SDavid Wu 		.route_val = BIT(16 + 6) | BIT(6),
63749c55878SDavid Wu 	},
63849c55878SDavid Wu };
63949c55878SDavid Wu 
64049c55878SDavid Wu static struct rockchip_mux_route_data rk3228_mux_route_data[] = {
64149c55878SDavid Wu 	{
64249c55878SDavid Wu 		/* pwm0-0 */
64349c55878SDavid Wu 		.bank_num = 0,
64449c55878SDavid Wu 		.pin = 26,
64549c55878SDavid Wu 		.func = 1,
64649c55878SDavid Wu 		.route_offset = 0x50,
64749c55878SDavid Wu 		.route_val = BIT(16),
64849c55878SDavid Wu 	}, {
64949c55878SDavid Wu 		/* pwm0-1 */
65049c55878SDavid Wu 		.bank_num = 3,
65149c55878SDavid Wu 		.pin = 21,
65249c55878SDavid Wu 		.func = 1,
65349c55878SDavid Wu 		.route_offset = 0x50,
65449c55878SDavid Wu 		.route_val = BIT(16) | BIT(0),
65549c55878SDavid Wu 	}, {
65649c55878SDavid Wu 		/* pwm1-0 */
65749c55878SDavid Wu 		.bank_num = 0,
65849c55878SDavid Wu 		.pin = 27,
65949c55878SDavid Wu 		.func = 1,
66049c55878SDavid Wu 		.route_offset = 0x50,
66149c55878SDavid Wu 		.route_val = BIT(16 + 1),
66249c55878SDavid Wu 	}, {
66349c55878SDavid Wu 		/* pwm1-1 */
66449c55878SDavid Wu 		.bank_num = 0,
66549c55878SDavid Wu 		.pin = 30,
66649c55878SDavid Wu 		.func = 2,
66749c55878SDavid Wu 		.route_offset = 0x50,
66849c55878SDavid Wu 		.route_val = BIT(16 + 1) | BIT(1),
66949c55878SDavid Wu 	}, {
67049c55878SDavid Wu 		/* pwm2-0 */
67149c55878SDavid Wu 		.bank_num = 0,
67249c55878SDavid Wu 		.pin = 28,
67349c55878SDavid Wu 		.func = 1,
67449c55878SDavid Wu 		.route_offset = 0x50,
67549c55878SDavid Wu 		.route_val = BIT(16 + 2),
67649c55878SDavid Wu 	}, {
67749c55878SDavid Wu 		/* pwm2-1 */
67849c55878SDavid Wu 		.bank_num = 1,
67949c55878SDavid Wu 		.pin = 12,
68049c55878SDavid Wu 		.func = 2,
68149c55878SDavid Wu 		.route_offset = 0x50,
68249c55878SDavid Wu 		.route_val = BIT(16 + 2) | BIT(2),
68349c55878SDavid Wu 	}, {
68449c55878SDavid Wu 		/* pwm3-0 */
68549c55878SDavid Wu 		.bank_num = 3,
68649c55878SDavid Wu 		.pin = 26,
68749c55878SDavid Wu 		.func = 1,
68849c55878SDavid Wu 		.route_offset = 0x50,
68949c55878SDavid Wu 		.route_val = BIT(16 + 3),
69049c55878SDavid Wu 	}, {
69149c55878SDavid Wu 		/* pwm3-1 */
69249c55878SDavid Wu 		.bank_num = 1,
69349c55878SDavid Wu 		.pin = 11,
69449c55878SDavid Wu 		.func = 2,
69549c55878SDavid Wu 		.route_offset = 0x50,
69649c55878SDavid Wu 		.route_val = BIT(16 + 3) | BIT(3),
69749c55878SDavid Wu 	}, {
69849c55878SDavid Wu 		/* sdio-0_d0 */
69949c55878SDavid Wu 		.bank_num = 1,
70049c55878SDavid Wu 		.pin = 1,
70149c55878SDavid Wu 		.func = 1,
70249c55878SDavid Wu 		.route_offset = 0x50,
70349c55878SDavid Wu 		.route_val = BIT(16 + 4),
70449c55878SDavid Wu 	}, {
70549c55878SDavid Wu 		/* sdio-1_d0 */
70649c55878SDavid Wu 		.bank_num = 3,
70749c55878SDavid Wu 		.pin = 2,
70849c55878SDavid Wu 		.func = 1,
70949c55878SDavid Wu 		.route_offset = 0x50,
71049c55878SDavid Wu 		.route_val = BIT(16 + 4) | BIT(4),
71149c55878SDavid Wu 	}, {
71249c55878SDavid Wu 		/* spi-0_rx */
71349c55878SDavid Wu 		.bank_num = 0,
71449c55878SDavid Wu 		.pin = 13,
71549c55878SDavid Wu 		.func = 2,
71649c55878SDavid Wu 		.route_offset = 0x50,
71749c55878SDavid Wu 		.route_val = BIT(16 + 5),
71849c55878SDavid Wu 	}, {
71949c55878SDavid Wu 		/* spi-1_rx */
72049c55878SDavid Wu 		.bank_num = 2,
72149c55878SDavid Wu 		.pin = 0,
72249c55878SDavid Wu 		.func = 2,
72349c55878SDavid Wu 		.route_offset = 0x50,
72449c55878SDavid Wu 		.route_val = BIT(16 + 5) | BIT(5),
72549c55878SDavid Wu 	}, {
72649c55878SDavid Wu 		/* emmc-0_cmd */
72749c55878SDavid Wu 		.bank_num = 1,
72849c55878SDavid Wu 		.pin = 22,
72949c55878SDavid Wu 		.func = 2,
73049c55878SDavid Wu 		.route_offset = 0x50,
73149c55878SDavid Wu 		.route_val = BIT(16 + 7),
73249c55878SDavid Wu 	}, {
73349c55878SDavid Wu 		/* emmc-1_cmd */
73449c55878SDavid Wu 		.bank_num = 2,
73549c55878SDavid Wu 		.pin = 4,
73649c55878SDavid Wu 		.func = 2,
73749c55878SDavid Wu 		.route_offset = 0x50,
73849c55878SDavid Wu 		.route_val = BIT(16 + 7) | BIT(7),
73949c55878SDavid Wu 	}, {
74049c55878SDavid Wu 		/* uart2-0_rx */
74149c55878SDavid Wu 		.bank_num = 1,
74249c55878SDavid Wu 		.pin = 19,
74349c55878SDavid Wu 		.func = 2,
74449c55878SDavid Wu 		.route_offset = 0x50,
74549c55878SDavid Wu 		.route_val = BIT(16 + 8),
74649c55878SDavid Wu 	}, {
74749c55878SDavid Wu 		/* uart2-1_rx */
74849c55878SDavid Wu 		.bank_num = 1,
74949c55878SDavid Wu 		.pin = 10,
75049c55878SDavid Wu 		.func = 2,
75149c55878SDavid Wu 		.route_offset = 0x50,
75249c55878SDavid Wu 		.route_val = BIT(16 + 8) | BIT(8),
75349c55878SDavid Wu 	}, {
75449c55878SDavid Wu 		/* uart1-0_rx */
75549c55878SDavid Wu 		.bank_num = 1,
75649c55878SDavid Wu 		.pin = 10,
75749c55878SDavid Wu 		.func = 1,
75849c55878SDavid Wu 		.route_offset = 0x50,
75949c55878SDavid Wu 		.route_val = BIT(16 + 11),
76049c55878SDavid Wu 	}, {
76149c55878SDavid Wu 		/* uart1-1_rx */
76249c55878SDavid Wu 		.bank_num = 3,
76349c55878SDavid Wu 		.pin = 13,
76449c55878SDavid Wu 		.func = 1,
76549c55878SDavid Wu 		.route_offset = 0x50,
76649c55878SDavid Wu 		.route_val = BIT(16 + 11) | BIT(11),
76749c55878SDavid Wu 	},
76849c55878SDavid Wu };
76949c55878SDavid Wu 
77049c55878SDavid Wu static struct rockchip_mux_route_data rk3288_mux_route_data[] = {
77149c55878SDavid Wu 	{
77249c55878SDavid Wu 		/* edphdmi_cecinoutt1 */
77349c55878SDavid Wu 		.bank_num = 7,
77449c55878SDavid Wu 		.pin = 16,
77549c55878SDavid Wu 		.func = 2,
77649c55878SDavid Wu 		.route_offset = 0x264,
77749c55878SDavid Wu 		.route_val = BIT(16 + 12) | BIT(12),
77849c55878SDavid Wu 	}, {
77949c55878SDavid Wu 		/* edphdmi_cecinout */
78049c55878SDavid Wu 		.bank_num = 7,
78149c55878SDavid Wu 		.pin = 23,
78249c55878SDavid Wu 		.func = 4,
78349c55878SDavid Wu 		.route_offset = 0x264,
78449c55878SDavid Wu 		.route_val = BIT(16 + 12),
78549c55878SDavid Wu 	},
78649c55878SDavid Wu };
78749c55878SDavid Wu 
788b3077611SDavid Wu static struct rockchip_mux_route_data rk3308_mux_route_data[] = {
789b3077611SDavid Wu 	{
790b3077611SDavid Wu 		/* uart2_rxm0 */
791b3077611SDavid Wu 		.bank_num = 1,
792b3077611SDavid Wu 		.pin = 22,
793b3077611SDavid Wu 		.func = 2,
794b3077611SDavid Wu 		.route_offset = 0x314,
795b3077611SDavid Wu 		.route_val = BIT(16 + 2) | BIT(16 + 3),
796b3077611SDavid Wu 	}, {
797b3077611SDavid Wu 		/* uart2_rxm1 */
798b3077611SDavid Wu 		.bank_num = 4,
799b3077611SDavid Wu 		.pin = 26,
800b3077611SDavid Wu 		.func = 2,
801b3077611SDavid Wu 		.route_offset = 0x314,
802b3077611SDavid Wu 		.route_val = BIT(16 + 2) | BIT(16 + 3) | BIT(2),
803b3077611SDavid Wu 	}, {
804b3077611SDavid Wu 		/* i2c3_sdam0 */
805b3077611SDavid Wu 		.bank_num = 0,
806b3077611SDavid Wu 		.pin = 23,
807b3077611SDavid Wu 		.func = 2,
808b3077611SDavid Wu 		.route_offset = 0x314,
809b3077611SDavid Wu 		.route_val = BIT(16 + 4),
810b3077611SDavid Wu 	}, {
811b3077611SDavid Wu 		/* i2c3_sdam1 */
812b3077611SDavid Wu 		.bank_num = 3,
813b3077611SDavid Wu 		.pin = 12,
814b3077611SDavid Wu 		.func = 2,
815b3077611SDavid Wu 		.route_offset = 0x314,
816b3077611SDavid Wu 		.route_val =  BIT(16 + 4) | BIT(4),
817b3077611SDavid Wu 	},
818b3077611SDavid Wu };
819b3077611SDavid Wu 
82049c55878SDavid Wu static struct rockchip_mux_route_data rk3328_mux_route_data[] = {
82149c55878SDavid Wu 	{
82249c55878SDavid Wu 		/* uart2dbg_rxm0 */
82349c55878SDavid Wu 		.bank_num = 1,
82449c55878SDavid Wu 		.pin = 1,
82549c55878SDavid Wu 		.func = 2,
82649c55878SDavid Wu 		.route_offset = 0x50,
82749c55878SDavid Wu 		.route_val = BIT(16) | BIT(16 + 1),
82849c55878SDavid Wu 	}, {
82949c55878SDavid Wu 		/* uart2dbg_rxm1 */
83049c55878SDavid Wu 		.bank_num = 2,
83149c55878SDavid Wu 		.pin = 1,
83249c55878SDavid Wu 		.func = 1,
83349c55878SDavid Wu 		.route_offset = 0x50,
83449c55878SDavid Wu 		.route_val = BIT(16) | BIT(16 + 1) | BIT(0),
83549c55878SDavid Wu 	}, {
83649c55878SDavid Wu 		/* gmac-m1_rxd0 */
83749c55878SDavid Wu 		.bank_num = 1,
83849c55878SDavid Wu 		.pin = 11,
83949c55878SDavid Wu 		.func = 2,
84049c55878SDavid Wu 		.route_offset = 0x50,
84149c55878SDavid Wu 		.route_val = BIT(16 + 2) | BIT(2),
84249c55878SDavid Wu 	}, {
84349c55878SDavid Wu 		/* gmac-m1-optimized_rxd3 */
84449c55878SDavid Wu 		.bank_num = 1,
84549c55878SDavid Wu 		.pin = 14,
84649c55878SDavid Wu 		.func = 2,
84749c55878SDavid Wu 		.route_offset = 0x50,
84849c55878SDavid Wu 		.route_val = BIT(16 + 10) | BIT(10),
84949c55878SDavid Wu 	}, {
85049c55878SDavid Wu 		/* pdm_sdi0m0 */
85149c55878SDavid Wu 		.bank_num = 2,
85249c55878SDavid Wu 		.pin = 19,
85349c55878SDavid Wu 		.func = 2,
85449c55878SDavid Wu 		.route_offset = 0x50,
85549c55878SDavid Wu 		.route_val = BIT(16 + 3),
85649c55878SDavid Wu 	}, {
85749c55878SDavid Wu 		/* pdm_sdi0m1 */
85849c55878SDavid Wu 		.bank_num = 1,
85949c55878SDavid Wu 		.pin = 23,
86049c55878SDavid Wu 		.func = 3,
86149c55878SDavid Wu 		.route_offset = 0x50,
86249c55878SDavid Wu 		.route_val =  BIT(16 + 3) | BIT(3),
86349c55878SDavid Wu 	}, {
86449c55878SDavid Wu 		/* spi_rxdm2 */
86549c55878SDavid Wu 		.bank_num = 3,
86649c55878SDavid Wu 		.pin = 2,
86749c55878SDavid Wu 		.func = 4,
86849c55878SDavid Wu 		.route_offset = 0x50,
86949c55878SDavid Wu 		.route_val =  BIT(16 + 4) | BIT(16 + 5) | BIT(5),
87049c55878SDavid Wu 	}, {
87149c55878SDavid Wu 		/* i2s2_sdim0 */
87249c55878SDavid Wu 		.bank_num = 1,
87349c55878SDavid Wu 		.pin = 24,
87449c55878SDavid Wu 		.func = 1,
87549c55878SDavid Wu 		.route_offset = 0x50,
87649c55878SDavid Wu 		.route_val = BIT(16 + 6),
87749c55878SDavid Wu 	}, {
87849c55878SDavid Wu 		/* i2s2_sdim1 */
87949c55878SDavid Wu 		.bank_num = 3,
88049c55878SDavid Wu 		.pin = 2,
88149c55878SDavid Wu 		.func = 6,
88249c55878SDavid Wu 		.route_offset = 0x50,
88349c55878SDavid Wu 		.route_val =  BIT(16 + 6) | BIT(6),
88449c55878SDavid Wu 	}, {
88549c55878SDavid Wu 		/* card_iom1 */
88649c55878SDavid Wu 		.bank_num = 2,
88749c55878SDavid Wu 		.pin = 22,
88849c55878SDavid Wu 		.func = 3,
88949c55878SDavid Wu 		.route_offset = 0x50,
89049c55878SDavid Wu 		.route_val =  BIT(16 + 7) | BIT(7),
89149c55878SDavid Wu 	}, {
89249c55878SDavid Wu 		/* tsp_d5m1 */
89349c55878SDavid Wu 		.bank_num = 2,
89449c55878SDavid Wu 		.pin = 16,
89549c55878SDavid Wu 		.func = 3,
89649c55878SDavid Wu 		.route_offset = 0x50,
89749c55878SDavid Wu 		.route_val =  BIT(16 + 8) | BIT(8),
89849c55878SDavid Wu 	}, {
89949c55878SDavid Wu 		/* cif_data5m1 */
90049c55878SDavid Wu 		.bank_num = 2,
90149c55878SDavid Wu 		.pin = 16,
90249c55878SDavid Wu 		.func = 4,
90349c55878SDavid Wu 		.route_offset = 0x50,
90449c55878SDavid Wu 		.route_val =  BIT(16 + 9) | BIT(9),
90549c55878SDavid Wu 	},
90649c55878SDavid Wu };
90749c55878SDavid Wu 
90849c55878SDavid Wu static struct rockchip_mux_route_data rk3399_mux_route_data[] = {
90949c55878SDavid Wu 	{
91049c55878SDavid Wu 		/* uart2dbga_rx */
91149c55878SDavid Wu 		.bank_num = 4,
91249c55878SDavid Wu 		.pin = 8,
91349c55878SDavid Wu 		.func = 2,
91449c55878SDavid Wu 		.route_offset = 0xe21c,
91549c55878SDavid Wu 		.route_val = BIT(16 + 10) | BIT(16 + 11),
91649c55878SDavid Wu 	}, {
91749c55878SDavid Wu 		/* uart2dbgb_rx */
91849c55878SDavid Wu 		.bank_num = 4,
91949c55878SDavid Wu 		.pin = 16,
92049c55878SDavid Wu 		.func = 2,
92149c55878SDavid Wu 		.route_offset = 0xe21c,
92249c55878SDavid Wu 		.route_val = BIT(16 + 10) | BIT(16 + 11) | BIT(10),
92349c55878SDavid Wu 	}, {
92449c55878SDavid Wu 		/* uart2dbgc_rx */
92549c55878SDavid Wu 		.bank_num = 4,
92649c55878SDavid Wu 		.pin = 19,
92749c55878SDavid Wu 		.func = 1,
92849c55878SDavid Wu 		.route_offset = 0xe21c,
92949c55878SDavid Wu 		.route_val = BIT(16 + 10) | BIT(16 + 11) | BIT(11),
93049c55878SDavid Wu 	}, {
93149c55878SDavid Wu 		/* pcie_clkreqn */
93249c55878SDavid Wu 		.bank_num = 2,
93349c55878SDavid Wu 		.pin = 26,
93449c55878SDavid Wu 		.func = 2,
93549c55878SDavid Wu 		.route_offset = 0xe21c,
93649c55878SDavid Wu 		.route_val = BIT(16 + 14),
93749c55878SDavid Wu 	}, {
93849c55878SDavid Wu 		/* pcie_clkreqnb */
93949c55878SDavid Wu 		.bank_num = 4,
94049c55878SDavid Wu 		.pin = 24,
94149c55878SDavid Wu 		.func = 1,
94249c55878SDavid Wu 		.route_offset = 0xe21c,
94349c55878SDavid Wu 		.route_val = BIT(16 + 14) | BIT(14),
94449c55878SDavid Wu 	},
94549c55878SDavid Wu };
94649c55878SDavid Wu 
94749c55878SDavid Wu static bool rockchip_get_mux_route(struct rockchip_pin_bank *bank, int pin,
94849c55878SDavid Wu 				   int mux, u32 *reg, u32 *value)
94949c55878SDavid Wu {
95049c55878SDavid Wu 	struct rockchip_pinctrl_priv *priv = bank->priv;
95149c55878SDavid Wu 	struct rockchip_pin_ctrl *ctrl = priv->ctrl;
95249c55878SDavid Wu 	struct rockchip_mux_route_data *data;
95349c55878SDavid Wu 	int i;
95449c55878SDavid Wu 
95549c55878SDavid Wu 	for (i = 0; i < ctrl->niomux_routes; i++) {
95649c55878SDavid Wu 		data = &ctrl->iomux_routes[i];
95749c55878SDavid Wu 		if ((data->bank_num == bank->bank_num) &&
95849c55878SDavid Wu 		    (data->pin == pin) && (data->func == mux))
95949c55878SDavid Wu 			break;
96049c55878SDavid Wu 	}
96149c55878SDavid Wu 
96249c55878SDavid Wu 	if (i >= ctrl->niomux_routes)
96349c55878SDavid Wu 		return false;
96449c55878SDavid Wu 
96549c55878SDavid Wu 	*reg = data->route_offset;
96649c55878SDavid Wu 	*value = data->route_val;
96749c55878SDavid Wu 
96849c55878SDavid Wu 	return true;
96949c55878SDavid Wu }
97049c55878SDavid Wu 
97149c55878SDavid Wu static int rockchip_get_mux(struct rockchip_pin_bank *bank, int pin)
97249c55878SDavid Wu {
97349c55878SDavid Wu 	struct rockchip_pinctrl_priv *priv = bank->priv;
97449c55878SDavid Wu 	int iomux_num = (pin / 8);
97549c55878SDavid Wu 	struct regmap *regmap;
97649c55878SDavid Wu 	unsigned int val;
97749c55878SDavid Wu 	int reg, ret, mask, mux_type;
97849c55878SDavid Wu 	u8 bit;
97949c55878SDavid Wu 
98049c55878SDavid Wu 	if (iomux_num > 3)
98149c55878SDavid Wu 		return -EINVAL;
98249c55878SDavid Wu 
98349c55878SDavid Wu 	if (bank->iomux[iomux_num].type & IOMUX_UNROUTED) {
98449c55878SDavid Wu 		debug("pin %d is unrouted\n", pin);
98549c55878SDavid Wu 		return -EINVAL;
98649c55878SDavid Wu 	}
98749c55878SDavid Wu 
98849c55878SDavid Wu 	if (bank->iomux[iomux_num].type & IOMUX_GPIO_ONLY)
98949c55878SDavid Wu 		return RK_FUNC_GPIO;
99049c55878SDavid Wu 
99149c55878SDavid Wu 	regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU)
99249c55878SDavid Wu 				? priv->regmap_pmu : priv->regmap_base;
99349c55878SDavid Wu 
99449c55878SDavid Wu 	/* get basic quadrupel of mux registers and the correct reg inside */
99549c55878SDavid Wu 	mux_type = bank->iomux[iomux_num].type;
99649c55878SDavid Wu 	reg = bank->iomux[iomux_num].offset;
99749c55878SDavid Wu 	if (mux_type & IOMUX_WIDTH_4BIT) {
99849c55878SDavid Wu 		if ((pin % 8) >= 4)
99949c55878SDavid Wu 			reg += 0x4;
100049c55878SDavid Wu 		bit = (pin % 4) * 4;
100149c55878SDavid Wu 		mask = 0xf;
100249c55878SDavid Wu 	} else if (mux_type & IOMUX_WIDTH_3BIT) {
100349c55878SDavid Wu 		if ((pin % 8) >= 5)
100449c55878SDavid Wu 			reg += 0x4;
100549c55878SDavid Wu 		bit = (pin % 8 % 5) * 3;
100649c55878SDavid Wu 		mask = 0x7;
100749c55878SDavid Wu 	} else {
100849c55878SDavid Wu 		bit = (pin % 8) * 2;
100949c55878SDavid Wu 		mask = 0x3;
101049c55878SDavid Wu 	}
101149c55878SDavid Wu 
101249c55878SDavid Wu 	if (bank->recalced_mask & BIT(pin))
101349c55878SDavid Wu 		rockchip_get_recalced_mux(bank, pin, &reg, &bit, &mask);
101449c55878SDavid Wu 
101549c55878SDavid Wu 	ret = regmap_read(regmap, reg, &val);
101649c55878SDavid Wu 	if (ret)
101749c55878SDavid Wu 		return ret;
101849c55878SDavid Wu 
101949c55878SDavid Wu 	return ((val >> bit) & mask);
102049c55878SDavid Wu }
102149c55878SDavid Wu 
102249c55878SDavid Wu static int rockchip_pinctrl_get_gpio_mux(struct udevice *dev, int banknum,
102349c55878SDavid Wu 					 int index)
102449c55878SDavid Wu {	struct rockchip_pinctrl_priv *priv = dev_get_priv(dev);
102549c55878SDavid Wu 	struct rockchip_pin_ctrl *ctrl = priv->ctrl;
102649c55878SDavid Wu 
102749c55878SDavid Wu 	return rockchip_get_mux(&ctrl->pin_banks[banknum], index);
102849c55878SDavid Wu }
102949c55878SDavid Wu 
103049c55878SDavid Wu static int rockchip_verify_mux(struct rockchip_pin_bank *bank,
103149c55878SDavid Wu 			       int pin, int mux)
103249c55878SDavid Wu {
103349c55878SDavid Wu 	int iomux_num = (pin / 8);
103449c55878SDavid Wu 
103549c55878SDavid Wu 	if (iomux_num > 3)
103649c55878SDavid Wu 		return -EINVAL;
103749c55878SDavid Wu 
103849c55878SDavid Wu 	if (bank->iomux[iomux_num].type & IOMUX_UNROUTED) {
103949c55878SDavid Wu 		debug("pin %d is unrouted\n", pin);
104049c55878SDavid Wu 		return -EINVAL;
104149c55878SDavid Wu 	}
104249c55878SDavid Wu 
104349c55878SDavid Wu 	if (bank->iomux[iomux_num].type & IOMUX_GPIO_ONLY) {
104449c55878SDavid Wu 		if (mux != IOMUX_GPIO_ONLY) {
104549c55878SDavid Wu 			debug("pin %d only supports a gpio mux\n", pin);
104649c55878SDavid Wu 			return -ENOTSUPP;
104749c55878SDavid Wu 		}
104849c55878SDavid Wu 	}
104949c55878SDavid Wu 
105049c55878SDavid Wu 	return 0;
105149c55878SDavid Wu }
105249c55878SDavid Wu 
105349c55878SDavid Wu /*
105449c55878SDavid Wu  * Set a new mux function for a pin.
105549c55878SDavid Wu  *
105649c55878SDavid Wu  * The register is divided into the upper and lower 16 bit. When changing
105749c55878SDavid Wu  * a value, the previous register value is not read and changed. Instead
105849c55878SDavid Wu  * it seems the changed bits are marked in the upper 16 bit, while the
105949c55878SDavid Wu  * changed value gets set in the same offset in the lower 16 bit.
106049c55878SDavid Wu  * All pin settings seem to be 2 bit wide in both the upper and lower
106149c55878SDavid Wu  * parts.
106249c55878SDavid Wu  * @bank: pin bank to change
106349c55878SDavid Wu  * @pin: pin to change
106449c55878SDavid Wu  * @mux: new mux function to set
106549c55878SDavid Wu  */
106649c55878SDavid Wu static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
106749c55878SDavid Wu {
106849c55878SDavid Wu 	struct rockchip_pinctrl_priv *priv = bank->priv;
106949c55878SDavid Wu 	int iomux_num = (pin / 8);
107049c55878SDavid Wu 	struct regmap *regmap;
107149c55878SDavid Wu 	int reg, ret, mask, mux_type;
107249c55878SDavid Wu 	u8 bit;
107349c55878SDavid Wu 	u32 data, route_reg, route_val;
107449c55878SDavid Wu 
107549c55878SDavid Wu 	ret = rockchip_verify_mux(bank, pin, mux);
107649c55878SDavid Wu 	if (ret < 0)
107749c55878SDavid Wu 		return ret;
107849c55878SDavid Wu 
107949c55878SDavid Wu 	if (bank->iomux[iomux_num].type & IOMUX_GPIO_ONLY)
108049c55878SDavid Wu 		return 0;
108149c55878SDavid Wu 
108249c55878SDavid Wu 	debug("setting mux of GPIO%d-%d to %d\n", bank->bank_num, pin, mux);
108349c55878SDavid Wu 
108449c55878SDavid Wu 	regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU)
108549c55878SDavid Wu 				? priv->regmap_pmu : priv->regmap_base;
108649c55878SDavid Wu 
108749c55878SDavid Wu 	/* get basic quadrupel of mux registers and the correct reg inside */
108849c55878SDavid Wu 	mux_type = bank->iomux[iomux_num].type;
108949c55878SDavid Wu 	reg = bank->iomux[iomux_num].offset;
109049c55878SDavid Wu 	if (mux_type & IOMUX_WIDTH_4BIT) {
109149c55878SDavid Wu 		if ((pin % 8) >= 4)
109249c55878SDavid Wu 			reg += 0x4;
109349c55878SDavid Wu 		bit = (pin % 4) * 4;
109449c55878SDavid Wu 		mask = 0xf;
109549c55878SDavid Wu 	} else if (mux_type & IOMUX_WIDTH_3BIT) {
109649c55878SDavid Wu 		if ((pin % 8) >= 5)
109749c55878SDavid Wu 			reg += 0x4;
109849c55878SDavid Wu 		bit = (pin % 8 % 5) * 3;
109949c55878SDavid Wu 		mask = 0x7;
110049c55878SDavid Wu 	} else {
110149c55878SDavid Wu 		bit = (pin % 8) * 2;
110249c55878SDavid Wu 		mask = 0x3;
110349c55878SDavid Wu 	}
110449c55878SDavid Wu 
110549c55878SDavid Wu 	if (bank->recalced_mask & BIT(pin))
110649c55878SDavid Wu 		rockchip_get_recalced_mux(bank, pin, &reg, &bit, &mask);
110749c55878SDavid Wu 
110849c55878SDavid Wu 	if (bank->route_mask & BIT(pin)) {
110949c55878SDavid Wu 		if (rockchip_get_mux_route(bank, pin, mux, &route_reg,
111049c55878SDavid Wu 					   &route_val)) {
111149c55878SDavid Wu 			ret = regmap_write(regmap, route_reg, route_val);
111249c55878SDavid Wu 			if (ret)
111349c55878SDavid Wu 				return ret;
111449c55878SDavid Wu 		}
111549c55878SDavid Wu 	}
111649c55878SDavid Wu 
1117*4bafc2daSDavid Wu 	if (mux_type & IOMUX_WRITABLE_32BIT) {
11188bf1bc66SDavid Wu 		regmap_read(regmap, reg, &data);
1119*4bafc2daSDavid Wu 		data &= ~(mask << bit);
1120*4bafc2daSDavid Wu 	} else {
112149c55878SDavid Wu 		data = (mask << (bit + 16));
1122*4bafc2daSDavid Wu 	}
11238bf1bc66SDavid Wu 
112449c55878SDavid Wu 	data |= (mux & mask) << bit;
112549c55878SDavid Wu 	ret = regmap_write(regmap, reg, data);
112649c55878SDavid Wu 
112749c55878SDavid Wu 	return ret;
112849c55878SDavid Wu }
112949c55878SDavid Wu 
113049c55878SDavid Wu #define PX30_PULL_PMU_OFFSET		0x10
113149c55878SDavid Wu #define PX30_PULL_GRF_OFFSET		0x60
113249c55878SDavid Wu #define PX30_PULL_BITS_PER_PIN		2
113349c55878SDavid Wu #define PX30_PULL_PINS_PER_REG		8
113449c55878SDavid Wu #define PX30_PULL_BANK_STRIDE		16
113549c55878SDavid Wu 
113649c55878SDavid Wu static void px30_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
113749c55878SDavid Wu 				       int pin_num, struct regmap **regmap,
113849c55878SDavid Wu 				       int *reg, u8 *bit)
113949c55878SDavid Wu {
114049c55878SDavid Wu 	struct rockchip_pinctrl_priv *priv = bank->priv;
114149c55878SDavid Wu 
114249c55878SDavid Wu 	/* The first 32 pins of the first bank are located in PMU */
114349c55878SDavid Wu 	if (bank->bank_num == 0) {
114449c55878SDavid Wu 		*regmap = priv->regmap_pmu;
114549c55878SDavid Wu 		*reg = PX30_PULL_PMU_OFFSET;
114649c55878SDavid Wu 	} else {
114749c55878SDavid Wu 		*regmap = priv->regmap_base;
114849c55878SDavid Wu 		*reg = PX30_PULL_GRF_OFFSET;
114949c55878SDavid Wu 
115049c55878SDavid Wu 		/* correct the offset, as we're starting with the 2nd bank */
115149c55878SDavid Wu 		*reg -= 0x10;
115249c55878SDavid Wu 		*reg += bank->bank_num * PX30_PULL_BANK_STRIDE;
115349c55878SDavid Wu 	}
115449c55878SDavid Wu 
115549c55878SDavid Wu 	*reg += ((pin_num / PX30_PULL_PINS_PER_REG) * 4);
115649c55878SDavid Wu 	*bit = (pin_num % PX30_PULL_PINS_PER_REG);
115749c55878SDavid Wu 	*bit *= PX30_PULL_BITS_PER_PIN;
115849c55878SDavid Wu }
115949c55878SDavid Wu 
116049c55878SDavid Wu #define PX30_DRV_PMU_OFFSET		0x20
116149c55878SDavid Wu #define PX30_DRV_GRF_OFFSET		0xf0
116249c55878SDavid Wu #define PX30_DRV_BITS_PER_PIN		2
116349c55878SDavid Wu #define PX30_DRV_PINS_PER_REG		8
116449c55878SDavid Wu #define PX30_DRV_BANK_STRIDE		16
116549c55878SDavid Wu 
116649c55878SDavid Wu static void px30_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
116749c55878SDavid Wu 				      int pin_num, struct regmap **regmap,
116849c55878SDavid Wu 				      int *reg, u8 *bit)
116949c55878SDavid Wu {
117049c55878SDavid Wu 	struct rockchip_pinctrl_priv *priv = bank->priv;
117149c55878SDavid Wu 
117249c55878SDavid Wu 	/* The first 32 pins of the first bank are located in PMU */
117349c55878SDavid Wu 	if (bank->bank_num == 0) {
117449c55878SDavid Wu 		*regmap = priv->regmap_pmu;
117549c55878SDavid Wu 		*reg = PX30_DRV_PMU_OFFSET;
117649c55878SDavid Wu 	} else {
117749c55878SDavid Wu 		*regmap = priv->regmap_base;
117849c55878SDavid Wu 		*reg = PX30_DRV_GRF_OFFSET;
117949c55878SDavid Wu 
118049c55878SDavid Wu 		/* correct the offset, as we're starting with the 2nd bank */
118149c55878SDavid Wu 		*reg -= 0x10;
118249c55878SDavid Wu 		*reg += bank->bank_num * PX30_DRV_BANK_STRIDE;
118349c55878SDavid Wu 	}
118449c55878SDavid Wu 
118549c55878SDavid Wu 	*reg += ((pin_num / PX30_DRV_PINS_PER_REG) * 4);
118649c55878SDavid Wu 	*bit = (pin_num % PX30_DRV_PINS_PER_REG);
118749c55878SDavid Wu 	*bit *= PX30_DRV_BITS_PER_PIN;
118849c55878SDavid Wu }
118949c55878SDavid Wu 
119049c55878SDavid Wu #define PX30_SCHMITT_PMU_OFFSET			0x38
119149c55878SDavid Wu #define PX30_SCHMITT_GRF_OFFSET			0xc0
119249c55878SDavid Wu #define PX30_SCHMITT_PINS_PER_PMU_REG		16
119349c55878SDavid Wu #define PX30_SCHMITT_BANK_STRIDE		16
119449c55878SDavid Wu #define PX30_SCHMITT_PINS_PER_GRF_REG		8
119549c55878SDavid Wu 
119649c55878SDavid Wu static int px30_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank,
119749c55878SDavid Wu 					 int pin_num,
119849c55878SDavid Wu 					 struct regmap **regmap,
119949c55878SDavid Wu 					 int *reg, u8 *bit)
120049c55878SDavid Wu {
120149c55878SDavid Wu 	struct rockchip_pinctrl_priv *priv = bank->priv;
120249c55878SDavid Wu 	int pins_per_reg;
120349c55878SDavid Wu 
120449c55878SDavid Wu 	if (bank->bank_num == 0) {
120549c55878SDavid Wu 		*regmap = priv->regmap_pmu;
120649c55878SDavid Wu 		*reg = PX30_SCHMITT_PMU_OFFSET;
120749c55878SDavid Wu 		pins_per_reg = PX30_SCHMITT_PINS_PER_PMU_REG;
120849c55878SDavid Wu 	} else {
120949c55878SDavid Wu 		*regmap = priv->regmap_base;
121049c55878SDavid Wu 		*reg = PX30_SCHMITT_GRF_OFFSET;
121149c55878SDavid Wu 		pins_per_reg = PX30_SCHMITT_PINS_PER_GRF_REG;
121249c55878SDavid Wu 		*reg += (bank->bank_num - 1) * PX30_SCHMITT_BANK_STRIDE;
121349c55878SDavid Wu 	}
121449c55878SDavid Wu 	*reg += ((pin_num / pins_per_reg) * 4);
121549c55878SDavid Wu 	*bit = pin_num % pins_per_reg;
121649c55878SDavid Wu 
121749c55878SDavid Wu 	return 0;
121849c55878SDavid Wu }
121949c55878SDavid Wu 
122049c55878SDavid Wu #define RV1108_PULL_PMU_OFFSET		0x10
122149c55878SDavid Wu #define RV1108_PULL_OFFSET		0x110
122249c55878SDavid Wu #define RV1108_PULL_PINS_PER_REG	8
122349c55878SDavid Wu #define RV1108_PULL_BITS_PER_PIN	2
122449c55878SDavid Wu #define RV1108_PULL_BANK_STRIDE		16
122549c55878SDavid Wu 
122649c55878SDavid Wu static void rv1108_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
122749c55878SDavid Wu 					 int pin_num, struct regmap **regmap,
122849c55878SDavid Wu 					 int *reg, u8 *bit)
122949c55878SDavid Wu {
123049c55878SDavid Wu 	struct rockchip_pinctrl_priv *priv = bank->priv;
123149c55878SDavid Wu 
123249c55878SDavid Wu 	/* The first 24 pins of the first bank are located in PMU */
123349c55878SDavid Wu 	if (bank->bank_num == 0) {
123449c55878SDavid Wu 		*regmap = priv->regmap_pmu;
123549c55878SDavid Wu 		*reg = RV1108_PULL_PMU_OFFSET;
123649c55878SDavid Wu 	} else {
123749c55878SDavid Wu 		*reg = RV1108_PULL_OFFSET;
123849c55878SDavid Wu 		*regmap = priv->regmap_base;
123949c55878SDavid Wu 		/* correct the offset, as we're starting with the 2nd bank */
124049c55878SDavid Wu 		*reg -= 0x10;
124149c55878SDavid Wu 		*reg += bank->bank_num * RV1108_PULL_BANK_STRIDE;
124249c55878SDavid Wu 	}
124349c55878SDavid Wu 
124449c55878SDavid Wu 	*reg += ((pin_num / RV1108_PULL_PINS_PER_REG) * 4);
124549c55878SDavid Wu 	*bit = (pin_num % RV1108_PULL_PINS_PER_REG);
124649c55878SDavid Wu 	*bit *= RV1108_PULL_BITS_PER_PIN;
124749c55878SDavid Wu }
124849c55878SDavid Wu 
124949c55878SDavid Wu #define RV1108_DRV_PMU_OFFSET		0x20
125049c55878SDavid Wu #define RV1108_DRV_GRF_OFFSET		0x210
125149c55878SDavid Wu #define RV1108_DRV_BITS_PER_PIN		2
125249c55878SDavid Wu #define RV1108_DRV_PINS_PER_REG		8
125349c55878SDavid Wu #define RV1108_DRV_BANK_STRIDE		16
125449c55878SDavid Wu 
125549c55878SDavid Wu static void rv1108_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
125649c55878SDavid Wu 					int pin_num, struct regmap **regmap,
125749c55878SDavid Wu 					int *reg, u8 *bit)
125849c55878SDavid Wu {
125949c55878SDavid Wu 	struct rockchip_pinctrl_priv *priv = bank->priv;
126049c55878SDavid Wu 
126149c55878SDavid Wu 	/* The first 24 pins of the first bank are located in PMU */
126249c55878SDavid Wu 	if (bank->bank_num == 0) {
126349c55878SDavid Wu 		*regmap = priv->regmap_pmu;
126449c55878SDavid Wu 		*reg = RV1108_DRV_PMU_OFFSET;
126549c55878SDavid Wu 	} else {
126649c55878SDavid Wu 		*regmap = priv->regmap_base;
126749c55878SDavid Wu 		*reg = RV1108_DRV_GRF_OFFSET;
126849c55878SDavid Wu 
126949c55878SDavid Wu 		/* correct the offset, as we're starting with the 2nd bank */
127049c55878SDavid Wu 		*reg -= 0x10;
127149c55878SDavid Wu 		*reg += bank->bank_num * RV1108_DRV_BANK_STRIDE;
127249c55878SDavid Wu 	}
127349c55878SDavid Wu 
127449c55878SDavid Wu 	*reg += ((pin_num / RV1108_DRV_PINS_PER_REG) * 4);
127549c55878SDavid Wu 	*bit = pin_num % RV1108_DRV_PINS_PER_REG;
127649c55878SDavid Wu 	*bit *= RV1108_DRV_BITS_PER_PIN;
127749c55878SDavid Wu }
127849c55878SDavid Wu 
127949c55878SDavid Wu #define RV1108_SCHMITT_PMU_OFFSET		0x30
128049c55878SDavid Wu #define RV1108_SCHMITT_GRF_OFFSET		0x388
128149c55878SDavid Wu #define RV1108_SCHMITT_BANK_STRIDE		8
128249c55878SDavid Wu #define RV1108_SCHMITT_PINS_PER_GRF_REG		16
128349c55878SDavid Wu #define RV1108_SCHMITT_PINS_PER_PMU_REG		8
128449c55878SDavid Wu 
128549c55878SDavid Wu static int rv1108_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank,
128649c55878SDavid Wu 					   int pin_num,
128749c55878SDavid Wu 					   struct regmap **regmap,
128849c55878SDavid Wu 					   int *reg, u8 *bit)
128949c55878SDavid Wu {
129049c55878SDavid Wu 	struct rockchip_pinctrl_priv *priv = bank->priv;
129149c55878SDavid Wu 	int pins_per_reg;
129249c55878SDavid Wu 
129349c55878SDavid Wu 	if (bank->bank_num == 0) {
129449c55878SDavid Wu 		*regmap = priv->regmap_pmu;
129549c55878SDavid Wu 		*reg = RV1108_SCHMITT_PMU_OFFSET;
129649c55878SDavid Wu 		pins_per_reg = RV1108_SCHMITT_PINS_PER_PMU_REG;
129749c55878SDavid Wu 	} else {
129849c55878SDavid Wu 		*regmap = priv->regmap_base;
129949c55878SDavid Wu 		*reg = RV1108_SCHMITT_GRF_OFFSET;
130049c55878SDavid Wu 		pins_per_reg = RV1108_SCHMITT_PINS_PER_GRF_REG;
130149c55878SDavid Wu 		*reg += (bank->bank_num  - 1) * RV1108_SCHMITT_BANK_STRIDE;
130249c55878SDavid Wu 	}
130349c55878SDavid Wu 	*reg += ((pin_num / pins_per_reg) * 4);
130449c55878SDavid Wu 	*bit = pin_num % pins_per_reg;
130549c55878SDavid Wu 
130649c55878SDavid Wu 	return 0;
130749c55878SDavid Wu }
130849c55878SDavid Wu 
130949c55878SDavid Wu #define RK2928_PULL_OFFSET		0x118
131049c55878SDavid Wu #define RK2928_PULL_PINS_PER_REG	16
131149c55878SDavid Wu #define RK2928_PULL_BANK_STRIDE		8
131249c55878SDavid Wu 
131349c55878SDavid Wu static void rk2928_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
131449c55878SDavid Wu 					 int pin_num, struct regmap **regmap,
131549c55878SDavid Wu 					 int *reg, u8 *bit)
131649c55878SDavid Wu {
131749c55878SDavid Wu 	struct rockchip_pinctrl_priv *priv = bank->priv;
131849c55878SDavid Wu 
131949c55878SDavid Wu 	*regmap = priv->regmap_base;
132049c55878SDavid Wu 	*reg = RK2928_PULL_OFFSET;
132149c55878SDavid Wu 	*reg += bank->bank_num * RK2928_PULL_BANK_STRIDE;
132249c55878SDavid Wu 	*reg += (pin_num / RK2928_PULL_PINS_PER_REG) * 4;
132349c55878SDavid Wu 
132449c55878SDavid Wu 	*bit = pin_num % RK2928_PULL_PINS_PER_REG;
132549c55878SDavid Wu };
132649c55878SDavid Wu 
132749c55878SDavid Wu #define RK3128_PULL_OFFSET	0x118
132849c55878SDavid Wu 
132949c55878SDavid Wu static void rk3128_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
133049c55878SDavid Wu 					 int pin_num, struct regmap **regmap,
133149c55878SDavid Wu 					 int *reg, u8 *bit)
133249c55878SDavid Wu {
133349c55878SDavid Wu 	struct rockchip_pinctrl_priv *priv = bank->priv;
133449c55878SDavid Wu 
133549c55878SDavid Wu 	*regmap = priv->regmap_base;
133649c55878SDavid Wu 	*reg = RK3128_PULL_OFFSET;
133749c55878SDavid Wu 	*reg += bank->bank_num * RK2928_PULL_BANK_STRIDE;
133849c55878SDavid Wu 	*reg += ((pin_num / RK2928_PULL_PINS_PER_REG) * 4);
133949c55878SDavid Wu 
134049c55878SDavid Wu 	*bit = pin_num % RK2928_PULL_PINS_PER_REG;
134149c55878SDavid Wu }
134249c55878SDavid Wu 
134349c55878SDavid Wu #define RK3188_PULL_OFFSET		0x164
134449c55878SDavid Wu #define RK3188_PULL_BITS_PER_PIN	2
134549c55878SDavid Wu #define RK3188_PULL_PINS_PER_REG	8
134649c55878SDavid Wu #define RK3188_PULL_BANK_STRIDE		16
134749c55878SDavid Wu #define RK3188_PULL_PMU_OFFSET		0x64
134849c55878SDavid Wu 
134949c55878SDavid Wu static void rk3188_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
135049c55878SDavid Wu 					 int pin_num, struct regmap **regmap,
135149c55878SDavid Wu 					 int *reg, u8 *bit)
135249c55878SDavid Wu {
135349c55878SDavid Wu 	struct rockchip_pinctrl_priv *priv = bank->priv;
135449c55878SDavid Wu 
135549c55878SDavid Wu 	/* The first 12 pins of the first bank are located elsewhere */
135649c55878SDavid Wu 	if (bank->bank_num == 0 && pin_num < 12) {
135749c55878SDavid Wu 		*regmap = priv->regmap_pmu;
135849c55878SDavid Wu 		*reg = RK3188_PULL_PMU_OFFSET;
135949c55878SDavid Wu 
136049c55878SDavid Wu 		*reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4);
136149c55878SDavid Wu 		*bit = pin_num % RK3188_PULL_PINS_PER_REG;
136249c55878SDavid Wu 		*bit *= RK3188_PULL_BITS_PER_PIN;
136349c55878SDavid Wu 	} else {
136449c55878SDavid Wu 		*regmap = priv->regmap_base;
136549c55878SDavid Wu 		*reg = RK3188_PULL_OFFSET;
136649c55878SDavid Wu 
136749c55878SDavid Wu 		/* correct the offset, as it is the 2nd pull register */
136849c55878SDavid Wu 		*reg -= 4;
136949c55878SDavid Wu 		*reg += bank->bank_num * RK3188_PULL_BANK_STRIDE;
137049c55878SDavid Wu 		*reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4);
137149c55878SDavid Wu 
137249c55878SDavid Wu 		/*
137349c55878SDavid Wu 		 * The bits in these registers have an inverse ordering
137449c55878SDavid Wu 		 * with the lowest pin being in bits 15:14 and the highest
137549c55878SDavid Wu 		 * pin in bits 1:0
137649c55878SDavid Wu 		 */
137749c55878SDavid Wu 		*bit = 7 - (pin_num % RK3188_PULL_PINS_PER_REG);
137849c55878SDavid Wu 		*bit *= RK3188_PULL_BITS_PER_PIN;
137949c55878SDavid Wu 	}
138049c55878SDavid Wu }
138149c55878SDavid Wu 
138249c55878SDavid Wu #define RK3288_PULL_OFFSET		0x140
138349c55878SDavid Wu static void rk3288_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
138449c55878SDavid Wu 					 int pin_num, struct regmap **regmap,
138549c55878SDavid Wu 					 int *reg, u8 *bit)
138649c55878SDavid Wu {
138749c55878SDavid Wu 	struct rockchip_pinctrl_priv *priv = bank->priv;
138849c55878SDavid Wu 
138949c55878SDavid Wu 	/* The first 24 pins of the first bank are located in PMU */
139049c55878SDavid Wu 	if (bank->bank_num == 0) {
139149c55878SDavid Wu 		*regmap = priv->regmap_pmu;
139249c55878SDavid Wu 		*reg = RK3188_PULL_PMU_OFFSET;
139349c55878SDavid Wu 
139449c55878SDavid Wu 		*reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4);
139549c55878SDavid Wu 		*bit = pin_num % RK3188_PULL_PINS_PER_REG;
139649c55878SDavid Wu 		*bit *= RK3188_PULL_BITS_PER_PIN;
139749c55878SDavid Wu 	} else {
139849c55878SDavid Wu 		*regmap = priv->regmap_base;
139949c55878SDavid Wu 		*reg = RK3288_PULL_OFFSET;
140049c55878SDavid Wu 
140149c55878SDavid Wu 		/* correct the offset, as we're starting with the 2nd bank */
140249c55878SDavid Wu 		*reg -= 0x10;
140349c55878SDavid Wu 		*reg += bank->bank_num * RK3188_PULL_BANK_STRIDE;
140449c55878SDavid Wu 		*reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4);
140549c55878SDavid Wu 
140649c55878SDavid Wu 		*bit = (pin_num % RK3188_PULL_PINS_PER_REG);
140749c55878SDavid Wu 		*bit *= RK3188_PULL_BITS_PER_PIN;
140849c55878SDavid Wu 	}
140949c55878SDavid Wu }
141049c55878SDavid Wu 
141149c55878SDavid Wu #define RK3288_DRV_PMU_OFFSET		0x70
141249c55878SDavid Wu #define RK3288_DRV_GRF_OFFSET		0x1c0
141349c55878SDavid Wu #define RK3288_DRV_BITS_PER_PIN		2
141449c55878SDavid Wu #define RK3288_DRV_PINS_PER_REG		8
141549c55878SDavid Wu #define RK3288_DRV_BANK_STRIDE		16
141649c55878SDavid Wu 
141749c55878SDavid Wu static void rk3288_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
141849c55878SDavid Wu 					int pin_num, struct regmap **regmap,
141949c55878SDavid Wu 					int *reg, u8 *bit)
142049c55878SDavid Wu {
142149c55878SDavid Wu 	struct rockchip_pinctrl_priv *priv = bank->priv;
142249c55878SDavid Wu 
142349c55878SDavid Wu 	/* The first 24 pins of the first bank are located in PMU */
142449c55878SDavid Wu 	if (bank->bank_num == 0) {
142549c55878SDavid Wu 		*regmap = priv->regmap_pmu;
142649c55878SDavid Wu 		*reg = RK3288_DRV_PMU_OFFSET;
142749c55878SDavid Wu 
142849c55878SDavid Wu 		*reg += ((pin_num / RK3288_DRV_PINS_PER_REG) * 4);
142949c55878SDavid Wu 		*bit = pin_num % RK3288_DRV_PINS_PER_REG;
143049c55878SDavid Wu 		*bit *= RK3288_DRV_BITS_PER_PIN;
143149c55878SDavid Wu 	} else {
143249c55878SDavid Wu 		*regmap = priv->regmap_base;
143349c55878SDavid Wu 		*reg = RK3288_DRV_GRF_OFFSET;
143449c55878SDavid Wu 
143549c55878SDavid Wu 		/* correct the offset, as we're starting with the 2nd bank */
143649c55878SDavid Wu 		*reg -= 0x10;
143749c55878SDavid Wu 		*reg += bank->bank_num * RK3288_DRV_BANK_STRIDE;
143849c55878SDavid Wu 		*reg += ((pin_num / RK3288_DRV_PINS_PER_REG) * 4);
143949c55878SDavid Wu 
144049c55878SDavid Wu 		*bit = (pin_num % RK3288_DRV_PINS_PER_REG);
144149c55878SDavid Wu 		*bit *= RK3288_DRV_BITS_PER_PIN;
144249c55878SDavid Wu 	}
144349c55878SDavid Wu }
144449c55878SDavid Wu 
144549c55878SDavid Wu #define RK3228_PULL_OFFSET		0x100
144649c55878SDavid Wu 
144749c55878SDavid Wu static void rk3228_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
144849c55878SDavid Wu 					 int pin_num, struct regmap **regmap,
144949c55878SDavid Wu 					 int *reg, u8 *bit)
145049c55878SDavid Wu {
145149c55878SDavid Wu 	struct rockchip_pinctrl_priv *priv = bank->priv;
145249c55878SDavid Wu 
145349c55878SDavid Wu 	*regmap = priv->regmap_base;
145449c55878SDavid Wu 	*reg = RK3228_PULL_OFFSET;
145549c55878SDavid Wu 	*reg += bank->bank_num * RK3188_PULL_BANK_STRIDE;
145649c55878SDavid Wu 	*reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4);
145749c55878SDavid Wu 
145849c55878SDavid Wu 	*bit = (pin_num % RK3188_PULL_PINS_PER_REG);
145949c55878SDavid Wu 	*bit *= RK3188_PULL_BITS_PER_PIN;
146049c55878SDavid Wu }
146149c55878SDavid Wu 
146249c55878SDavid Wu #define RK3228_DRV_GRF_OFFSET		0x200
146349c55878SDavid Wu 
146449c55878SDavid Wu static void rk3228_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
146549c55878SDavid Wu 					int pin_num, struct regmap **regmap,
146649c55878SDavid Wu 					int *reg, u8 *bit)
146749c55878SDavid Wu {
146849c55878SDavid Wu 	struct rockchip_pinctrl_priv *priv = bank->priv;
146949c55878SDavid Wu 
147049c55878SDavid Wu 	*regmap = priv->regmap_base;
147149c55878SDavid Wu 	*reg = RK3228_DRV_GRF_OFFSET;
147249c55878SDavid Wu 	*reg += bank->bank_num * RK3288_DRV_BANK_STRIDE;
147349c55878SDavid Wu 	*reg += ((pin_num / RK3288_DRV_PINS_PER_REG) * 4);
147449c55878SDavid Wu 
147549c55878SDavid Wu 	*bit = (pin_num % RK3288_DRV_PINS_PER_REG);
147649c55878SDavid Wu 	*bit *= RK3288_DRV_BITS_PER_PIN;
147749c55878SDavid Wu }
147849c55878SDavid Wu 
1479b3077611SDavid Wu #define RK3308_PULL_OFFSET		0xa0
1480b3077611SDavid Wu 
1481b3077611SDavid Wu static void rk3308_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
1482b3077611SDavid Wu 					 int pin_num, struct regmap **regmap,
1483b3077611SDavid Wu 					 int *reg, u8 *bit)
1484b3077611SDavid Wu {
1485b3077611SDavid Wu 	struct rockchip_pinctrl_priv *priv = bank->priv;
1486b3077611SDavid Wu 
1487b3077611SDavid Wu 	*regmap = priv->regmap_base;
1488b3077611SDavid Wu 	*reg = RK3308_PULL_OFFSET;
1489b3077611SDavid Wu 	*reg += bank->bank_num * RK3188_PULL_BANK_STRIDE;
1490b3077611SDavid Wu 	*reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4);
1491b3077611SDavid Wu 
1492b3077611SDavid Wu 	*bit = (pin_num % RK3188_PULL_PINS_PER_REG);
1493b3077611SDavid Wu 	*bit *= RK3188_PULL_BITS_PER_PIN;
1494b3077611SDavid Wu }
1495b3077611SDavid Wu 
1496b3077611SDavid Wu #define RK3308_DRV_GRF_OFFSET		0x100
1497b3077611SDavid Wu 
1498b3077611SDavid Wu static void rk3308_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
1499b3077611SDavid Wu 					int pin_num, struct regmap **regmap,
1500b3077611SDavid Wu 					int *reg, u8 *bit)
1501b3077611SDavid Wu {
1502b3077611SDavid Wu 	struct rockchip_pinctrl_priv *priv = bank->priv;
1503b3077611SDavid Wu 
1504b3077611SDavid Wu 	*regmap = priv->regmap_base;
1505b3077611SDavid Wu 	*reg = RK3308_DRV_GRF_OFFSET;
1506b3077611SDavid Wu 	*reg += bank->bank_num * RK3288_DRV_BANK_STRIDE;
1507b3077611SDavid Wu 	*reg += ((pin_num / RK3288_DRV_PINS_PER_REG) * 4);
1508b3077611SDavid Wu 
1509b3077611SDavid Wu 	*bit = (pin_num % RK3288_DRV_PINS_PER_REG);
1510b3077611SDavid Wu 	*bit *= RK3288_DRV_BITS_PER_PIN;
1511b3077611SDavid Wu }
1512b3077611SDavid Wu 
1513b3077611SDavid Wu #define RK3308_SCHMITT_PINS_PER_REG	8
1514b3077611SDavid Wu #define RK3308_SCHMITT_BANK_STRIDE	16
1515b3077611SDavid Wu #define RK3308_SCHMITT_GRF_OFFSET	0x1a0
1516b3077611SDavid Wu 
1517b3077611SDavid Wu static int rk3308_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank,
1518b3077611SDavid Wu 					   int pin_num,
1519b3077611SDavid Wu 					   struct regmap **regmap,
1520b3077611SDavid Wu 					   int *reg, u8 *bit)
1521b3077611SDavid Wu {
1522b3077611SDavid Wu 	struct rockchip_pinctrl_priv *priv = bank->priv;
1523b3077611SDavid Wu 
1524b3077611SDavid Wu 	*regmap = priv->regmap_base;
1525b3077611SDavid Wu 	*reg = RK3308_SCHMITT_GRF_OFFSET;
1526b3077611SDavid Wu 
1527b3077611SDavid Wu 	*reg += bank->bank_num * RK3308_SCHMITT_BANK_STRIDE;
1528b3077611SDavid Wu 	*reg += ((pin_num / RK3308_SCHMITT_PINS_PER_REG) * 4);
1529b3077611SDavid Wu 	*bit = pin_num % RK3308_SCHMITT_PINS_PER_REG;
1530b3077611SDavid Wu 
1531b3077611SDavid Wu 	return 0;
1532b3077611SDavid Wu }
1533b3077611SDavid Wu 
153449c55878SDavid Wu #define RK3368_PULL_GRF_OFFSET		0x100
153549c55878SDavid Wu #define RK3368_PULL_PMU_OFFSET		0x10
153649c55878SDavid Wu 
153749c55878SDavid Wu static void rk3368_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
153849c55878SDavid Wu 					 int pin_num, struct regmap **regmap,
153949c55878SDavid Wu 					 int *reg, u8 *bit)
154049c55878SDavid Wu {
154149c55878SDavid Wu 	struct rockchip_pinctrl_priv *priv = bank->priv;
154249c55878SDavid Wu 
154349c55878SDavid Wu 	/* The first 32 pins of the first bank are located in PMU */
154449c55878SDavid Wu 	if (bank->bank_num == 0) {
154549c55878SDavid Wu 		*regmap = priv->regmap_pmu;
154649c55878SDavid Wu 		*reg = RK3368_PULL_PMU_OFFSET;
154749c55878SDavid Wu 
154849c55878SDavid Wu 		*reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4);
154949c55878SDavid Wu 		*bit = pin_num % RK3188_PULL_PINS_PER_REG;
155049c55878SDavid Wu 		*bit *= RK3188_PULL_BITS_PER_PIN;
155149c55878SDavid Wu 	} else {
155249c55878SDavid Wu 		*regmap = priv->regmap_base;
155349c55878SDavid Wu 		*reg = RK3368_PULL_GRF_OFFSET;
155449c55878SDavid Wu 
155549c55878SDavid Wu 		/* correct the offset, as we're starting with the 2nd bank */
155649c55878SDavid Wu 		*reg -= 0x10;
155749c55878SDavid Wu 		*reg += bank->bank_num * RK3188_PULL_BANK_STRIDE;
155849c55878SDavid Wu 		*reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4);
155949c55878SDavid Wu 
156049c55878SDavid Wu 		*bit = (pin_num % RK3188_PULL_PINS_PER_REG);
156149c55878SDavid Wu 		*bit *= RK3188_PULL_BITS_PER_PIN;
156249c55878SDavid Wu 	}
156349c55878SDavid Wu }
156449c55878SDavid Wu 
156549c55878SDavid Wu #define RK3368_DRV_PMU_OFFSET		0x20
156649c55878SDavid Wu #define RK3368_DRV_GRF_OFFSET		0x200
156749c55878SDavid Wu 
156849c55878SDavid Wu static void rk3368_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
156949c55878SDavid Wu 					int pin_num, struct regmap **regmap,
157049c55878SDavid Wu 					int *reg, u8 *bit)
157149c55878SDavid Wu {
157249c55878SDavid Wu 	struct rockchip_pinctrl_priv *priv = bank->priv;
157349c55878SDavid Wu 
157449c55878SDavid Wu 	/* The first 32 pins of the first bank are located in PMU */
157549c55878SDavid Wu 	if (bank->bank_num == 0) {
157649c55878SDavid Wu 		*regmap = priv->regmap_pmu;
157749c55878SDavid Wu 		*reg = RK3368_DRV_PMU_OFFSET;
157849c55878SDavid Wu 
157949c55878SDavid Wu 		*reg += ((pin_num / RK3288_DRV_PINS_PER_REG) * 4);
158049c55878SDavid Wu 		*bit = pin_num % RK3288_DRV_PINS_PER_REG;
158149c55878SDavid Wu 		*bit *= RK3288_DRV_BITS_PER_PIN;
158249c55878SDavid Wu 	} else {
158349c55878SDavid Wu 		*regmap = priv->regmap_base;
158449c55878SDavid Wu 		*reg = RK3368_DRV_GRF_OFFSET;
158549c55878SDavid Wu 
158649c55878SDavid Wu 		/* correct the offset, as we're starting with the 2nd bank */
158749c55878SDavid Wu 		*reg -= 0x10;
158849c55878SDavid Wu 		*reg += bank->bank_num * RK3288_DRV_BANK_STRIDE;
158949c55878SDavid Wu 		*reg += ((pin_num / RK3288_DRV_PINS_PER_REG) * 4);
159049c55878SDavid Wu 
159149c55878SDavid Wu 		*bit = (pin_num % RK3288_DRV_PINS_PER_REG);
159249c55878SDavid Wu 		*bit *= RK3288_DRV_BITS_PER_PIN;
159349c55878SDavid Wu 	}
159449c55878SDavid Wu }
159549c55878SDavid Wu 
159649c55878SDavid Wu #define RK3399_PULL_GRF_OFFSET		0xe040
159749c55878SDavid Wu #define RK3399_PULL_PMU_OFFSET		0x40
159849c55878SDavid Wu #define RK3399_DRV_3BITS_PER_PIN	3
159949c55878SDavid Wu 
160049c55878SDavid Wu static void rk3399_calc_pull_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 bank0:16 and bank1:32 pins are located in PMU */
160749c55878SDavid Wu 	if ((bank->bank_num == 0) || (bank->bank_num == 1)) {
160849c55878SDavid Wu 		*regmap = priv->regmap_pmu;
160949c55878SDavid Wu 		*reg = RK3399_PULL_PMU_OFFSET;
161049c55878SDavid Wu 
161149c55878SDavid Wu 		*reg += bank->bank_num * RK3188_PULL_BANK_STRIDE;
161249c55878SDavid Wu 
161349c55878SDavid Wu 		*reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4);
161449c55878SDavid Wu 		*bit = pin_num % RK3188_PULL_PINS_PER_REG;
161549c55878SDavid Wu 		*bit *= RK3188_PULL_BITS_PER_PIN;
161649c55878SDavid Wu 	} else {
161749c55878SDavid Wu 		*regmap = priv->regmap_base;
161849c55878SDavid Wu 		*reg = RK3399_PULL_GRF_OFFSET;
161949c55878SDavid Wu 
162049c55878SDavid Wu 		/* correct the offset, as we're starting with the 3rd bank */
162149c55878SDavid Wu 		*reg -= 0x20;
162249c55878SDavid Wu 		*reg += bank->bank_num * RK3188_PULL_BANK_STRIDE;
162349c55878SDavid Wu 		*reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4);
162449c55878SDavid Wu 
162549c55878SDavid Wu 		*bit = (pin_num % RK3188_PULL_PINS_PER_REG);
162649c55878SDavid Wu 		*bit *= RK3188_PULL_BITS_PER_PIN;
162749c55878SDavid Wu 	}
162849c55878SDavid Wu }
162949c55878SDavid Wu 
163049c55878SDavid Wu static void rk3399_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
163149c55878SDavid Wu 					int pin_num, struct regmap **regmap,
163249c55878SDavid Wu 					int *reg, u8 *bit)
163349c55878SDavid Wu {
163449c55878SDavid Wu 	struct rockchip_pinctrl_priv *priv = bank->priv;
163549c55878SDavid Wu 	int drv_num = (pin_num / 8);
163649c55878SDavid Wu 
163749c55878SDavid Wu 	/*  The bank0:16 and bank1:32 pins are located in PMU */
163849c55878SDavid Wu 	if ((bank->bank_num == 0) || (bank->bank_num == 1))
163949c55878SDavid Wu 		*regmap = priv->regmap_pmu;
164049c55878SDavid Wu 	else
164149c55878SDavid Wu 		*regmap = priv->regmap_base;
164249c55878SDavid Wu 
164349c55878SDavid Wu 	*reg = bank->drv[drv_num].offset;
164449c55878SDavid Wu 	if ((bank->drv[drv_num].drv_type == DRV_TYPE_IO_1V8_3V0_AUTO) ||
164549c55878SDavid Wu 	    (bank->drv[drv_num].drv_type == DRV_TYPE_IO_3V3_ONLY))
164649c55878SDavid Wu 		*bit = (pin_num % 8) * 3;
164749c55878SDavid Wu 	else
164849c55878SDavid Wu 		*bit = (pin_num % 8) * 2;
164949c55878SDavid Wu }
165049c55878SDavid Wu 
165149c55878SDavid Wu static int rockchip_perpin_drv_list[DRV_TYPE_MAX][8] = {
165249c55878SDavid Wu 	{ 2, 4, 8, 12, -1, -1, -1, -1 },
165349c55878SDavid Wu 	{ 3, 6, 9, 12, -1, -1, -1, -1 },
165449c55878SDavid Wu 	{ 5, 10, 15, 20, -1, -1, -1, -1 },
165549c55878SDavid Wu 	{ 4, 6, 8, 10, 12, 14, 16, 18 },
165649c55878SDavid Wu 	{ 4, 7, 10, 13, 16, 19, 22, 26 }
165749c55878SDavid Wu };
165849c55878SDavid Wu 
165949c55878SDavid Wu static int rockchip_set_drive_perpin(struct rockchip_pin_bank *bank,
166049c55878SDavid Wu 				     int pin_num, int strength)
166149c55878SDavid Wu {
166249c55878SDavid Wu 	struct rockchip_pinctrl_priv *priv = bank->priv;
166349c55878SDavid Wu 	struct rockchip_pin_ctrl *ctrl = priv->ctrl;
166449c55878SDavid Wu 	struct regmap *regmap;
166549c55878SDavid Wu 	int reg, ret, i;
166649c55878SDavid Wu 	u32 data, rmask_bits, temp;
166749c55878SDavid Wu 	u8 bit;
166849c55878SDavid Wu 	int drv_type = bank->drv[pin_num / 8].drv_type;
166949c55878SDavid Wu 
167049c55878SDavid Wu 	debug("setting drive of GPIO%d-%d to %d\n", bank->bank_num,
167149c55878SDavid Wu 	      pin_num, strength);
167249c55878SDavid Wu 
167349c55878SDavid Wu 	ctrl->drv_calc_reg(bank, pin_num, &regmap, &reg, &bit);
167449c55878SDavid Wu 
167549c55878SDavid Wu 	ret = -EINVAL;
167649c55878SDavid Wu 	for (i = 0; i < ARRAY_SIZE(rockchip_perpin_drv_list[drv_type]); i++) {
167749c55878SDavid Wu 		if (rockchip_perpin_drv_list[drv_type][i] == strength) {
167849c55878SDavid Wu 			ret = i;
167949c55878SDavid Wu 			break;
168049c55878SDavid Wu 		} else if (rockchip_perpin_drv_list[drv_type][i] < 0) {
168149c55878SDavid Wu 			ret = rockchip_perpin_drv_list[drv_type][i];
168249c55878SDavid Wu 			break;
168349c55878SDavid Wu 		}
168449c55878SDavid Wu 	}
168549c55878SDavid Wu 
168649c55878SDavid Wu 	if (ret < 0) {
168749c55878SDavid Wu 		debug("unsupported driver strength %d\n", strength);
168849c55878SDavid Wu 		return ret;
168949c55878SDavid Wu 	}
169049c55878SDavid Wu 
169149c55878SDavid Wu 	switch (drv_type) {
169249c55878SDavid Wu 	case DRV_TYPE_IO_1V8_3V0_AUTO:
169349c55878SDavid Wu 	case DRV_TYPE_IO_3V3_ONLY:
169449c55878SDavid Wu 		rmask_bits = RK3399_DRV_3BITS_PER_PIN;
169549c55878SDavid Wu 		switch (bit) {
169649c55878SDavid Wu 		case 0 ... 12:
169749c55878SDavid Wu 			/* regular case, nothing to do */
169849c55878SDavid Wu 			break;
169949c55878SDavid Wu 		case 15:
170049c55878SDavid Wu 			/*
170149c55878SDavid Wu 			 * drive-strength offset is special, as it is spread
170249c55878SDavid Wu 			 * over 2 registers, the bit data[15] contains bit 0
170349c55878SDavid Wu 			 * of the value while temp[1:0] contains bits 2 and 1
170449c55878SDavid Wu 			 */
170549c55878SDavid Wu 			data = (ret & 0x1) << 15;
170649c55878SDavid Wu 			temp = (ret >> 0x1) & 0x3;
170749c55878SDavid Wu 
170849c55878SDavid Wu 			data |= BIT(31);
170949c55878SDavid Wu 			ret = regmap_write(regmap, reg, data);
171049c55878SDavid Wu 			if (ret)
171149c55878SDavid Wu 				return ret;
171249c55878SDavid Wu 
171349c55878SDavid Wu 			temp |= (0x3 << 16);
171449c55878SDavid Wu 			reg += 0x4;
171549c55878SDavid Wu 			ret = regmap_write(regmap, reg, temp);
171649c55878SDavid Wu 
171749c55878SDavid Wu 			return ret;
171849c55878SDavid Wu 		case 18 ... 21:
171949c55878SDavid Wu 			/* setting fully enclosed in the second register */
172049c55878SDavid Wu 			reg += 4;
172149c55878SDavid Wu 			bit -= 16;
172249c55878SDavid Wu 			break;
172349c55878SDavid Wu 		default:
172449c55878SDavid Wu 			debug("unsupported bit: %d for pinctrl drive type: %d\n",
172549c55878SDavid Wu 			      bit, drv_type);
172649c55878SDavid Wu 			return -EINVAL;
172749c55878SDavid Wu 		}
172849c55878SDavid Wu 		break;
172949c55878SDavid Wu 	case DRV_TYPE_IO_DEFAULT:
173049c55878SDavid Wu 	case DRV_TYPE_IO_1V8_OR_3V0:
173149c55878SDavid Wu 	case DRV_TYPE_IO_1V8_ONLY:
173249c55878SDavid Wu 		rmask_bits = RK3288_DRV_BITS_PER_PIN;
173349c55878SDavid Wu 		break;
173449c55878SDavid Wu 	default:
173549c55878SDavid Wu 		debug("unsupported pinctrl drive type: %d\n",
173649c55878SDavid Wu 		      drv_type);
173749c55878SDavid Wu 		return -EINVAL;
173849c55878SDavid Wu 	}
173949c55878SDavid Wu 
174049c55878SDavid Wu 	/* enable the write to the equivalent lower bits */
174149c55878SDavid Wu 	data = ((1 << rmask_bits) - 1) << (bit + 16);
174249c55878SDavid Wu 	data |= (ret << bit);
174349c55878SDavid Wu 
174449c55878SDavid Wu 	ret = regmap_write(regmap, reg, data);
174549c55878SDavid Wu 	return ret;
174649c55878SDavid Wu }
174749c55878SDavid Wu 
174849c55878SDavid Wu static int rockchip_pull_list[PULL_TYPE_MAX][4] = {
174949c55878SDavid Wu 	{
175049c55878SDavid Wu 		PIN_CONFIG_BIAS_DISABLE,
175149c55878SDavid Wu 		PIN_CONFIG_BIAS_PULL_UP,
175249c55878SDavid Wu 		PIN_CONFIG_BIAS_PULL_DOWN,
175349c55878SDavid Wu 		PIN_CONFIG_BIAS_BUS_HOLD
175449c55878SDavid Wu 	},
175549c55878SDavid Wu 	{
175649c55878SDavid Wu 		PIN_CONFIG_BIAS_DISABLE,
175749c55878SDavid Wu 		PIN_CONFIG_BIAS_PULL_DOWN,
175849c55878SDavid Wu 		PIN_CONFIG_BIAS_DISABLE,
175949c55878SDavid Wu 		PIN_CONFIG_BIAS_PULL_UP
176049c55878SDavid Wu 	},
176149c55878SDavid Wu };
176249c55878SDavid Wu 
176349c55878SDavid Wu static int rockchip_set_pull(struct rockchip_pin_bank *bank,
176449c55878SDavid Wu 			     int pin_num, int pull)
176549c55878SDavid Wu {
176649c55878SDavid Wu 	struct rockchip_pinctrl_priv *priv = bank->priv;
176749c55878SDavid Wu 	struct rockchip_pin_ctrl *ctrl = priv->ctrl;
176849c55878SDavid Wu 	struct regmap *regmap;
176949c55878SDavid Wu 	int reg, ret, i, pull_type;
177049c55878SDavid Wu 	u8 bit;
177149c55878SDavid Wu 	u32 data;
177249c55878SDavid Wu 
177349c55878SDavid Wu 	debug("setting pull of GPIO%d-%d to %d\n", bank->bank_num,
177449c55878SDavid Wu 	      pin_num, pull);
177549c55878SDavid Wu 
177649c55878SDavid Wu 	/* rk3066b does support any pulls */
177749c55878SDavid Wu 	if (ctrl->type == RK3066B)
177849c55878SDavid Wu 		return pull ? -EINVAL : 0;
177949c55878SDavid Wu 
178049c55878SDavid Wu 	ctrl->pull_calc_reg(bank, pin_num, &regmap, &reg, &bit);
178149c55878SDavid Wu 
178249c55878SDavid Wu 	switch (ctrl->type) {
178349c55878SDavid Wu 	case RK2928:
178449c55878SDavid Wu 	case RK3128:
178549c55878SDavid Wu 		data = BIT(bit + 16);
178649c55878SDavid Wu 		if (pull == PIN_CONFIG_BIAS_DISABLE)
178749c55878SDavid Wu 			data |= BIT(bit);
178849c55878SDavid Wu 		ret = regmap_write(regmap, reg, data);
178949c55878SDavid Wu 		break;
179049c55878SDavid Wu 	case PX30:
179149c55878SDavid Wu 	case RV1108:
179249c55878SDavid Wu 	case RK3188:
179349c55878SDavid Wu 	case RK3288:
1794b3077611SDavid Wu 	case RK3308:
179549c55878SDavid Wu 	case RK3368:
179649c55878SDavid Wu 	case RK3399:
179749c55878SDavid Wu 		pull_type = bank->pull_type[pin_num / 8];
179849c55878SDavid Wu 		ret = -EINVAL;
179949c55878SDavid Wu 		for (i = 0; i < ARRAY_SIZE(rockchip_pull_list[pull_type]);
180049c55878SDavid Wu 			i++) {
180149c55878SDavid Wu 			if (rockchip_pull_list[pull_type][i] == pull) {
180249c55878SDavid Wu 				ret = i;
180349c55878SDavid Wu 				break;
180449c55878SDavid Wu 			}
180549c55878SDavid Wu 		}
180649c55878SDavid Wu 
180749c55878SDavid Wu 		if (ret < 0) {
180849c55878SDavid Wu 			debug("unsupported pull setting %d\n", pull);
180949c55878SDavid Wu 			return ret;
181049c55878SDavid Wu 		}
181149c55878SDavid Wu 
181249c55878SDavid Wu 		/* enable the write to the equivalent lower bits */
181349c55878SDavid Wu 		data = ((1 << RK3188_PULL_BITS_PER_PIN) - 1) << (bit + 16);
181449c55878SDavid Wu 		data |= (ret << bit);
181549c55878SDavid Wu 
181649c55878SDavid Wu 		ret = regmap_write(regmap, reg, data);
181749c55878SDavid Wu 		break;
181849c55878SDavid Wu 	default:
181949c55878SDavid Wu 		debug("unsupported pinctrl type\n");
182049c55878SDavid Wu 		return -EINVAL;
182149c55878SDavid Wu 	}
182249c55878SDavid Wu 
182349c55878SDavid Wu 	return ret;
182449c55878SDavid Wu }
182549c55878SDavid Wu 
182649c55878SDavid Wu #define RK3328_SCHMITT_BITS_PER_PIN		1
182749c55878SDavid Wu #define RK3328_SCHMITT_PINS_PER_REG		16
182849c55878SDavid Wu #define RK3328_SCHMITT_BANK_STRIDE		8
182949c55878SDavid Wu #define RK3328_SCHMITT_GRF_OFFSET		0x380
183049c55878SDavid Wu 
183149c55878SDavid Wu static int rk3328_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank,
183249c55878SDavid Wu 					   int pin_num,
183349c55878SDavid Wu 					   struct regmap **regmap,
183449c55878SDavid Wu 					   int *reg, u8 *bit)
183549c55878SDavid Wu {
183649c55878SDavid Wu 	struct rockchip_pinctrl_priv *priv = bank->priv;
183749c55878SDavid Wu 
183849c55878SDavid Wu 	*regmap = priv->regmap_base;
183949c55878SDavid Wu 	*reg = RK3328_SCHMITT_GRF_OFFSET;
184049c55878SDavid Wu 
184149c55878SDavid Wu 	*reg += bank->bank_num * RK3328_SCHMITT_BANK_STRIDE;
184249c55878SDavid Wu 	*reg += ((pin_num / RK3328_SCHMITT_PINS_PER_REG) * 4);
184349c55878SDavid Wu 	*bit = pin_num % RK3328_SCHMITT_PINS_PER_REG;
184449c55878SDavid Wu 
184549c55878SDavid Wu 	return 0;
184649c55878SDavid Wu }
184749c55878SDavid Wu 
184849c55878SDavid Wu static int rockchip_set_schmitt(struct rockchip_pin_bank *bank,
184949c55878SDavid Wu 				int pin_num, int enable)
185049c55878SDavid Wu {
185149c55878SDavid Wu 	struct rockchip_pinctrl_priv *priv = bank->priv;
185249c55878SDavid Wu 	struct rockchip_pin_ctrl *ctrl = priv->ctrl;
185349c55878SDavid Wu 	struct regmap *regmap;
185449c55878SDavid Wu 	int reg, ret;
185549c55878SDavid Wu 	u8 bit;
185649c55878SDavid Wu 	u32 data;
185749c55878SDavid Wu 
185849c55878SDavid Wu 	debug("setting input schmitt of GPIO%d-%d to %d\n", bank->bank_num,
185949c55878SDavid Wu 	      pin_num, enable);
186049c55878SDavid Wu 
186149c55878SDavid Wu 	ret = ctrl->schmitt_calc_reg(bank, pin_num, &regmap, &reg, &bit);
186249c55878SDavid Wu 	if (ret)
186349c55878SDavid Wu 		return ret;
186449c55878SDavid Wu 
186549c55878SDavid Wu 	/* enable the write to the equivalent lower bits */
186649c55878SDavid Wu 	data = BIT(bit + 16) | (enable << bit);
186749c55878SDavid Wu 
186849c55878SDavid Wu 	return regmap_write(regmap, reg, data);
186949c55878SDavid Wu }
187049c55878SDavid Wu 
187149c55878SDavid Wu /*
187249c55878SDavid Wu  * Pinconf_ops handling
187349c55878SDavid Wu  */
187449c55878SDavid Wu static bool rockchip_pinconf_pull_valid(struct rockchip_pin_ctrl *ctrl,
187549c55878SDavid Wu 					unsigned int pull)
187649c55878SDavid Wu {
187749c55878SDavid Wu 	switch (ctrl->type) {
187849c55878SDavid Wu 	case RK2928:
187949c55878SDavid Wu 	case RK3128:
188049c55878SDavid Wu 		return (pull == PIN_CONFIG_BIAS_PULL_PIN_DEFAULT ||
188149c55878SDavid Wu 			pull == PIN_CONFIG_BIAS_DISABLE);
188249c55878SDavid Wu 	case RK3066B:
188349c55878SDavid Wu 		return pull ? false : true;
188449c55878SDavid Wu 	case PX30:
188549c55878SDavid Wu 	case RV1108:
188649c55878SDavid Wu 	case RK3188:
188749c55878SDavid Wu 	case RK3288:
1888b3077611SDavid Wu 	case RK3308:
188949c55878SDavid Wu 	case RK3368:
189049c55878SDavid Wu 	case RK3399:
189149c55878SDavid Wu 		return (pull != PIN_CONFIG_BIAS_PULL_PIN_DEFAULT);
189249c55878SDavid Wu 	}
189349c55878SDavid Wu 
189449c55878SDavid Wu 	return false;
189549c55878SDavid Wu }
189649c55878SDavid Wu 
189749c55878SDavid Wu /* set the pin config settings for a specified pin */
189849c55878SDavid Wu static int rockchip_pinconf_set(struct rockchip_pin_bank *bank,
189949c55878SDavid Wu 				u32 pin, u32 param, u32 arg)
190049c55878SDavid Wu {
190149c55878SDavid Wu 	struct rockchip_pinctrl_priv *priv = bank->priv;
190249c55878SDavid Wu 	struct rockchip_pin_ctrl *ctrl = priv->ctrl;
190349c55878SDavid Wu 	int rc;
190449c55878SDavid Wu 
190549c55878SDavid Wu 	switch (param) {
190649c55878SDavid Wu 	case PIN_CONFIG_BIAS_DISABLE:
190749c55878SDavid Wu 		rc =  rockchip_set_pull(bank, pin, param);
190849c55878SDavid Wu 		if (rc)
190949c55878SDavid Wu 			return rc;
191049c55878SDavid Wu 		break;
191149c55878SDavid Wu 
191249c55878SDavid Wu 	case PIN_CONFIG_BIAS_PULL_UP:
191349c55878SDavid Wu 	case PIN_CONFIG_BIAS_PULL_DOWN:
191449c55878SDavid Wu 	case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT:
191549c55878SDavid Wu 	case PIN_CONFIG_BIAS_BUS_HOLD:
191649c55878SDavid Wu 		if (!rockchip_pinconf_pull_valid(ctrl, param))
191749c55878SDavid Wu 			return -ENOTSUPP;
191849c55878SDavid Wu 
191949c55878SDavid Wu 		if (!arg)
192049c55878SDavid Wu 			return -EINVAL;
192149c55878SDavid Wu 
192249c55878SDavid Wu 		rc = rockchip_set_pull(bank, pin, param);
192349c55878SDavid Wu 		if (rc)
192449c55878SDavid Wu 			return rc;
192549c55878SDavid Wu 		break;
192649c55878SDavid Wu 
192749c55878SDavid Wu 	case PIN_CONFIG_DRIVE_STRENGTH:
192849c55878SDavid Wu 		if (!ctrl->drv_calc_reg)
192949c55878SDavid Wu 			return -ENOTSUPP;
193049c55878SDavid Wu 
193149c55878SDavid Wu 		rc = rockchip_set_drive_perpin(bank, pin, arg);
193249c55878SDavid Wu 		if (rc < 0)
193349c55878SDavid Wu 			return rc;
193449c55878SDavid Wu 		break;
193549c55878SDavid Wu 
193649c55878SDavid Wu 	case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
193749c55878SDavid Wu 		if (!ctrl->schmitt_calc_reg)
193849c55878SDavid Wu 			return -ENOTSUPP;
193949c55878SDavid Wu 
194049c55878SDavid Wu 		rc = rockchip_set_schmitt(bank, pin, arg);
194149c55878SDavid Wu 		if (rc < 0)
194249c55878SDavid Wu 			return rc;
194349c55878SDavid Wu 		break;
194449c55878SDavid Wu 
194549c55878SDavid Wu 	default:
194649c55878SDavid Wu 		break;
194749c55878SDavid Wu 	}
194849c55878SDavid Wu 
194949c55878SDavid Wu 	return 0;
195049c55878SDavid Wu }
195149c55878SDavid Wu 
195249c55878SDavid Wu static const struct pinconf_param rockchip_conf_params[] = {
195349c55878SDavid Wu 	{ "bias-disable", PIN_CONFIG_BIAS_DISABLE, 0 },
195449c55878SDavid Wu 	{ "bias-bus-hold", PIN_CONFIG_BIAS_BUS_HOLD, 0 },
195549c55878SDavid Wu 	{ "bias-pull-up", PIN_CONFIG_BIAS_PULL_UP, 1 },
195649c55878SDavid Wu 	{ "bias-pull-down", PIN_CONFIG_BIAS_PULL_DOWN, 1 },
195749c55878SDavid Wu 	{ "drive-strength", PIN_CONFIG_DRIVE_STRENGTH, 0 },
195849c55878SDavid Wu 	{ "input-enable", PIN_CONFIG_INPUT_ENABLE, 1 },
195949c55878SDavid Wu 	{ "input-disable", PIN_CONFIG_INPUT_ENABLE, 0 },
196049c55878SDavid Wu 	{ "input-schmitt-disable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 0 },
196149c55878SDavid Wu 	{ "input-schmitt-enable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 1 },
196249c55878SDavid Wu };
196349c55878SDavid Wu 
196449c55878SDavid Wu static int rockchip_pinconf_prop_name_to_param(const char *property,
196549c55878SDavid Wu 					       u32 *default_value)
196649c55878SDavid Wu {
196749c55878SDavid Wu 	const struct pinconf_param *p, *end;
196849c55878SDavid Wu 
196949c55878SDavid Wu 	p = rockchip_conf_params;
197049c55878SDavid Wu 	end = p + sizeof(rockchip_conf_params) / sizeof(struct pinconf_param);
197149c55878SDavid Wu 
197249c55878SDavid Wu 	/* See if this pctldev supports this parameter */
197349c55878SDavid Wu 	for (; p < end; p++) {
197449c55878SDavid Wu 		if (!strcmp(property, p->property)) {
197549c55878SDavid Wu 			*default_value = p->default_value;
197649c55878SDavid Wu 			return p->param;
197749c55878SDavid Wu 		}
197849c55878SDavid Wu 	}
197949c55878SDavid Wu 
198049c55878SDavid Wu 	*default_value = 0;
198149c55878SDavid Wu 	return -EPERM;
198249c55878SDavid Wu }
198349c55878SDavid Wu 
198449c55878SDavid Wu static int rockchip_pinctrl_set_state(struct udevice *dev,
198549c55878SDavid Wu 				      struct udevice *config)
198649c55878SDavid Wu {
198749c55878SDavid Wu 	struct rockchip_pinctrl_priv *priv = dev_get_priv(dev);
198849c55878SDavid Wu 	struct rockchip_pin_ctrl *ctrl = priv->ctrl;
198949c55878SDavid Wu 	u32 cells[MAX_ROCKCHIP_PINS_ENTRIES * 4];
199049c55878SDavid Wu 	u32 bank, pin, mux, conf, arg, default_val;
199149c55878SDavid Wu 	int ret, count, i;
199249c55878SDavid Wu 	const char *prop_name;
199349c55878SDavid Wu 	const void *value;
19942208cfa9SKever Yang 	int prop_len, param;
19952208cfa9SKever Yang 	const u32 *data;
19962208cfa9SKever Yang 	ofnode node;
19972208cfa9SKever Yang #ifdef CONFIG_OF_LIVE
19982208cfa9SKever Yang 	const struct device_node *np;
19992208cfa9SKever Yang 	struct property *pp;
20002208cfa9SKever Yang #else
20012208cfa9SKever Yang 	int property_offset, pcfg_node;
20022208cfa9SKever Yang 	const void *blob = gd->fdt_blob;
20032208cfa9SKever Yang #endif
20042208cfa9SKever Yang 	data = dev_read_prop(config, "rockchip,pins", &count);
200549c55878SDavid Wu 	if (count < 0) {
200687f0ac57SDavid Wu 		debug("%s: bad array size %d\n", __func__, count);
200749c55878SDavid Wu 		return -EINVAL;
200849c55878SDavid Wu 	}
200949c55878SDavid Wu 
201087f0ac57SDavid Wu 	count /= sizeof(u32);
201149c55878SDavid Wu 	if (count > MAX_ROCKCHIP_PINS_ENTRIES * 4) {
201249c55878SDavid Wu 		debug("%s: unsupported pins array count %d\n",
201349c55878SDavid Wu 		      __func__, count);
201449c55878SDavid Wu 		return -EINVAL;
201549c55878SDavid Wu 	}
201649c55878SDavid Wu 
201787f0ac57SDavid Wu 	for (i = 0; i < count; i++)
201887f0ac57SDavid Wu 		cells[i] = fdt32_to_cpu(data[i]);
201987f0ac57SDavid Wu 
202049c55878SDavid Wu 	for (i = 0; i < (count >> 2); i++) {
202149c55878SDavid Wu 		bank = cells[4 * i + 0];
202249c55878SDavid Wu 		pin = cells[4 * i + 1];
202349c55878SDavid Wu 		mux = cells[4 * i + 2];
202449c55878SDavid Wu 		conf = cells[4 * i + 3];
202549c55878SDavid Wu 
202649c55878SDavid Wu 		ret = rockchip_verify_config(dev, bank, pin);
202749c55878SDavid Wu 		if (ret)
202849c55878SDavid Wu 			return ret;
202949c55878SDavid Wu 
203049c55878SDavid Wu 		ret = rockchip_set_mux(&ctrl->pin_banks[bank], pin, mux);
203149c55878SDavid Wu 		if (ret)
203249c55878SDavid Wu 			return ret;
203349c55878SDavid Wu 
20342208cfa9SKever Yang 		node = ofnode_get_by_phandle(conf);
20352208cfa9SKever Yang 		if (!ofnode_valid(node))
203649c55878SDavid Wu 			return -ENODEV;
20372208cfa9SKever Yang #ifdef CONFIG_OF_LIVE
20382208cfa9SKever Yang 		np = ofnode_to_np(node);
20392208cfa9SKever Yang 		for (pp = np->properties; pp; pp = pp->next) {
20402208cfa9SKever Yang 			prop_name = pp->name;
20412208cfa9SKever Yang 			prop_len = pp->length;
20422208cfa9SKever Yang 			value = pp->value;
20432208cfa9SKever Yang #else
20442208cfa9SKever Yang 		pcfg_node = ofnode_to_offset(node);
204549c55878SDavid Wu 		fdt_for_each_property_offset(property_offset, blob, pcfg_node) {
204649c55878SDavid Wu 			value = fdt_getprop_by_offset(blob, property_offset,
204749c55878SDavid Wu 						      &prop_name, &prop_len);
204849c55878SDavid Wu 			if (!value)
204949c55878SDavid Wu 				return -ENOENT;
20502208cfa9SKever Yang #endif
205149c55878SDavid Wu 			param = rockchip_pinconf_prop_name_to_param(prop_name,
205249c55878SDavid Wu 								    &default_val);
205349c55878SDavid Wu 			if (param < 0)
205449c55878SDavid Wu 				break;
205549c55878SDavid Wu 
205649c55878SDavid Wu 			if (prop_len >= sizeof(fdt32_t))
205749c55878SDavid Wu 				arg = fdt32_to_cpu(*(fdt32_t *)value);
205849c55878SDavid Wu 			else
205949c55878SDavid Wu 				arg = default_val;
206049c55878SDavid Wu 
206149c55878SDavid Wu 			ret = rockchip_pinconf_set(&ctrl->pin_banks[bank], pin,
206249c55878SDavid Wu 						   param, arg);
206349c55878SDavid Wu 			if (ret) {
206449c55878SDavid Wu 				debug("%s: rockchip_pinconf_set fail: %d\n",
206549c55878SDavid Wu 				      __func__, ret);
206649c55878SDavid Wu 				return ret;
206749c55878SDavid Wu 			}
206849c55878SDavid Wu 		}
206949c55878SDavid Wu 	}
207049c55878SDavid Wu 
207149c55878SDavid Wu 	return 0;
207249c55878SDavid Wu }
207349c55878SDavid Wu 
207449c55878SDavid Wu static struct pinctrl_ops rockchip_pinctrl_ops = {
207549c55878SDavid Wu 	.set_state			= rockchip_pinctrl_set_state,
207649c55878SDavid Wu 	.get_gpio_mux			= rockchip_pinctrl_get_gpio_mux,
207749c55878SDavid Wu };
207849c55878SDavid Wu 
207949c55878SDavid Wu /* retrieve the soc specific data */
208049c55878SDavid Wu static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data(struct udevice *dev)
208149c55878SDavid Wu {
208249c55878SDavid Wu 	struct rockchip_pinctrl_priv *priv = dev_get_priv(dev);
208349c55878SDavid Wu 	struct rockchip_pin_ctrl *ctrl =
208449c55878SDavid Wu 			(struct rockchip_pin_ctrl *)dev_get_driver_data(dev);
208549c55878SDavid Wu 	struct rockchip_pin_bank *bank;
208649c55878SDavid Wu 	int grf_offs, pmu_offs, drv_grf_offs, drv_pmu_offs, i, j;
208749c55878SDavid Wu 
208849c55878SDavid Wu 	grf_offs = ctrl->grf_mux_offset;
208949c55878SDavid Wu 	pmu_offs = ctrl->pmu_mux_offset;
209049c55878SDavid Wu 	drv_pmu_offs = ctrl->pmu_drv_offset;
209149c55878SDavid Wu 	drv_grf_offs = ctrl->grf_drv_offset;
209249c55878SDavid Wu 	bank = ctrl->pin_banks;
209349c55878SDavid Wu 
209449c55878SDavid Wu 	for (i = 0; i < ctrl->nr_banks; ++i, ++bank) {
209549c55878SDavid Wu 		int bank_pins = 0;
209649c55878SDavid Wu 
209749c55878SDavid Wu 		bank->priv = priv;
209849c55878SDavid Wu 		bank->pin_base = ctrl->nr_pins;
209949c55878SDavid Wu 		ctrl->nr_pins += bank->nr_pins;
210049c55878SDavid Wu 
210149c55878SDavid Wu 		/* calculate iomux and drv offsets */
210249c55878SDavid Wu 		for (j = 0; j < 4; j++) {
210349c55878SDavid Wu 			struct rockchip_iomux *iom = &bank->iomux[j];
210449c55878SDavid Wu 			struct rockchip_drv *drv = &bank->drv[j];
210549c55878SDavid Wu 			int inc;
210649c55878SDavid Wu 
210749c55878SDavid Wu 			if (bank_pins >= bank->nr_pins)
210849c55878SDavid Wu 				break;
210949c55878SDavid Wu 
211049c55878SDavid Wu 			/* preset iomux offset value, set new start value */
211149c55878SDavid Wu 			if (iom->offset >= 0) {
211249c55878SDavid Wu 				if (iom->type & IOMUX_SOURCE_PMU)
211349c55878SDavid Wu 					pmu_offs = iom->offset;
211449c55878SDavid Wu 				else
211549c55878SDavid Wu 					grf_offs = iom->offset;
211649c55878SDavid Wu 			} else { /* set current iomux offset */
211749c55878SDavid Wu 				iom->offset = (iom->type & IOMUX_SOURCE_PMU) ?
211849c55878SDavid Wu 							pmu_offs : grf_offs;
211949c55878SDavid Wu 			}
212049c55878SDavid Wu 
212149c55878SDavid Wu 			/* preset drv offset value, set new start value */
212249c55878SDavid Wu 			if (drv->offset >= 0) {
212349c55878SDavid Wu 				if (iom->type & IOMUX_SOURCE_PMU)
212449c55878SDavid Wu 					drv_pmu_offs = drv->offset;
212549c55878SDavid Wu 				else
212649c55878SDavid Wu 					drv_grf_offs = drv->offset;
212749c55878SDavid Wu 			} else { /* set current drv offset */
212849c55878SDavid Wu 				drv->offset = (iom->type & IOMUX_SOURCE_PMU) ?
212949c55878SDavid Wu 						drv_pmu_offs : drv_grf_offs;
213049c55878SDavid Wu 			}
213149c55878SDavid Wu 
213249c55878SDavid Wu 			debug("bank %d, iomux %d has iom_offset 0x%x drv_offset 0x%x\n",
213349c55878SDavid Wu 			      i, j, iom->offset, drv->offset);
213449c55878SDavid Wu 
213549c55878SDavid Wu 			/*
213649c55878SDavid Wu 			 * Increase offset according to iomux width.
213749c55878SDavid Wu 			 * 4bit iomux'es are spread over two registers.
213849c55878SDavid Wu 			 */
213949c55878SDavid Wu 			inc = (iom->type & (IOMUX_WIDTH_4BIT |
214088a1f7ffSDavid Wu 					    IOMUX_WIDTH_3BIT |
214188a1f7ffSDavid Wu 					    IOMUX_8WIDTH_2BIT)) ? 8 : 4;
214249c55878SDavid Wu 			if (iom->type & IOMUX_SOURCE_PMU)
214349c55878SDavid Wu 				pmu_offs += inc;
214449c55878SDavid Wu 			else
214549c55878SDavid Wu 				grf_offs += inc;
214649c55878SDavid Wu 
214749c55878SDavid Wu 			/*
214849c55878SDavid Wu 			 * Increase offset according to drv width.
214949c55878SDavid Wu 			 * 3bit drive-strenth'es are spread over two registers.
215049c55878SDavid Wu 			 */
215149c55878SDavid Wu 			if ((drv->drv_type == DRV_TYPE_IO_1V8_3V0_AUTO) ||
215249c55878SDavid Wu 			    (drv->drv_type == DRV_TYPE_IO_3V3_ONLY))
215349c55878SDavid Wu 				inc = 8;
215449c55878SDavid Wu 			else
215549c55878SDavid Wu 				inc = 4;
215649c55878SDavid Wu 
215749c55878SDavid Wu 			if (iom->type & IOMUX_SOURCE_PMU)
215849c55878SDavid Wu 				drv_pmu_offs += inc;
215949c55878SDavid Wu 			else
216049c55878SDavid Wu 				drv_grf_offs += inc;
216149c55878SDavid Wu 
216249c55878SDavid Wu 			bank_pins += 8;
216349c55878SDavid Wu 		}
216449c55878SDavid Wu 
216549c55878SDavid Wu 		/* calculate the per-bank recalced_mask */
216649c55878SDavid Wu 		for (j = 0; j < ctrl->niomux_recalced; j++) {
216749c55878SDavid Wu 			int pin = 0;
216849c55878SDavid Wu 
216949c55878SDavid Wu 			if (ctrl->iomux_recalced[j].num == bank->bank_num) {
217049c55878SDavid Wu 				pin = ctrl->iomux_recalced[j].pin;
217149c55878SDavid Wu 				bank->recalced_mask |= BIT(pin);
217249c55878SDavid Wu 			}
217349c55878SDavid Wu 		}
217449c55878SDavid Wu 
217549c55878SDavid Wu 		/* calculate the per-bank route_mask */
217649c55878SDavid Wu 		for (j = 0; j < ctrl->niomux_routes; j++) {
217749c55878SDavid Wu 			int pin = 0;
217849c55878SDavid Wu 
217949c55878SDavid Wu 			if (ctrl->iomux_routes[j].bank_num == bank->bank_num) {
218049c55878SDavid Wu 				pin = ctrl->iomux_routes[j].pin;
218149c55878SDavid Wu 				bank->route_mask |= BIT(pin);
218249c55878SDavid Wu 			}
218349c55878SDavid Wu 		}
218449c55878SDavid Wu 	}
218549c55878SDavid Wu 
218649c55878SDavid Wu 	return ctrl;
218749c55878SDavid Wu }
218849c55878SDavid Wu 
218949c55878SDavid Wu static int rockchip_pinctrl_probe(struct udevice *dev)
219049c55878SDavid Wu {
219149c55878SDavid Wu 	struct rockchip_pinctrl_priv *priv = dev_get_priv(dev);
219249c55878SDavid Wu 	struct rockchip_pin_ctrl *ctrl;
219349c55878SDavid Wu 	struct udevice *syscon;
219449c55878SDavid Wu 	struct regmap *regmap;
219549c55878SDavid Wu 	int ret = 0;
219649c55878SDavid Wu 
219749c55878SDavid Wu 	/* get rockchip grf syscon phandle */
219849c55878SDavid Wu 	ret = uclass_get_device_by_phandle(UCLASS_SYSCON, dev, "rockchip,grf",
219949c55878SDavid Wu 					   &syscon);
220049c55878SDavid Wu 	if (ret) {
220149c55878SDavid Wu 		debug("unable to find rockchip,grf syscon device (%d)\n", ret);
220249c55878SDavid Wu 		return ret;
220349c55878SDavid Wu 	}
220449c55878SDavid Wu 
220549c55878SDavid Wu 	/* get grf-reg base address */
220649c55878SDavid Wu 	regmap = syscon_get_regmap(syscon);
220749c55878SDavid Wu 	if (!regmap) {
220849c55878SDavid Wu 		debug("unable to find rockchip grf regmap\n");
220949c55878SDavid Wu 		return -ENODEV;
221049c55878SDavid Wu 	}
221149c55878SDavid Wu 	priv->regmap_base = regmap;
221249c55878SDavid Wu 
221349c55878SDavid Wu 	/* option: get pmu-reg base address */
221449c55878SDavid Wu 	ret = uclass_get_device_by_phandle(UCLASS_SYSCON, dev, "rockchip,pmu",
221549c55878SDavid Wu 					   &syscon);
221649c55878SDavid Wu 	if (!ret) {
221749c55878SDavid Wu 		/* get pmugrf-reg base address */
221849c55878SDavid Wu 		regmap = syscon_get_regmap(syscon);
221949c55878SDavid Wu 		if (!regmap) {
222049c55878SDavid Wu 			debug("unable to find rockchip pmu regmap\n");
222149c55878SDavid Wu 			return -ENODEV;
222249c55878SDavid Wu 		}
222349c55878SDavid Wu 		priv->regmap_pmu = regmap;
222449c55878SDavid Wu 	}
222549c55878SDavid Wu 
222649c55878SDavid Wu 	ctrl = rockchip_pinctrl_get_soc_data(dev);
222749c55878SDavid Wu 	if (!ctrl) {
222849c55878SDavid Wu 		debug("driver data not available\n");
222949c55878SDavid Wu 		return -EINVAL;
223049c55878SDavid Wu 	}
223149c55878SDavid Wu 
223249c55878SDavid Wu 	priv->ctrl = ctrl;
223349c55878SDavid Wu 	return 0;
223449c55878SDavid Wu }
223549c55878SDavid Wu 
223649c55878SDavid Wu static struct rockchip_pin_bank px30_pin_banks[] = {
223749c55878SDavid Wu 	PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_SOURCE_PMU,
223849c55878SDavid Wu 					     IOMUX_SOURCE_PMU,
223949c55878SDavid Wu 					     IOMUX_SOURCE_PMU,
224049c55878SDavid Wu 					     IOMUX_SOURCE_PMU
224149c55878SDavid Wu 			    ),
224249c55878SDavid Wu 	PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", IOMUX_WIDTH_4BIT,
224349c55878SDavid Wu 					     IOMUX_WIDTH_4BIT,
224449c55878SDavid Wu 					     IOMUX_WIDTH_4BIT,
224549c55878SDavid Wu 					     IOMUX_WIDTH_4BIT
224649c55878SDavid Wu 			    ),
224749c55878SDavid Wu 	PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", IOMUX_WIDTH_4BIT,
224849c55878SDavid Wu 					     IOMUX_WIDTH_4BIT,
224949c55878SDavid Wu 					     IOMUX_WIDTH_4BIT,
225049c55878SDavid Wu 					     IOMUX_WIDTH_4BIT
225149c55878SDavid Wu 			    ),
225249c55878SDavid Wu 	PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", IOMUX_WIDTH_4BIT,
225349c55878SDavid Wu 					     IOMUX_WIDTH_4BIT,
225449c55878SDavid Wu 					     IOMUX_WIDTH_4BIT,
225549c55878SDavid Wu 					     IOMUX_WIDTH_4BIT
225649c55878SDavid Wu 			    ),
225749c55878SDavid Wu };
225849c55878SDavid Wu 
225949c55878SDavid Wu static struct rockchip_pin_ctrl px30_pin_ctrl = {
226049c55878SDavid Wu 		.pin_banks		= px30_pin_banks,
226149c55878SDavid Wu 		.nr_banks		= ARRAY_SIZE(px30_pin_banks),
226249c55878SDavid Wu 		.label			= "PX30-GPIO",
226349c55878SDavid Wu 		.type			= PX30,
226449c55878SDavid Wu 		.grf_mux_offset		= 0x0,
226549c55878SDavid Wu 		.pmu_mux_offset		= 0x0,
226649c55878SDavid Wu 		.iomux_routes		= px30_mux_route_data,
226749c55878SDavid Wu 		.niomux_routes		= ARRAY_SIZE(px30_mux_route_data),
226849c55878SDavid Wu 		.pull_calc_reg		= px30_calc_pull_reg_and_bit,
226949c55878SDavid Wu 		.drv_calc_reg		= px30_calc_drv_reg_and_bit,
227049c55878SDavid Wu 		.schmitt_calc_reg	= px30_calc_schmitt_reg_and_bit,
227149c55878SDavid Wu };
227249c55878SDavid Wu 
227349c55878SDavid Wu static struct rockchip_pin_bank rv1108_pin_banks[] = {
227449c55878SDavid Wu 	PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_SOURCE_PMU,
227549c55878SDavid Wu 					     IOMUX_SOURCE_PMU,
227649c55878SDavid Wu 					     IOMUX_SOURCE_PMU,
227749c55878SDavid Wu 					     IOMUX_SOURCE_PMU),
227849c55878SDavid Wu 	PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", 0, 0, 0, 0),
227949c55878SDavid Wu 	PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", 0, 0, 0, 0),
228049c55878SDavid Wu 	PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", 0, 0, 0, 0),
228149c55878SDavid Wu };
228249c55878SDavid Wu 
228349c55878SDavid Wu static struct rockchip_pin_ctrl rv1108_pin_ctrl = {
228449c55878SDavid Wu 	.pin_banks		= rv1108_pin_banks,
228549c55878SDavid Wu 	.nr_banks		= ARRAY_SIZE(rv1108_pin_banks),
228649c55878SDavid Wu 	.label			= "RV1108-GPIO",
228749c55878SDavid Wu 	.type			= RV1108,
228849c55878SDavid Wu 	.grf_mux_offset		= 0x10,
228949c55878SDavid Wu 	.pmu_mux_offset		= 0x0,
229049c55878SDavid Wu 	.iomux_recalced		= rv1108_mux_recalced_data,
229149c55878SDavid Wu 	.niomux_recalced	= ARRAY_SIZE(rv1108_mux_recalced_data),
229249c55878SDavid Wu 	.pull_calc_reg		= rv1108_calc_pull_reg_and_bit,
229349c55878SDavid Wu 	.drv_calc_reg		= rv1108_calc_drv_reg_and_bit,
229449c55878SDavid Wu 	.schmitt_calc_reg	= rv1108_calc_schmitt_reg_and_bit,
229549c55878SDavid Wu };
229649c55878SDavid Wu 
229749c55878SDavid Wu static struct rockchip_pin_bank rk2928_pin_banks[] = {
229849c55878SDavid Wu 	PIN_BANK(0, 32, "gpio0"),
229949c55878SDavid Wu 	PIN_BANK(1, 32, "gpio1"),
230049c55878SDavid Wu 	PIN_BANK(2, 32, "gpio2"),
230149c55878SDavid Wu 	PIN_BANK(3, 32, "gpio3"),
230249c55878SDavid Wu };
230349c55878SDavid Wu 
230449c55878SDavid Wu static struct rockchip_pin_ctrl rk2928_pin_ctrl = {
230549c55878SDavid Wu 		.pin_banks		= rk2928_pin_banks,
230649c55878SDavid Wu 		.nr_banks		= ARRAY_SIZE(rk2928_pin_banks),
230749c55878SDavid Wu 		.label			= "RK2928-GPIO",
230849c55878SDavid Wu 		.type			= RK2928,
230949c55878SDavid Wu 		.grf_mux_offset		= 0xa8,
231049c55878SDavid Wu 		.pull_calc_reg		= rk2928_calc_pull_reg_and_bit,
231149c55878SDavid Wu };
231249c55878SDavid Wu 
231349c55878SDavid Wu static struct rockchip_pin_bank rk3036_pin_banks[] = {
231449c55878SDavid Wu 	PIN_BANK(0, 32, "gpio0"),
231549c55878SDavid Wu 	PIN_BANK(1, 32, "gpio1"),
231649c55878SDavid Wu 	PIN_BANK(2, 32, "gpio2"),
231749c55878SDavid Wu };
231849c55878SDavid Wu 
231949c55878SDavid Wu static struct rockchip_pin_ctrl rk3036_pin_ctrl = {
232049c55878SDavid Wu 		.pin_banks		= rk3036_pin_banks,
232149c55878SDavid Wu 		.nr_banks		= ARRAY_SIZE(rk3036_pin_banks),
232249c55878SDavid Wu 		.label			= "RK3036-GPIO",
232349c55878SDavid Wu 		.type			= RK2928,
232449c55878SDavid Wu 		.grf_mux_offset		= 0xa8,
232549c55878SDavid Wu 		.pull_calc_reg		= rk2928_calc_pull_reg_and_bit,
232649c55878SDavid Wu };
232749c55878SDavid Wu 
232849c55878SDavid Wu static struct rockchip_pin_bank rk3066a_pin_banks[] = {
232949c55878SDavid Wu 	PIN_BANK(0, 32, "gpio0"),
233049c55878SDavid Wu 	PIN_BANK(1, 32, "gpio1"),
233149c55878SDavid Wu 	PIN_BANK(2, 32, "gpio2"),
233249c55878SDavid Wu 	PIN_BANK(3, 32, "gpio3"),
233349c55878SDavid Wu 	PIN_BANK(4, 32, "gpio4"),
233449c55878SDavid Wu 	PIN_BANK(6, 16, "gpio6"),
233549c55878SDavid Wu };
233649c55878SDavid Wu 
233749c55878SDavid Wu static struct rockchip_pin_ctrl rk3066a_pin_ctrl = {
233849c55878SDavid Wu 		.pin_banks		= rk3066a_pin_banks,
233949c55878SDavid Wu 		.nr_banks		= ARRAY_SIZE(rk3066a_pin_banks),
234049c55878SDavid Wu 		.label			= "RK3066a-GPIO",
234149c55878SDavid Wu 		.type			= RK2928,
234249c55878SDavid Wu 		.grf_mux_offset		= 0xa8,
234349c55878SDavid Wu 		.pull_calc_reg		= rk2928_calc_pull_reg_and_bit,
234449c55878SDavid Wu };
234549c55878SDavid Wu 
234649c55878SDavid Wu static struct rockchip_pin_bank rk3066b_pin_banks[] = {
234749c55878SDavid Wu 	PIN_BANK(0, 32, "gpio0"),
234849c55878SDavid Wu 	PIN_BANK(1, 32, "gpio1"),
234949c55878SDavid Wu 	PIN_BANK(2, 32, "gpio2"),
235049c55878SDavid Wu 	PIN_BANK(3, 32, "gpio3"),
235149c55878SDavid Wu };
235249c55878SDavid Wu 
235349c55878SDavid Wu static struct rockchip_pin_ctrl rk3066b_pin_ctrl = {
235449c55878SDavid Wu 		.pin_banks	= rk3066b_pin_banks,
235549c55878SDavid Wu 		.nr_banks	= ARRAY_SIZE(rk3066b_pin_banks),
235649c55878SDavid Wu 		.label		= "RK3066b-GPIO",
235749c55878SDavid Wu 		.type		= RK3066B,
235849c55878SDavid Wu 		.grf_mux_offset	= 0x60,
235949c55878SDavid Wu };
236049c55878SDavid Wu 
236149c55878SDavid Wu static struct rockchip_pin_bank rk3128_pin_banks[] = {
236249c55878SDavid Wu 	PIN_BANK(0, 32, "gpio0"),
236349c55878SDavid Wu 	PIN_BANK(1, 32, "gpio1"),
236449c55878SDavid Wu 	PIN_BANK(2, 32, "gpio2"),
236549c55878SDavid Wu 	PIN_BANK(3, 32, "gpio3"),
236649c55878SDavid Wu };
236749c55878SDavid Wu 
236849c55878SDavid Wu static struct rockchip_pin_ctrl rk3128_pin_ctrl = {
236949c55878SDavid Wu 		.pin_banks		= rk3128_pin_banks,
237049c55878SDavid Wu 		.nr_banks		= ARRAY_SIZE(rk3128_pin_banks),
237149c55878SDavid Wu 		.label			= "RK3128-GPIO",
237249c55878SDavid Wu 		.type			= RK3128,
237349c55878SDavid Wu 		.grf_mux_offset		= 0xa8,
237449c55878SDavid Wu 		.iomux_recalced		= rk3128_mux_recalced_data,
237549c55878SDavid Wu 		.niomux_recalced	= ARRAY_SIZE(rk3128_mux_recalced_data),
237649c55878SDavid Wu 		.iomux_routes		= rk3128_mux_route_data,
237749c55878SDavid Wu 		.niomux_routes		= ARRAY_SIZE(rk3128_mux_route_data),
237849c55878SDavid Wu 		.pull_calc_reg		= rk3128_calc_pull_reg_and_bit,
237949c55878SDavid Wu };
238049c55878SDavid Wu 
238149c55878SDavid Wu static struct rockchip_pin_bank rk3188_pin_banks[] = {
238249c55878SDavid Wu 	PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_GPIO_ONLY, 0, 0, 0),
238349c55878SDavid Wu 	PIN_BANK(1, 32, "gpio1"),
238449c55878SDavid Wu 	PIN_BANK(2, 32, "gpio2"),
238549c55878SDavid Wu 	PIN_BANK(3, 32, "gpio3"),
238649c55878SDavid Wu };
238749c55878SDavid Wu 
238849c55878SDavid Wu static struct rockchip_pin_ctrl rk3188_pin_ctrl = {
238949c55878SDavid Wu 		.pin_banks		= rk3188_pin_banks,
239049c55878SDavid Wu 		.nr_banks		= ARRAY_SIZE(rk3188_pin_banks),
239149c55878SDavid Wu 		.label			= "RK3188-GPIO",
239249c55878SDavid Wu 		.type			= RK3188,
239349c55878SDavid Wu 		.grf_mux_offset		= 0x60,
239449c55878SDavid Wu 		.pull_calc_reg		= rk3188_calc_pull_reg_and_bit,
239549c55878SDavid Wu };
239649c55878SDavid Wu 
239749c55878SDavid Wu static struct rockchip_pin_bank rk3228_pin_banks[] = {
239849c55878SDavid Wu 	PIN_BANK(0, 32, "gpio0"),
239949c55878SDavid Wu 	PIN_BANK(1, 32, "gpio1"),
240049c55878SDavid Wu 	PIN_BANK(2, 32, "gpio2"),
240149c55878SDavid Wu 	PIN_BANK(3, 32, "gpio3"),
240249c55878SDavid Wu };
240349c55878SDavid Wu 
240449c55878SDavid Wu static struct rockchip_pin_ctrl rk3228_pin_ctrl = {
240549c55878SDavid Wu 		.pin_banks		= rk3228_pin_banks,
240649c55878SDavid Wu 		.nr_banks		= ARRAY_SIZE(rk3228_pin_banks),
240749c55878SDavid Wu 		.label			= "RK3228-GPIO",
240849c55878SDavid Wu 		.type			= RK3288,
240949c55878SDavid Wu 		.grf_mux_offset		= 0x0,
241049c55878SDavid Wu 		.iomux_routes		= rk3228_mux_route_data,
241149c55878SDavid Wu 		.niomux_routes		= ARRAY_SIZE(rk3228_mux_route_data),
241249c55878SDavid Wu 		.pull_calc_reg		= rk3228_calc_pull_reg_and_bit,
241349c55878SDavid Wu 		.drv_calc_reg		= rk3228_calc_drv_reg_and_bit,
241449c55878SDavid Wu };
241549c55878SDavid Wu 
241649c55878SDavid Wu static struct rockchip_pin_bank rk3288_pin_banks[] = {
2417*4bafc2daSDavid Wu 	PIN_BANK_IOMUX_FLAGS(0, 24, "gpio0", IOMUX_SOURCE_PMU | IOMUX_WRITABLE_32BIT,
2418*4bafc2daSDavid Wu 					     IOMUX_SOURCE_PMU | IOMUX_WRITABLE_32BIT,
2419*4bafc2daSDavid Wu 					     IOMUX_SOURCE_PMU | IOMUX_WRITABLE_32BIT,
242049c55878SDavid Wu 					     IOMUX_UNROUTED
242149c55878SDavid Wu 			    ),
242249c55878SDavid Wu 	PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", IOMUX_UNROUTED,
242349c55878SDavid Wu 					     IOMUX_UNROUTED,
242449c55878SDavid Wu 					     IOMUX_UNROUTED,
242549c55878SDavid Wu 					     0
242649c55878SDavid Wu 			    ),
242749c55878SDavid Wu 	PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", 0, 0, 0, IOMUX_UNROUTED),
242849c55878SDavid Wu 	PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", 0, 0, 0, IOMUX_WIDTH_4BIT),
242949c55878SDavid Wu 	PIN_BANK_IOMUX_FLAGS(4, 32, "gpio4", IOMUX_WIDTH_4BIT,
243049c55878SDavid Wu 					     IOMUX_WIDTH_4BIT,
243149c55878SDavid Wu 					     0,
243249c55878SDavid Wu 					     0
243349c55878SDavid Wu 			    ),
243449c55878SDavid Wu 	PIN_BANK_IOMUX_FLAGS(5, 32, "gpio5", IOMUX_UNROUTED,
243549c55878SDavid Wu 					     0,
243649c55878SDavid Wu 					     0,
243749c55878SDavid Wu 					     IOMUX_UNROUTED
243849c55878SDavid Wu 			    ),
243949c55878SDavid Wu 	PIN_BANK_IOMUX_FLAGS(6, 32, "gpio6", 0, 0, 0, IOMUX_UNROUTED),
244049c55878SDavid Wu 	PIN_BANK_IOMUX_FLAGS(7, 32, "gpio7", 0,
244149c55878SDavid Wu 					     0,
244249c55878SDavid Wu 					     IOMUX_WIDTH_4BIT,
244349c55878SDavid Wu 					     IOMUX_UNROUTED
244449c55878SDavid Wu 			    ),
244549c55878SDavid Wu 	PIN_BANK(8, 16, "gpio8"),
244649c55878SDavid Wu };
244749c55878SDavid Wu 
244849c55878SDavid Wu static struct rockchip_pin_ctrl rk3288_pin_ctrl = {
244949c55878SDavid Wu 		.pin_banks		= rk3288_pin_banks,
245049c55878SDavid Wu 		.nr_banks		= ARRAY_SIZE(rk3288_pin_banks),
245149c55878SDavid Wu 		.label			= "RK3288-GPIO",
245249c55878SDavid Wu 		.type			= RK3288,
245349c55878SDavid Wu 		.grf_mux_offset		= 0x0,
245449c55878SDavid Wu 		.pmu_mux_offset		= 0x84,
245549c55878SDavid Wu 		.iomux_routes		= rk3288_mux_route_data,
245649c55878SDavid Wu 		.niomux_routes		= ARRAY_SIZE(rk3288_mux_route_data),
245749c55878SDavid Wu 		.pull_calc_reg		= rk3288_calc_pull_reg_and_bit,
245849c55878SDavid Wu 		.drv_calc_reg		= rk3288_calc_drv_reg_and_bit,
245949c55878SDavid Wu };
246049c55878SDavid Wu 
2461b3077611SDavid Wu static struct rockchip_pin_bank rk3308_pin_banks[] = {
2462b3077611SDavid Wu 	PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_8WIDTH_2BIT,
2463b3077611SDavid Wu 					     IOMUX_8WIDTH_2BIT,
2464b3077611SDavid Wu 					     IOMUX_8WIDTH_2BIT,
2465b3077611SDavid Wu 					     IOMUX_8WIDTH_2BIT),
2466b3077611SDavid Wu 	PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", IOMUX_8WIDTH_2BIT,
2467b3077611SDavid Wu 					     IOMUX_8WIDTH_2BIT,
2468b3077611SDavid Wu 					     IOMUX_8WIDTH_2BIT,
2469b3077611SDavid Wu 					     IOMUX_8WIDTH_2BIT),
2470b3077611SDavid Wu 	PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", IOMUX_8WIDTH_2BIT,
2471b3077611SDavid Wu 					     IOMUX_8WIDTH_2BIT,
2472b3077611SDavid Wu 					     IOMUX_8WIDTH_2BIT,
2473b3077611SDavid Wu 					     IOMUX_8WIDTH_2BIT),
2474b3077611SDavid Wu 	PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", IOMUX_8WIDTH_2BIT,
2475b3077611SDavid Wu 					     IOMUX_8WIDTH_2BIT,
2476b3077611SDavid Wu 					     IOMUX_8WIDTH_2BIT,
2477b3077611SDavid Wu 					     IOMUX_8WIDTH_2BIT),
2478b3077611SDavid Wu 	PIN_BANK_IOMUX_FLAGS(4, 32, "gpio4", IOMUX_8WIDTH_2BIT,
2479b3077611SDavid Wu 					     IOMUX_8WIDTH_2BIT,
2480b3077611SDavid Wu 					     IOMUX_8WIDTH_2BIT,
2481b3077611SDavid Wu 					     IOMUX_8WIDTH_2BIT),
2482b3077611SDavid Wu };
2483b3077611SDavid Wu 
2484b3077611SDavid Wu static struct rockchip_pin_ctrl rk3308_pin_ctrl = {
2485b3077611SDavid Wu 		.pin_banks		= rk3308_pin_banks,
2486b3077611SDavid Wu 		.nr_banks		= ARRAY_SIZE(rk3308_pin_banks),
2487b3077611SDavid Wu 		.label			= "RK3308-GPIO",
2488b3077611SDavid Wu 		.type			= RK3308,
2489b3077611SDavid Wu 		.grf_mux_offset		= 0x0,
2490b3077611SDavid Wu 		.iomux_recalced		= rk3308_mux_recalced_data,
2491b3077611SDavid Wu 		.niomux_recalced	= ARRAY_SIZE(rk3308_mux_recalced_data),
2492b3077611SDavid Wu 		.iomux_routes		= rk3308_mux_route_data,
2493b3077611SDavid Wu 		.niomux_routes		= ARRAY_SIZE(rk3308_mux_route_data),
2494b3077611SDavid Wu 		.pull_calc_reg		= rk3308_calc_pull_reg_and_bit,
2495b3077611SDavid Wu 		.drv_calc_reg		= rk3308_calc_drv_reg_and_bit,
2496b3077611SDavid Wu 		.schmitt_calc_reg	= rk3308_calc_schmitt_reg_and_bit,
2497b3077611SDavid Wu };
2498b3077611SDavid Wu 
249949c55878SDavid Wu static struct rockchip_pin_bank rk3328_pin_banks[] = {
250049c55878SDavid Wu 	PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", 0, 0, 0, 0),
250149c55878SDavid Wu 	PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", 0, 0, 0, 0),
250249c55878SDavid Wu 	PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", 0,
250349c55878SDavid Wu 			     IOMUX_WIDTH_3BIT,
250449c55878SDavid Wu 			     IOMUX_WIDTH_3BIT,
250549c55878SDavid Wu 			     0),
250649c55878SDavid Wu 	PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3",
250749c55878SDavid Wu 			     IOMUX_WIDTH_3BIT,
250849c55878SDavid Wu 			     IOMUX_WIDTH_3BIT,
250949c55878SDavid Wu 			     0,
251049c55878SDavid Wu 			     0),
251149c55878SDavid Wu };
251249c55878SDavid Wu 
251349c55878SDavid Wu static struct rockchip_pin_ctrl rk3328_pin_ctrl = {
251449c55878SDavid Wu 		.pin_banks		= rk3328_pin_banks,
251549c55878SDavid Wu 		.nr_banks		= ARRAY_SIZE(rk3328_pin_banks),
251649c55878SDavid Wu 		.label			= "RK3328-GPIO",
251749c55878SDavid Wu 		.type			= RK3288,
251849c55878SDavid Wu 		.grf_mux_offset		= 0x0,
251949c55878SDavid Wu 		.iomux_recalced		= rk3328_mux_recalced_data,
252049c55878SDavid Wu 		.niomux_recalced	= ARRAY_SIZE(rk3328_mux_recalced_data),
252149c55878SDavid Wu 		.iomux_routes		= rk3328_mux_route_data,
252249c55878SDavid Wu 		.niomux_routes		= ARRAY_SIZE(rk3328_mux_route_data),
252349c55878SDavid Wu 		.pull_calc_reg		= rk3228_calc_pull_reg_and_bit,
252449c55878SDavid Wu 		.drv_calc_reg		= rk3228_calc_drv_reg_and_bit,
252549c55878SDavid Wu 		.schmitt_calc_reg	= rk3328_calc_schmitt_reg_and_bit,
252649c55878SDavid Wu };
252749c55878SDavid Wu 
252849c55878SDavid Wu static struct rockchip_pin_bank rk3368_pin_banks[] = {
252949c55878SDavid Wu 	PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_SOURCE_PMU,
253049c55878SDavid Wu 					     IOMUX_SOURCE_PMU,
253149c55878SDavid Wu 					     IOMUX_SOURCE_PMU,
253249c55878SDavid Wu 					     IOMUX_SOURCE_PMU
253349c55878SDavid Wu 			    ),
253449c55878SDavid Wu 	PIN_BANK(1, 32, "gpio1"),
253549c55878SDavid Wu 	PIN_BANK(2, 32, "gpio2"),
253649c55878SDavid Wu 	PIN_BANK(3, 32, "gpio3"),
253749c55878SDavid Wu };
253849c55878SDavid Wu 
253949c55878SDavid Wu static struct rockchip_pin_ctrl rk3368_pin_ctrl = {
254049c55878SDavid Wu 		.pin_banks		= rk3368_pin_banks,
254149c55878SDavid Wu 		.nr_banks		= ARRAY_SIZE(rk3368_pin_banks),
254249c55878SDavid Wu 		.label			= "RK3368-GPIO",
254349c55878SDavid Wu 		.type			= RK3368,
254449c55878SDavid Wu 		.grf_mux_offset		= 0x0,
254549c55878SDavid Wu 		.pmu_mux_offset		= 0x0,
254649c55878SDavid Wu 		.pull_calc_reg		= rk3368_calc_pull_reg_and_bit,
254749c55878SDavid Wu 		.drv_calc_reg		= rk3368_calc_drv_reg_and_bit,
254849c55878SDavid Wu };
254949c55878SDavid Wu 
255049c55878SDavid Wu static struct rockchip_pin_bank rk3399_pin_banks[] = {
255149c55878SDavid Wu 	PIN_BANK_IOMUX_FLAGS_DRV_FLAGS_OFFSET_PULL_FLAGS(0, 32, "gpio0",
255249c55878SDavid Wu 							 IOMUX_SOURCE_PMU,
255349c55878SDavid Wu 							 IOMUX_SOURCE_PMU,
255449c55878SDavid Wu 							 IOMUX_SOURCE_PMU,
255549c55878SDavid Wu 							 IOMUX_SOURCE_PMU,
255649c55878SDavid Wu 							 DRV_TYPE_IO_1V8_ONLY,
255749c55878SDavid Wu 							 DRV_TYPE_IO_1V8_ONLY,
255849c55878SDavid Wu 							 DRV_TYPE_IO_DEFAULT,
255949c55878SDavid Wu 							 DRV_TYPE_IO_DEFAULT,
256049c55878SDavid Wu 							 0x80,
256149c55878SDavid Wu 							 0x88,
256249c55878SDavid Wu 							 -1,
256349c55878SDavid Wu 							 -1,
256449c55878SDavid Wu 							 PULL_TYPE_IO_1V8_ONLY,
256549c55878SDavid Wu 							 PULL_TYPE_IO_1V8_ONLY,
256649c55878SDavid Wu 							 PULL_TYPE_IO_DEFAULT,
256749c55878SDavid Wu 							 PULL_TYPE_IO_DEFAULT
256849c55878SDavid Wu 							),
256949c55878SDavid Wu 	PIN_BANK_IOMUX_DRV_FLAGS_OFFSET(1, 32, "gpio1", IOMUX_SOURCE_PMU,
257049c55878SDavid Wu 					IOMUX_SOURCE_PMU,
257149c55878SDavid Wu 					IOMUX_SOURCE_PMU,
257249c55878SDavid Wu 					IOMUX_SOURCE_PMU,
257349c55878SDavid Wu 					DRV_TYPE_IO_1V8_OR_3V0,
257449c55878SDavid Wu 					DRV_TYPE_IO_1V8_OR_3V0,
257549c55878SDavid Wu 					DRV_TYPE_IO_1V8_OR_3V0,
257649c55878SDavid Wu 					DRV_TYPE_IO_1V8_OR_3V0,
257749c55878SDavid Wu 					0xa0,
257849c55878SDavid Wu 					0xa8,
257949c55878SDavid Wu 					0xb0,
258049c55878SDavid Wu 					0xb8
258149c55878SDavid Wu 					),
258249c55878SDavid Wu 	PIN_BANK_DRV_FLAGS_PULL_FLAGS(2, 32, "gpio2", DRV_TYPE_IO_1V8_OR_3V0,
258349c55878SDavid Wu 				      DRV_TYPE_IO_1V8_OR_3V0,
258449c55878SDavid Wu 				      DRV_TYPE_IO_1V8_ONLY,
258549c55878SDavid Wu 				      DRV_TYPE_IO_1V8_ONLY,
258649c55878SDavid Wu 				      PULL_TYPE_IO_DEFAULT,
258749c55878SDavid Wu 				      PULL_TYPE_IO_DEFAULT,
258849c55878SDavid Wu 				      PULL_TYPE_IO_1V8_ONLY,
258949c55878SDavid Wu 				      PULL_TYPE_IO_1V8_ONLY
259049c55878SDavid Wu 				      ),
259149c55878SDavid Wu 	PIN_BANK_DRV_FLAGS(3, 32, "gpio3", DRV_TYPE_IO_3V3_ONLY,
259249c55878SDavid Wu 			   DRV_TYPE_IO_3V3_ONLY,
259349c55878SDavid Wu 			   DRV_TYPE_IO_3V3_ONLY,
259449c55878SDavid Wu 			   DRV_TYPE_IO_1V8_OR_3V0
259549c55878SDavid Wu 			   ),
259649c55878SDavid Wu 	PIN_BANK_DRV_FLAGS(4, 32, "gpio4", DRV_TYPE_IO_1V8_OR_3V0,
259749c55878SDavid Wu 			   DRV_TYPE_IO_1V8_3V0_AUTO,
259849c55878SDavid Wu 			   DRV_TYPE_IO_1V8_OR_3V0,
259949c55878SDavid Wu 			   DRV_TYPE_IO_1V8_OR_3V0
260049c55878SDavid Wu 			   ),
260149c55878SDavid Wu };
260249c55878SDavid Wu 
260349c55878SDavid Wu static struct rockchip_pin_ctrl rk3399_pin_ctrl = {
260449c55878SDavid Wu 		.pin_banks		= rk3399_pin_banks,
260549c55878SDavid Wu 		.nr_banks		= ARRAY_SIZE(rk3399_pin_banks),
260649c55878SDavid Wu 		.label			= "RK3399-GPIO",
260749c55878SDavid Wu 		.type			= RK3399,
260849c55878SDavid Wu 		.grf_mux_offset		= 0xe000,
260949c55878SDavid Wu 		.pmu_mux_offset		= 0x0,
261049c55878SDavid Wu 		.grf_drv_offset		= 0xe100,
261149c55878SDavid Wu 		.pmu_drv_offset		= 0x80,
261249c55878SDavid Wu 		.iomux_routes		= rk3399_mux_route_data,
261349c55878SDavid Wu 		.niomux_routes		= ARRAY_SIZE(rk3399_mux_route_data),
261449c55878SDavid Wu 		.pull_calc_reg		= rk3399_calc_pull_reg_and_bit,
261549c55878SDavid Wu 		.drv_calc_reg		= rk3399_calc_drv_reg_and_bit,
261649c55878SDavid Wu };
261749c55878SDavid Wu 
261849c55878SDavid Wu static const struct udevice_id rockchip_pinctrl_dt_match[] = {
261949c55878SDavid Wu 	{ .compatible = "rockchip,px30-pinctrl",
262049c55878SDavid Wu 		.data = (ulong)&px30_pin_ctrl },
262149c55878SDavid Wu 	{ .compatible = "rockchip,rv1108-pinctrl",
262249c55878SDavid Wu 		.data = (ulong)&rv1108_pin_ctrl },
262349c55878SDavid Wu 	{ .compatible = "rockchip,rk2928-pinctrl",
262449c55878SDavid Wu 		.data = (ulong)&rk2928_pin_ctrl },
262549c55878SDavid Wu 	{ .compatible = "rockchip,rk3036-pinctrl",
262649c55878SDavid Wu 		.data = (ulong)&rk3036_pin_ctrl },
262749c55878SDavid Wu 	{ .compatible = "rockchip,rk3066a-pinctrl",
262849c55878SDavid Wu 		.data = (ulong)&rk3066a_pin_ctrl },
262949c55878SDavid Wu 	{ .compatible = "rockchip,rk3066b-pinctrl",
263049c55878SDavid Wu 		.data = (ulong)&rk3066b_pin_ctrl },
263149c55878SDavid Wu 	{ .compatible = "rockchip,rk3128-pinctrl",
263249c55878SDavid Wu 		.data = (ulong)&rk3128_pin_ctrl },
263349c55878SDavid Wu 	{ .compatible = "rockchip,rk3188-pinctrl",
263449c55878SDavid Wu 		.data = (ulong)&rk3188_pin_ctrl },
263549c55878SDavid Wu 	{ .compatible = "rockchip,rk3228-pinctrl",
263649c55878SDavid Wu 		.data = (ulong)&rk3228_pin_ctrl },
263749c55878SDavid Wu 	{ .compatible = "rockchip,rk3288-pinctrl",
263849c55878SDavid Wu 		.data = (ulong)&rk3288_pin_ctrl },
2639b3077611SDavid Wu 	{ .compatible = "rockchip,rk3308-pinctrl",
2640b3077611SDavid Wu 		.data = (ulong)&rk3308_pin_ctrl },
264149c55878SDavid Wu 	{ .compatible = "rockchip,rk3328-pinctrl",
264249c55878SDavid Wu 		.data = (ulong)&rk3328_pin_ctrl },
264349c55878SDavid Wu 	{ .compatible = "rockchip,rk3368-pinctrl",
264449c55878SDavid Wu 		.data = (ulong)&rk3368_pin_ctrl },
264549c55878SDavid Wu 	{ .compatible = "rockchip,rk3399-pinctrl",
264649c55878SDavid Wu 		.data = (ulong)&rk3399_pin_ctrl },
264749c55878SDavid Wu 	{},
264849c55878SDavid Wu };
264949c55878SDavid Wu 
265049c55878SDavid Wu U_BOOT_DRIVER(pinctrl_rockchip) = {
265149c55878SDavid Wu 	.name		= "rockchip_pinctrl",
265249c55878SDavid Wu 	.id		= UCLASS_PINCTRL,
265349c55878SDavid Wu 	.of_match	= rockchip_pinctrl_dt_match,
265449c55878SDavid Wu 	.priv_auto_alloc_size = sizeof(struct rockchip_pinctrl_priv),
265549c55878SDavid Wu 	.ops		= &rockchip_pinctrl_ops,
265649c55878SDavid Wu #if !CONFIG_IS_ENABLED(OF_PLATDATA)
265749c55878SDavid Wu 	.bind		= dm_scan_fdt_dev,
265849c55878SDavid Wu #endif
265949c55878SDavid Wu 	.probe		= rockchip_pinctrl_probe,
266049c55878SDavid Wu };
2661