1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
|
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2019 Stefan Roese <sr@denx.de>
*
* Derived from linux/drivers/phy/ralink/phy-ralink-usb.c
* Copyright (C) 2017 John Crispin <john@phrozen.org>
*/
#include <common.h>
#include <dm.h>
#include <generic-phy.h>
#include <regmap.h>
#include <reset-uclass.h>
#include <syscon.h>
#include <asm/io.h>
#define RT_SYSC_REG_SYSCFG1 0x014
#define RT_SYSC_REG_CLKCFG1 0x030
#define RT_SYSC_REG_USB_PHY_CFG 0x05c
#define OFS_U2_PHY_AC0 0x800
#define OFS_U2_PHY_AC1 0x804
#define OFS_U2_PHY_AC2 0x808
#define OFS_U2_PHY_ACR0 0x810
#define OFS_U2_PHY_ACR1 0x814
#define OFS_U2_PHY_ACR2 0x818
#define OFS_U2_PHY_ACR3 0x81C
#define OFS_U2_PHY_ACR4 0x820
#define OFS_U2_PHY_AMON0 0x824
#define OFS_U2_PHY_DCR0 0x860
#define OFS_U2_PHY_DCR1 0x864
#define OFS_U2_PHY_DTM0 0x868
#define OFS_U2_PHY_DTM1 0x86C
#define RT_RSTCTRL_UDEV BIT(25)
#define RT_RSTCTRL_UHST BIT(22)
#define RT_SYSCFG1_USB0_HOST_MODE BIT(10)
#define MT7620_CLKCFG1_UPHY0_CLK_EN BIT(25)
#define MT7620_CLKCFG1_UPHY1_CLK_EN BIT(22)
#define RT_CLKCFG1_UPHY1_CLK_EN BIT(20)
#define RT_CLKCFG1_UPHY0_CLK_EN BIT(18)
#define USB_PHY_UTMI_8B60M BIT(1)
#define UDEV_WAKEUP BIT(0)
struct mt76x8_usb_phy {
u32 clk;
void __iomem *base;
struct regmap *sysctl;
};
static void u2_phy_w32(struct mt76x8_usb_phy *phy, u32 val, u32 reg)
{
writel(val, phy->base + reg);
}
static u32 u2_phy_r32(struct mt76x8_usb_phy *phy, u32 reg)
{
return readl(phy->base + reg);
}
static void mt76x8_usb_phy_init(struct mt76x8_usb_phy *phy)
{
u2_phy_r32(phy, OFS_U2_PHY_AC2);
u2_phy_r32(phy, OFS_U2_PHY_ACR0);
u2_phy_r32(phy, OFS_U2_PHY_DCR0);
u2_phy_w32(phy, 0x00ffff02, OFS_U2_PHY_DCR0);
u2_phy_r32(phy, OFS_U2_PHY_DCR0);
u2_phy_w32(phy, 0x00555502, OFS_U2_PHY_DCR0);
u2_phy_r32(phy, OFS_U2_PHY_DCR0);
u2_phy_w32(phy, 0x00aaaa02, OFS_U2_PHY_DCR0);
u2_phy_r32(phy, OFS_U2_PHY_DCR0);
u2_phy_w32(phy, 0x00000402, OFS_U2_PHY_DCR0);
u2_phy_r32(phy, OFS_U2_PHY_DCR0);
u2_phy_w32(phy, 0x0048086a, OFS_U2_PHY_AC0);
u2_phy_w32(phy, 0x4400001c, OFS_U2_PHY_AC1);
u2_phy_w32(phy, 0xc0200000, OFS_U2_PHY_ACR3);
u2_phy_w32(phy, 0x02000000, OFS_U2_PHY_DTM0);
}
static int mt76x8_usb_phy_power_on(struct phy *_phy)
{
struct mt76x8_usb_phy *phy = dev_get_priv(_phy->dev);
u32 t;
/* enable the phy */
regmap_update_bits(phy->sysctl, RT_SYSC_REG_CLKCFG1,
phy->clk, phy->clk);
/* setup host mode */
regmap_update_bits(phy->sysctl, RT_SYSC_REG_SYSCFG1,
RT_SYSCFG1_USB0_HOST_MODE,
RT_SYSCFG1_USB0_HOST_MODE);
/*
* The SDK kernel had a delay of 100ms. however on device
* testing showed that 10ms is enough
*/
mdelay(10);
if (phy->base)
mt76x8_usb_phy_init(phy);
/* print some status info */
regmap_read(phy->sysctl, RT_SYSC_REG_USB_PHY_CFG, &t);
printf("remote usb device wakeup %s\n",
(t & UDEV_WAKEUP) ? "enabled" : "disabled");
if (t & USB_PHY_UTMI_8B60M)
printf("UTMI 8bit 60MHz\n");
else
printf("UTMI 16bit 30MHz\n");
return 0;
}
static int mt76x8_usb_phy_power_off(struct phy *_phy)
{
struct mt76x8_usb_phy *phy = dev_get_priv(_phy->dev);
/* disable the phy */
regmap_update_bits(phy->sysctl, RT_SYSC_REG_CLKCFG1,
phy->clk, 0);
return 0;
}
static int mt76x8_usb_phy_probe(struct udevice *dev)
{
struct mt76x8_usb_phy *phy = dev_get_priv(dev);
phy->sysctl = syscon_regmap_lookup_by_phandle(dev, "ralink,sysctl");
if (IS_ERR(phy->sysctl))
return PTR_ERR(phy->sysctl);
phy->base = dev_read_addr_ptr(dev);
if (!phy->base)
return -EINVAL;
return 0;
}
static struct phy_ops mt76x8_usb_phy_ops = {
.power_on = mt76x8_usb_phy_power_on,
.power_off = mt76x8_usb_phy_power_off,
};
static const struct udevice_id mt76x8_usb_phy_ids[] = {
{ .compatible = "mediatek,mt7628-usbphy" },
{ }
};
U_BOOT_DRIVER(mt76x8_usb_phy) = {
.name = "mt76x8_usb_phy",
.id = UCLASS_PHY,
.of_match = mt76x8_usb_phy_ids,
.ops = &mt76x8_usb_phy_ops,
.probe = mt76x8_usb_phy_probe,
.priv_auto_alloc_size = sizeof(struct mt76x8_usb_phy),
};
|