• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2014-2015, NVIDIA CORPORATION.  All rights reserved.
4  */
5 
6 #define pr_fmt(fmt) "tegra-xusb-padctl: " fmt
7 
8 #include <common.h>
9 #include <errno.h>
10 #include <dm/of_access.h>
11 #include <dm/ofnode.h>
12 
13 #include "../xusb-padctl-common.h"
14 
15 #include <dt-bindings/pinctrl/pinctrl-tegra-xusb.h>
16 
17 #define XUSB_PADCTL_ELPG_PROGRAM 0x01c
18 #define XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_VCORE_DOWN (1 << 26)
19 #define XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN_EARLY (1 << 25)
20 #define XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN (1 << 24)
21 
22 #define XUSB_PADCTL_IOPHY_PLL_P0_CTL1 0x040
23 #define XUSB_PADCTL_IOPHY_PLL_P0_CTL1_PLL0_LOCKDET (1 << 19)
24 #define XUSB_PADCTL_IOPHY_PLL_P0_CTL1_REFCLK_SEL_MASK (0xf << 12)
25 #define XUSB_PADCTL_IOPHY_PLL_P0_CTL1_PLL_RST (1 << 1)
26 
27 #define XUSB_PADCTL_IOPHY_PLL_P0_CTL2 0x044
28 #define XUSB_PADCTL_IOPHY_PLL_P0_CTL2_REFCLKBUF_EN (1 << 6)
29 #define XUSB_PADCTL_IOPHY_PLL_P0_CTL2_TXCLKREF_EN (1 << 5)
30 #define XUSB_PADCTL_IOPHY_PLL_P0_CTL2_TXCLKREF_SEL (1 << 4)
31 
32 #define XUSB_PADCTL_IOPHY_PLL_S0_CTL1 0x138
33 #define XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL1_LOCKDET (1 << 27)
34 #define XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL1_MODE (1 << 24)
35 #define XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_PWR_OVRD (1 << 3)
36 #define XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_RST (1 << 1)
37 #define XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_IDDQ (1 << 0)
38 
39 #define XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1 0x148
40 #define XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1_IDDQ_OVRD (1 << 1)
41 #define XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1_IDDQ (1 << 0)
42 
43 enum tegra124_function {
44 	TEGRA124_FUNC_SNPS,
45 	TEGRA124_FUNC_XUSB,
46 	TEGRA124_FUNC_UART,
47 	TEGRA124_FUNC_PCIE,
48 	TEGRA124_FUNC_USB3,
49 	TEGRA124_FUNC_SATA,
50 	TEGRA124_FUNC_RSVD,
51 };
52 
53 static const char *const tegra124_functions[] = {
54 	"snps",
55 	"xusb",
56 	"uart",
57 	"pcie",
58 	"usb3",
59 	"sata",
60 	"rsvd",
61 };
62 
63 static const unsigned int tegra124_otg_functions[] = {
64 	TEGRA124_FUNC_SNPS,
65 	TEGRA124_FUNC_XUSB,
66 	TEGRA124_FUNC_UART,
67 	TEGRA124_FUNC_RSVD,
68 };
69 
70 static const unsigned int tegra124_usb_functions[] = {
71 	TEGRA124_FUNC_SNPS,
72 	TEGRA124_FUNC_XUSB,
73 };
74 
75 static const unsigned int tegra124_pci_functions[] = {
76 	TEGRA124_FUNC_PCIE,
77 	TEGRA124_FUNC_USB3,
78 	TEGRA124_FUNC_SATA,
79 	TEGRA124_FUNC_RSVD,
80 };
81 
82 #define TEGRA124_LANE(_name, _offset, _shift, _mask, _iddq, _funcs)	\
83 	{								\
84 		.name = _name,						\
85 		.offset = _offset,					\
86 		.shift = _shift,					\
87 		.mask = _mask,						\
88 		.iddq = _iddq,						\
89 		.num_funcs = ARRAY_SIZE(tegra124_##_funcs##_functions),	\
90 		.funcs = tegra124_##_funcs##_functions,			\
91 	}
92 
93 static const struct tegra_xusb_padctl_lane tegra124_lanes[] = {
94 	TEGRA124_LANE("otg-0",  0x004,  0, 0x3, 0, otg),
95 	TEGRA124_LANE("otg-1",  0x004,  2, 0x3, 0, otg),
96 	TEGRA124_LANE("otg-2",  0x004,  4, 0x3, 0, otg),
97 	TEGRA124_LANE("ulpi-0", 0x004, 12, 0x1, 0, usb),
98 	TEGRA124_LANE("hsic-0", 0x004, 14, 0x1, 0, usb),
99 	TEGRA124_LANE("hsic-1", 0x004, 15, 0x1, 0, usb),
100 	TEGRA124_LANE("pcie-0", 0x134, 16, 0x3, 1, pci),
101 	TEGRA124_LANE("pcie-1", 0x134, 18, 0x3, 2, pci),
102 	TEGRA124_LANE("pcie-2", 0x134, 20, 0x3, 3, pci),
103 	TEGRA124_LANE("pcie-3", 0x134, 22, 0x3, 4, pci),
104 	TEGRA124_LANE("pcie-4", 0x134, 24, 0x3, 5, pci),
105 	TEGRA124_LANE("sata-0", 0x134, 26, 0x3, 6, pci),
106 };
107 
tegra_xusb_padctl_enable(struct tegra_xusb_padctl * padctl)108 static int tegra_xusb_padctl_enable(struct tegra_xusb_padctl *padctl)
109 {
110 	u32 value;
111 
112 	if (padctl->enable++ > 0)
113 		return 0;
114 
115 	value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM);
116 	value &= ~XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN;
117 	padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM);
118 
119 	udelay(100);
120 
121 	value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM);
122 	value &= ~XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN_EARLY;
123 	padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM);
124 
125 	udelay(100);
126 
127 	value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM);
128 	value &= ~XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_VCORE_DOWN;
129 	padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM);
130 
131 	return 0;
132 }
133 
tegra_xusb_padctl_disable(struct tegra_xusb_padctl * padctl)134 static int tegra_xusb_padctl_disable(struct tegra_xusb_padctl *padctl)
135 {
136 	u32 value;
137 
138 	if (padctl->enable == 0) {
139 		pr_err("unbalanced enable/disable");
140 		return 0;
141 	}
142 
143 	if (--padctl->enable > 0)
144 		return 0;
145 
146 	value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM);
147 	value |= XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_VCORE_DOWN;
148 	padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM);
149 
150 	udelay(100);
151 
152 	value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM);
153 	value |= XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN_EARLY;
154 	padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM);
155 
156 	udelay(100);
157 
158 	value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM);
159 	value |= XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN;
160 	padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM);
161 
162 	return 0;
163 }
164 
phy_prepare(struct tegra_xusb_phy * phy)165 static int phy_prepare(struct tegra_xusb_phy *phy)
166 {
167 	return tegra_xusb_padctl_enable(phy->padctl);
168 }
169 
phy_unprepare(struct tegra_xusb_phy * phy)170 static int phy_unprepare(struct tegra_xusb_phy *phy)
171 {
172 	return tegra_xusb_padctl_disable(phy->padctl);
173 }
174 
pcie_phy_enable(struct tegra_xusb_phy * phy)175 static int pcie_phy_enable(struct tegra_xusb_phy *phy)
176 {
177 	struct tegra_xusb_padctl *padctl = phy->padctl;
178 	int err = -ETIMEDOUT;
179 	unsigned long start;
180 	u32 value;
181 
182 	value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_P0_CTL1);
183 	value &= ~XUSB_PADCTL_IOPHY_PLL_P0_CTL1_REFCLK_SEL_MASK;
184 	padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_P0_CTL1);
185 
186 	value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_P0_CTL2);
187 	value |= XUSB_PADCTL_IOPHY_PLL_P0_CTL2_REFCLKBUF_EN |
188 		 XUSB_PADCTL_IOPHY_PLL_P0_CTL2_TXCLKREF_EN |
189 		 XUSB_PADCTL_IOPHY_PLL_P0_CTL2_TXCLKREF_SEL;
190 	padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_P0_CTL2);
191 
192 	value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_P0_CTL1);
193 	value |= XUSB_PADCTL_IOPHY_PLL_P0_CTL1_PLL_RST;
194 	padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_P0_CTL1);
195 
196 	start = get_timer(0);
197 
198 	while (get_timer(start) < 50) {
199 		value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_P0_CTL1);
200 		if (value & XUSB_PADCTL_IOPHY_PLL_P0_CTL1_PLL0_LOCKDET) {
201 			err = 0;
202 			break;
203 		}
204 	}
205 
206 	return err;
207 }
208 
pcie_phy_disable(struct tegra_xusb_phy * phy)209 static int pcie_phy_disable(struct tegra_xusb_phy *phy)
210 {
211 	struct tegra_xusb_padctl *padctl = phy->padctl;
212 	u32 value;
213 
214 	value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_P0_CTL1);
215 	value &= ~XUSB_PADCTL_IOPHY_PLL_P0_CTL1_PLL_RST;
216 	padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_P0_CTL1);
217 
218 	return 0;
219 }
220 
sata_phy_enable(struct tegra_xusb_phy * phy)221 static int sata_phy_enable(struct tegra_xusb_phy *phy)
222 {
223 	struct tegra_xusb_padctl *padctl = phy->padctl;
224 	int err = -ETIMEDOUT;
225 	unsigned long start;
226 	u32 value;
227 
228 	value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1);
229 	value &= ~XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1_IDDQ_OVRD;
230 	value &= ~XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1_IDDQ;
231 	padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1);
232 
233 	value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1);
234 	value &= ~XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_PWR_OVRD;
235 	value &= ~XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_IDDQ;
236 	padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_S0_CTL1);
237 
238 	value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1);
239 	value |= XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL1_MODE;
240 	padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_S0_CTL1);
241 
242 	value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1);
243 	value |= XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_RST;
244 	padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_S0_CTL1);
245 
246 	start = get_timer(0);
247 
248 	while (get_timer(start) < 50) {
249 		value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1);
250 		if (value & XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL1_LOCKDET) {
251 			err = 0;
252 			break;
253 		}
254 	}
255 
256 	return err;
257 }
258 
sata_phy_disable(struct tegra_xusb_phy * phy)259 static int sata_phy_disable(struct tegra_xusb_phy *phy)
260 {
261 	struct tegra_xusb_padctl *padctl = phy->padctl;
262 	u32 value;
263 
264 	value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1);
265 	value &= ~XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_RST;
266 	padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_S0_CTL1);
267 
268 	value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1);
269 	value &= ~XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL1_MODE;
270 	padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_S0_CTL1);
271 
272 	value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1);
273 	value |= XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_PWR_OVRD;
274 	value |= XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_IDDQ;
275 	padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_S0_CTL1);
276 
277 	value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1);
278 	value |= ~XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1_IDDQ_OVRD;
279 	value |= ~XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1_IDDQ;
280 	padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1);
281 
282 	return 0;
283 }
284 
285 static const struct tegra_xusb_phy_ops pcie_phy_ops = {
286 	.prepare = phy_prepare,
287 	.enable = pcie_phy_enable,
288 	.disable = pcie_phy_disable,
289 	.unprepare = phy_unprepare,
290 };
291 
292 static const struct tegra_xusb_phy_ops sata_phy_ops = {
293 	.prepare = phy_prepare,
294 	.enable = sata_phy_enable,
295 	.disable = sata_phy_disable,
296 	.unprepare = phy_unprepare,
297 };
298 
299 static struct tegra_xusb_phy tegra124_phys[] = {
300 	{
301 		.type = TEGRA_XUSB_PADCTL_PCIE,
302 		.ops = &pcie_phy_ops,
303 		.padctl = &padctl,
304 	},
305 	{
306 		.type = TEGRA_XUSB_PADCTL_SATA,
307 		.ops = &sata_phy_ops,
308 		.padctl = &padctl,
309 	},
310 };
311 
312 static const struct tegra_xusb_padctl_soc tegra124_socdata = {
313 	.lanes = tegra124_lanes,
314 	.num_lanes = ARRAY_SIZE(tegra124_lanes),
315 	.functions = tegra124_functions,
316 	.num_functions = ARRAY_SIZE(tegra124_functions),
317 	.phys = tegra124_phys,
318 	.num_phys = ARRAY_SIZE(tegra124_phys),
319 };
320 
tegra_xusb_padctl_init(void)321 void tegra_xusb_padctl_init(void)
322 {
323 	ofnode nodes[1];
324 	int count = 0;
325 	int ret;
326 
327 	debug("%s: start\n", __func__);
328 	if (of_live_active()) {
329 		struct device_node *np = of_find_compatible_node(NULL, NULL,
330 						"nvidia,tegra124-xusb-padctl");
331 
332 		debug("np=%p\n", np);
333 		if (np) {
334 			nodes[0] = np_to_ofnode(np);
335 			count = 1;
336 		}
337 	} else {
338 		int node_offsets[1];
339 		int i;
340 
341 		count = fdtdec_find_aliases_for_id(gd->fdt_blob, "padctl",
342 				COMPAT_NVIDIA_TEGRA124_XUSB_PADCTL,
343 				node_offsets, ARRAY_SIZE(node_offsets));
344 		for (i = 0; i < count; i++)
345 			nodes[i] = offset_to_ofnode(node_offsets[i]);
346 	}
347 
348 	ret = tegra_xusb_process_nodes(nodes, count, &tegra124_socdata);
349 	debug("%s: done, ret=%d\n", __func__, ret);
350 }
351