1 /* 2 * Copyright (C) 2015-2016 Socionext Inc. 3 * Author: Masahiro Yamada <yamada.masahiro@socionext.com> 4 * 5 * SPDX-License-Identifier: GPL-2.0+ 6 */ 7 8 #include <linux/io.h> 9 #include <linux/err.h> 10 #include <linux/sizes.h> 11 #include <dm/device.h> 12 #include <dm/pinctrl.h> 13 14 #include "pinctrl-uniphier.h" 15 16 #define UNIPHIER_PINCTRL_PINMUX_BASE 0x1000 17 #define UNIPHIER_PINCTRL_LOAD_PINMUX 0x1700 18 #define UNIPHIER_PINCTRL_IECTRL 0x1d00 19 20 static const char *uniphier_pinctrl_dummy_name = "_dummy"; 21 22 static int uniphier_pinctrl_get_groups_count(struct udevice *dev) 23 { 24 struct uniphier_pinctrl_priv *priv = dev_get_priv(dev); 25 26 return priv->socdata->groups_count; 27 } 28 29 static const char *uniphier_pinctrl_get_group_name(struct udevice *dev, 30 unsigned selector) 31 { 32 struct uniphier_pinctrl_priv *priv = dev_get_priv(dev); 33 34 if (!priv->socdata->groups[selector].name) 35 return uniphier_pinctrl_dummy_name; 36 37 return priv->socdata->groups[selector].name; 38 } 39 40 static int uniphier_pinmux_get_functions_count(struct udevice *dev) 41 { 42 struct uniphier_pinctrl_priv *priv = dev_get_priv(dev); 43 44 return priv->socdata->functions_count; 45 } 46 47 static const char *uniphier_pinmux_get_function_name(struct udevice *dev, 48 unsigned selector) 49 { 50 struct uniphier_pinctrl_priv *priv = dev_get_priv(dev); 51 52 if (!priv->socdata->functions[selector]) 53 return uniphier_pinctrl_dummy_name; 54 55 return priv->socdata->functions[selector]; 56 } 57 58 static void uniphier_pinconf_input_enable_perpin(struct udevice *dev, 59 unsigned pin) 60 { 61 struct uniphier_pinctrl_priv *priv = dev_get_priv(dev); 62 unsigned reg; 63 u32 mask, tmp; 64 65 reg = UNIPHIER_PINCTRL_IECTRL + pin / 32 * 4; 66 mask = BIT(pin % 32); 67 68 tmp = readl(priv->base + reg); 69 tmp |= mask; 70 writel(tmp, priv->base + reg); 71 } 72 73 static void uniphier_pinconf_input_enable_legacy(struct udevice *dev, 74 unsigned pin) 75 { 76 struct uniphier_pinctrl_priv *priv = dev_get_priv(dev); 77 int pins_count = priv->socdata->pins_count; 78 const struct uniphier_pinctrl_pin *pins = priv->socdata->pins; 79 int i; 80 81 for (i = 0; i < pins_count; i++) { 82 if (pins[i].number == pin) { 83 unsigned int iectrl; 84 u32 tmp; 85 86 iectrl = uniphier_pin_get_iectrl(pins[i].data); 87 tmp = readl(priv->base + UNIPHIER_PINCTRL_IECTRL); 88 tmp |= 1 << iectrl; 89 writel(tmp, priv->base + UNIPHIER_PINCTRL_IECTRL); 90 } 91 } 92 } 93 94 static void uniphier_pinconf_input_enable(struct udevice *dev, unsigned pin) 95 { 96 struct uniphier_pinctrl_priv *priv = dev_get_priv(dev); 97 98 if (priv->socdata->caps & UNIPHIER_PINCTRL_CAPS_PERPIN_IECTRL) 99 uniphier_pinconf_input_enable_perpin(dev, pin); 100 else 101 uniphier_pinconf_input_enable_legacy(dev, pin); 102 } 103 104 static void uniphier_pinmux_set_one(struct udevice *dev, unsigned pin, 105 int muxval) 106 { 107 struct uniphier_pinctrl_priv *priv = dev_get_priv(dev); 108 unsigned mux_bits, reg_stride, reg, reg_end, shift, mask; 109 bool load_pinctrl; 110 u32 tmp; 111 112 /* some pins need input-enabling */ 113 uniphier_pinconf_input_enable(dev, pin); 114 115 if (muxval < 0) 116 return; /* dedicated pin; nothing to do for pin-mux */ 117 118 if (priv->socdata->caps & UNIPHIER_PINCTRL_CAPS_DBGMUX_SEPARATE) { 119 /* 120 * Mode offset bit 121 * Normal 4 * n shift+3:shift 122 * Debug 4 * n shift+7:shift+4 123 */ 124 mux_bits = 4; 125 reg_stride = 8; 126 load_pinctrl = true; 127 } else { 128 /* 129 * Mode offset bit 130 * Normal 8 * n shift+3:shift 131 * Debug 8 * n + 4 shift+3:shift 132 */ 133 mux_bits = 8; 134 reg_stride = 4; 135 load_pinctrl = false; 136 } 137 138 reg = UNIPHIER_PINCTRL_PINMUX_BASE + pin * mux_bits / 32 * reg_stride; 139 reg_end = reg + reg_stride; 140 shift = pin * mux_bits % 32; 141 mask = (1U << mux_bits) - 1; 142 143 /* 144 * If reg_stride is greater than 4, the MSB of each pinsel shall be 145 * stored in the offset+4. 146 */ 147 for (; reg < reg_end; reg += 4) { 148 tmp = readl(priv->base + reg); 149 tmp &= ~(mask << shift); 150 tmp |= (mask & muxval) << shift; 151 writel(tmp, priv->base + reg); 152 153 muxval >>= mux_bits; 154 } 155 156 if (load_pinctrl) 157 writel(1, priv->base + UNIPHIER_PINCTRL_LOAD_PINMUX); 158 } 159 160 static int uniphier_pinmux_group_set(struct udevice *dev, 161 unsigned group_selector, 162 unsigned func_selector) 163 { 164 struct uniphier_pinctrl_priv *priv = dev_get_priv(dev); 165 const struct uniphier_pinctrl_group *grp = 166 &priv->socdata->groups[group_selector]; 167 int i; 168 169 for (i = 0; i < grp->num_pins; i++) 170 uniphier_pinmux_set_one(dev, grp->pins[i], grp->muxvals[i]); 171 172 return 0; 173 } 174 175 const struct pinctrl_ops uniphier_pinctrl_ops = { 176 .get_groups_count = uniphier_pinctrl_get_groups_count, 177 .get_group_name = uniphier_pinctrl_get_group_name, 178 .get_functions_count = uniphier_pinmux_get_functions_count, 179 .get_function_name = uniphier_pinmux_get_function_name, 180 .pinmux_group_set = uniphier_pinmux_group_set, 181 .set_state = pinctrl_generic_set_state, 182 }; 183 184 int uniphier_pinctrl_probe(struct udevice *dev, 185 struct uniphier_pinctrl_socdata *socdata) 186 { 187 struct uniphier_pinctrl_priv *priv = dev_get_priv(dev); 188 fdt_addr_t addr; 189 190 addr = dev_get_addr(dev->parent); 191 if (addr == FDT_ADDR_T_NONE) 192 return -EINVAL; 193 194 priv->base = devm_ioremap(dev, addr, SZ_4K); 195 if (!priv->base) 196 return -ENOMEM; 197 198 priv->socdata = socdata; 199 200 return 0; 201 } 202