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