1 // SPDX-License-Identifier: GPL-2.0+
3 * Pinctrl driver for Nexell SoCs
4 * (C) Copyright 2016 Nexell
13 #include <asm/global_data.h>
15 #include <dm/pinctrl.h>
17 #include "pinctrl-nexell.h"
18 #include "pinctrl-s5pxx18.h"
20 DECLARE_GLOBAL_DATA_PTR;
22 static void nx_gpio_set_bit(u32 *value, u32 bit, int enable)
24 register u32 newvalue;
27 newvalue &= ~(1ul << bit);
28 newvalue |= (u32)enable << bit;
29 writel(newvalue, value);
32 static void nx_gpio_set_bit2(u32 *value, u32 bit, u32 bit_value)
34 register u32 newvalue = *value;
36 newvalue = (u32)(newvalue & ~(3ul << (bit * 2)));
37 newvalue = (u32)(newvalue | (bit_value << (bit * 2)));
39 writel(newvalue, value);
42 static int nx_gpio_open_module(void *base)
44 writel(0xFFFFFFFF, base + GPIOX_SLEW_DISABLE_DEFAULT);
45 writel(0xFFFFFFFF, base + GPIOX_DRV1_DISABLE_DEFAULT);
46 writel(0xFFFFFFFF, base + GPIOX_DRV0_DISABLE_DEFAULT);
47 writel(0xFFFFFFFF, base + GPIOX_PULLSEL_DISABLE_DEFAULT);
48 writel(0xFFFFFFFF, base + GPIOX_PULLENB_DISABLE_DEFAULT);
52 static void nx_gpio_set_pad_function(void *base, u32 pin, u32 padfunc)
54 u32 reg = (pin / 16) ? GPIOX_ALTFN1 : GPIOX_ALTFN0;
56 nx_gpio_set_bit2(base + reg, pin % 16, padfunc);
59 static void nx_gpio_set_drive_strength(void *base, u32 pin, u32 drv)
61 nx_gpio_set_bit(base + GPIOX_DRV1, pin, (int)(((u32)drv >> 0) & 0x1));
62 nx_gpio_set_bit(base + GPIOX_DRV0, pin, (int)(((u32)drv >> 1) & 0x1));
65 static void nx_gpio_set_pull_mode(void *base, u32 pin, u32 mode)
67 if (mode == nx_gpio_pull_off) {
68 nx_gpio_set_bit(base + GPIOX_PULLENB, pin, false);
69 nx_gpio_set_bit(base + GPIOX_PULLSEL, pin, false);
71 nx_gpio_set_bit(base + GPIOX_PULLSEL,
72 pin, (mode & 1 ? true : false));
73 nx_gpio_set_bit(base + GPIOX_PULLENB, pin, true);
77 static void nx_alive_set_pullup(void *base, u32 pin, bool enable)
81 PULLUP_MASK = (1UL << pin);
83 writel(PULLUP_MASK, base + ALIVE_PADPULLUPSET);
85 writel(PULLUP_MASK, base + ALIVE_PADPULLUPRST);
88 static int s5pxx18_pinctrl_gpio_init(struct udevice *dev)
90 struct nexell_pinctrl_priv *priv = dev_get_priv(dev);
91 const struct nexell_pin_ctrl *ctrl = priv->pin_ctrl;
92 unsigned long reg = priv->base;
95 for (i = 0; i < ctrl->nr_banks - 1; i++) /* except alive bank */
96 nx_gpio_open_module((void *)(reg + ctrl->pin_banks[i].offset));
101 static int s5pxx18_pinctrl_alive_init(struct udevice *dev)
103 struct nexell_pinctrl_priv *priv = dev_get_priv(dev);
104 const struct nexell_pin_ctrl *ctrl = priv->pin_ctrl;
105 unsigned long reg = priv->base;
107 reg += ctrl->pin_banks[ctrl->nr_banks - 1].offset;
109 writel(1, reg + ALIVE_PWRGATE);
113 int s5pxx18_pinctrl_init(struct udevice *dev)
115 s5pxx18_pinctrl_gpio_init(dev);
116 s5pxx18_pinctrl_alive_init(dev);
121 static int is_pin_alive(const char *name)
123 return !strncmp(name, "alive", 5);
127 * s5pxx18_pinctrl_set_state: configure a pin state.
128 * dev: the pinctrl device to be configured.
129 * config: the state to be configured.
131 static int s5pxx18_pinctrl_set_state(struct udevice *dev,
132 struct udevice *config)
134 unsigned int count, idx, pin;
135 unsigned int pinfunc, pinpud, pindrv;
141 * refer to the following document for the pinctrl bindings
142 * doc/device-tree-bindings/pinctrl/nexell,s5pxx18-pinctrl.txt
144 count = dev_read_string_count(config, "pins");
149 pinfunc = dev_read_s32_default(config, "pin-function", -1);
150 pinpud = dev_read_s32_default(config, "pin-pull", -1);
151 pindrv = dev_read_s32_default(config, "pin-strength", -1);
153 for (idx = 0; idx < count; idx++) {
154 ret = dev_read_string_index(config, "pins", idx, &name);
159 reg = pin_to_bank_base(dev, name, &pin);
161 if (is_pin_alive(name)) {
162 /* pin pull up/down */
164 nx_alive_set_pullup((void *)reg, pin,
171 nx_gpio_set_pad_function((void *)reg, pin, pinfunc);
173 /* pin pull up/down/off */
175 nx_gpio_set_pull_mode((void *)reg, pin, pinpud);
177 /* pin drive strength */
179 nx_gpio_set_drive_strength((void *)reg, pin, pindrv);
185 static struct pinctrl_ops s5pxx18_pinctrl_ops = {
186 .set_state = s5pxx18_pinctrl_set_state,
189 /* pin banks of s5pxx18 pin-controller */
190 static const struct nexell_pin_bank_data s5pxx18_pin_banks[] = {
191 NEXELL_PIN_BANK(32, 0xA000, "gpioa"),
192 NEXELL_PIN_BANK(32, 0xB000, "gpiob"),
193 NEXELL_PIN_BANK(32, 0xC000, "gpioc"),
194 NEXELL_PIN_BANK(32, 0xD000, "gpiod"),
195 NEXELL_PIN_BANK(32, 0xE000, "gpioe"),
196 NEXELL_PIN_BANK(6, 0x0800, "alive"),
199 const struct nexell_pin_ctrl s5pxx18_pin_ctrl[] = {
201 /* pin-controller data */
202 .pin_banks = s5pxx18_pin_banks,
203 .nr_banks = ARRAY_SIZE(s5pxx18_pin_banks),
207 static const struct udevice_id s5pxx18_pinctrl_ids[] = {
208 { .compatible = "nexell,s5pxx18-pinctrl",
209 .data = (ulong)s5pxx18_pin_ctrl },
213 U_BOOT_DRIVER(pinctrl_s5pxx18) = {
214 .name = "pinctrl_s5pxx18",
215 .id = UCLASS_PINCTRL,
216 .of_match = s5pxx18_pinctrl_ids,
217 .priv_auto = sizeof(struct nexell_pinctrl_priv),
218 .ops = &s5pxx18_pinctrl_ops,
219 .probe = nexell_pinctrl_probe,
220 .flags = DM_FLAG_PRE_RELOC