1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * Copyright (C) 2020 Broadcom 4 */ 5 6#include <common.h> 7#include <errno.h> 8#include <asm/gpio.h> 9#include <asm/io.h> 10#include <dm.h> 11#include <dm/device_compat.h> 12#include <dm/devres.h> 13#include <dm/pinctrl.h> 14 15/* 16 * There are five GPIO bank register. Each bank can configure max of 32 gpios. 17 * BANK0 - gpios 0 to 31 18 * BANK1 - gpios 32 to 63 19 * BANK2 - gpios 64 to 95 20 * BANK3 - gpios 96 to 127 21 * BANK4 - gpios 128 to 150 22 * 23 * Offset difference between consecutive bank register is 0x200 24 */ 25#define NGPIO_PER_BANK 32 26#define GPIO_BANK_SIZE 0x200 27#define GPIO_BANK(pin) ((pin) / NGPIO_PER_BANK) 28#define GPIO_SHIFT(pin) ((pin) % NGPIO_PER_BANK) 29#define GPIO_REG(pin, reg) (GPIO_BANK_SIZE * GPIO_BANK(pin) + (reg)) 30 31/* device register offset */ 32#define DATA_IN_OFFSET 0x00 33#define DATA_OUT_OFFSET 0x04 34#define OUT_EN_OFFSET 0x08 35 36/** 37 * struct iproc_gpio_pctrl_map - gpio and pinctrl mapping 38 * @gpio_pin: start of gpio number in gpio-ranges 39 * @pctrl_pin: start of pinctrl number in gpio-ranges 40 * @npins: total number of pins in gpio-ranges 41 * @node: list node 42 */ 43struct iproc_gpio_pctrl_map { 44 u32 gpio_pin; 45 u32 pctrl_pin; 46 u32 npins; 47 struct list_head node; 48}; 49 50/** 51 * struct iproc_gpio_pctrl_map - gpio device instance 52 * @pinctrl_dev:pointer to pinctrl device 53 * @gpiomap: list node having mapping between gpio and pinctrl 54 * @base: I/O register base address of gpio device 55 * @name: gpio device name, ex GPIO0, GPIO1 56 * @ngpios: total number of gpios 57 */ 58struct iproc_gpio_plat { 59 struct udevice *pinctrl_dev; 60 struct list_head gpiomap; 61 void __iomem *base; 62 char *name; 63 u32 ngpios; 64}; 65 66/** 67 * iproc_gpio_set_bit - set or clear one bit in an iproc GPIO register. 68 * 69 * The bit relates to a GPIO pin. 70 * 71 * @plat: iproc GPIO device 72 * @reg: register offset 73 * @gpio: GPIO pin 74 * @set: set or clear 75 */ 76static inline void iproc_gpio_set_bit(struct iproc_gpio_plat *plat, 77 u32 reg, u32 gpio, bool set) 78{ 79 u32 offset = GPIO_REG(gpio, reg); 80 u32 shift = GPIO_SHIFT(gpio); 81 82 clrsetbits_le32(plat->base + offset, BIT(shift), 83 (set ? BIT(shift) : 0)); 84} 85 86static inline bool iproc_gpio_get_bit(struct iproc_gpio_plat *plat, 87 u32 reg, u32 gpio) 88{ 89 u32 offset = GPIO_REG(gpio, reg); 90 u32 shift = GPIO_SHIFT(gpio); 91 92 return readl(plat->base + offset) & BIT(shift); 93} 94 95/** 96 * iproc_get_gpio_pctrl_mapping() - get associated pinctrl pin from gpio pin 97 * 98 * @plat: iproc GPIO device 99 * @gpio: GPIO pin 100 */ 101static u32 iproc_get_pctrl_from_gpio(struct iproc_gpio_plat *plat, u32 gpio) 102{ 103 struct iproc_gpio_pctrl_map *range = NULL; 104 struct list_head *pos, *tmp; 105 u32 ret = 0; 106 107 list_for_each_safe(pos, tmp, &plat->gpiomap) { 108 range = list_entry(pos, struct iproc_gpio_pctrl_map, node); 109 if (gpio == range->gpio_pin || 110 gpio < (range->gpio_pin + range->npins)) { 111 ret = range->pctrl_pin + (gpio - range->gpio_pin); 112 break; 113 } 114 } 115 116 return ret; 117} 118 119/** 120 * iproc_get_gpio_pctrl_mapping() - get mapping between gpio and pinctrl 121 * 122 * Read dt node "gpio-ranges" to get gpio and pinctrl mapping and store 123 * in private data structure to use it later while enabling gpio. 124 * 125 * @dev: pointer to GPIO device 126 * Return: 0 on success and -ENOMEM on failure 127 */ 128static int iproc_get_gpio_pctrl_mapping(struct udevice *dev) 129{ 130 struct iproc_gpio_plat *plat = dev_get_plat(dev); 131 struct iproc_gpio_pctrl_map *range = NULL; 132 struct ofnode_phandle_args args; 133 int index = 0, ret; 134 135 for (;; index++) { 136 ret = dev_read_phandle_with_args(dev, "gpio-ranges", 137 NULL, 3, index, &args); 138 if (ret) 139 break; 140 141 range = devm_kzalloc(dev, sizeof(*range), GFP_KERNEL); 142 if (!range) 143 return -ENOMEM; 144 145 range->gpio_pin = args.args[0]; 146 range->pctrl_pin = args.args[1]; 147 range->npins = args.args[2]; 148 list_add_tail(&range->node, &plat->gpiomap); 149 } 150 151 return 0; 152} 153 154static int iproc_gpio_request(struct udevice *dev, u32 gpio, const char *label) 155{ 156 struct iproc_gpio_plat *plat = dev_get_plat(dev); 157 u32 pctrl; 158 159 /* nothing to do if there is no corresponding pinctrl device */ 160 if (!plat->pinctrl_dev) 161 return 0; 162 163 pctrl = iproc_get_pctrl_from_gpio(plat, gpio); 164 165 return pinctrl_request(plat->pinctrl_dev, pctrl, 0); 166} 167 168static int iproc_gpio_direction_input(struct udevice *dev, u32 gpio) 169{ 170 struct iproc_gpio_plat *plat = dev_get_plat(dev); 171 172 iproc_gpio_set_bit(plat, OUT_EN_OFFSET, gpio, false); 173 dev_dbg(dev, "gpio:%u set input\n", gpio); 174 175 return 0; 176} 177 178static int iproc_gpio_direction_output(struct udevice *dev, u32 gpio, int value) 179{ 180 struct iproc_gpio_plat *plat = dev_get_plat(dev); 181 182 iproc_gpio_set_bit(plat, OUT_EN_OFFSET, gpio, true); 183 iproc_gpio_set_bit(plat, DATA_OUT_OFFSET, gpio, value); 184 dev_dbg(dev, "gpio:%u set output, value:%d\n", gpio, value); 185 186 return 0; 187} 188 189static int iproc_gpio_get_value(struct udevice *dev, u32 gpio) 190{ 191 struct iproc_gpio_plat *plat = dev_get_plat(dev); 192 int value; 193 194 value = iproc_gpio_get_bit(plat, DATA_IN_OFFSET, gpio); 195 dev_dbg(dev, "gpio:%u get, value:%d\n", gpio, value); 196 197 return value; 198} 199 200static int iproc_gpio_set_value(struct udevice *dev, u32 gpio, int value) 201{ 202 struct iproc_gpio_plat *plat = dev_get_plat(dev); 203 204 if (iproc_gpio_get_bit(plat, OUT_EN_OFFSET, gpio)) 205 iproc_gpio_set_bit(plat, DATA_OUT_OFFSET, gpio, value); 206 207 dev_dbg(dev, "gpio:%u set, value:%d\n", gpio, value); 208 return 0; 209} 210 211static int iproc_gpio_get_function(struct udevice *dev, u32 gpio) 212{ 213 struct iproc_gpio_plat *plat = dev_get_plat(dev); 214 215 if (iproc_gpio_get_bit(plat, OUT_EN_OFFSET, gpio)) 216 return GPIOF_OUTPUT; 217 else 218 return GPIOF_INPUT; 219} 220 221static int iproc_gpio_of_to_plat(struct udevice *dev) 222{ 223 struct iproc_gpio_plat *plat = dev_get_plat(dev); 224 struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); 225 int ret; 226 char name[10]; 227 228 plat->base = dev_read_addr_ptr(dev); 229 if (!plat->base) { 230 debug("%s: Failed to get base address\n", __func__); 231 return -EINVAL; 232 } 233 234 ret = dev_read_u32(dev, "ngpios", &plat->ngpios); 235 if (ret < 0) { 236 dev_err(dev, "%s: Failed to get ngpios\n", __func__); 237 return ret; 238 } 239 240 uclass_get_device_by_phandle(UCLASS_PINCTRL, dev, "gpio-ranges", 241 &plat->pinctrl_dev); 242 if (ret < 0) { 243 dev_err(dev, "%s: Failed to get pinctrl phandle\n", __func__); 244 return ret; 245 } 246 247 INIT_LIST_HEAD(&plat->gpiomap); 248 ret = iproc_get_gpio_pctrl_mapping(dev); 249 if (ret < 0) { 250 dev_err(dev, "%s: Failed to get gpio to pctrl map ret(%d)\n", 251 __func__, ret); 252 return ret; 253 } 254 255 snprintf(name, sizeof(name), "GPIO%d", dev_seq(dev)); 256 plat->name = strdup(name); 257 if (!plat->name) 258 return -ENOMEM; 259 260 uc_priv->gpio_count = plat->ngpios; 261 uc_priv->bank_name = plat->name; 262 263 dev_info(dev, ":bank name(%s) base %p, #gpios %d\n", 264 plat->name, plat->base, plat->ngpios); 265 266 return 0; 267} 268 269static const struct dm_gpio_ops iproc_gpio_ops = { 270 .request = iproc_gpio_request, 271 .direction_input = iproc_gpio_direction_input, 272 .direction_output = iproc_gpio_direction_output, 273 .get_value = iproc_gpio_get_value, 274 .set_value = iproc_gpio_set_value, 275 .get_function = iproc_gpio_get_function, 276}; 277 278static const struct udevice_id iproc_gpio_ids[] = { 279 { .compatible = "brcm,iproc-gpio" }, 280 { } 281}; 282 283U_BOOT_DRIVER(iproc_gpio) = { 284 .name = "iproc_gpio", 285 .id = UCLASS_GPIO, 286 .of_match = iproc_gpio_ids, 287 .ops = &iproc_gpio_ops, 288 .of_to_plat = iproc_gpio_of_to_plat, 289 .plat_auto = sizeof(struct iproc_gpio_plat), 290}; 291