]> git.sur5r.net Git - u-boot/blob - drivers/pinctrl/uniphier/pinctrl-uniphier-core.c
pinctrl: uniphier: move register base macros from header to .c file
[u-boot] / drivers / pinctrl / uniphier / pinctrl-uniphier-core.c
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 }