faaa2ce1f705275d73ff5b99810b43deaabbc47a
[platform/kernel/u-boot.git] / drivers / pinctrl / rockchip / pinctrl-rk3288.c
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 <log.h>
9 #include <dm/pinctrl.h>
10 #include <regmap.h>
11 #include <linux/bitops.h>
12
13 #include "pinctrl-rockchip.h"
14
15 static struct rockchip_mux_route_data rk3288_mux_route_data[] = {
16         {
17                 /* edphdmi_cecinoutt1 */
18                 .bank_num = 7,
19                 .pin = 16,
20                 .func = 2,
21                 .route_offset = 0x264,
22                 .route_val = BIT(16 + 12) | BIT(12),
23         }, {
24                 /* edphdmi_cecinout */
25                 .bank_num = 7,
26                 .pin = 23,
27                 .func = 4,
28                 .route_offset = 0x264,
29                 .route_val = BIT(16 + 12),
30         },
31 };
32
33 static int rk3288_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
34 {
35         struct rockchip_pinctrl_priv *priv = bank->priv;
36         int iomux_num = (pin / 8);
37         struct regmap *regmap;
38         int reg, ret, mask, mux_type;
39         u8 bit;
40         u32 data, route_reg, route_val;
41
42         regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU)
43                                 ? priv->regmap_pmu : priv->regmap_base;
44
45         /* get basic quadrupel of mux registers and the correct reg inside */
46         mux_type = bank->iomux[iomux_num].type;
47         reg = bank->iomux[iomux_num].offset;
48         reg += rockchip_get_mux_data(mux_type, pin, &bit, &mask);
49
50         if (bank->route_mask & BIT(pin)) {
51                 if (rockchip_get_mux_route(bank, pin, mux, &route_reg,
52                                            &route_val)) {
53                         ret = regmap_write(regmap, route_reg, route_val);
54                         if (ret)
55                                 return ret;
56                 }
57         }
58
59         /* bank0 is special, there are no higher 16 bit writing bits. */
60         if (bank->bank_num == 0) {
61                 regmap_read(regmap, reg, &data);
62                 data &= ~(mask << bit);
63         } else {
64                 /* enable the write to the equivalent lower bits */
65                 data = (mask << (bit + 16));
66         }
67
68         data |= (mux & mask) << bit;
69         ret = regmap_write(regmap, reg, data);
70
71         return ret;
72 }
73
74 #define RK3288_PULL_OFFSET              0x140
75 #define RK3288_PULL_PMU_OFFSET          0x64
76
77 static void rk3288_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
78                                          int pin_num, struct regmap **regmap,
79                                          int *reg, u8 *bit)
80 {
81         struct rockchip_pinctrl_priv *priv = bank->priv;
82
83         /* The first 24 pins of the first bank are located in PMU */
84         if (bank->bank_num == 0) {
85                 *regmap = priv->regmap_pmu;
86                 *reg = RK3288_PULL_PMU_OFFSET;
87         } else {
88                 *regmap = priv->regmap_base;
89                 *reg = RK3288_PULL_OFFSET;
90
91                 /* correct the offset, as we're starting with the 2nd bank */
92                 *reg -= 0x10;
93                 *reg += bank->bank_num * ROCKCHIP_PULL_BANK_STRIDE;
94         }
95
96         *reg += ((pin_num / ROCKCHIP_PULL_PINS_PER_REG) * 4);
97
98         *bit = (pin_num % ROCKCHIP_PULL_PINS_PER_REG);
99         *bit *= ROCKCHIP_PULL_BITS_PER_PIN;
100 }
101
102 static int rk3288_set_pull(struct rockchip_pin_bank *bank,
103                            int pin_num, int pull)
104 {
105         struct regmap *regmap;
106         int reg, ret;
107         u8 bit, type;
108         u32 data;
109
110         if (pull == PIN_CONFIG_BIAS_PULL_PIN_DEFAULT)
111                 return -ENOTSUPP;
112
113         rk3288_calc_pull_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
114         type = bank->pull_type[pin_num / 8];
115         ret = rockchip_translate_pull_value(type, pull);
116         if (ret < 0) {
117                 debug("unsupported pull setting %d\n", pull);
118                 return ret;
119         }
120
121         /* bank0 is special, there are no higher 16 bit writing bits */
122         if (bank->bank_num == 0) {
123                 regmap_read(regmap, reg, &data);
124                 data &= ~(((1 << ROCKCHIP_PULL_BITS_PER_PIN) - 1) << bit);
125         } else {
126                 /* enable the write to the equivalent lower bits */
127                 data = ((1 << ROCKCHIP_PULL_BITS_PER_PIN) - 1) << (bit + 16);
128         }
129
130         data |= (ret << bit);
131         ret = regmap_write(regmap, reg, data);
132
133         return ret;
134 }
135
136 #define RK3288_DRV_PMU_OFFSET           0x70
137 #define RK3288_DRV_GRF_OFFSET           0x1c0
138
139 static void rk3288_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
140                                         int pin_num, struct regmap **regmap,
141                                         int *reg, u8 *bit)
142 {
143         struct rockchip_pinctrl_priv *priv = bank->priv;
144
145         /* The first 24 pins of the first bank are located in PMU */
146         if (bank->bank_num == 0) {
147                 *regmap = priv->regmap_pmu;
148                 *reg = RK3288_DRV_PMU_OFFSET;
149         } else {
150                 *regmap = priv->regmap_base;
151                 *reg = RK3288_DRV_GRF_OFFSET;
152
153                 /* correct the offset, as we're starting with the 2nd bank */
154                 *reg -= 0x10;
155                 *reg += bank->bank_num * ROCKCHIP_DRV_BANK_STRIDE;
156         }
157
158         *reg += ((pin_num / ROCKCHIP_DRV_PINS_PER_REG) * 4);
159         *bit = (pin_num % ROCKCHIP_DRV_PINS_PER_REG);
160         *bit *= ROCKCHIP_DRV_BITS_PER_PIN;
161 }
162
163 static int rk3288_set_drive(struct rockchip_pin_bank *bank,
164                             int pin_num, int strength)
165 {
166         struct regmap *regmap;
167         int reg, ret;
168         u32 data;
169         u8 bit;
170         int type = bank->drv[pin_num / 8].drv_type;
171
172         rk3288_calc_drv_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
173         ret = rockchip_translate_drive_value(type, strength);
174         if (ret < 0) {
175                 debug("unsupported driver strength %d\n", strength);
176                 return ret;
177         }
178
179         /* bank0 is special, there are no higher 16 bit writing bits. */
180         if (bank->bank_num == 0) {
181                 regmap_read(regmap, reg, &data);
182                 data &= ~(((1 << ROCKCHIP_DRV_BITS_PER_PIN) - 1) << bit);
183         } else {
184                 /* enable the write to the equivalent lower bits */
185                 data = ((1 << ROCKCHIP_DRV_BITS_PER_PIN) - 1) << (bit + 16);
186         }
187
188         data |= (ret << bit);
189         ret = regmap_write(regmap, reg, data);
190         return ret;
191 }
192
193 static struct rockchip_pin_bank rk3288_pin_banks[] = {
194         PIN_BANK_IOMUX_FLAGS(0, 24, "gpio0", IOMUX_SOURCE_PMU,
195                                              IOMUX_SOURCE_PMU,
196                                              IOMUX_SOURCE_PMU,
197                                              IOMUX_UNROUTED
198                             ),
199         PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", IOMUX_UNROUTED,
200                                              IOMUX_UNROUTED,
201                                              IOMUX_UNROUTED,
202                                              0
203                             ),
204         PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", 0, 0, 0, IOMUX_UNROUTED),
205         PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", 0, 0, 0, IOMUX_WIDTH_4BIT),
206         PIN_BANK_IOMUX_FLAGS(4, 32, "gpio4", IOMUX_WIDTH_4BIT,
207                                              IOMUX_WIDTH_4BIT,
208                                              0,
209                                              0
210                             ),
211         PIN_BANK_IOMUX_FLAGS(5, 32, "gpio5", IOMUX_UNROUTED,
212                                              0,
213                                              0,
214                                              IOMUX_UNROUTED
215                             ),
216         PIN_BANK_IOMUX_FLAGS(6, 32, "gpio6", 0, 0, 0, IOMUX_UNROUTED),
217         PIN_BANK_IOMUX_FLAGS(7, 32, "gpio7", 0,
218                                              0,
219                                              IOMUX_WIDTH_4BIT,
220                                              IOMUX_UNROUTED
221                             ),
222         PIN_BANK(8, 16, "gpio8"),
223 };
224
225 static struct rockchip_pin_ctrl rk3288_pin_ctrl = {
226         .pin_banks              = rk3288_pin_banks,
227         .nr_banks               = ARRAY_SIZE(rk3288_pin_banks),
228         .grf_mux_offset         = 0x0,
229         .pmu_mux_offset         = 0x84,
230         .iomux_routes           = rk3288_mux_route_data,
231         .niomux_routes          = ARRAY_SIZE(rk3288_mux_route_data),
232         .set_mux                = rk3288_set_mux,
233         .set_pull               = rk3288_set_pull,
234         .set_drive              = rk3288_set_drive,
235 };
236
237 static const struct udevice_id rk3288_pinctrl_ids[] = {
238         {
239                 .compatible = "rockchip,rk3288-pinctrl",
240                 .data = (ulong)&rk3288_pin_ctrl
241         },
242         { }
243 };
244
245 U_BOOT_DRIVER(pinctrl_rk3288) = {
246         .name           = "rockchip_rk3288_pinctrl",
247         .id             = UCLASS_PINCTRL,
248         .of_match       = rk3288_pinctrl_ids,
249         .priv_auto_alloc_size = sizeof(struct rockchip_pinctrl_priv),
250         .ops            = &rockchip_pinctrl_ops,
251 #if !CONFIG_IS_ENABLED(OF_PLATDATA)
252         .bind           = dm_scan_fdt_dev,
253 #endif
254         .probe          = rockchip_pinctrl_probe,
255 };