1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-only
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved.
4*4882a593Smuzhiyun */
5*4882a593Smuzhiyun
6*4882a593Smuzhiyun #include <linux/delay.h>
7*4882a593Smuzhiyun #include <linux/io.h>
8*4882a593Smuzhiyun #include <linux/module.h>
9*4882a593Smuzhiyun #include <linux/of.h>
10*4882a593Smuzhiyun #include <linux/phy/phy.h>
11*4882a593Smuzhiyun #include <linux/pinctrl/pinctrl.h>
12*4882a593Smuzhiyun #include <linux/pinctrl/pinmux.h>
13*4882a593Smuzhiyun #include <linux/platform_device.h>
14*4882a593Smuzhiyun #include <linux/reset.h>
15*4882a593Smuzhiyun #include <linux/slab.h>
16*4882a593Smuzhiyun
17*4882a593Smuzhiyun #include <dt-bindings/pinctrl/pinctrl-tegra-xusb.h>
18*4882a593Smuzhiyun
19*4882a593Smuzhiyun #include "../core.h"
20*4882a593Smuzhiyun #include "../pinctrl-utils.h"
21*4882a593Smuzhiyun
22*4882a593Smuzhiyun #define XUSB_PADCTL_ELPG_PROGRAM 0x01c
23*4882a593Smuzhiyun #define XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_VCORE_DOWN (1 << 26)
24*4882a593Smuzhiyun #define XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN_EARLY (1 << 25)
25*4882a593Smuzhiyun #define XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN (1 << 24)
26*4882a593Smuzhiyun
27*4882a593Smuzhiyun #define XUSB_PADCTL_IOPHY_PLL_P0_CTL1 0x040
28*4882a593Smuzhiyun #define XUSB_PADCTL_IOPHY_PLL_P0_CTL1_PLL0_LOCKDET (1 << 19)
29*4882a593Smuzhiyun #define XUSB_PADCTL_IOPHY_PLL_P0_CTL1_REFCLK_SEL_MASK (0xf << 12)
30*4882a593Smuzhiyun #define XUSB_PADCTL_IOPHY_PLL_P0_CTL1_PLL_RST (1 << 1)
31*4882a593Smuzhiyun
32*4882a593Smuzhiyun #define XUSB_PADCTL_IOPHY_PLL_P0_CTL2 0x044
33*4882a593Smuzhiyun #define XUSB_PADCTL_IOPHY_PLL_P0_CTL2_REFCLKBUF_EN (1 << 6)
34*4882a593Smuzhiyun #define XUSB_PADCTL_IOPHY_PLL_P0_CTL2_TXCLKREF_EN (1 << 5)
35*4882a593Smuzhiyun #define XUSB_PADCTL_IOPHY_PLL_P0_CTL2_TXCLKREF_SEL (1 << 4)
36*4882a593Smuzhiyun
37*4882a593Smuzhiyun #define XUSB_PADCTL_IOPHY_PLL_S0_CTL1 0x138
38*4882a593Smuzhiyun #define XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL1_LOCKDET (1 << 27)
39*4882a593Smuzhiyun #define XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL1_MODE (1 << 24)
40*4882a593Smuzhiyun #define XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_PWR_OVRD (1 << 3)
41*4882a593Smuzhiyun #define XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_RST (1 << 1)
42*4882a593Smuzhiyun #define XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_IDDQ (1 << 0)
43*4882a593Smuzhiyun
44*4882a593Smuzhiyun #define XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1 0x148
45*4882a593Smuzhiyun #define XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1_IDDQ_OVRD (1 << 1)
46*4882a593Smuzhiyun #define XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1_IDDQ (1 << 0)
47*4882a593Smuzhiyun
48*4882a593Smuzhiyun struct tegra_xusb_padctl_function {
49*4882a593Smuzhiyun const char *name;
50*4882a593Smuzhiyun const char * const *groups;
51*4882a593Smuzhiyun unsigned int num_groups;
52*4882a593Smuzhiyun };
53*4882a593Smuzhiyun
54*4882a593Smuzhiyun struct tegra_xusb_padctl_soc {
55*4882a593Smuzhiyun const struct pinctrl_pin_desc *pins;
56*4882a593Smuzhiyun unsigned int num_pins;
57*4882a593Smuzhiyun
58*4882a593Smuzhiyun const struct tegra_xusb_padctl_function *functions;
59*4882a593Smuzhiyun unsigned int num_functions;
60*4882a593Smuzhiyun
61*4882a593Smuzhiyun const struct tegra_xusb_padctl_lane *lanes;
62*4882a593Smuzhiyun unsigned int num_lanes;
63*4882a593Smuzhiyun };
64*4882a593Smuzhiyun
65*4882a593Smuzhiyun struct tegra_xusb_padctl_lane {
66*4882a593Smuzhiyun const char *name;
67*4882a593Smuzhiyun
68*4882a593Smuzhiyun unsigned int offset;
69*4882a593Smuzhiyun unsigned int shift;
70*4882a593Smuzhiyun unsigned int mask;
71*4882a593Smuzhiyun unsigned int iddq;
72*4882a593Smuzhiyun
73*4882a593Smuzhiyun const unsigned int *funcs;
74*4882a593Smuzhiyun unsigned int num_funcs;
75*4882a593Smuzhiyun };
76*4882a593Smuzhiyun
77*4882a593Smuzhiyun struct tegra_xusb_padctl {
78*4882a593Smuzhiyun struct device *dev;
79*4882a593Smuzhiyun void __iomem *regs;
80*4882a593Smuzhiyun struct mutex lock;
81*4882a593Smuzhiyun struct reset_control *rst;
82*4882a593Smuzhiyun
83*4882a593Smuzhiyun const struct tegra_xusb_padctl_soc *soc;
84*4882a593Smuzhiyun struct pinctrl_dev *pinctrl;
85*4882a593Smuzhiyun struct pinctrl_desc desc;
86*4882a593Smuzhiyun
87*4882a593Smuzhiyun struct phy_provider *provider;
88*4882a593Smuzhiyun struct phy *phys[2];
89*4882a593Smuzhiyun
90*4882a593Smuzhiyun unsigned int enable;
91*4882a593Smuzhiyun };
92*4882a593Smuzhiyun
padctl_writel(struct tegra_xusb_padctl * padctl,u32 value,unsigned long offset)93*4882a593Smuzhiyun static inline void padctl_writel(struct tegra_xusb_padctl *padctl, u32 value,
94*4882a593Smuzhiyun unsigned long offset)
95*4882a593Smuzhiyun {
96*4882a593Smuzhiyun writel(value, padctl->regs + offset);
97*4882a593Smuzhiyun }
98*4882a593Smuzhiyun
padctl_readl(struct tegra_xusb_padctl * padctl,unsigned long offset)99*4882a593Smuzhiyun static inline u32 padctl_readl(struct tegra_xusb_padctl *padctl,
100*4882a593Smuzhiyun unsigned long offset)
101*4882a593Smuzhiyun {
102*4882a593Smuzhiyun return readl(padctl->regs + offset);
103*4882a593Smuzhiyun }
104*4882a593Smuzhiyun
tegra_xusb_padctl_get_groups_count(struct pinctrl_dev * pinctrl)105*4882a593Smuzhiyun static int tegra_xusb_padctl_get_groups_count(struct pinctrl_dev *pinctrl)
106*4882a593Smuzhiyun {
107*4882a593Smuzhiyun struct tegra_xusb_padctl *padctl = pinctrl_dev_get_drvdata(pinctrl);
108*4882a593Smuzhiyun
109*4882a593Smuzhiyun return padctl->soc->num_pins;
110*4882a593Smuzhiyun }
111*4882a593Smuzhiyun
tegra_xusb_padctl_get_group_name(struct pinctrl_dev * pinctrl,unsigned int group)112*4882a593Smuzhiyun static const char *tegra_xusb_padctl_get_group_name(struct pinctrl_dev *pinctrl,
113*4882a593Smuzhiyun unsigned int group)
114*4882a593Smuzhiyun {
115*4882a593Smuzhiyun struct tegra_xusb_padctl *padctl = pinctrl_dev_get_drvdata(pinctrl);
116*4882a593Smuzhiyun
117*4882a593Smuzhiyun return padctl->soc->pins[group].name;
118*4882a593Smuzhiyun }
119*4882a593Smuzhiyun
tegra_xusb_padctl_get_group_pins(struct pinctrl_dev * pinctrl,unsigned group,const unsigned ** pins,unsigned * num_pins)120*4882a593Smuzhiyun static int tegra_xusb_padctl_get_group_pins(struct pinctrl_dev *pinctrl,
121*4882a593Smuzhiyun unsigned group,
122*4882a593Smuzhiyun const unsigned **pins,
123*4882a593Smuzhiyun unsigned *num_pins)
124*4882a593Smuzhiyun {
125*4882a593Smuzhiyun /*
126*4882a593Smuzhiyun * For the tegra-xusb pad controller groups are synonymous
127*4882a593Smuzhiyun * with lanes/pins and there is always one lane/pin per group.
128*4882a593Smuzhiyun */
129*4882a593Smuzhiyun *pins = &pinctrl->desc->pins[group].number;
130*4882a593Smuzhiyun *num_pins = 1;
131*4882a593Smuzhiyun
132*4882a593Smuzhiyun return 0;
133*4882a593Smuzhiyun }
134*4882a593Smuzhiyun
135*4882a593Smuzhiyun enum tegra_xusb_padctl_param {
136*4882a593Smuzhiyun TEGRA_XUSB_PADCTL_IDDQ,
137*4882a593Smuzhiyun };
138*4882a593Smuzhiyun
139*4882a593Smuzhiyun static const struct tegra_xusb_padctl_property {
140*4882a593Smuzhiyun const char *name;
141*4882a593Smuzhiyun enum tegra_xusb_padctl_param param;
142*4882a593Smuzhiyun } properties[] = {
143*4882a593Smuzhiyun { "nvidia,iddq", TEGRA_XUSB_PADCTL_IDDQ },
144*4882a593Smuzhiyun };
145*4882a593Smuzhiyun
146*4882a593Smuzhiyun #define TEGRA_XUSB_PADCTL_PACK(param, value) ((param) << 16 | (value))
147*4882a593Smuzhiyun #define TEGRA_XUSB_PADCTL_UNPACK_PARAM(config) ((config) >> 16)
148*4882a593Smuzhiyun #define TEGRA_XUSB_PADCTL_UNPACK_VALUE(config) ((config) & 0xffff)
149*4882a593Smuzhiyun
tegra_xusb_padctl_parse_subnode(struct tegra_xusb_padctl * padctl,struct device_node * np,struct pinctrl_map ** maps,unsigned int * reserved_maps,unsigned int * num_maps)150*4882a593Smuzhiyun static int tegra_xusb_padctl_parse_subnode(struct tegra_xusb_padctl *padctl,
151*4882a593Smuzhiyun struct device_node *np,
152*4882a593Smuzhiyun struct pinctrl_map **maps,
153*4882a593Smuzhiyun unsigned int *reserved_maps,
154*4882a593Smuzhiyun unsigned int *num_maps)
155*4882a593Smuzhiyun {
156*4882a593Smuzhiyun unsigned int i, reserve = 0, num_configs = 0;
157*4882a593Smuzhiyun unsigned long config, *configs = NULL;
158*4882a593Smuzhiyun const char *function, *group;
159*4882a593Smuzhiyun struct property *prop;
160*4882a593Smuzhiyun int err = 0;
161*4882a593Smuzhiyun u32 value;
162*4882a593Smuzhiyun
163*4882a593Smuzhiyun err = of_property_read_string(np, "nvidia,function", &function);
164*4882a593Smuzhiyun if (err < 0) {
165*4882a593Smuzhiyun if (err != -EINVAL)
166*4882a593Smuzhiyun return err;
167*4882a593Smuzhiyun
168*4882a593Smuzhiyun function = NULL;
169*4882a593Smuzhiyun }
170*4882a593Smuzhiyun
171*4882a593Smuzhiyun for (i = 0; i < ARRAY_SIZE(properties); i++) {
172*4882a593Smuzhiyun err = of_property_read_u32(np, properties[i].name, &value);
173*4882a593Smuzhiyun if (err < 0) {
174*4882a593Smuzhiyun if (err == -EINVAL)
175*4882a593Smuzhiyun continue;
176*4882a593Smuzhiyun
177*4882a593Smuzhiyun goto out;
178*4882a593Smuzhiyun }
179*4882a593Smuzhiyun
180*4882a593Smuzhiyun config = TEGRA_XUSB_PADCTL_PACK(properties[i].param, value);
181*4882a593Smuzhiyun
182*4882a593Smuzhiyun err = pinctrl_utils_add_config(padctl->pinctrl, &configs,
183*4882a593Smuzhiyun &num_configs, config);
184*4882a593Smuzhiyun if (err < 0)
185*4882a593Smuzhiyun goto out;
186*4882a593Smuzhiyun }
187*4882a593Smuzhiyun
188*4882a593Smuzhiyun if (function)
189*4882a593Smuzhiyun reserve++;
190*4882a593Smuzhiyun
191*4882a593Smuzhiyun if (num_configs)
192*4882a593Smuzhiyun reserve++;
193*4882a593Smuzhiyun
194*4882a593Smuzhiyun err = of_property_count_strings(np, "nvidia,lanes");
195*4882a593Smuzhiyun if (err < 0)
196*4882a593Smuzhiyun goto out;
197*4882a593Smuzhiyun
198*4882a593Smuzhiyun reserve *= err;
199*4882a593Smuzhiyun
200*4882a593Smuzhiyun err = pinctrl_utils_reserve_map(padctl->pinctrl, maps, reserved_maps,
201*4882a593Smuzhiyun num_maps, reserve);
202*4882a593Smuzhiyun if (err < 0)
203*4882a593Smuzhiyun goto out;
204*4882a593Smuzhiyun
205*4882a593Smuzhiyun of_property_for_each_string(np, "nvidia,lanes", prop, group) {
206*4882a593Smuzhiyun if (function) {
207*4882a593Smuzhiyun err = pinctrl_utils_add_map_mux(padctl->pinctrl, maps,
208*4882a593Smuzhiyun reserved_maps, num_maps, group,
209*4882a593Smuzhiyun function);
210*4882a593Smuzhiyun if (err < 0)
211*4882a593Smuzhiyun goto out;
212*4882a593Smuzhiyun }
213*4882a593Smuzhiyun
214*4882a593Smuzhiyun if (num_configs) {
215*4882a593Smuzhiyun err = pinctrl_utils_add_map_configs(padctl->pinctrl,
216*4882a593Smuzhiyun maps, reserved_maps, num_maps, group,
217*4882a593Smuzhiyun configs, num_configs,
218*4882a593Smuzhiyun PIN_MAP_TYPE_CONFIGS_GROUP);
219*4882a593Smuzhiyun if (err < 0)
220*4882a593Smuzhiyun goto out;
221*4882a593Smuzhiyun }
222*4882a593Smuzhiyun }
223*4882a593Smuzhiyun
224*4882a593Smuzhiyun err = 0;
225*4882a593Smuzhiyun
226*4882a593Smuzhiyun out:
227*4882a593Smuzhiyun kfree(configs);
228*4882a593Smuzhiyun return err;
229*4882a593Smuzhiyun }
230*4882a593Smuzhiyun
tegra_xusb_padctl_dt_node_to_map(struct pinctrl_dev * pinctrl,struct device_node * parent,struct pinctrl_map ** maps,unsigned int * num_maps)231*4882a593Smuzhiyun static int tegra_xusb_padctl_dt_node_to_map(struct pinctrl_dev *pinctrl,
232*4882a593Smuzhiyun struct device_node *parent,
233*4882a593Smuzhiyun struct pinctrl_map **maps,
234*4882a593Smuzhiyun unsigned int *num_maps)
235*4882a593Smuzhiyun {
236*4882a593Smuzhiyun struct tegra_xusb_padctl *padctl = pinctrl_dev_get_drvdata(pinctrl);
237*4882a593Smuzhiyun unsigned int reserved_maps = 0;
238*4882a593Smuzhiyun struct device_node *np;
239*4882a593Smuzhiyun int err;
240*4882a593Smuzhiyun
241*4882a593Smuzhiyun *num_maps = 0;
242*4882a593Smuzhiyun *maps = NULL;
243*4882a593Smuzhiyun
244*4882a593Smuzhiyun for_each_child_of_node(parent, np) {
245*4882a593Smuzhiyun err = tegra_xusb_padctl_parse_subnode(padctl, np, maps,
246*4882a593Smuzhiyun &reserved_maps,
247*4882a593Smuzhiyun num_maps);
248*4882a593Smuzhiyun if (err < 0) {
249*4882a593Smuzhiyun of_node_put(np);
250*4882a593Smuzhiyun return err;
251*4882a593Smuzhiyun }
252*4882a593Smuzhiyun }
253*4882a593Smuzhiyun
254*4882a593Smuzhiyun return 0;
255*4882a593Smuzhiyun }
256*4882a593Smuzhiyun
257*4882a593Smuzhiyun static const struct pinctrl_ops tegra_xusb_padctl_pinctrl_ops = {
258*4882a593Smuzhiyun .get_groups_count = tegra_xusb_padctl_get_groups_count,
259*4882a593Smuzhiyun .get_group_name = tegra_xusb_padctl_get_group_name,
260*4882a593Smuzhiyun .get_group_pins = tegra_xusb_padctl_get_group_pins,
261*4882a593Smuzhiyun .dt_node_to_map = tegra_xusb_padctl_dt_node_to_map,
262*4882a593Smuzhiyun .dt_free_map = pinctrl_utils_free_map,
263*4882a593Smuzhiyun };
264*4882a593Smuzhiyun
tegra_xusb_padctl_get_functions_count(struct pinctrl_dev * pinctrl)265*4882a593Smuzhiyun static int tegra_xusb_padctl_get_functions_count(struct pinctrl_dev *pinctrl)
266*4882a593Smuzhiyun {
267*4882a593Smuzhiyun struct tegra_xusb_padctl *padctl = pinctrl_dev_get_drvdata(pinctrl);
268*4882a593Smuzhiyun
269*4882a593Smuzhiyun return padctl->soc->num_functions;
270*4882a593Smuzhiyun }
271*4882a593Smuzhiyun
272*4882a593Smuzhiyun static const char *
tegra_xusb_padctl_get_function_name(struct pinctrl_dev * pinctrl,unsigned int function)273*4882a593Smuzhiyun tegra_xusb_padctl_get_function_name(struct pinctrl_dev *pinctrl,
274*4882a593Smuzhiyun unsigned int function)
275*4882a593Smuzhiyun {
276*4882a593Smuzhiyun struct tegra_xusb_padctl *padctl = pinctrl_dev_get_drvdata(pinctrl);
277*4882a593Smuzhiyun
278*4882a593Smuzhiyun return padctl->soc->functions[function].name;
279*4882a593Smuzhiyun }
280*4882a593Smuzhiyun
tegra_xusb_padctl_get_function_groups(struct pinctrl_dev * pinctrl,unsigned int function,const char * const ** groups,unsigned * const num_groups)281*4882a593Smuzhiyun static int tegra_xusb_padctl_get_function_groups(struct pinctrl_dev *pinctrl,
282*4882a593Smuzhiyun unsigned int function,
283*4882a593Smuzhiyun const char * const **groups,
284*4882a593Smuzhiyun unsigned * const num_groups)
285*4882a593Smuzhiyun {
286*4882a593Smuzhiyun struct tegra_xusb_padctl *padctl = pinctrl_dev_get_drvdata(pinctrl);
287*4882a593Smuzhiyun
288*4882a593Smuzhiyun *num_groups = padctl->soc->functions[function].num_groups;
289*4882a593Smuzhiyun *groups = padctl->soc->functions[function].groups;
290*4882a593Smuzhiyun
291*4882a593Smuzhiyun return 0;
292*4882a593Smuzhiyun }
293*4882a593Smuzhiyun
tegra_xusb_padctl_pinmux_set(struct pinctrl_dev * pinctrl,unsigned int function,unsigned int group)294*4882a593Smuzhiyun static int tegra_xusb_padctl_pinmux_set(struct pinctrl_dev *pinctrl,
295*4882a593Smuzhiyun unsigned int function,
296*4882a593Smuzhiyun unsigned int group)
297*4882a593Smuzhiyun {
298*4882a593Smuzhiyun struct tegra_xusb_padctl *padctl = pinctrl_dev_get_drvdata(pinctrl);
299*4882a593Smuzhiyun const struct tegra_xusb_padctl_lane *lane;
300*4882a593Smuzhiyun unsigned int i;
301*4882a593Smuzhiyun u32 value;
302*4882a593Smuzhiyun
303*4882a593Smuzhiyun lane = &padctl->soc->lanes[group];
304*4882a593Smuzhiyun
305*4882a593Smuzhiyun for (i = 0; i < lane->num_funcs; i++)
306*4882a593Smuzhiyun if (lane->funcs[i] == function)
307*4882a593Smuzhiyun break;
308*4882a593Smuzhiyun
309*4882a593Smuzhiyun if (i >= lane->num_funcs)
310*4882a593Smuzhiyun return -EINVAL;
311*4882a593Smuzhiyun
312*4882a593Smuzhiyun value = padctl_readl(padctl, lane->offset);
313*4882a593Smuzhiyun value &= ~(lane->mask << lane->shift);
314*4882a593Smuzhiyun value |= i << lane->shift;
315*4882a593Smuzhiyun padctl_writel(padctl, value, lane->offset);
316*4882a593Smuzhiyun
317*4882a593Smuzhiyun return 0;
318*4882a593Smuzhiyun }
319*4882a593Smuzhiyun
320*4882a593Smuzhiyun static const struct pinmux_ops tegra_xusb_padctl_pinmux_ops = {
321*4882a593Smuzhiyun .get_functions_count = tegra_xusb_padctl_get_functions_count,
322*4882a593Smuzhiyun .get_function_name = tegra_xusb_padctl_get_function_name,
323*4882a593Smuzhiyun .get_function_groups = tegra_xusb_padctl_get_function_groups,
324*4882a593Smuzhiyun .set_mux = tegra_xusb_padctl_pinmux_set,
325*4882a593Smuzhiyun };
326*4882a593Smuzhiyun
tegra_xusb_padctl_pinconf_group_get(struct pinctrl_dev * pinctrl,unsigned int group,unsigned long * config)327*4882a593Smuzhiyun static int tegra_xusb_padctl_pinconf_group_get(struct pinctrl_dev *pinctrl,
328*4882a593Smuzhiyun unsigned int group,
329*4882a593Smuzhiyun unsigned long *config)
330*4882a593Smuzhiyun {
331*4882a593Smuzhiyun struct tegra_xusb_padctl *padctl = pinctrl_dev_get_drvdata(pinctrl);
332*4882a593Smuzhiyun const struct tegra_xusb_padctl_lane *lane;
333*4882a593Smuzhiyun enum tegra_xusb_padctl_param param;
334*4882a593Smuzhiyun u32 value;
335*4882a593Smuzhiyun
336*4882a593Smuzhiyun param = TEGRA_XUSB_PADCTL_UNPACK_PARAM(*config);
337*4882a593Smuzhiyun lane = &padctl->soc->lanes[group];
338*4882a593Smuzhiyun
339*4882a593Smuzhiyun switch (param) {
340*4882a593Smuzhiyun case TEGRA_XUSB_PADCTL_IDDQ:
341*4882a593Smuzhiyun /* lanes with iddq == 0 don't support this parameter */
342*4882a593Smuzhiyun if (lane->iddq == 0)
343*4882a593Smuzhiyun return -EINVAL;
344*4882a593Smuzhiyun
345*4882a593Smuzhiyun value = padctl_readl(padctl, lane->offset);
346*4882a593Smuzhiyun
347*4882a593Smuzhiyun if (value & BIT(lane->iddq))
348*4882a593Smuzhiyun value = 0;
349*4882a593Smuzhiyun else
350*4882a593Smuzhiyun value = 1;
351*4882a593Smuzhiyun
352*4882a593Smuzhiyun *config = TEGRA_XUSB_PADCTL_PACK(param, value);
353*4882a593Smuzhiyun break;
354*4882a593Smuzhiyun
355*4882a593Smuzhiyun default:
356*4882a593Smuzhiyun dev_err(padctl->dev, "invalid configuration parameter: %04x\n",
357*4882a593Smuzhiyun param);
358*4882a593Smuzhiyun return -ENOTSUPP;
359*4882a593Smuzhiyun }
360*4882a593Smuzhiyun
361*4882a593Smuzhiyun return 0;
362*4882a593Smuzhiyun }
363*4882a593Smuzhiyun
tegra_xusb_padctl_pinconf_group_set(struct pinctrl_dev * pinctrl,unsigned int group,unsigned long * configs,unsigned int num_configs)364*4882a593Smuzhiyun static int tegra_xusb_padctl_pinconf_group_set(struct pinctrl_dev *pinctrl,
365*4882a593Smuzhiyun unsigned int group,
366*4882a593Smuzhiyun unsigned long *configs,
367*4882a593Smuzhiyun unsigned int num_configs)
368*4882a593Smuzhiyun {
369*4882a593Smuzhiyun struct tegra_xusb_padctl *padctl = pinctrl_dev_get_drvdata(pinctrl);
370*4882a593Smuzhiyun const struct tegra_xusb_padctl_lane *lane;
371*4882a593Smuzhiyun enum tegra_xusb_padctl_param param;
372*4882a593Smuzhiyun unsigned long value;
373*4882a593Smuzhiyun unsigned int i;
374*4882a593Smuzhiyun u32 regval;
375*4882a593Smuzhiyun
376*4882a593Smuzhiyun lane = &padctl->soc->lanes[group];
377*4882a593Smuzhiyun
378*4882a593Smuzhiyun for (i = 0; i < num_configs; i++) {
379*4882a593Smuzhiyun param = TEGRA_XUSB_PADCTL_UNPACK_PARAM(configs[i]);
380*4882a593Smuzhiyun value = TEGRA_XUSB_PADCTL_UNPACK_VALUE(configs[i]);
381*4882a593Smuzhiyun
382*4882a593Smuzhiyun switch (param) {
383*4882a593Smuzhiyun case TEGRA_XUSB_PADCTL_IDDQ:
384*4882a593Smuzhiyun /* lanes with iddq == 0 don't support this parameter */
385*4882a593Smuzhiyun if (lane->iddq == 0)
386*4882a593Smuzhiyun return -EINVAL;
387*4882a593Smuzhiyun
388*4882a593Smuzhiyun regval = padctl_readl(padctl, lane->offset);
389*4882a593Smuzhiyun
390*4882a593Smuzhiyun if (value)
391*4882a593Smuzhiyun regval &= ~BIT(lane->iddq);
392*4882a593Smuzhiyun else
393*4882a593Smuzhiyun regval |= BIT(lane->iddq);
394*4882a593Smuzhiyun
395*4882a593Smuzhiyun padctl_writel(padctl, regval, lane->offset);
396*4882a593Smuzhiyun break;
397*4882a593Smuzhiyun
398*4882a593Smuzhiyun default:
399*4882a593Smuzhiyun dev_err(padctl->dev,
400*4882a593Smuzhiyun "invalid configuration parameter: %04x\n",
401*4882a593Smuzhiyun param);
402*4882a593Smuzhiyun return -ENOTSUPP;
403*4882a593Smuzhiyun }
404*4882a593Smuzhiyun }
405*4882a593Smuzhiyun
406*4882a593Smuzhiyun return 0;
407*4882a593Smuzhiyun }
408*4882a593Smuzhiyun
409*4882a593Smuzhiyun #ifdef CONFIG_DEBUG_FS
strip_prefix(const char * s)410*4882a593Smuzhiyun static const char *strip_prefix(const char *s)
411*4882a593Smuzhiyun {
412*4882a593Smuzhiyun const char *comma = strchr(s, ',');
413*4882a593Smuzhiyun if (!comma)
414*4882a593Smuzhiyun return s;
415*4882a593Smuzhiyun
416*4882a593Smuzhiyun return comma + 1;
417*4882a593Smuzhiyun }
418*4882a593Smuzhiyun
419*4882a593Smuzhiyun static void
tegra_xusb_padctl_pinconf_group_dbg_show(struct pinctrl_dev * pinctrl,struct seq_file * s,unsigned int group)420*4882a593Smuzhiyun tegra_xusb_padctl_pinconf_group_dbg_show(struct pinctrl_dev *pinctrl,
421*4882a593Smuzhiyun struct seq_file *s,
422*4882a593Smuzhiyun unsigned int group)
423*4882a593Smuzhiyun {
424*4882a593Smuzhiyun unsigned int i;
425*4882a593Smuzhiyun
426*4882a593Smuzhiyun for (i = 0; i < ARRAY_SIZE(properties); i++) {
427*4882a593Smuzhiyun unsigned long config, value;
428*4882a593Smuzhiyun int err;
429*4882a593Smuzhiyun
430*4882a593Smuzhiyun config = TEGRA_XUSB_PADCTL_PACK(properties[i].param, 0);
431*4882a593Smuzhiyun
432*4882a593Smuzhiyun err = tegra_xusb_padctl_pinconf_group_get(pinctrl, group,
433*4882a593Smuzhiyun &config);
434*4882a593Smuzhiyun if (err < 0)
435*4882a593Smuzhiyun continue;
436*4882a593Smuzhiyun
437*4882a593Smuzhiyun value = TEGRA_XUSB_PADCTL_UNPACK_VALUE(config);
438*4882a593Smuzhiyun
439*4882a593Smuzhiyun seq_printf(s, "\n\t%s=%lu\n", strip_prefix(properties[i].name),
440*4882a593Smuzhiyun value);
441*4882a593Smuzhiyun }
442*4882a593Smuzhiyun }
443*4882a593Smuzhiyun
444*4882a593Smuzhiyun static void
tegra_xusb_padctl_pinconf_config_dbg_show(struct pinctrl_dev * pinctrl,struct seq_file * s,unsigned long config)445*4882a593Smuzhiyun tegra_xusb_padctl_pinconf_config_dbg_show(struct pinctrl_dev *pinctrl,
446*4882a593Smuzhiyun struct seq_file *s,
447*4882a593Smuzhiyun unsigned long config)
448*4882a593Smuzhiyun {
449*4882a593Smuzhiyun enum tegra_xusb_padctl_param param;
450*4882a593Smuzhiyun const char *name = "unknown";
451*4882a593Smuzhiyun unsigned long value;
452*4882a593Smuzhiyun unsigned int i;
453*4882a593Smuzhiyun
454*4882a593Smuzhiyun param = TEGRA_XUSB_PADCTL_UNPACK_PARAM(config);
455*4882a593Smuzhiyun value = TEGRA_XUSB_PADCTL_UNPACK_VALUE(config);
456*4882a593Smuzhiyun
457*4882a593Smuzhiyun for (i = 0; i < ARRAY_SIZE(properties); i++) {
458*4882a593Smuzhiyun if (properties[i].param == param) {
459*4882a593Smuzhiyun name = properties[i].name;
460*4882a593Smuzhiyun break;
461*4882a593Smuzhiyun }
462*4882a593Smuzhiyun }
463*4882a593Smuzhiyun
464*4882a593Smuzhiyun seq_printf(s, "%s=%lu", strip_prefix(name), value);
465*4882a593Smuzhiyun }
466*4882a593Smuzhiyun #endif
467*4882a593Smuzhiyun
468*4882a593Smuzhiyun static const struct pinconf_ops tegra_xusb_padctl_pinconf_ops = {
469*4882a593Smuzhiyun .pin_config_group_get = tegra_xusb_padctl_pinconf_group_get,
470*4882a593Smuzhiyun .pin_config_group_set = tegra_xusb_padctl_pinconf_group_set,
471*4882a593Smuzhiyun #ifdef CONFIG_DEBUG_FS
472*4882a593Smuzhiyun .pin_config_group_dbg_show = tegra_xusb_padctl_pinconf_group_dbg_show,
473*4882a593Smuzhiyun .pin_config_config_dbg_show = tegra_xusb_padctl_pinconf_config_dbg_show,
474*4882a593Smuzhiyun #endif
475*4882a593Smuzhiyun };
476*4882a593Smuzhiyun
tegra_xusb_padctl_enable(struct tegra_xusb_padctl * padctl)477*4882a593Smuzhiyun static int tegra_xusb_padctl_enable(struct tegra_xusb_padctl *padctl)
478*4882a593Smuzhiyun {
479*4882a593Smuzhiyun u32 value;
480*4882a593Smuzhiyun
481*4882a593Smuzhiyun mutex_lock(&padctl->lock);
482*4882a593Smuzhiyun
483*4882a593Smuzhiyun if (padctl->enable++ > 0)
484*4882a593Smuzhiyun goto out;
485*4882a593Smuzhiyun
486*4882a593Smuzhiyun value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM);
487*4882a593Smuzhiyun value &= ~XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN;
488*4882a593Smuzhiyun padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM);
489*4882a593Smuzhiyun
490*4882a593Smuzhiyun usleep_range(100, 200);
491*4882a593Smuzhiyun
492*4882a593Smuzhiyun value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM);
493*4882a593Smuzhiyun value &= ~XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN_EARLY;
494*4882a593Smuzhiyun padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM);
495*4882a593Smuzhiyun
496*4882a593Smuzhiyun usleep_range(100, 200);
497*4882a593Smuzhiyun
498*4882a593Smuzhiyun value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM);
499*4882a593Smuzhiyun value &= ~XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_VCORE_DOWN;
500*4882a593Smuzhiyun padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM);
501*4882a593Smuzhiyun
502*4882a593Smuzhiyun out:
503*4882a593Smuzhiyun mutex_unlock(&padctl->lock);
504*4882a593Smuzhiyun return 0;
505*4882a593Smuzhiyun }
506*4882a593Smuzhiyun
tegra_xusb_padctl_disable(struct tegra_xusb_padctl * padctl)507*4882a593Smuzhiyun static int tegra_xusb_padctl_disable(struct tegra_xusb_padctl *padctl)
508*4882a593Smuzhiyun {
509*4882a593Smuzhiyun u32 value;
510*4882a593Smuzhiyun
511*4882a593Smuzhiyun mutex_lock(&padctl->lock);
512*4882a593Smuzhiyun
513*4882a593Smuzhiyun if (WARN_ON(padctl->enable == 0))
514*4882a593Smuzhiyun goto out;
515*4882a593Smuzhiyun
516*4882a593Smuzhiyun if (--padctl->enable > 0)
517*4882a593Smuzhiyun goto out;
518*4882a593Smuzhiyun
519*4882a593Smuzhiyun value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM);
520*4882a593Smuzhiyun value |= XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_VCORE_DOWN;
521*4882a593Smuzhiyun padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM);
522*4882a593Smuzhiyun
523*4882a593Smuzhiyun usleep_range(100, 200);
524*4882a593Smuzhiyun
525*4882a593Smuzhiyun value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM);
526*4882a593Smuzhiyun value |= XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN_EARLY;
527*4882a593Smuzhiyun padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM);
528*4882a593Smuzhiyun
529*4882a593Smuzhiyun usleep_range(100, 200);
530*4882a593Smuzhiyun
531*4882a593Smuzhiyun value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM);
532*4882a593Smuzhiyun value |= XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN;
533*4882a593Smuzhiyun padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM);
534*4882a593Smuzhiyun
535*4882a593Smuzhiyun out:
536*4882a593Smuzhiyun mutex_unlock(&padctl->lock);
537*4882a593Smuzhiyun return 0;
538*4882a593Smuzhiyun }
539*4882a593Smuzhiyun
tegra_xusb_phy_init(struct phy * phy)540*4882a593Smuzhiyun static int tegra_xusb_phy_init(struct phy *phy)
541*4882a593Smuzhiyun {
542*4882a593Smuzhiyun struct tegra_xusb_padctl *padctl = phy_get_drvdata(phy);
543*4882a593Smuzhiyun
544*4882a593Smuzhiyun return tegra_xusb_padctl_enable(padctl);
545*4882a593Smuzhiyun }
546*4882a593Smuzhiyun
tegra_xusb_phy_exit(struct phy * phy)547*4882a593Smuzhiyun static int tegra_xusb_phy_exit(struct phy *phy)
548*4882a593Smuzhiyun {
549*4882a593Smuzhiyun struct tegra_xusb_padctl *padctl = phy_get_drvdata(phy);
550*4882a593Smuzhiyun
551*4882a593Smuzhiyun return tegra_xusb_padctl_disable(padctl);
552*4882a593Smuzhiyun }
553*4882a593Smuzhiyun
pcie_phy_power_on(struct phy * phy)554*4882a593Smuzhiyun static int pcie_phy_power_on(struct phy *phy)
555*4882a593Smuzhiyun {
556*4882a593Smuzhiyun struct tegra_xusb_padctl *padctl = phy_get_drvdata(phy);
557*4882a593Smuzhiyun unsigned long timeout;
558*4882a593Smuzhiyun int err = -ETIMEDOUT;
559*4882a593Smuzhiyun u32 value;
560*4882a593Smuzhiyun
561*4882a593Smuzhiyun value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_P0_CTL1);
562*4882a593Smuzhiyun value &= ~XUSB_PADCTL_IOPHY_PLL_P0_CTL1_REFCLK_SEL_MASK;
563*4882a593Smuzhiyun padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_P0_CTL1);
564*4882a593Smuzhiyun
565*4882a593Smuzhiyun value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_P0_CTL2);
566*4882a593Smuzhiyun value |= XUSB_PADCTL_IOPHY_PLL_P0_CTL2_REFCLKBUF_EN |
567*4882a593Smuzhiyun XUSB_PADCTL_IOPHY_PLL_P0_CTL2_TXCLKREF_EN |
568*4882a593Smuzhiyun XUSB_PADCTL_IOPHY_PLL_P0_CTL2_TXCLKREF_SEL;
569*4882a593Smuzhiyun padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_P0_CTL2);
570*4882a593Smuzhiyun
571*4882a593Smuzhiyun value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_P0_CTL1);
572*4882a593Smuzhiyun value |= XUSB_PADCTL_IOPHY_PLL_P0_CTL1_PLL_RST;
573*4882a593Smuzhiyun padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_P0_CTL1);
574*4882a593Smuzhiyun
575*4882a593Smuzhiyun timeout = jiffies + msecs_to_jiffies(50);
576*4882a593Smuzhiyun
577*4882a593Smuzhiyun while (time_before(jiffies, timeout)) {
578*4882a593Smuzhiyun value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_P0_CTL1);
579*4882a593Smuzhiyun if (value & XUSB_PADCTL_IOPHY_PLL_P0_CTL1_PLL0_LOCKDET) {
580*4882a593Smuzhiyun err = 0;
581*4882a593Smuzhiyun break;
582*4882a593Smuzhiyun }
583*4882a593Smuzhiyun
584*4882a593Smuzhiyun usleep_range(100, 200);
585*4882a593Smuzhiyun }
586*4882a593Smuzhiyun
587*4882a593Smuzhiyun return err;
588*4882a593Smuzhiyun }
589*4882a593Smuzhiyun
pcie_phy_power_off(struct phy * phy)590*4882a593Smuzhiyun static int pcie_phy_power_off(struct phy *phy)
591*4882a593Smuzhiyun {
592*4882a593Smuzhiyun struct tegra_xusb_padctl *padctl = phy_get_drvdata(phy);
593*4882a593Smuzhiyun u32 value;
594*4882a593Smuzhiyun
595*4882a593Smuzhiyun value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_P0_CTL1);
596*4882a593Smuzhiyun value &= ~XUSB_PADCTL_IOPHY_PLL_P0_CTL1_PLL_RST;
597*4882a593Smuzhiyun padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_P0_CTL1);
598*4882a593Smuzhiyun
599*4882a593Smuzhiyun return 0;
600*4882a593Smuzhiyun }
601*4882a593Smuzhiyun
602*4882a593Smuzhiyun static const struct phy_ops pcie_phy_ops = {
603*4882a593Smuzhiyun .init = tegra_xusb_phy_init,
604*4882a593Smuzhiyun .exit = tegra_xusb_phy_exit,
605*4882a593Smuzhiyun .power_on = pcie_phy_power_on,
606*4882a593Smuzhiyun .power_off = pcie_phy_power_off,
607*4882a593Smuzhiyun .owner = THIS_MODULE,
608*4882a593Smuzhiyun };
609*4882a593Smuzhiyun
sata_phy_power_on(struct phy * phy)610*4882a593Smuzhiyun static int sata_phy_power_on(struct phy *phy)
611*4882a593Smuzhiyun {
612*4882a593Smuzhiyun struct tegra_xusb_padctl *padctl = phy_get_drvdata(phy);
613*4882a593Smuzhiyun unsigned long timeout;
614*4882a593Smuzhiyun int err = -ETIMEDOUT;
615*4882a593Smuzhiyun u32 value;
616*4882a593Smuzhiyun
617*4882a593Smuzhiyun value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1);
618*4882a593Smuzhiyun value &= ~XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1_IDDQ_OVRD;
619*4882a593Smuzhiyun value &= ~XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1_IDDQ;
620*4882a593Smuzhiyun padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1);
621*4882a593Smuzhiyun
622*4882a593Smuzhiyun value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1);
623*4882a593Smuzhiyun value &= ~XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_PWR_OVRD;
624*4882a593Smuzhiyun value &= ~XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_IDDQ;
625*4882a593Smuzhiyun padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_S0_CTL1);
626*4882a593Smuzhiyun
627*4882a593Smuzhiyun value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1);
628*4882a593Smuzhiyun value |= XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL1_MODE;
629*4882a593Smuzhiyun padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_S0_CTL1);
630*4882a593Smuzhiyun
631*4882a593Smuzhiyun value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1);
632*4882a593Smuzhiyun value |= XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_RST;
633*4882a593Smuzhiyun padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_S0_CTL1);
634*4882a593Smuzhiyun
635*4882a593Smuzhiyun timeout = jiffies + msecs_to_jiffies(50);
636*4882a593Smuzhiyun
637*4882a593Smuzhiyun while (time_before(jiffies, timeout)) {
638*4882a593Smuzhiyun value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1);
639*4882a593Smuzhiyun if (value & XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL1_LOCKDET) {
640*4882a593Smuzhiyun err = 0;
641*4882a593Smuzhiyun break;
642*4882a593Smuzhiyun }
643*4882a593Smuzhiyun
644*4882a593Smuzhiyun usleep_range(100, 200);
645*4882a593Smuzhiyun }
646*4882a593Smuzhiyun
647*4882a593Smuzhiyun return err;
648*4882a593Smuzhiyun }
649*4882a593Smuzhiyun
sata_phy_power_off(struct phy * phy)650*4882a593Smuzhiyun static int sata_phy_power_off(struct phy *phy)
651*4882a593Smuzhiyun {
652*4882a593Smuzhiyun struct tegra_xusb_padctl *padctl = phy_get_drvdata(phy);
653*4882a593Smuzhiyun u32 value;
654*4882a593Smuzhiyun
655*4882a593Smuzhiyun value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1);
656*4882a593Smuzhiyun value &= ~XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_RST;
657*4882a593Smuzhiyun padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_S0_CTL1);
658*4882a593Smuzhiyun
659*4882a593Smuzhiyun value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1);
660*4882a593Smuzhiyun value &= ~XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL1_MODE;
661*4882a593Smuzhiyun padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_S0_CTL1);
662*4882a593Smuzhiyun
663*4882a593Smuzhiyun value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1);
664*4882a593Smuzhiyun value |= XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_PWR_OVRD;
665*4882a593Smuzhiyun value |= XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_IDDQ;
666*4882a593Smuzhiyun padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_S0_CTL1);
667*4882a593Smuzhiyun
668*4882a593Smuzhiyun value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1);
669*4882a593Smuzhiyun value |= ~XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1_IDDQ_OVRD;
670*4882a593Smuzhiyun value |= ~XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1_IDDQ;
671*4882a593Smuzhiyun padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1);
672*4882a593Smuzhiyun
673*4882a593Smuzhiyun return 0;
674*4882a593Smuzhiyun }
675*4882a593Smuzhiyun
676*4882a593Smuzhiyun static const struct phy_ops sata_phy_ops = {
677*4882a593Smuzhiyun .init = tegra_xusb_phy_init,
678*4882a593Smuzhiyun .exit = tegra_xusb_phy_exit,
679*4882a593Smuzhiyun .power_on = sata_phy_power_on,
680*4882a593Smuzhiyun .power_off = sata_phy_power_off,
681*4882a593Smuzhiyun .owner = THIS_MODULE,
682*4882a593Smuzhiyun };
683*4882a593Smuzhiyun
tegra_xusb_padctl_xlate(struct device * dev,struct of_phandle_args * args)684*4882a593Smuzhiyun static struct phy *tegra_xusb_padctl_xlate(struct device *dev,
685*4882a593Smuzhiyun struct of_phandle_args *args)
686*4882a593Smuzhiyun {
687*4882a593Smuzhiyun struct tegra_xusb_padctl *padctl = dev_get_drvdata(dev);
688*4882a593Smuzhiyun unsigned int index = args->args[0];
689*4882a593Smuzhiyun
690*4882a593Smuzhiyun if (args->args_count <= 0)
691*4882a593Smuzhiyun return ERR_PTR(-EINVAL);
692*4882a593Smuzhiyun
693*4882a593Smuzhiyun if (index >= ARRAY_SIZE(padctl->phys))
694*4882a593Smuzhiyun return ERR_PTR(-EINVAL);
695*4882a593Smuzhiyun
696*4882a593Smuzhiyun return padctl->phys[index];
697*4882a593Smuzhiyun }
698*4882a593Smuzhiyun
699*4882a593Smuzhiyun #define PIN_OTG_0 0
700*4882a593Smuzhiyun #define PIN_OTG_1 1
701*4882a593Smuzhiyun #define PIN_OTG_2 2
702*4882a593Smuzhiyun #define PIN_ULPI_0 3
703*4882a593Smuzhiyun #define PIN_HSIC_0 4
704*4882a593Smuzhiyun #define PIN_HSIC_1 5
705*4882a593Smuzhiyun #define PIN_PCIE_0 6
706*4882a593Smuzhiyun #define PIN_PCIE_1 7
707*4882a593Smuzhiyun #define PIN_PCIE_2 8
708*4882a593Smuzhiyun #define PIN_PCIE_3 9
709*4882a593Smuzhiyun #define PIN_PCIE_4 10
710*4882a593Smuzhiyun #define PIN_SATA_0 11
711*4882a593Smuzhiyun
712*4882a593Smuzhiyun static const struct pinctrl_pin_desc tegra124_pins[] = {
713*4882a593Smuzhiyun PINCTRL_PIN(PIN_OTG_0, "otg-0"),
714*4882a593Smuzhiyun PINCTRL_PIN(PIN_OTG_1, "otg-1"),
715*4882a593Smuzhiyun PINCTRL_PIN(PIN_OTG_2, "otg-2"),
716*4882a593Smuzhiyun PINCTRL_PIN(PIN_ULPI_0, "ulpi-0"),
717*4882a593Smuzhiyun PINCTRL_PIN(PIN_HSIC_0, "hsic-0"),
718*4882a593Smuzhiyun PINCTRL_PIN(PIN_HSIC_1, "hsic-1"),
719*4882a593Smuzhiyun PINCTRL_PIN(PIN_PCIE_0, "pcie-0"),
720*4882a593Smuzhiyun PINCTRL_PIN(PIN_PCIE_1, "pcie-1"),
721*4882a593Smuzhiyun PINCTRL_PIN(PIN_PCIE_2, "pcie-2"),
722*4882a593Smuzhiyun PINCTRL_PIN(PIN_PCIE_3, "pcie-3"),
723*4882a593Smuzhiyun PINCTRL_PIN(PIN_PCIE_4, "pcie-4"),
724*4882a593Smuzhiyun PINCTRL_PIN(PIN_SATA_0, "sata-0"),
725*4882a593Smuzhiyun };
726*4882a593Smuzhiyun
727*4882a593Smuzhiyun static const char * const tegra124_snps_groups[] = {
728*4882a593Smuzhiyun "otg-0",
729*4882a593Smuzhiyun "otg-1",
730*4882a593Smuzhiyun "otg-2",
731*4882a593Smuzhiyun "ulpi-0",
732*4882a593Smuzhiyun "hsic-0",
733*4882a593Smuzhiyun "hsic-1",
734*4882a593Smuzhiyun };
735*4882a593Smuzhiyun
736*4882a593Smuzhiyun static const char * const tegra124_xusb_groups[] = {
737*4882a593Smuzhiyun "otg-0",
738*4882a593Smuzhiyun "otg-1",
739*4882a593Smuzhiyun "otg-2",
740*4882a593Smuzhiyun "ulpi-0",
741*4882a593Smuzhiyun "hsic-0",
742*4882a593Smuzhiyun "hsic-1",
743*4882a593Smuzhiyun };
744*4882a593Smuzhiyun
745*4882a593Smuzhiyun static const char * const tegra124_uart_groups[] = {
746*4882a593Smuzhiyun "otg-0",
747*4882a593Smuzhiyun "otg-1",
748*4882a593Smuzhiyun "otg-2",
749*4882a593Smuzhiyun };
750*4882a593Smuzhiyun
751*4882a593Smuzhiyun static const char * const tegra124_pcie_groups[] = {
752*4882a593Smuzhiyun "pcie-0",
753*4882a593Smuzhiyun "pcie-1",
754*4882a593Smuzhiyun "pcie-2",
755*4882a593Smuzhiyun "pcie-3",
756*4882a593Smuzhiyun "pcie-4",
757*4882a593Smuzhiyun };
758*4882a593Smuzhiyun
759*4882a593Smuzhiyun static const char * const tegra124_usb3_groups[] = {
760*4882a593Smuzhiyun "pcie-0",
761*4882a593Smuzhiyun "pcie-1",
762*4882a593Smuzhiyun "sata-0",
763*4882a593Smuzhiyun };
764*4882a593Smuzhiyun
765*4882a593Smuzhiyun static const char * const tegra124_sata_groups[] = {
766*4882a593Smuzhiyun "sata-0",
767*4882a593Smuzhiyun };
768*4882a593Smuzhiyun
769*4882a593Smuzhiyun static const char * const tegra124_rsvd_groups[] = {
770*4882a593Smuzhiyun "otg-0",
771*4882a593Smuzhiyun "otg-1",
772*4882a593Smuzhiyun "otg-2",
773*4882a593Smuzhiyun "pcie-0",
774*4882a593Smuzhiyun "pcie-1",
775*4882a593Smuzhiyun "pcie-2",
776*4882a593Smuzhiyun "pcie-3",
777*4882a593Smuzhiyun "pcie-4",
778*4882a593Smuzhiyun "sata-0",
779*4882a593Smuzhiyun };
780*4882a593Smuzhiyun
781*4882a593Smuzhiyun #define TEGRA124_FUNCTION(_name) \
782*4882a593Smuzhiyun { \
783*4882a593Smuzhiyun .name = #_name, \
784*4882a593Smuzhiyun .num_groups = ARRAY_SIZE(tegra124_##_name##_groups), \
785*4882a593Smuzhiyun .groups = tegra124_##_name##_groups, \
786*4882a593Smuzhiyun }
787*4882a593Smuzhiyun
788*4882a593Smuzhiyun static struct tegra_xusb_padctl_function tegra124_functions[] = {
789*4882a593Smuzhiyun TEGRA124_FUNCTION(snps),
790*4882a593Smuzhiyun TEGRA124_FUNCTION(xusb),
791*4882a593Smuzhiyun TEGRA124_FUNCTION(uart),
792*4882a593Smuzhiyun TEGRA124_FUNCTION(pcie),
793*4882a593Smuzhiyun TEGRA124_FUNCTION(usb3),
794*4882a593Smuzhiyun TEGRA124_FUNCTION(sata),
795*4882a593Smuzhiyun TEGRA124_FUNCTION(rsvd),
796*4882a593Smuzhiyun };
797*4882a593Smuzhiyun
798*4882a593Smuzhiyun enum tegra124_function {
799*4882a593Smuzhiyun TEGRA124_FUNC_SNPS,
800*4882a593Smuzhiyun TEGRA124_FUNC_XUSB,
801*4882a593Smuzhiyun TEGRA124_FUNC_UART,
802*4882a593Smuzhiyun TEGRA124_FUNC_PCIE,
803*4882a593Smuzhiyun TEGRA124_FUNC_USB3,
804*4882a593Smuzhiyun TEGRA124_FUNC_SATA,
805*4882a593Smuzhiyun TEGRA124_FUNC_RSVD,
806*4882a593Smuzhiyun };
807*4882a593Smuzhiyun
808*4882a593Smuzhiyun static const unsigned int tegra124_otg_functions[] = {
809*4882a593Smuzhiyun TEGRA124_FUNC_SNPS,
810*4882a593Smuzhiyun TEGRA124_FUNC_XUSB,
811*4882a593Smuzhiyun TEGRA124_FUNC_UART,
812*4882a593Smuzhiyun TEGRA124_FUNC_RSVD,
813*4882a593Smuzhiyun };
814*4882a593Smuzhiyun
815*4882a593Smuzhiyun static const unsigned int tegra124_usb_functions[] = {
816*4882a593Smuzhiyun TEGRA124_FUNC_SNPS,
817*4882a593Smuzhiyun TEGRA124_FUNC_XUSB,
818*4882a593Smuzhiyun };
819*4882a593Smuzhiyun
820*4882a593Smuzhiyun static const unsigned int tegra124_pci_functions[] = {
821*4882a593Smuzhiyun TEGRA124_FUNC_PCIE,
822*4882a593Smuzhiyun TEGRA124_FUNC_USB3,
823*4882a593Smuzhiyun TEGRA124_FUNC_SATA,
824*4882a593Smuzhiyun TEGRA124_FUNC_RSVD,
825*4882a593Smuzhiyun };
826*4882a593Smuzhiyun
827*4882a593Smuzhiyun #define TEGRA124_LANE(_name, _offset, _shift, _mask, _iddq, _funcs) \
828*4882a593Smuzhiyun { \
829*4882a593Smuzhiyun .name = _name, \
830*4882a593Smuzhiyun .offset = _offset, \
831*4882a593Smuzhiyun .shift = _shift, \
832*4882a593Smuzhiyun .mask = _mask, \
833*4882a593Smuzhiyun .iddq = _iddq, \
834*4882a593Smuzhiyun .num_funcs = ARRAY_SIZE(tegra124_##_funcs##_functions), \
835*4882a593Smuzhiyun .funcs = tegra124_##_funcs##_functions, \
836*4882a593Smuzhiyun }
837*4882a593Smuzhiyun
838*4882a593Smuzhiyun static const struct tegra_xusb_padctl_lane tegra124_lanes[] = {
839*4882a593Smuzhiyun TEGRA124_LANE("otg-0", 0x004, 0, 0x3, 0, otg),
840*4882a593Smuzhiyun TEGRA124_LANE("otg-1", 0x004, 2, 0x3, 0, otg),
841*4882a593Smuzhiyun TEGRA124_LANE("otg-2", 0x004, 4, 0x3, 0, otg),
842*4882a593Smuzhiyun TEGRA124_LANE("ulpi-0", 0x004, 12, 0x1, 0, usb),
843*4882a593Smuzhiyun TEGRA124_LANE("hsic-0", 0x004, 14, 0x1, 0, usb),
844*4882a593Smuzhiyun TEGRA124_LANE("hsic-1", 0x004, 15, 0x1, 0, usb),
845*4882a593Smuzhiyun TEGRA124_LANE("pcie-0", 0x134, 16, 0x3, 1, pci),
846*4882a593Smuzhiyun TEGRA124_LANE("pcie-1", 0x134, 18, 0x3, 2, pci),
847*4882a593Smuzhiyun TEGRA124_LANE("pcie-2", 0x134, 20, 0x3, 3, pci),
848*4882a593Smuzhiyun TEGRA124_LANE("pcie-3", 0x134, 22, 0x3, 4, pci),
849*4882a593Smuzhiyun TEGRA124_LANE("pcie-4", 0x134, 24, 0x3, 5, pci),
850*4882a593Smuzhiyun TEGRA124_LANE("sata-0", 0x134, 26, 0x3, 6, pci),
851*4882a593Smuzhiyun };
852*4882a593Smuzhiyun
853*4882a593Smuzhiyun static const struct tegra_xusb_padctl_soc tegra124_soc = {
854*4882a593Smuzhiyun .num_pins = ARRAY_SIZE(tegra124_pins),
855*4882a593Smuzhiyun .pins = tegra124_pins,
856*4882a593Smuzhiyun .num_functions = ARRAY_SIZE(tegra124_functions),
857*4882a593Smuzhiyun .functions = tegra124_functions,
858*4882a593Smuzhiyun .num_lanes = ARRAY_SIZE(tegra124_lanes),
859*4882a593Smuzhiyun .lanes = tegra124_lanes,
860*4882a593Smuzhiyun };
861*4882a593Smuzhiyun
862*4882a593Smuzhiyun static const struct of_device_id tegra_xusb_padctl_of_match[] = {
863*4882a593Smuzhiyun { .compatible = "nvidia,tegra124-xusb-padctl", .data = &tegra124_soc },
864*4882a593Smuzhiyun { }
865*4882a593Smuzhiyun };
866*4882a593Smuzhiyun MODULE_DEVICE_TABLE(of, tegra_xusb_padctl_of_match);
867*4882a593Smuzhiyun
868*4882a593Smuzhiyun /* predeclare these in order to silence sparse */
869*4882a593Smuzhiyun int tegra_xusb_padctl_legacy_probe(struct platform_device *pdev);
870*4882a593Smuzhiyun int tegra_xusb_padctl_legacy_remove(struct platform_device *pdev);
871*4882a593Smuzhiyun
tegra_xusb_padctl_legacy_probe(struct platform_device * pdev)872*4882a593Smuzhiyun int tegra_xusb_padctl_legacy_probe(struct platform_device *pdev)
873*4882a593Smuzhiyun {
874*4882a593Smuzhiyun struct tegra_xusb_padctl *padctl;
875*4882a593Smuzhiyun const struct of_device_id *match;
876*4882a593Smuzhiyun struct phy *phy;
877*4882a593Smuzhiyun int err;
878*4882a593Smuzhiyun
879*4882a593Smuzhiyun padctl = devm_kzalloc(&pdev->dev, sizeof(*padctl), GFP_KERNEL);
880*4882a593Smuzhiyun if (!padctl)
881*4882a593Smuzhiyun return -ENOMEM;
882*4882a593Smuzhiyun
883*4882a593Smuzhiyun platform_set_drvdata(pdev, padctl);
884*4882a593Smuzhiyun mutex_init(&padctl->lock);
885*4882a593Smuzhiyun padctl->dev = &pdev->dev;
886*4882a593Smuzhiyun
887*4882a593Smuzhiyun /*
888*4882a593Smuzhiyun * Note that we can't replace this by of_device_get_match_data()
889*4882a593Smuzhiyun * because we need the separate matching table for this legacy code on
890*4882a593Smuzhiyun * Tegra124. of_device_get_match_data() would attempt to use the table
891*4882a593Smuzhiyun * from the updated driver and fail.
892*4882a593Smuzhiyun */
893*4882a593Smuzhiyun match = of_match_node(tegra_xusb_padctl_of_match, pdev->dev.of_node);
894*4882a593Smuzhiyun padctl->soc = match->data;
895*4882a593Smuzhiyun
896*4882a593Smuzhiyun padctl->regs = devm_platform_ioremap_resource(pdev, 0);
897*4882a593Smuzhiyun if (IS_ERR(padctl->regs))
898*4882a593Smuzhiyun return PTR_ERR(padctl->regs);
899*4882a593Smuzhiyun
900*4882a593Smuzhiyun padctl->rst = devm_reset_control_get_exclusive(&pdev->dev, NULL);
901*4882a593Smuzhiyun if (IS_ERR(padctl->rst))
902*4882a593Smuzhiyun return PTR_ERR(padctl->rst);
903*4882a593Smuzhiyun
904*4882a593Smuzhiyun err = reset_control_deassert(padctl->rst);
905*4882a593Smuzhiyun if (err < 0)
906*4882a593Smuzhiyun return err;
907*4882a593Smuzhiyun
908*4882a593Smuzhiyun memset(&padctl->desc, 0, sizeof(padctl->desc));
909*4882a593Smuzhiyun padctl->desc.name = dev_name(padctl->dev);
910*4882a593Smuzhiyun padctl->desc.pins = tegra124_pins;
911*4882a593Smuzhiyun padctl->desc.npins = ARRAY_SIZE(tegra124_pins);
912*4882a593Smuzhiyun padctl->desc.pctlops = &tegra_xusb_padctl_pinctrl_ops;
913*4882a593Smuzhiyun padctl->desc.pmxops = &tegra_xusb_padctl_pinmux_ops;
914*4882a593Smuzhiyun padctl->desc.confops = &tegra_xusb_padctl_pinconf_ops;
915*4882a593Smuzhiyun padctl->desc.owner = THIS_MODULE;
916*4882a593Smuzhiyun
917*4882a593Smuzhiyun padctl->pinctrl = devm_pinctrl_register(&pdev->dev, &padctl->desc,
918*4882a593Smuzhiyun padctl);
919*4882a593Smuzhiyun if (IS_ERR(padctl->pinctrl)) {
920*4882a593Smuzhiyun dev_err(&pdev->dev, "failed to register pincontrol\n");
921*4882a593Smuzhiyun err = PTR_ERR(padctl->pinctrl);
922*4882a593Smuzhiyun goto reset;
923*4882a593Smuzhiyun }
924*4882a593Smuzhiyun
925*4882a593Smuzhiyun phy = devm_phy_create(&pdev->dev, NULL, &pcie_phy_ops);
926*4882a593Smuzhiyun if (IS_ERR(phy)) {
927*4882a593Smuzhiyun err = PTR_ERR(phy);
928*4882a593Smuzhiyun goto reset;
929*4882a593Smuzhiyun }
930*4882a593Smuzhiyun
931*4882a593Smuzhiyun padctl->phys[TEGRA_XUSB_PADCTL_PCIE] = phy;
932*4882a593Smuzhiyun phy_set_drvdata(phy, padctl);
933*4882a593Smuzhiyun
934*4882a593Smuzhiyun phy = devm_phy_create(&pdev->dev, NULL, &sata_phy_ops);
935*4882a593Smuzhiyun if (IS_ERR(phy)) {
936*4882a593Smuzhiyun err = PTR_ERR(phy);
937*4882a593Smuzhiyun goto reset;
938*4882a593Smuzhiyun }
939*4882a593Smuzhiyun
940*4882a593Smuzhiyun padctl->phys[TEGRA_XUSB_PADCTL_SATA] = phy;
941*4882a593Smuzhiyun phy_set_drvdata(phy, padctl);
942*4882a593Smuzhiyun
943*4882a593Smuzhiyun padctl->provider = devm_of_phy_provider_register(&pdev->dev,
944*4882a593Smuzhiyun tegra_xusb_padctl_xlate);
945*4882a593Smuzhiyun if (IS_ERR(padctl->provider)) {
946*4882a593Smuzhiyun err = PTR_ERR(padctl->provider);
947*4882a593Smuzhiyun dev_err(&pdev->dev, "failed to register PHYs: %d\n", err);
948*4882a593Smuzhiyun goto reset;
949*4882a593Smuzhiyun }
950*4882a593Smuzhiyun
951*4882a593Smuzhiyun return 0;
952*4882a593Smuzhiyun
953*4882a593Smuzhiyun reset:
954*4882a593Smuzhiyun reset_control_assert(padctl->rst);
955*4882a593Smuzhiyun return err;
956*4882a593Smuzhiyun }
957*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(tegra_xusb_padctl_legacy_probe);
958*4882a593Smuzhiyun
tegra_xusb_padctl_legacy_remove(struct platform_device * pdev)959*4882a593Smuzhiyun int tegra_xusb_padctl_legacy_remove(struct platform_device *pdev)
960*4882a593Smuzhiyun {
961*4882a593Smuzhiyun struct tegra_xusb_padctl *padctl = platform_get_drvdata(pdev);
962*4882a593Smuzhiyun int err;
963*4882a593Smuzhiyun
964*4882a593Smuzhiyun err = reset_control_assert(padctl->rst);
965*4882a593Smuzhiyun if (err < 0)
966*4882a593Smuzhiyun dev_err(&pdev->dev, "failed to assert reset: %d\n", err);
967*4882a593Smuzhiyun
968*4882a593Smuzhiyun return err;
969*4882a593Smuzhiyun }
970*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(tegra_xusb_padctl_legacy_remove);
971