1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * (C) Copyright 2019 Rockchip Electronics Co., Ltd
4  */
5 
6 #include <common.h>
7 #include <dm.h>
8 #include <dm/pinctrl.h>
9 #include <regmap.h>
10 #include <syscon.h>
11 
12 #include "pinctrl-rockchip.h"
13 
14 #define RK3368_PULL_GRF_OFFSET		0x100
15 #define RK3368_PULL_PMU_OFFSET		0x10
16 
rk3368_calc_pull_reg_and_bit(struct rockchip_pin_bank * bank,int pin_num,struct regmap ** regmap,int * reg,u8 * bit)17 static void rk3368_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
18 					 int pin_num, struct regmap **regmap,
19 					 int *reg, u8 *bit)
20 {
21 	struct rockchip_pinctrl_priv *priv = bank->priv;
22 
23 	/* The first 32 pins of the first bank are located in PMU */
24 	if (bank->bank_num == 0) {
25 		*regmap = priv->regmap_pmu;
26 		*reg = RK3368_PULL_PMU_OFFSET;
27 
28 		*reg += ((pin_num / ROCKCHIP_PULL_PINS_PER_REG) * 4);
29 		*bit = pin_num % ROCKCHIP_PULL_PINS_PER_REG;
30 		*bit *= ROCKCHIP_PULL_BITS_PER_PIN;
31 	} else {
32 		*regmap = priv->regmap_base;
33 		*reg = RK3368_PULL_GRF_OFFSET;
34 
35 		/* correct the offset, as we're starting with the 2nd bank */
36 		*reg -= 0x10;
37 		*reg += bank->bank_num * ROCKCHIP_PULL_BANK_STRIDE;
38 		*reg += ((pin_num / ROCKCHIP_PULL_PINS_PER_REG) * 4);
39 
40 		*bit = (pin_num % ROCKCHIP_PULL_PINS_PER_REG);
41 		*bit *= ROCKCHIP_PULL_BITS_PER_PIN;
42 	}
43 }
44 
45 #define RK3368_DRV_PMU_OFFSET		0x20
46 #define RK3368_DRV_GRF_OFFSET		0x200
47 
rk3368_calc_drv_reg_and_bit(struct rockchip_pin_bank * bank,int pin_num,struct regmap ** regmap,int * reg,u8 * bit)48 static void rk3368_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
49 					int pin_num, struct regmap **regmap,
50 					int *reg, u8 *bit)
51 {
52 	struct rockchip_pinctrl_priv *priv = bank->priv;
53 
54 	/* The first 32 pins of the first bank are located in PMU */
55 	if (bank->bank_num == 0) {
56 		*regmap = priv->regmap_pmu;
57 		*reg = RK3368_DRV_PMU_OFFSET;
58 
59 		*reg += ((pin_num / ROCKCHIP_DRV_PINS_PER_REG) * 4);
60 		*bit = pin_num % ROCKCHIP_DRV_PINS_PER_REG;
61 		*bit *= ROCKCHIP_DRV_BITS_PER_PIN;
62 	} else {
63 		*regmap = priv->regmap_base;
64 		*reg = RK3368_DRV_GRF_OFFSET;
65 
66 		/* correct the offset, as we're starting with the 2nd bank */
67 		*reg -= 0x10;
68 		*reg += bank->bank_num * ROCKCHIP_DRV_BANK_STRIDE;
69 		*reg += ((pin_num / ROCKCHIP_DRV_PINS_PER_REG) * 4);
70 
71 		*bit = (pin_num % ROCKCHIP_DRV_PINS_PER_REG);
72 		*bit *= ROCKCHIP_DRV_BITS_PER_PIN;
73 	}
74 }
75 
76 static struct rockchip_pin_bank rk3368_pin_banks[] = {
77 	PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_SOURCE_PMU,
78 					     IOMUX_SOURCE_PMU,
79 					     IOMUX_SOURCE_PMU,
80 					     IOMUX_SOURCE_PMU
81 			    ),
82 	PIN_BANK(1, 32, "gpio1"),
83 	PIN_BANK(2, 32, "gpio2"),
84 	PIN_BANK(3, 32, "gpio3"),
85 };
86 
87 static struct rockchip_pin_ctrl rk3368_pin_ctrl = {
88 		.pin_banks		= rk3368_pin_banks,
89 		.nr_banks		= ARRAY_SIZE(rk3368_pin_banks),
90 		.label			= "RK3368-GPIO",
91 		.type			= RK3368,
92 		.grf_mux_offset		= 0x0,
93 		.pmu_mux_offset		= 0x0,
94 		.pull_calc_reg		= rk3368_calc_pull_reg_and_bit,
95 		.drv_calc_reg		= rk3368_calc_drv_reg_and_bit,
96 };
97 
98 static const struct udevice_id rk3368_pinctrl_ids[] = {
99 	{
100 		.compatible = "rockchip,rk3368-pinctrl",
101 		.data = (ulong)&rk3368_pin_ctrl
102 	},
103 	{ }
104 };
105 
106 U_BOOT_DRIVER(pinctrl_rk3368) = {
107 	.name		= "rockchip_rk3368_pinctrl",
108 	.id		= UCLASS_PINCTRL,
109 	.of_match	= rk3368_pinctrl_ids,
110 	.priv_auto_alloc_size = sizeof(struct rockchip_pinctrl_priv),
111 	.ops		= &rockchip_pinctrl_ops,
112 #if !CONFIG_IS_ENABLED(OF_PLATDATA)
113 	.bind		= dm_scan_fdt_dev,
114 #endif
115 	.probe		= rockchip_pinctrl_probe,
116 };
117