]> Git Repo - J-u-boot.git/blob - drivers/pinctrl/nexell/pinctrl-s5pxx18.c
common: Drop asm/global_data.h from common header
[J-u-boot.git] / drivers / pinctrl / nexell / pinctrl-s5pxx18.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Pinctrl driver for Nexell SoCs
4  * (C) Copyright 2016 Nexell
5  * Bongyu, KOO <[email protected]>
6  *
7  * (C) Copyright 2019 Stefan Bosch <[email protected]>
8  */
9
10 #include <common.h>
11 #include <dm.h>
12 #include <errno.h>
13 #include <asm/global_data.h>
14 #include <asm/io.h>
15 #include <dm/pinctrl.h>
16 #include <dm/root.h>
17 #include "pinctrl-nexell.h"
18 #include "pinctrl-s5pxx18.h"
19
20 DECLARE_GLOBAL_DATA_PTR;
21
22 static void nx_gpio_set_bit(u32 *value, u32 bit, int enable)
23 {
24         register u32 newvalue;
25
26         newvalue = *value;
27         newvalue &= ~(1ul << bit);
28         newvalue |= (u32)enable << bit;
29         writel(newvalue, value);
30 }
31
32 static void nx_gpio_set_bit2(u32 *value, u32 bit, u32 bit_value)
33 {
34         register u32 newvalue = *value;
35
36         newvalue = (u32)(newvalue & ~(3ul << (bit * 2)));
37         newvalue = (u32)(newvalue | (bit_value << (bit * 2)));
38
39         writel(newvalue, value);
40 }
41
42 static int nx_gpio_open_module(void *base)
43 {
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);
49         return true;
50 }
51
52 static void nx_gpio_set_pad_function(void *base, u32 pin, u32 padfunc)
53 {
54         u32 reg = (pin / 16) ? GPIOX_ALTFN1 : GPIOX_ALTFN0;
55
56         nx_gpio_set_bit2(base + reg, pin % 16, padfunc);
57 }
58
59 static void nx_gpio_set_drive_strength(void *base, u32 pin, u32 drv)
60 {
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));
63 }
64
65 static void nx_gpio_set_pull_mode(void *base, u32 pin, u32 mode)
66 {
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);
70         } else {
71                 nx_gpio_set_bit(base + GPIOX_PULLSEL,
72                                 pin, (mode & 1 ? true : false));
73                 nx_gpio_set_bit(base + GPIOX_PULLENB, pin, true);
74         }
75 }
76
77 static void nx_alive_set_pullup(void *base, u32 pin, bool enable)
78 {
79         u32 PULLUP_MASK;
80
81         PULLUP_MASK = (1UL << pin);
82         if (enable)
83                 writel(PULLUP_MASK, base + ALIVE_PADPULLUPSET);
84         else
85                 writel(PULLUP_MASK, base + ALIVE_PADPULLUPRST);
86 }
87
88 static int s5pxx18_pinctrl_gpio_init(struct udevice *dev)
89 {
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;
93         int i;
94
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));
97
98         return 0;
99 }
100
101 static int s5pxx18_pinctrl_alive_init(struct udevice *dev)
102 {
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;
106
107         reg += ctrl->pin_banks[ctrl->nr_banks - 1].offset;
108
109         writel(1, reg + ALIVE_PWRGATE);
110         return 0;
111 }
112
113 int s5pxx18_pinctrl_init(struct udevice *dev)
114 {
115         s5pxx18_pinctrl_gpio_init(dev);
116         s5pxx18_pinctrl_alive_init(dev);
117
118         return 0;
119 }
120
121 static int is_pin_alive(const char *name)
122 {
123         return !strncmp(name, "alive", 5);
124 }
125
126 /**
127  * s5pxx18_pinctrl_set_state: configure a pin state.
128  * dev: the pinctrl device to be configured.
129  * config: the state to be configured.
130  */
131 static int s5pxx18_pinctrl_set_state(struct udevice *dev,
132                                      struct udevice *config)
133 {
134         unsigned int count, idx, pin;
135         unsigned int pinfunc, pinpud, pindrv;
136         unsigned long reg;
137         const char *name;
138         int ret;
139
140         /*
141          * refer to the following document for the pinctrl bindings
142          * doc/device-tree-bindings/pinctrl/nexell,s5pxx18-pinctrl.txt
143          */
144         count = dev_read_string_count(config, "pins");
145
146         if (count <= 0)
147                 return -EINVAL;
148
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);
152
153         for (idx = 0; idx < count; idx++) {
154                 ret = dev_read_string_index(config, "pins", idx, &name);
155                 if (ret)
156                         return ret;
157                 if (!name)
158                         continue;
159                 reg = pin_to_bank_base(dev, name, &pin);
160
161                 if (is_pin_alive(name)) {
162                         /* pin pull up/down */
163                         if (pinpud != -1)
164                                 nx_alive_set_pullup((void *)reg, pin,
165                                                     pinpud & 1);
166                         continue;
167                 }
168
169                 /* pin function */
170                 if (pinfunc != -1)
171                         nx_gpio_set_pad_function((void *)reg, pin, pinfunc);
172
173                 /* pin pull up/down/off */
174                 if (pinpud != -1)
175                         nx_gpio_set_pull_mode((void *)reg, pin, pinpud);
176
177                 /* pin drive strength */
178                 if (pindrv != -1)
179                         nx_gpio_set_drive_strength((void *)reg, pin, pindrv);
180         }
181
182         return 0;
183 }
184
185 static struct pinctrl_ops s5pxx18_pinctrl_ops = {
186         .set_state      = s5pxx18_pinctrl_set_state,
187 };
188
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"),
197 };
198
199 const struct nexell_pin_ctrl s5pxx18_pin_ctrl[] = {
200         {
201                 /* pin-controller data */
202                 .pin_banks      = s5pxx18_pin_banks,
203                 .nr_banks       = ARRAY_SIZE(s5pxx18_pin_banks),
204         },
205 };
206
207 static const struct udevice_id s5pxx18_pinctrl_ids[] = {
208         { .compatible = "nexell,s5pxx18-pinctrl",
209                 .data = (ulong)s5pxx18_pin_ctrl },
210         { }
211 };
212
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
221 };
This page took 0.040736 seconds and 4 git commands to generate.