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 static int rk3188_set_mux(struct rockchip_pin_bank *bank, int pin, int mux) 15 { 16 struct rockchip_pinctrl_priv *priv = bank->priv; 17 int iomux_num = (pin / 8); 18 struct regmap *regmap; 19 int reg, ret, mask, mux_type; 20 u8 bit; 21 u32 data; 22 23 regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU) 24 ? priv->regmap_pmu : priv->regmap_base; 25 26 /* get basic quadrupel of mux registers and the correct reg inside */ 27 mux_type = bank->iomux[iomux_num].type; 28 reg = bank->iomux[iomux_num].offset; 29 reg += rockchip_get_mux_data(mux_type, pin, &bit, &mask); 30 31 data = (mask << (bit + 16)); 32 data |= (mux & mask) << bit; 33 ret = regmap_write(regmap, reg, data); 34 35 return ret; 36 } 37 38 #define RK3188_PULL_OFFSET 0x164 39 #define RK3188_PULL_PMU_OFFSET 0x64 40 41 static void rk3188_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, 42 int pin_num, struct regmap **regmap, 43 int *reg, u8 *bit) 44 { 45 struct rockchip_pinctrl_priv *priv = bank->priv; 46 47 /* The first 12 pins of the first bank are located elsewhere */ 48 if (bank->bank_num == 0 && pin_num < 12) { 49 *regmap = priv->regmap_pmu; 50 *reg = RK3188_PULL_PMU_OFFSET; 51 52 *reg += ((pin_num / ROCKCHIP_PULL_PINS_PER_REG) * 4); 53 *bit = pin_num % ROCKCHIP_PULL_PINS_PER_REG; 54 *bit *= ROCKCHIP_PULL_BITS_PER_PIN; 55 } else { 56 *regmap = priv->regmap_base; 57 *reg = RK3188_PULL_OFFSET; 58 59 /* correct the offset, as it is the 2nd pull register */ 60 *reg -= 4; 61 *reg += bank->bank_num * ROCKCHIP_PULL_BANK_STRIDE; 62 *reg += ((pin_num / ROCKCHIP_PULL_PINS_PER_REG) * 4); 63 64 /* 65 * The bits in these registers have an inverse ordering 66 * with the lowest pin being in bits 15:14 and the highest 67 * pin in bits 1:0 68 */ 69 *bit = 7 - (pin_num % ROCKCHIP_PULL_PINS_PER_REG); 70 *bit *= ROCKCHIP_PULL_BITS_PER_PIN; 71 } 72 } 73 74 static int rk3188_set_pull(struct rockchip_pin_bank *bank, 75 int pin_num, int pull) 76 { 77 struct regmap *regmap; 78 int reg, ret; 79 u8 bit, type; 80 u32 data; 81 82 if (pull == PIN_CONFIG_BIAS_PULL_PIN_DEFAULT) 83 return -ENOTSUPP; 84 85 rk3188_calc_pull_reg_and_bit(bank, pin_num, ®map, ®, &bit); 86 type = bank->pull_type[pin_num / 8]; 87 ret = rockchip_translate_pull_value(type, pull); 88 if (ret < 0) { 89 debug("unsupported pull setting %d\n", pull); 90 return ret; 91 } 92 93 /* enable the write to the equivalent lower bits */ 94 data = ((1 << ROCKCHIP_PULL_BITS_PER_PIN) - 1) << (bit + 16); 95 data |= (ret << bit); 96 ret = regmap_write(regmap, reg, data); 97 98 return ret; 99 } 100 101 static struct rockchip_pin_bank rk3188_pin_banks[] = { 102 PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_GPIO_ONLY, 0, 0, 0), 103 PIN_BANK(1, 32, "gpio1"), 104 PIN_BANK(2, 32, "gpio2"), 105 PIN_BANK(3, 32, "gpio3"), 106 }; 107 108 static struct rockchip_pin_ctrl rk3188_pin_ctrl = { 109 .pin_banks = rk3188_pin_banks, 110 .nr_banks = ARRAY_SIZE(rk3188_pin_banks), 111 .nr_pins = 128, 112 .grf_mux_offset = 0x60, 113 .set_mux = rk3188_set_mux, 114 .set_pull = rk3188_set_pull, 115 }; 116 117 static const struct udevice_id rk3188_pinctrl_ids[] = { 118 { .compatible = "rockchip,rk3188-pinctrl", 119 .data = (ulong)&rk3188_pin_ctrl }, 120 { } 121 }; 122 123 U_BOOT_DRIVER(pinctrl_rk3188) = { 124 .name = "rockchip_rk3188_pinctrl", 125 .id = UCLASS_PINCTRL, 126 .of_match = rk3188_pinctrl_ids, 127 .priv_auto_alloc_size = sizeof(struct rockchip_pinctrl_priv), 128 .ops = &rockchip_pinctrl_ops, 129 #if !CONFIG_IS_ENABLED(OF_PLATDATA) 130 .bind = dm_scan_fdt_dev, 131 #endif 132 .probe = rockchip_pinctrl_probe, 133 }; 134