1 // SPDX-License-Identifier: (GPL-2.0 OR MIT) 2 /* 3 * Microsemi SoCs pinctrl driver 4 * 5 * Author: <alexandre.belloni@free-electrons.com> 6 * Author: <gregory.clement@bootlin.com> 7 * License: Dual MIT/GPL 8 * Copyright (c) 2017 Microsemi Corporation 9 */ 10 11 #include <asm/gpio.h> 12 #include <asm/system.h> 13 #include <common.h> 14 #include <config.h> 15 #include <dm.h> 16 #include <dm/device-internal.h> 17 #include <dm/lists.h> 18 #include <dm/pinctrl.h> 19 #include <dm/root.h> 20 #include <errno.h> 21 #include <fdtdec.h> 22 #include <linux/io.h> 23 #include "mscc-common.h" 24 25 #define MSCC_GPIO_OUT_SET 0x0 26 #define MSCC_GPIO_OUT_CLR 0x4 27 #define MSCC_GPIO_OUT 0x8 28 #define MSCC_GPIO_IN 0xc 29 #define MSCC_GPIO_OE 0x10 30 #define MSCC_GPIO_INTR 0x14 31 #define MSCC_GPIO_INTR_ENA 0x18 32 #define MSCC_GPIO_INTR_IDENT 0x1c 33 #define MSCC_GPIO_ALT0 0x20 34 #define MSCC_GPIO_ALT1 0x24 35 36 static int mscc_get_functions_count(struct udevice *dev) 37 { 38 struct mscc_pinctrl *info = dev_get_priv(dev); 39 40 return info->num_func; 41 } 42 43 static const char *mscc_get_function_name(struct udevice *dev, 44 unsigned int function) 45 { 46 struct mscc_pinctrl *info = dev_get_priv(dev); 47 48 return info->function_names[function]; 49 } 50 51 static int mscc_pin_function_idx(unsigned int pin, unsigned int function, 52 const struct mscc_pin_data *mscc_pins) 53 { 54 struct mscc_pin_caps *p = mscc_pins[pin].drv_data; 55 int i; 56 57 for (i = 0; i < MSCC_FUNC_PER_PIN; i++) { 58 if (function == p->functions[i]) 59 return i; 60 } 61 62 return -1; 63 } 64 65 static int mscc_pinmux_set_mux(struct udevice *dev, 66 unsigned int pin_selector, unsigned int selector) 67 { 68 struct mscc_pinctrl *info = dev_get_priv(dev); 69 struct mscc_pin_caps *pin = info->mscc_pins[pin_selector].drv_data; 70 int f; 71 72 f = mscc_pin_function_idx(pin_selector, selector, info->mscc_pins); 73 if (f < 0) 74 return -EINVAL; 75 /* 76 * f is encoded on two bits. 77 * bit 0 of f goes in BIT(pin) of ALT0, bit 1 of f goes in BIT(pin) of 78 * ALT1 79 * This is racy because both registers can't be updated at the same time 80 * but it doesn't matter much for now. 81 */ 82 if (f & BIT(0)) 83 setbits_le32(info->regs + MSCC_GPIO_ALT0, BIT(pin->pin)); 84 else 85 clrbits_le32(info->regs + MSCC_GPIO_ALT0, BIT(pin->pin)); 86 87 if (f & BIT(1)) 88 setbits_le32(info->regs + MSCC_GPIO_ALT1, BIT(pin->pin - 1)); 89 else 90 clrbits_le32(info->regs + MSCC_GPIO_ALT1, BIT(pin->pin - 1)); 91 92 return 0; 93 } 94 95 static int mscc_pctl_get_groups_count(struct udevice *dev) 96 { 97 struct mscc_pinctrl *info = dev_get_priv(dev); 98 99 return info->num_pins; 100 } 101 102 static const char *mscc_pctl_get_group_name(struct udevice *dev, 103 unsigned int group) 104 { 105 struct mscc_pinctrl *info = dev_get_priv(dev); 106 107 return info->mscc_pins[group].name; 108 } 109 110 static int mscc_create_group_func_map(struct udevice *dev, 111 struct mscc_pinctrl *info) 112 { 113 u16 pins[info->num_pins]; 114 int f, npins, i; 115 116 for (f = 0; f < info->num_func; f++) { 117 for (npins = 0, i = 0; i < info->num_pins; i++) { 118 if (mscc_pin_function_idx(i, f, info->mscc_pins) >= 0) 119 pins[npins++] = i; 120 } 121 122 info->func[f].ngroups = npins; 123 info->func[f].groups = devm_kzalloc(dev, npins * 124 sizeof(char *), GFP_KERNEL); 125 if (!info->func[f].groups) 126 return -ENOMEM; 127 128 for (i = 0; i < npins; i++) 129 info->func[f].groups[i] = info->mscc_pins[pins[i]].name; 130 } 131 132 return 0; 133 } 134 135 static int mscc_pinctrl_register(struct udevice *dev, struct mscc_pinctrl *info) 136 { 137 int ret; 138 139 ret = mscc_create_group_func_map(dev, info); 140 if (ret) { 141 dev_err(dev, "Unable to create group func map.\n"); 142 return ret; 143 } 144 145 return 0; 146 } 147 148 static int mscc_gpio_get(struct udevice *dev, unsigned int offset) 149 { 150 struct mscc_pinctrl *info = dev_get_priv(dev->parent); 151 unsigned int val; 152 153 val = readl(info->regs + MSCC_GPIO_IN); 154 155 return !!(val & BIT(offset)); 156 } 157 158 static int mscc_gpio_set(struct udevice *dev, unsigned int offset, int value) 159 { 160 struct mscc_pinctrl *info = dev_get_priv(dev->parent); 161 162 if (value) 163 writel(BIT(offset), info->regs + MSCC_GPIO_OUT_SET); 164 else 165 writel(BIT(offset), info->regs + MSCC_GPIO_OUT_CLR); 166 167 return 0; 168 } 169 170 static int mscc_gpio_get_direction(struct udevice *dev, unsigned int offset) 171 { 172 struct mscc_pinctrl *info = dev_get_priv(dev->parent); 173 unsigned int val; 174 175 val = readl(info->regs + MSCC_GPIO_OE); 176 177 return (val & BIT(offset)) ? GPIOF_OUTPUT : GPIOF_INPUT; 178 } 179 180 static int mscc_gpio_direction_input(struct udevice *dev, unsigned int offset) 181 { 182 struct mscc_pinctrl *info = dev_get_priv(dev->parent); 183 184 clrbits_le32(info->regs + MSCC_GPIO_OE, BIT(offset)); 185 186 return 0; 187 } 188 189 static int mscc_gpio_direction_output(struct udevice *dev, 190 unsigned int offset, int value) 191 { 192 struct mscc_pinctrl *info = dev_get_priv(dev->parent); 193 194 setbits_le32(info->regs + MSCC_GPIO_OE, BIT(offset)); 195 196 return mscc_gpio_set(dev, offset, value); 197 } 198 199 const struct dm_gpio_ops mscc_gpio_ops = { 200 .set_value = mscc_gpio_set, 201 .get_value = mscc_gpio_get, 202 .get_function = mscc_gpio_get_direction, 203 .direction_input = mscc_gpio_direction_input, 204 .direction_output = mscc_gpio_direction_output, 205 }; 206 207 const struct pinctrl_ops mscc_pinctrl_ops = { 208 .get_pins_count = mscc_pctl_get_groups_count, 209 .get_pin_name = mscc_pctl_get_group_name, 210 .get_functions_count = mscc_get_functions_count, 211 .get_function_name = mscc_get_function_name, 212 .pinmux_set = mscc_pinmux_set_mux, 213 .set_state = pinctrl_generic_set_state, 214 }; 215 216 int mscc_pinctrl_probe(struct udevice *dev, int num_func, 217 const struct mscc_pin_data *mscc_pins, int num_pins, 218 char *const *function_names) 219 { 220 struct mscc_pinctrl *priv = dev_get_priv(dev); 221 int ret; 222 223 priv->regs = dev_remap_addr(dev); 224 if (!priv->regs) 225 return -EINVAL; 226 227 priv->func = devm_kzalloc(dev, num_func * sizeof(struct mscc_pmx_func), 228 GFP_KERNEL); 229 priv->num_func = num_func; 230 priv->mscc_pins = mscc_pins; 231 priv->num_pins = num_pins; 232 priv->function_names = function_names; 233 ret = mscc_pinctrl_register(dev, priv); 234 235 return ret; 236 } 237