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 <syscon.h> 12#include <linux/bitops.h> 13 14#include "pinctrl-rockchip.h" 15 16static struct rockchip_mux_route_data rk3228_mux_route_data[] = { 17 { 18 /* pwm0-0 */ 19 .bank_num = 0, 20 .pin = 26, 21 .func = 1, 22 .route_offset = 0x50, 23 .route_val = BIT(16), 24 }, { 25 /* pwm0-1 */ 26 .bank_num = 3, 27 .pin = 21, 28 .func = 1, 29 .route_offset = 0x50, 30 .route_val = BIT(16) | BIT(0), 31 }, { 32 /* pwm1-0 */ 33 .bank_num = 0, 34 .pin = 27, 35 .func = 1, 36 .route_offset = 0x50, 37 .route_val = BIT(16 + 1), 38 }, { 39 /* pwm1-1 */ 40 .bank_num = 0, 41 .pin = 30, 42 .func = 2, 43 .route_offset = 0x50, 44 .route_val = BIT(16 + 1) | BIT(1), 45 }, { 46 /* pwm2-0 */ 47 .bank_num = 0, 48 .pin = 28, 49 .func = 1, 50 .route_offset = 0x50, 51 .route_val = BIT(16 + 2), 52 }, { 53 /* pwm2-1 */ 54 .bank_num = 1, 55 .pin = 12, 56 .func = 2, 57 .route_offset = 0x50, 58 .route_val = BIT(16 + 2) | BIT(2), 59 }, { 60 /* pwm3-0 */ 61 .bank_num = 3, 62 .pin = 26, 63 .func = 1, 64 .route_offset = 0x50, 65 .route_val = BIT(16 + 3), 66 }, { 67 /* pwm3-1 */ 68 .bank_num = 1, 69 .pin = 11, 70 .func = 2, 71 .route_offset = 0x50, 72 .route_val = BIT(16 + 3) | BIT(3), 73 }, { 74 /* sdio-0_d0 */ 75 .bank_num = 1, 76 .pin = 1, 77 .func = 1, 78 .route_offset = 0x50, 79 .route_val = BIT(16 + 4), 80 }, { 81 /* sdio-1_d0 */ 82 .bank_num = 3, 83 .pin = 2, 84 .func = 1, 85 .route_offset = 0x50, 86 .route_val = BIT(16 + 4) | BIT(4), 87 }, { 88 /* spi-0_rx */ 89 .bank_num = 0, 90 .pin = 13, 91 .func = 2, 92 .route_offset = 0x50, 93 .route_val = BIT(16 + 5), 94 }, { 95 /* spi-1_rx */ 96 .bank_num = 2, 97 .pin = 0, 98 .func = 2, 99 .route_offset = 0x50, 100 .route_val = BIT(16 + 5) | BIT(5), 101 }, { 102 /* emmc-0_cmd */ 103 .bank_num = 1, 104 .pin = 22, 105 .func = 2, 106 .route_offset = 0x50, 107 .route_val = BIT(16 + 7), 108 }, { 109 /* emmc-1_cmd */ 110 .bank_num = 2, 111 .pin = 4, 112 .func = 2, 113 .route_offset = 0x50, 114 .route_val = BIT(16 + 7) | BIT(7), 115 }, { 116 /* uart2-0_rx */ 117 .bank_num = 1, 118 .pin = 19, 119 .func = 2, 120 .route_offset = 0x50, 121 .route_val = BIT(16 + 8), 122 }, { 123 /* uart2-1_rx */ 124 .bank_num = 1, 125 .pin = 10, 126 .func = 2, 127 .route_offset = 0x50, 128 .route_val = BIT(16 + 8) | BIT(8), 129 }, { 130 /* uart1-0_rx */ 131 .bank_num = 1, 132 .pin = 10, 133 .func = 1, 134 .route_offset = 0x50, 135 .route_val = BIT(16 + 11), 136 }, { 137 /* uart1-1_rx */ 138 .bank_num = 3, 139 .pin = 13, 140 .func = 1, 141 .route_offset = 0x50, 142 .route_val = BIT(16 + 11) | BIT(11), 143 }, 144}; 145 146static int rk3228_set_mux(struct rockchip_pin_bank *bank, int pin, int mux) 147{ 148 struct rockchip_pinctrl_priv *priv = bank->priv; 149 int iomux_num = (pin / 8); 150 struct regmap *regmap; 151 int reg, ret, mask, mux_type; 152 u8 bit; 153 u32 data; 154 155 regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU) 156 ? priv->regmap_pmu : priv->regmap_base; 157 158 /* get basic quadrupel of mux registers and the correct reg inside */ 159 mux_type = bank->iomux[iomux_num].type; 160 reg = bank->iomux[iomux_num].offset; 161 reg += rockchip_get_mux_data(mux_type, pin, &bit, &mask); 162 163 data = (mask << (bit + 16)); 164 data |= (mux & mask) << bit; 165 ret = regmap_write(regmap, reg, data); 166 167 return ret; 168} 169 170#define RK3228_PULL_OFFSET 0x100 171 172static void rk3228_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, 173 int pin_num, struct regmap **regmap, 174 int *reg, u8 *bit) 175{ 176 struct rockchip_pinctrl_priv *priv = bank->priv; 177 178 *regmap = priv->regmap_base; 179 *reg = RK3228_PULL_OFFSET; 180 *reg += bank->bank_num * ROCKCHIP_PULL_BANK_STRIDE; 181 *reg += ((pin_num / ROCKCHIP_PULL_PINS_PER_REG) * 4); 182 183 *bit = (pin_num % ROCKCHIP_PULL_PINS_PER_REG); 184 *bit *= ROCKCHIP_PULL_BITS_PER_PIN; 185} 186 187static int rk3228_set_pull(struct rockchip_pin_bank *bank, 188 int pin_num, int pull) 189{ 190 struct regmap *regmap; 191 int reg, ret; 192 u8 bit, type; 193 u32 data; 194 195 if (pull == PIN_CONFIG_BIAS_PULL_PIN_DEFAULT) 196 return -ENOTSUPP; 197 198 rk3228_calc_pull_reg_and_bit(bank, pin_num, ®map, ®, &bit); 199 type = bank->pull_type[pin_num / 8]; 200 ret = rockchip_translate_pull_value(type, pull); 201 if (ret < 0) { 202 debug("unsupported pull setting %d\n", pull); 203 return ret; 204 } 205 206 /* enable the write to the equivalent lower bits */ 207 data = ((1 << ROCKCHIP_PULL_BITS_PER_PIN) - 1) << (bit + 16); 208 data |= (ret << bit); 209 ret = regmap_write(regmap, reg, data); 210 211 return ret; 212} 213 214#define RK3228_DRV_GRF_OFFSET 0x200 215 216static void rk3228_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, 217 int pin_num, struct regmap **regmap, 218 int *reg, u8 *bit) 219{ 220 struct rockchip_pinctrl_priv *priv = bank->priv; 221 222 *regmap = priv->regmap_base; 223 *reg = RK3228_DRV_GRF_OFFSET; 224 *reg += bank->bank_num * ROCKCHIP_DRV_BANK_STRIDE; 225 *reg += ((pin_num / ROCKCHIP_DRV_PINS_PER_REG) * 4); 226 227 *bit = (pin_num % ROCKCHIP_DRV_PINS_PER_REG); 228 *bit *= ROCKCHIP_DRV_BITS_PER_PIN; 229} 230 231static int rk3228_set_drive(struct rockchip_pin_bank *bank, 232 int pin_num, int strength) 233{ 234 struct regmap *regmap; 235 int reg, ret; 236 u32 data; 237 u8 bit; 238 int type = bank->drv[pin_num / 8].drv_type; 239 240 rk3228_calc_drv_reg_and_bit(bank, pin_num, ®map, ®, &bit); 241 ret = rockchip_translate_drive_value(type, strength); 242 if (ret < 0) { 243 debug("unsupported driver strength %d\n", strength); 244 return ret; 245 } 246 247 /* enable the write to the equivalent lower bits */ 248 data = ((1 << ROCKCHIP_DRV_BITS_PER_PIN) - 1) << (bit + 16); 249 data |= (ret << bit); 250 ret = regmap_write(regmap, reg, data); 251 return ret; 252} 253 254static struct rockchip_pin_bank rk3228_pin_banks[] = { 255 PIN_BANK(0, 32, "gpio0"), 256 PIN_BANK(1, 32, "gpio1"), 257 PIN_BANK(2, 32, "gpio2"), 258 PIN_BANK(3, 32, "gpio3"), 259}; 260 261static struct rockchip_pin_ctrl rk3228_pin_ctrl = { 262 .pin_banks = rk3228_pin_banks, 263 .nr_banks = ARRAY_SIZE(rk3228_pin_banks), 264 .grf_mux_offset = 0x0, 265 .iomux_routes = rk3228_mux_route_data, 266 .niomux_routes = ARRAY_SIZE(rk3228_mux_route_data), 267 .set_mux = rk3228_set_mux, 268 .set_pull = rk3228_set_pull, 269 .set_drive = rk3228_set_drive, 270}; 271 272static const struct udevice_id rk3228_pinctrl_ids[] = { 273 { 274 .compatible = "rockchip,rk3228-pinctrl", 275 .data = (ulong)&rk3228_pin_ctrl 276 }, 277 { } 278}; 279 280U_BOOT_DRIVER(pinctrl_rk3228) = { 281 .name = "rockchip_rk3228_pinctrl", 282 .id = UCLASS_PINCTRL, 283 .of_match = rk3228_pinctrl_ids, 284 .priv_auto = sizeof(struct rockchip_pinctrl_priv), 285 .ops = &rockchip_pinctrl_ops, 286#if CONFIG_IS_ENABLED(OF_REAL) 287 .bind = dm_scan_fdt_dev, 288#endif 289 .probe = rockchip_pinctrl_probe, 290}; 291