blob: 0905da42033b5cbba36a3bd0a2db78406e51d848 [file] [log] [blame]
Googler25e92cf2023-12-13 10:05:01 +00001// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
2/*
3 * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
4 */
5
6#include <common.h>
7#include <asm/io.h>
8#include <bitfield.h>
9#include <dm.h>
10#include <errno.h>
11#include <generic-phy.h>
12#include <regmap.h>
13#include <power/regulator.h>
14#include <clk.h>
15#include <asm/arch/usb.h>
16#include <amlogic/cpu_id.h>
17
18#include <linux/compat.h>
19#include <linux/ioport.h>
20#include <asm-generic/gpio.h>
21
22#define PHY20_RESET_LEVEL_BIT 8
23#define PHY21_RESET_LEVEL_BIT 9
24#define USB_RESET_BIT 4
25
26#define USB2_PHY_PLL_OFFSET_40 (0x09400414)
27#define USB2_PHY_PLL_OFFSET_44 (0x927E0000)
28#define USB2_PHY_PLL_OFFSET_48 (0xac5f69e5)
29
30#define USB2_PHY_PLL_OFFSET_10 (0x80000fff)
31#define USB2_PHY_PLL_OFFSET_34 (0x78000)
32#define USB2_REVB_PHY_PLL_OFFSET_34 (0x70000)
33
34#define USB2_PHY_PLL_OFFSET_38_CLEAR (0)
35#define USB2_PHY_PLL_OFFSET_38_SET (0xe0004)
36#define USB2_PHY_PLL_OFFSET_50 (0xfe18)
37#define USB2_PHY_PLL_OFFSET_54 (0x2a)
38
39#define TUNING_DISCONNECT_THRESHOLD 0x3C
40
41#define PHY_21_BASE 0xfe03e000
42#define PHY_20_BASE 0xfe03c000
43#define PHY_COMP_BASE 0xfe03a000
44#define RESET_BASE 0xFE002000
45
46static int Rev_flag = 0;
47
48static struct phy usb_phys[4];
49
50/*Rev_flag == 0XB, g12b and revB, tl1 */
51/*Rev_flag == 1, sm1 */
52static void phy_aml_usb2_check_rev (void)
53{
54 cpu_id_t cpu_id = get_cpu_id();
55
56 if (cpu_id.family_id == MESON_CPU_MAJOR_ID_G12B) {
57 if (cpu_id.chip_rev == 0xb)
58 Rev_flag = 0xb;
59 else
60 Rev_flag = 0;
61 } else if (cpu_id.family_id == MESON_CPU_MAJOR_ID_SM1) {
62 Rev_flag = MESON_CPU_MAJOR_ID_SM1;
63 } else if (cpu_id.family_id == MESON_CPU_MAJOR_ID_A1) {
64 Rev_flag = MESON_CPU_MAJOR_ID_A1;
65 } else if (cpu_id.family_id == MESON_CPU_MAJOR_ID_C1) {
66 Rev_flag = MESON_CPU_MAJOR_ID_C1;
67 } else if (cpu_id.family_id == MESON_CPU_MAJOR_ID_SC2) {
68 Rev_flag = MESON_CPU_MAJOR_ID_SC2;
69 } else if (cpu_id.family_id == MESON_CPU_MAJOR_ID_T7) {
70 Rev_flag = MESON_CPU_MAJOR_ID_T7;
71 }
72
73 return;
74}
75
76static int phy_aml_usb2_get_rev_type (void)
77{
78 int val = 0;
79
80 switch (Rev_flag) {
81 case MESON_CPU_MAJOR_ID_SM1:
82 case MESON_CPU_MAJOR_ID_A1:
83 case MESON_CPU_MAJOR_ID_C1:
84 case MESON_CPU_MAJOR_ID_SC2:
85 case MESON_CPU_MAJOR_ID_T7:
86 case 0xb:
87 val = 1;
88 break;
89 default:
90 printk("amlogic usb phy need tuning\n");
91 val = 0;
92 break;
93 }
94
95 return val;
96}
97
98int get_usbphy_baseinfo(struct phy *usb_phys)
99{
100 struct udevice *bus;
101 struct uclass *uc;
102 int ret, i;
103 int count;
104
105 if (usb_phys[0].dev && usb_phys[1].dev)
106 return 0;
107
108 ret = uclass_get(UCLASS_USB, &uc);
109 if (ret)
110 return ret;
111 uclass_foreach_dev(bus, uc) {
112 debug("bus->name=%s, bus->driver->name =%s\n",
113 bus->name, bus->driver->name);
114 count = dev_count_phandle_with_args(bus, "phys", "#phy-cells");
115 debug("usb phy count=%u\n", count);
116 if (count <= 0)
117 return count;
118 for (i = 0; i < count; i++) {
119 ret = generic_phy_get_by_index(bus, i, &usb_phys[i]);
120 if (ret && ret != -ENOENT) {
121 pr_err("Failed to get USB PHY%d for %s\n",
122 i, bus->name);
123 return ret;
124 }
125 ret = generic_phy_getinfo(&usb_phys[i]);
126 if (ret)
127 return ret;
128 }
129 }
130 return 0;
131}
132
133void usb_aml_detect_operation(int argc, char * const argv[])
134{
135 struct phy_aml_usb2_priv *usb2_priv;
136 struct phy_aml_usb3_priv *usb3_priv;
137 int ret;
138
139 ret = get_usbphy_baseinfo(usb_phys);
140 if (ret) {
141 printf("get usb dts failed\n");
142 return;
143 }
144 usb2_priv = dev_get_priv(usb_phys[0].dev);
145 usb3_priv = dev_get_priv(usb_phys[1].dev);
146
147 if (usb3_priv) {
148 printf("priv->usb3 port num = %d, config addr=0x%08x\n",
149 usb3_priv->usb3_port_num, usb3_priv->base_addr);
150 }
151 if (usb2_priv) {
152 printf("usb2 phy: config addr = 0x%08x, reset addr=0x%08x\n",
153 usb2_priv->base_addr, usb2_priv->reset_addr);
154
155 printf("usb2 phy: portnum=%d, phy-addr1= 0x%08x, phy-addr2= 0x%08x\n",
156 usb2_priv->u2_port_num, usb2_priv->usb_phy2_pll_base_addr[0],
157 usb2_priv->usb_phy2_pll_base_addr[1]);
158 printf("dwc2_a base addr: 0x%08x\n", usb2_priv->dwc2_a_addr);
159 }
160 phy_aml_usb2_check_rev();
161 printf("PHY version is 0x%02x\n", Rev_flag);
162}
163
164static void set_pll_Calibration_default(uint32_t phy2_pll_base)
165{
166 u32 tmp;
167
168 tmp = (*(volatile uint32_t *)(unsigned long)((unsigned long)phy2_pll_base + 0x8));
169 tmp &= 0xfff;
170 tmp |= (*(volatile uint32_t *)(unsigned long)((unsigned long)phy2_pll_base + 0x10));
171 (*(volatile uint32_t *)(unsigned long)((unsigned long)phy2_pll_base + 0x10))
172 = tmp;
173}
174
175void usb_reset(unsigned int reset_addr, int bit){
176 *(volatile unsigned int *)(unsigned long)reset_addr = (1 << bit);
177}
178
179static void usb_enable_phy_pll (u32 base_addr)
180{
181 if (base_addr == PHY_20_BASE) {
182 *(volatile uint32_t *)(unsigned long)
183 RESETCTRL_RESET0_LEVEL |= (1 << PHY20_RESET_LEVEL_BIT);
184 } else if (base_addr == PHY_21_BASE) {
185 *(volatile uint32_t *)(unsigned long)
186 RESETCTRL_RESET0_LEVEL |= (1 << PHY21_RESET_LEVEL_BIT);
187 }
188}
189
190void set_usb_pll(uint32_t phy2_pll_base)
191{
192 int hardware_rev;
193
194 (*(volatile uint32_t *)((unsigned long)phy2_pll_base + 0x40))
195 = (USB2_PHY_PLL_OFFSET_40 | USB_PHY2_RESET | USB_PHY2_ENABLE);
196 (*(volatile uint32_t *)((unsigned long)phy2_pll_base + 0x44)) =
197 USB2_PHY_PLL_OFFSET_44;
198 hardware_rev = phy_aml_usb2_get_rev_type();
199 (*(volatile uint32_t *)((unsigned long)phy2_pll_base + 0x48)) =
200 USB2_PHY_PLL_OFFSET_48;
201 udelay(100);
202 (*(volatile uint32_t *)(unsigned long)((unsigned long)phy2_pll_base + 0x40))
203 = (((USB2_PHY_PLL_OFFSET_40) | (USB_PHY2_ENABLE))
204 & (~(USB_PHY2_RESET)));
205
206 if (hardware_rev) {
207 (*(volatile uint32_t *)(unsigned long)((unsigned long)phy2_pll_base + 0x50))
208 = USB2_PHY_PLL_OFFSET_50;
209 (*(volatile uint32_t *)(unsigned long)((unsigned long)phy2_pll_base + 0x54))
210 = USB2_PHY_PLL_OFFSET_54;
211 set_pll_Calibration_default(phy2_pll_base);
212 } else {
213 (*(volatile uint32_t *)(unsigned long)((unsigned long)phy2_pll_base + 0x50))
214 = USB2_PHY_PLL_OFFSET_50;
215 (*(volatile uint32_t *)(unsigned long)((unsigned long)phy2_pll_base + 0x10))
216 = USB2_PHY_PLL_OFFSET_10;
217 (*(volatile uint32_t *)(unsigned long)((unsigned long)phy2_pll_base + 0x38))
218 = USB2_PHY_PLL_OFFSET_38_CLEAR;
219 }
220
221 (*(volatile uint32_t *)((unsigned long)phy2_pll_base + 0xc)) =
222 TUNING_DISCONNECT_THRESHOLD;
223 (*(volatile uint32_t *)(unsigned long)((unsigned long)phy2_pll_base + 0x34))
224 = USB2_PHY_PLL_OFFSET_34;
225 debug("tuning_disconnect_threshold=0x%x\n", TUNING_DISCONNECT_THRESHOLD);
226}
227
228int usb_save_phy_dev (unsigned int number, struct phy *phy)
229{
230 usb_phys[number].dev = phy->dev;
231 usb_phys[number].id = phy->id;
232 return 0;
233}
234
235void power_down_usb3(void)
236{
237 u32 val;
238#define USB_PHY30_BASE 0xFE062000
239
240 val = readl(USB_PHY30_BASE);
241 val &= (~(3 << 5));
242 val |= 0x1;
243 writel(val, USB_PHY30_BASE);
244 udelay(12);
245
246 val = readl(USB_PHY30_BASE + 0x18);
247 val &= (~(0x3 << 17));
248 val |= (0x1 << 17);
249 writel(val, USB_PHY30_BASE + 0x18);
250 udelay(12);
251}
252
253int usb2_phy_init (struct phy *phy) {
254 struct phy_aml_usb2_priv *priv = dev_get_priv(phy->dev);
255 struct u2p_aml_regs *u2p_aml_reg;
256 u2p_r0_t dev_u2p_r0;
257 u2p_r1_t dev_u2p_r1;
258 int i,cnt;
259
260 power_down_usb3();
261 usb_save_phy_dev(0, phy);
262 usb_enable_phy_pll(priv->base_addr);
263 //usb_set_power_domain();
264 phy_aml_usb2_check_rev();
265
266 if (priv->usb_phy2_pll_base_addr[0] == PHY_20_BASE) {
267 *(volatile unsigned int *)(unsigned long)priv->reset_addr = (1 << 6);
268
269 udelay(500);
270 priv->usbphy_reset_bit[0] = PHY20_RESET_LEVEL_BIT;
271 } else if (priv->usb_phy2_pll_base_addr[0] == PHY_21_BASE) {
272 *(volatile unsigned int *)(unsigned long)priv->reset_addr = (1 << 5);
273
274 udelay(500);
275 priv->usbphy_reset_bit[0] = PHY21_RESET_LEVEL_BIT;
276 }
277
278 for (i = 0; i < priv->u2_port_num; i++) {
279 u2p_aml_reg = (struct u2p_aml_regs *)((ulong)(priv->base_addr + i * PHY_REGISTER_SIZE));
280 dev_u2p_r0.d32 = u2p_aml_reg->u2p_r0;
281 dev_u2p_r0.b.host_device= 1;
282 dev_u2p_r0.b.POR= 0;
283 u2p_aml_reg->u2p_r0 = dev_u2p_r0.d32;
284 udelay(10);
285 *(volatile unsigned int *)(unsigned long)priv->reset_addr = (1 << priv->usbphy_reset_bit[i]);
286 udelay(50);
287
288 /* wait for phy ready */
289 dev_u2p_r1.d32 = u2p_aml_reg->u2p_r1;
290 cnt = 0;
291 while (dev_u2p_r1.b.phy_rdy != 1) {
292 dev_u2p_r1.d32 = u2p_aml_reg->u2p_r1;
293 /*we wait phy ready max 1ms, common is 100us*/
294 if (cnt > 200)
295 break;
296 else {
297 cnt++;
298 udelay(5);
299 }
300 }
301 }
302
303 for (i = 0; i < priv->u2_port_num; i++) {
304 debug("------set usb pll\n");
305 set_usb_pll(priv->usb_phy2_pll_base_addr[i]);
306 }
307 return 0;
308
309}
310
311int usb2_phy_tuning(uint32_t phy2_pll_base, int port)
312{
313 return 0;
314}
315
316/**************************************************************/
317/* device mode config */
318/**************************************************************/
319void usb_device_mode_init(int phy_num) {
320 u2p_r0_t dev_u2p_r0;
321 u2p_r1_t dev_u2p_r1;
322
323 usb_r0_t dev_usb_r0;
324 usb_r4_t dev_usb_r4;
325 int cnt;
326 u2p_aml_regs_t * u2p_aml_regs;
327 usb_aml_regs_t *usb_aml_regs;
328 unsigned int phy_base_addr, reset_addr;
329
330 phy_aml_usb2_check_rev();
331 if (phy_num == 1) {
332 u2p_aml_regs = (u2p_aml_regs_t * )((unsigned long)(PHY_COMP_BASE + PHY_REGISTER_SIZE));
333 usb_aml_regs = (usb_aml_regs_t * )((ulong)(PHY_COMP_BASE + 0x80));
334 phy_base_addr = PHY_21_BASE;
335 reset_addr = RESET_BASE;
336 } else {
337 u2p_aml_regs = (u2p_aml_regs_t * )((unsigned long)(PHY_COMP_BASE));
338 usb_aml_regs = (usb_aml_regs_t * )((ulong)(PHY_COMP_BASE + 0x80));
339 phy_base_addr = PHY_20_BASE;
340 reset_addr = RESET_BASE;
341 }
342
343 //printf("PHY2=0x%08x,PHY3=0x%08x\n", u2p_aml_regs, usb_aml_regs);
344 printf("PHY2=%p,PHY3=%p\n", u2p_aml_regs, usb_aml_regs);
345 //if ((*(volatile uint32_t *)(unsigned long)(phy_base_addr + 0x38)) != 0) {
346 //usb_phy_tuning_reset(phy_num);
347 //mdelay(150);
348 //}
349
350 //step 1: usb controller reset
351 usb_reset(reset_addr, USB_RESET_BIT);
352
353 // step 3: enable usb INT internal USB
354 dev_usb_r0.d32 = usb_aml_regs->usb_r0;
355 dev_usb_r0.b.u2d_ss_scaledown_mode = 0;
356 dev_usb_r0.b.u2d_act = 1;
357 usb_aml_regs->usb_r0 = dev_usb_r0.d32;
358
359 // step 4: disable usb phy sleep
360 dev_usb_r4.d32 = usb_aml_regs->usb_r4;
361 dev_usb_r4.b.p21_SLEEPM0 = 1;
362 usb_aml_regs->usb_r4 = dev_usb_r4.d32;
363
364 // step 5: config phy21 device mode
365 dev_u2p_r0.d32 = u2p_aml_regs->u2p_r0;
366 dev_u2p_r0.b.host_device= 0;
367 dev_u2p_r0.b.POR= 0;
368 u2p_aml_regs->u2p_r0 = dev_u2p_r0.d32;
369
370 udelay(10);
371 //step 6: phy21 reset
372 if (phy_num == 1) {
373 usb_reset(reset_addr, PHY21_RESET_LEVEL_BIT);
374 } else {
375 usb_reset(reset_addr, PHY20_RESET_LEVEL_BIT);
376 }
377 udelay(50);
378
379 // step 6: wait for phy ready
380 dev_u2p_r1.d32 = u2p_aml_regs->u2p_r1;
381 cnt = 0;
382 while ((dev_u2p_r1.d32 & 0x00000001) != 1) {
383 dev_u2p_r1.d32 = u2p_aml_regs->u2p_r1;
384 if (cnt > 200)
385 break;
386 else {
387 cnt++;
388 udelay(5);
389 }
390 }
391
392 //set_usb_phy21_pll();
393 set_usb_pll(phy_base_addr);
394 //--------------------------------------------------
395
396 // ------------- usb phy21 initinal end ----------
397
398 //--------------------------------------------------
399}