xref: /OK3568_Linux_fs/kernel/drivers/pinctrl/tegra/pinctrl-tegra-xusb.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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