1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * Copyright (C) 2015-2016 Socionext Inc. 4 * Author: Masahiro Yamada <yamada.masahiro@socionext.com> 5 */ 6 7#include <common.h> 8#include <dm.h> 9#include <dm/device_compat.h> 10#include <linux/bitops.h> 11#include <linux/bug.h> 12#include <linux/io.h> 13#include <linux/err.h> 14#include <linux/kernel.h> 15#include <linux/sizes.h> 16#include <dm/pinctrl.h> 17 18#include "pinctrl-uniphier.h" 19 20#define UNIPHIER_PINCTRL_PINMUX_BASE 0x1000 21#define UNIPHIER_PINCTRL_LOAD_PINMUX 0x1700 22#define UNIPHIER_PINCTRL_DRVCTRL_BASE 0x1800 23#define UNIPHIER_PINCTRL_DRV2CTRL_BASE 0x1900 24#define UNIPHIER_PINCTRL_DRV3CTRL_BASE 0x1980 25#define UNIPHIER_PINCTRL_PUPDCTRL_BASE 0x1a00 26#define UNIPHIER_PINCTRL_IECTRL 0x1d00 27 28static const char *uniphier_pinctrl_dummy_name = "_dummy"; 29 30static int uniphier_pinctrl_get_pins_count(struct udevice *dev) 31{ 32 struct uniphier_pinctrl_priv *priv = dev_get_priv(dev); 33 const struct uniphier_pinctrl_pin *pins = priv->socdata->pins; 34 int pins_count = priv->socdata->pins_count; 35 36 if (WARN_ON(!pins_count)) 37 return 0; /* no table of pins */ 38 39 /* 40 * We do not list all pins in the pin table to save memory footprint. 41 * Report the max pin number + 1 to fake the framework. 42 */ 43 return pins[pins_count - 1].number + 1; 44} 45 46static const char *uniphier_pinctrl_get_pin_name(struct udevice *dev, 47 unsigned int selector) 48{ 49 struct uniphier_pinctrl_priv *priv = dev_get_priv(dev); 50 const struct uniphier_pinctrl_pin *pins = priv->socdata->pins; 51 int pins_count = priv->socdata->pins_count; 52 int i; 53 54 for (i = 0; i < pins_count; i++) 55 if (pins[i].number == selector) 56 return pins[i].name; 57 58 return uniphier_pinctrl_dummy_name; 59} 60 61static int uniphier_pinctrl_get_groups_count(struct udevice *dev) 62{ 63 struct uniphier_pinctrl_priv *priv = dev_get_priv(dev); 64 65 return priv->socdata->groups_count; 66} 67 68static const char *uniphier_pinctrl_get_group_name(struct udevice *dev, 69 unsigned selector) 70{ 71 struct uniphier_pinctrl_priv *priv = dev_get_priv(dev); 72 73 if (!priv->socdata->groups[selector].name) 74 return uniphier_pinctrl_dummy_name; 75 76 return priv->socdata->groups[selector].name; 77} 78 79static int uniphier_pinmux_get_functions_count(struct udevice *dev) 80{ 81 struct uniphier_pinctrl_priv *priv = dev_get_priv(dev); 82 83 return priv->socdata->functions_count; 84} 85 86static const char *uniphier_pinmux_get_function_name(struct udevice *dev, 87 unsigned selector) 88{ 89 struct uniphier_pinctrl_priv *priv = dev_get_priv(dev); 90 91 if (!priv->socdata->functions[selector]) 92 return uniphier_pinctrl_dummy_name; 93 94 return priv->socdata->functions[selector]; 95} 96 97static int uniphier_pinconf_input_enable_perpin(struct udevice *dev, 98 unsigned int pin, int enable) 99{ 100 struct uniphier_pinctrl_priv *priv = dev_get_priv(dev); 101 unsigned reg; 102 u32 mask, tmp; 103 104 reg = UNIPHIER_PINCTRL_IECTRL + pin / 32 * 4; 105 mask = BIT(pin % 32); 106 107 tmp = readl(priv->base + reg); 108 if (enable) 109 tmp |= mask; 110 else 111 tmp &= ~mask; 112 writel(tmp, priv->base + reg); 113 114 return 0; 115} 116 117static int uniphier_pinconf_input_enable_legacy(struct udevice *dev, 118 unsigned int pin, int enable) 119{ 120 struct uniphier_pinctrl_priv *priv = dev_get_priv(dev); 121 122 /* 123 * Multiple pins share one input enable, per-pin disabling is 124 * impossible. 125 */ 126 if (!enable) 127 return -EINVAL; 128 129 /* Set all bits instead of having a bunch of pin data */ 130 writel(U32_MAX, priv->base + UNIPHIER_PINCTRL_IECTRL); 131 132 return 0; 133} 134 135static int uniphier_pinconf_input_enable(struct udevice *dev, 136 unsigned int pin, int enable) 137{ 138 struct uniphier_pinctrl_priv *priv = dev_get_priv(dev); 139 140 if (priv->socdata->caps & UNIPHIER_PINCTRL_CAPS_PERPIN_IECTRL) 141 return uniphier_pinconf_input_enable_perpin(dev, pin, enable); 142 else 143 return uniphier_pinconf_input_enable_legacy(dev, pin, enable); 144} 145 146#if CONFIG_IS_ENABLED(PINCONF) 147 148static const struct pinconf_param uniphier_pinconf_params[] = { 149 { "bias-disable", PIN_CONFIG_BIAS_DISABLE, 0 }, 150 { "bias-pull-up", PIN_CONFIG_BIAS_PULL_UP, 1 }, 151 { "bias-pull-down", PIN_CONFIG_BIAS_PULL_DOWN, 1 }, 152 { "bias-pull-pin-default", PIN_CONFIG_BIAS_PULL_PIN_DEFAULT, 1 }, 153 { "drive-strength", PIN_CONFIG_DRIVE_STRENGTH, 0 }, 154 { "input-enable", PIN_CONFIG_INPUT_ENABLE, 1 }, 155 { "input-disable", PIN_CONFIG_INPUT_ENABLE, 0 }, 156}; 157 158static const struct uniphier_pinctrl_pin * 159uniphier_pinctrl_pin_get(struct uniphier_pinctrl_priv *priv, unsigned int pin) 160{ 161 const struct uniphier_pinctrl_pin *pins = priv->socdata->pins; 162 int pins_count = priv->socdata->pins_count; 163 int i; 164 165 for (i = 0; i < pins_count; i++) 166 if (pins[i].number == pin) 167 return &pins[i]; 168 169 return NULL; 170} 171 172static int uniphier_pinconf_bias_set(struct udevice *dev, unsigned int pin, 173 unsigned int param, unsigned int arg) 174{ 175 struct uniphier_pinctrl_priv *priv = dev_get_priv(dev); 176 unsigned int enable = 1; 177 unsigned int reg; 178 u32 mask, tmp; 179 180 if (!(priv->socdata->caps & UNIPHIER_PINCTRL_CAPS_PUPD_SIMPLE)) 181 return -ENOTSUPP; 182 183 switch (param) { 184 case PIN_CONFIG_BIAS_DISABLE: 185 enable = 0; 186 break; 187 case PIN_CONFIG_BIAS_PULL_UP: 188 case PIN_CONFIG_BIAS_PULL_DOWN: 189 if (arg == 0) /* total bias is not supported */ 190 return -EINVAL; 191 break; 192 case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT: 193 if (arg == 0) /* configuration ignored */ 194 return 0; 195 default: 196 BUG(); 197 } 198 199 reg = UNIPHIER_PINCTRL_PUPDCTRL_BASE + pin / 32 * 4; 200 mask = BIT(pin % 32); 201 202 tmp = readl(priv->base + reg); 203 if (enable) 204 tmp |= mask; 205 else 206 tmp &= ~mask; 207 writel(tmp, priv->base + reg); 208 209 return 0; 210} 211 212static const unsigned int uniphier_pinconf_drv_strengths_1bit[] = { 213 4, 8, 214}; 215 216static const unsigned int uniphier_pinconf_drv_strengths_2bit[] = { 217 8, 12, 16, 20, 218}; 219 220static const unsigned int uniphier_pinconf_drv_strengths_3bit[] = { 221 4, 5, 7, 9, 11, 12, 14, 16, 222}; 223 224static int uniphier_pinconf_drive_set(struct udevice *dev, unsigned int pin, 225 unsigned int strength) 226{ 227 struct uniphier_pinctrl_priv *priv = dev_get_priv(dev); 228 const struct uniphier_pinctrl_pin *desc; 229 const unsigned int *strengths; 230 unsigned int base, stride, width, drvctrl, reg, shift; 231 u32 val, mask, tmp; 232 233 desc = uniphier_pinctrl_pin_get(priv, pin); 234 if (WARN_ON(!desc)) 235 return -EINVAL; 236 237 switch (uniphier_pin_get_drv_type(desc->data)) { 238 case UNIPHIER_PIN_DRV_1BIT: 239 strengths = uniphier_pinconf_drv_strengths_1bit; 240 base = UNIPHIER_PINCTRL_DRVCTRL_BASE; 241 stride = 1; 242 width = 1; 243 break; 244 case UNIPHIER_PIN_DRV_2BIT: 245 strengths = uniphier_pinconf_drv_strengths_2bit; 246 base = UNIPHIER_PINCTRL_DRV2CTRL_BASE; 247 stride = 2; 248 width = 2; 249 break; 250 case UNIPHIER_PIN_DRV_3BIT: 251 strengths = uniphier_pinconf_drv_strengths_3bit; 252 base = UNIPHIER_PINCTRL_DRV3CTRL_BASE; 253 stride = 4; 254 width = 3; 255 break; 256 default: 257 /* drive strength control is not supported for this pin */ 258 return -EINVAL; 259 } 260 261 drvctrl = uniphier_pin_get_drvctrl(desc->data); 262 drvctrl *= stride; 263 264 reg = base + drvctrl / 32 * 4; 265 shift = drvctrl % 32; 266 mask = (1U << width) - 1; 267 268 for (val = 0; val <= mask; val++) { 269 if (strengths[val] > strength) 270 break; 271 } 272 273 if (val == 0) { 274 dev_err(dev, "unsupported drive strength %u mA for pin %s\n", 275 strength, desc->name); 276 return -EINVAL; 277 } 278 279 if (!mask) 280 return 0; 281 282 val--; 283 284 tmp = readl(priv->base + reg); 285 tmp &= ~(mask << shift); 286 tmp |= (mask & val) << shift; 287 writel(tmp, priv->base + reg); 288 289 return 0; 290} 291 292static int uniphier_pinconf_set(struct udevice *dev, unsigned int pin, 293 unsigned int param, unsigned int arg) 294{ 295 int ret; 296 297 switch (param) { 298 case PIN_CONFIG_BIAS_DISABLE: 299 case PIN_CONFIG_BIAS_PULL_UP: 300 case PIN_CONFIG_BIAS_PULL_DOWN: 301 case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT: 302 ret = uniphier_pinconf_bias_set(dev, pin, param, arg); 303 break; 304 case PIN_CONFIG_DRIVE_STRENGTH: 305 ret = uniphier_pinconf_drive_set(dev, pin, arg); 306 break; 307 case PIN_CONFIG_INPUT_ENABLE: 308 ret = uniphier_pinconf_input_enable(dev, pin, arg); 309 break; 310 default: 311 dev_err(dev, "unsupported configuration parameter %u\n", param); 312 return -EINVAL; 313 } 314 315 return ret; 316} 317 318static int uniphier_pinconf_group_set(struct udevice *dev, 319 unsigned int group_selector, 320 unsigned int param, unsigned int arg) 321{ 322 struct uniphier_pinctrl_priv *priv = dev_get_priv(dev); 323 const struct uniphier_pinctrl_group *grp = 324 &priv->socdata->groups[group_selector]; 325 int i, ret; 326 327 for (i = 0; i < grp->num_pins; i++) { 328 ret = uniphier_pinconf_set(dev, grp->pins[i], param, arg); 329 if (ret) 330 return ret; 331 } 332 333 return 0; 334} 335 336#endif /* CONFIG_IS_ENABLED(PINCONF) */ 337 338static void uniphier_pinmux_set_one(struct udevice *dev, unsigned pin, 339 int muxval) 340{ 341 struct uniphier_pinctrl_priv *priv = dev_get_priv(dev); 342 unsigned reg, reg_end, shift, mask; 343 unsigned mux_bits = 8; 344 unsigned reg_stride = 4; 345 bool load_pinctrl = false; 346 u32 tmp; 347 348 /* some pins need input-enabling */ 349 uniphier_pinconf_input_enable(dev, pin, 1); 350 351 if (muxval < 0) 352 return; /* dedicated pin; nothing to do for pin-mux */ 353 354 if (priv->socdata->caps & UNIPHIER_PINCTRL_CAPS_MUX_4BIT) 355 mux_bits = 4; 356 357 if (priv->socdata->caps & UNIPHIER_PINCTRL_CAPS_DBGMUX_SEPARATE) { 358 /* 359 * Mode offset bit 360 * Normal 4 * n shift+3:shift 361 * Debug 4 * n shift+7:shift+4 362 */ 363 mux_bits /= 2; 364 reg_stride = 8; 365 load_pinctrl = true; 366 } 367 368 reg = UNIPHIER_PINCTRL_PINMUX_BASE + pin * mux_bits / 32 * reg_stride; 369 reg_end = reg + reg_stride; 370 shift = pin * mux_bits % 32; 371 mask = (1U << mux_bits) - 1; 372 373 /* 374 * If reg_stride is greater than 4, the MSB of each pinsel shall be 375 * stored in the offset+4. 376 */ 377 for (; reg < reg_end; reg += 4) { 378 tmp = readl(priv->base + reg); 379 tmp &= ~(mask << shift); 380 tmp |= (mask & muxval) << shift; 381 writel(tmp, priv->base + reg); 382 383 muxval >>= mux_bits; 384 } 385 386 if (load_pinctrl) 387 writel(1, priv->base + UNIPHIER_PINCTRL_LOAD_PINMUX); 388} 389 390static int uniphier_pinmux_group_set(struct udevice *dev, 391 unsigned group_selector, 392 unsigned func_selector) 393{ 394 struct uniphier_pinctrl_priv *priv = dev_get_priv(dev); 395 const struct uniphier_pinctrl_group *grp = 396 &priv->socdata->groups[group_selector]; 397 int i; 398 399 for (i = 0; i < grp->num_pins; i++) 400 uniphier_pinmux_set_one(dev, grp->pins[i], grp->muxvals[i]); 401 402 return 0; 403} 404 405const struct pinctrl_ops uniphier_pinctrl_ops = { 406 .get_pins_count = uniphier_pinctrl_get_pins_count, 407 .get_pin_name = uniphier_pinctrl_get_pin_name, 408 .get_groups_count = uniphier_pinctrl_get_groups_count, 409 .get_group_name = uniphier_pinctrl_get_group_name, 410 .get_functions_count = uniphier_pinmux_get_functions_count, 411 .get_function_name = uniphier_pinmux_get_function_name, 412 .pinmux_group_set = uniphier_pinmux_group_set, 413#if CONFIG_IS_ENABLED(PINCONF) 414 .pinconf_num_params = ARRAY_SIZE(uniphier_pinconf_params), 415 .pinconf_params = uniphier_pinconf_params, 416 .pinconf_set = uniphier_pinconf_set, 417 .pinconf_group_set = uniphier_pinconf_group_set, 418#endif 419 .set_state = pinctrl_generic_set_state, 420}; 421 422int uniphier_pinctrl_probe(struct udevice *dev, 423 struct uniphier_pinctrl_socdata *socdata) 424{ 425 struct uniphier_pinctrl_priv *priv = dev_get_priv(dev); 426 fdt_addr_t addr; 427 428 addr = dev_read_addr(dev->parent); 429 if (addr == FDT_ADDR_T_NONE) 430 return -EINVAL; 431 432 priv->base = devm_ioremap(dev, addr, SZ_4K); 433 if (!priv->base) 434 return -ENOMEM; 435 436 priv->socdata = socdata; 437 438 return 0; 439} 440