1 // SPDX-License-Identifier: GPL-2.0+
3 * (C) Copyright 2019 Rockchip Electronics Co., Ltd
9 #include <dm/pinctrl.h>
12 #include <linux/bitops.h>
14 #include "pinctrl-rockchip.h"
16 static struct rockchip_mux_recalced_data rk3308_mux_recalced_data[] = {
110 static struct rockchip_mux_route_data rk3308_mux_route_data[] = {
116 .route_offset = 0x314,
117 .route_val = BIT(16 + 0) | BIT(0),
123 .route_offset = 0x314,
124 .route_val = BIT(16 + 2) | BIT(16 + 3),
130 .route_offset = 0x314,
131 .route_val = BIT(16 + 2) | BIT(16 + 3) | BIT(2),
137 .route_offset = 0x608,
138 .route_val = BIT(16 + 8) | BIT(16 + 9),
144 .route_offset = 0x608,
145 .route_val = BIT(16 + 8) | BIT(16 + 9) | BIT(8),
151 .route_offset = 0x608,
152 .route_val = BIT(16 + 8) | BIT(16 + 9) | BIT(9),
154 /* i2s-8ch-1-sclktxm0 */
158 .route_offset = 0x308,
159 .route_val = BIT(16 + 3),
161 /* i2s-8ch-1-sclkrxm0 */
165 .route_offset = 0x308,
166 .route_val = BIT(16 + 3),
168 /* i2s-8ch-1-sclktxm1 */
172 .route_offset = 0x308,
173 .route_val = BIT(16 + 3) | BIT(3),
175 /* i2s-8ch-1-sclkrxm1 */
179 .route_offset = 0x308,
180 .route_val = BIT(16 + 3) | BIT(3),
186 .route_offset = 0x308,
187 .route_val = BIT(16 + 12) | BIT(16 + 13),
193 .route_offset = 0x308,
194 .route_val = BIT(16 + 12) | BIT(16 + 13) | BIT(12),
200 .route_offset = 0x308,
201 .route_val = BIT(16 + 12) | BIT(16 + 13) | BIT(13),
207 .route_offset = 0x600,
208 .route_val = BIT(16 + 2) | BIT(2),
214 .route_offset = 0x314,
215 .route_val = BIT(16 + 9),
221 .route_offset = 0x314,
222 .route_val = BIT(16 + 9) | BIT(9),
228 .route_offset = 0x314,
229 .route_val = BIT(16 + 14),
235 .route_offset = 0x314,
236 .route_val = BIT(16 + 14) | BIT(14),
242 .route_offset = 0x314,
243 .route_val = BIT(16 + 15),
249 .route_offset = 0x314,
250 .route_val = BIT(16 + 15) | BIT(15),
254 static int rk3308_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
256 struct rockchip_pinctrl_priv *priv = bank->priv;
257 int iomux_num = (pin / 8);
258 struct regmap *regmap;
259 int reg, ret, mask, mux_type;
261 u32 data, route_reg, route_val;
263 regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU)
264 ? priv->regmap_pmu : priv->regmap_base;
266 /* get basic quadrupel of mux registers and the correct reg inside */
267 mux_type = bank->iomux[iomux_num].type;
268 reg = bank->iomux[iomux_num].offset;
269 reg += rockchip_get_mux_data(mux_type, pin, &bit, &mask);
271 if (bank->recalced_mask & BIT(pin))
272 rockchip_get_recalced_mux(bank, pin, ®, &bit, &mask);
274 if (bank->route_mask & BIT(pin)) {
275 if (rockchip_get_mux_route(bank, pin, mux, &route_reg,
277 ret = regmap_write(regmap, route_reg, route_val);
283 data = (mask << (bit + 16));
284 data |= (mux & mask) << bit;
285 ret = regmap_write(regmap, reg, data);
290 #define RK3308_PULL_OFFSET 0xa0
292 static void rk3308_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
293 int pin_num, struct regmap **regmap,
296 struct rockchip_pinctrl_priv *priv = bank->priv;
298 *regmap = priv->regmap_base;
299 *reg = RK3308_PULL_OFFSET;
300 *reg += bank->bank_num * ROCKCHIP_PULL_BANK_STRIDE;
301 *reg += ((pin_num / ROCKCHIP_PULL_PINS_PER_REG) * 4);
303 *bit = (pin_num % ROCKCHIP_PULL_PINS_PER_REG);
304 *bit *= ROCKCHIP_PULL_BITS_PER_PIN;
307 static int rk3308_set_pull(struct rockchip_pin_bank *bank,
308 int pin_num, int pull)
310 struct regmap *regmap;
315 if (pull == PIN_CONFIG_BIAS_PULL_PIN_DEFAULT)
318 rk3308_calc_pull_reg_and_bit(bank, pin_num, ®map, ®, &bit);
319 type = bank->pull_type[pin_num / 8];
320 ret = rockchip_translate_pull_value(type, pull);
322 debug("unsupported pull setting %d\n", pull);
326 /* enable the write to the equivalent lower bits */
327 data = ((1 << ROCKCHIP_PULL_BITS_PER_PIN) - 1) << (bit + 16);
328 data |= (ret << bit);
330 ret = regmap_write(regmap, reg, data);
335 #define RK3308_DRV_GRF_OFFSET 0x100
337 static void rk3308_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
338 int pin_num, struct regmap **regmap,
341 struct rockchip_pinctrl_priv *priv = bank->priv;
343 *regmap = priv->regmap_base;
344 *reg = RK3308_DRV_GRF_OFFSET;
345 *reg += bank->bank_num * ROCKCHIP_DRV_BANK_STRIDE;
346 *reg += ((pin_num / ROCKCHIP_DRV_PINS_PER_REG) * 4);
348 *bit = (pin_num % ROCKCHIP_DRV_PINS_PER_REG);
349 *bit *= ROCKCHIP_DRV_BITS_PER_PIN;
352 static int rk3308_set_drive(struct rockchip_pin_bank *bank,
353 int pin_num, int strength)
355 struct regmap *regmap;
359 int type = bank->drv[pin_num / 8].drv_type;
361 rk3308_calc_drv_reg_and_bit(bank, pin_num, ®map, ®, &bit);
362 ret = rockchip_translate_drive_value(type, strength);
364 debug("unsupported driver strength %d\n", strength);
368 /* enable the write to the equivalent lower bits */
369 data = ((1 << ROCKCHIP_DRV_BITS_PER_PIN) - 1) << (bit + 16);
370 data |= (ret << bit);
371 ret = regmap_write(regmap, reg, data);
375 #define RK3308_SCHMITT_PINS_PER_REG 8
376 #define RK3308_SCHMITT_BANK_STRIDE 16
377 #define RK3308_SCHMITT_GRF_OFFSET 0x1a0
379 static int rk3308_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank,
381 struct regmap **regmap,
384 struct rockchip_pinctrl_priv *priv = bank->priv;
386 *regmap = priv->regmap_base;
387 *reg = RK3308_SCHMITT_GRF_OFFSET;
389 *reg += bank->bank_num * RK3308_SCHMITT_BANK_STRIDE;
390 *reg += ((pin_num / RK3308_SCHMITT_PINS_PER_REG) * 4);
391 *bit = pin_num % RK3308_SCHMITT_PINS_PER_REG;
396 static int rk3308_set_schmitt(struct rockchip_pin_bank *bank,
397 int pin_num, int enable)
399 struct regmap *regmap;
404 rk3308_calc_schmitt_reg_and_bit(bank, pin_num, ®map, ®, &bit);
405 /* enable the write to the equivalent lower bits */
406 data = BIT(bit + 16) | (enable << bit);
408 return regmap_write(regmap, reg, data);
411 static struct rockchip_pin_bank rk3308_pin_banks[] = {
412 PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_8WIDTH_2BIT,
416 PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", IOMUX_8WIDTH_2BIT,
420 PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", IOMUX_8WIDTH_2BIT,
424 PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", IOMUX_8WIDTH_2BIT,
428 PIN_BANK_IOMUX_FLAGS(4, 32, "gpio4", IOMUX_8WIDTH_2BIT,
434 static struct rockchip_pin_ctrl rk3308_pin_ctrl = {
435 .pin_banks = rk3308_pin_banks,
436 .nr_banks = ARRAY_SIZE(rk3308_pin_banks),
437 .grf_mux_offset = 0x0,
438 .iomux_recalced = rk3308_mux_recalced_data,
439 .niomux_recalced = ARRAY_SIZE(rk3308_mux_recalced_data),
440 .iomux_routes = rk3308_mux_route_data,
441 .niomux_routes = ARRAY_SIZE(rk3308_mux_route_data),
442 .set_mux = rk3308_set_mux,
443 .set_drive = rk3308_set_drive,
444 .set_pull = rk3308_set_pull,
445 .set_schmitt = rk3308_set_schmitt,
448 static const struct udevice_id rk3308_pinctrl_ids[] = {
450 .compatible = "rockchip,rk3308-pinctrl",
451 .data = (ulong)&rk3308_pin_ctrl
456 U_BOOT_DRIVER(pinctrl_rk3308) = {
457 .name = "rockchip_rk3308_pinctrl",
458 .id = UCLASS_PINCTRL,
459 .of_match = rk3308_pinctrl_ids,
460 .priv_auto_alloc_size = sizeof(struct rockchip_pinctrl_priv),
461 .ops = &rockchip_pinctrl_ops,
462 #if !CONFIG_IS_ENABLED(OF_PLATDATA)
463 .bind = dm_scan_fdt_dev,
465 .probe = rockchip_pinctrl_probe,