Commit 4cce51141f2d65e3a76b618159cc96dda099810e
Committed by
Daniel Schwierzeck
1 parent
6658ebc96a
Exists in
smarc_8mq_lf_v2020.04
and in
9 other branches
phy: mt76x8-usb-phy: add slew rate calibration and remove non-mt7628 part
This patch adds slew rate calibration for mt76x8-usb-phy, removes code which belongs to mt7620, and gets rid of using syscon and regmap by using clock driver and reset controller. Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
Showing 2 changed files with 158 additions and 68 deletions Side-by-side Diff
drivers/phy/Kconfig
drivers/phy/mt76x8-usb-phy.c
... | ... | @@ -6,93 +6,185 @@ |
6 | 6 | * Copyright (C) 2017 John Crispin <john@phrozen.org> |
7 | 7 | */ |
8 | 8 | |
9 | +#include <clk.h> | |
9 | 10 | #include <common.h> |
10 | 11 | #include <dm.h> |
11 | 12 | #include <generic-phy.h> |
12 | -#include <regmap.h> | |
13 | -#include <reset-uclass.h> | |
14 | -#include <syscon.h> | |
13 | +#include <reset.h> | |
15 | 14 | #include <asm/io.h> |
15 | +#include <linux/bitops.h> | |
16 | 16 | |
17 | -#define RT_SYSC_REG_SYSCFG1 0x014 | |
18 | -#define RT_SYSC_REG_CLKCFG1 0x030 | |
19 | -#define RT_SYSC_REG_USB_PHY_CFG 0x05c | |
20 | - | |
21 | 17 | #define OFS_U2_PHY_AC0 0x800 |
18 | +#define USBPLL_FBDIV_S 16 | |
19 | +#define USBPLL_FBDIV_M GENMASK(22, 16) | |
20 | +#define BG_TRIM_S 8 | |
21 | +#define BG_TRIM_M GENMASK(11, 8) | |
22 | +#define BG_RBSEL_S 6 | |
23 | +#define BG_RBSEL_M GENMASK(7, 6) | |
24 | +#define BG_RASEL_S 4 | |
25 | +#define BG_RASEL_M GENMASK(5, 4) | |
26 | +#define BGR_DIV_S 2 | |
27 | +#define BGR_DIV_M GENMASK(3, 2) | |
28 | +#define CHP_EN BIT(1) | |
29 | + | |
22 | 30 | #define OFS_U2_PHY_AC1 0x804 |
31 | +#define VRT_VREF_SEL_S 28 | |
32 | +#define VRT_VREF_SEL_M GENMASK(30, 28) | |
33 | +#define TERM_VREF_SEL_S 24 | |
34 | +#define TERM_VREF_SEL_M GENMASK(26, 24) | |
35 | +#define USBPLL_RSVD BIT(4) | |
36 | +#define USBPLL_ACCEN BIT(3) | |
37 | +#define USBPLL_LF BIT(2) | |
38 | + | |
23 | 39 | #define OFS_U2_PHY_AC2 0x808 |
40 | + | |
24 | 41 | #define OFS_U2_PHY_ACR0 0x810 |
25 | -#define OFS_U2_PHY_ACR1 0x814 | |
26 | -#define OFS_U2_PHY_ACR2 0x818 | |
42 | +#define HSTX_SRCAL_EN BIT(23) | |
43 | +#define HSTX_SRCTRL_S 16 | |
44 | +#define HSTX_SRCTRL_M GENMASK(18, 16) | |
45 | + | |
27 | 46 | #define OFS_U2_PHY_ACR3 0x81C |
28 | -#define OFS_U2_PHY_ACR4 0x820 | |
29 | -#define OFS_U2_PHY_AMON0 0x824 | |
47 | +#define HSTX_DBIST_S 28 | |
48 | +#define HSTX_DBIST_M GENMASK(31, 28) | |
49 | +#define HSRX_BIAS_EN_SEL_S 20 | |
50 | +#define HSRX_BIAS_EN_SEL_M GENMASK(21, 20) | |
51 | + | |
30 | 52 | #define OFS_U2_PHY_DCR0 0x860 |
31 | -#define OFS_U2_PHY_DCR1 0x864 | |
53 | +#define PHYD_RESERVE_S 8 | |
54 | +#define PHYD_RESERVE_M GENMASK(23, 8) | |
55 | +#define CDR_FILT_S 0 | |
56 | +#define CDR_FILT_M GENMASK(3, 0) | |
57 | + | |
32 | 58 | #define OFS_U2_PHY_DTM0 0x868 |
33 | -#define OFS_U2_PHY_DTM1 0x86C | |
59 | +#define FORCE_USB_CLKEN BIT(25) | |
34 | 60 | |
35 | -#define RT_RSTCTRL_UDEV BIT(25) | |
36 | -#define RT_RSTCTRL_UHST BIT(22) | |
37 | -#define RT_SYSCFG1_USB0_HOST_MODE BIT(10) | |
61 | +#define OFS_FM_CR0 0xf00 | |
62 | +#define FREQDET_EN BIT(24) | |
63 | +#define CYCLECNT_S 0 | |
64 | +#define CYCLECNT_M GENMASK(23, 0) | |
38 | 65 | |
39 | -#define MT7620_CLKCFG1_UPHY0_CLK_EN BIT(25) | |
40 | -#define MT7620_CLKCFG1_UPHY1_CLK_EN BIT(22) | |
41 | -#define RT_CLKCFG1_UPHY1_CLK_EN BIT(20) | |
42 | -#define RT_CLKCFG1_UPHY0_CLK_EN BIT(18) | |
66 | +#define OFS_FM_MONR0 0xf0c | |
43 | 67 | |
44 | -#define USB_PHY_UTMI_8B60M BIT(1) | |
45 | -#define UDEV_WAKEUP BIT(0) | |
68 | +#define OFS_FM_MONR1 0xf10 | |
69 | +#define FRCK_EN BIT(8) | |
46 | 70 | |
71 | +#define U2_SR_COEF_7628 32 | |
72 | + | |
47 | 73 | struct mt76x8_usb_phy { |
48 | - u32 clk; | |
49 | 74 | void __iomem *base; |
50 | - struct regmap *sysctl; | |
75 | + struct clk cg; /* for clock gating */ | |
76 | + struct reset_ctl rst_phy; | |
51 | 77 | }; |
52 | 78 | |
53 | -static void u2_phy_w32(struct mt76x8_usb_phy *phy, u32 val, u32 reg) | |
79 | +static void phy_w32(struct mt76x8_usb_phy *phy, u32 reg, u32 val) | |
54 | 80 | { |
55 | 81 | writel(val, phy->base + reg); |
56 | 82 | } |
57 | 83 | |
58 | -static u32 u2_phy_r32(struct mt76x8_usb_phy *phy, u32 reg) | |
84 | +static u32 phy_r32(struct mt76x8_usb_phy *phy, u32 reg) | |
59 | 85 | { |
60 | 86 | return readl(phy->base + reg); |
61 | 87 | } |
62 | 88 | |
89 | +static void phy_rmw32(struct mt76x8_usb_phy *phy, u32 reg, u32 clr, u32 set) | |
90 | +{ | |
91 | + clrsetbits_32(phy->base + reg, clr, set); | |
92 | +} | |
93 | + | |
63 | 94 | static void mt76x8_usb_phy_init(struct mt76x8_usb_phy *phy) |
64 | 95 | { |
65 | - u2_phy_r32(phy, OFS_U2_PHY_AC2); | |
66 | - u2_phy_r32(phy, OFS_U2_PHY_ACR0); | |
67 | - u2_phy_r32(phy, OFS_U2_PHY_DCR0); | |
96 | + phy_r32(phy, OFS_U2_PHY_AC2); | |
97 | + phy_r32(phy, OFS_U2_PHY_ACR0); | |
98 | + phy_r32(phy, OFS_U2_PHY_DCR0); | |
68 | 99 | |
69 | - u2_phy_w32(phy, 0x00ffff02, OFS_U2_PHY_DCR0); | |
70 | - u2_phy_r32(phy, OFS_U2_PHY_DCR0); | |
71 | - u2_phy_w32(phy, 0x00555502, OFS_U2_PHY_DCR0); | |
72 | - u2_phy_r32(phy, OFS_U2_PHY_DCR0); | |
73 | - u2_phy_w32(phy, 0x00aaaa02, OFS_U2_PHY_DCR0); | |
74 | - u2_phy_r32(phy, OFS_U2_PHY_DCR0); | |
75 | - u2_phy_w32(phy, 0x00000402, OFS_U2_PHY_DCR0); | |
76 | - u2_phy_r32(phy, OFS_U2_PHY_DCR0); | |
77 | - u2_phy_w32(phy, 0x0048086a, OFS_U2_PHY_AC0); | |
78 | - u2_phy_w32(phy, 0x4400001c, OFS_U2_PHY_AC1); | |
79 | - u2_phy_w32(phy, 0xc0200000, OFS_U2_PHY_ACR3); | |
80 | - u2_phy_w32(phy, 0x02000000, OFS_U2_PHY_DTM0); | |
100 | + phy_w32(phy, OFS_U2_PHY_DCR0, | |
101 | + (0xffff << PHYD_RESERVE_S) | (2 << CDR_FILT_S)); | |
102 | + phy_r32(phy, OFS_U2_PHY_DCR0); | |
103 | + | |
104 | + phy_w32(phy, OFS_U2_PHY_DCR0, | |
105 | + (0x5555 << PHYD_RESERVE_S) | (2 << CDR_FILT_S)); | |
106 | + phy_r32(phy, OFS_U2_PHY_DCR0); | |
107 | + | |
108 | + phy_w32(phy, OFS_U2_PHY_DCR0, | |
109 | + (0xaaaa << PHYD_RESERVE_S) | (2 << CDR_FILT_S)); | |
110 | + phy_r32(phy, OFS_U2_PHY_DCR0); | |
111 | + | |
112 | + phy_w32(phy, OFS_U2_PHY_DCR0, | |
113 | + (4 << PHYD_RESERVE_S) | (2 << CDR_FILT_S)); | |
114 | + phy_r32(phy, OFS_U2_PHY_DCR0); | |
115 | + | |
116 | + phy_w32(phy, OFS_U2_PHY_AC0, | |
117 | + (0x48 << USBPLL_FBDIV_S) | (8 << BG_TRIM_S) | | |
118 | + (1 << BG_RBSEL_S) | (2 << BG_RASEL_S) | (2 << BGR_DIV_S) | | |
119 | + CHP_EN); | |
120 | + | |
121 | + phy_w32(phy, OFS_U2_PHY_AC1, | |
122 | + (4 << VRT_VREF_SEL_S) | (4 << TERM_VREF_SEL_S) | USBPLL_RSVD | | |
123 | + USBPLL_ACCEN | USBPLL_LF); | |
124 | + | |
125 | + phy_w32(phy, OFS_U2_PHY_ACR3, | |
126 | + (12 << HSTX_DBIST_S) | (2 << HSRX_BIAS_EN_SEL_S)); | |
127 | + | |
128 | + phy_w32(phy, OFS_U2_PHY_DTM0, FORCE_USB_CLKEN); | |
81 | 129 | } |
82 | 130 | |
131 | +static void mt76x8_usb_phy_sr_calibrate(struct mt76x8_usb_phy *phy) | |
132 | +{ | |
133 | + u32 fmout, tmp = 4; | |
134 | + int i; | |
135 | + | |
136 | + /* Enable HS TX SR calibration */ | |
137 | + phy_rmw32(phy, OFS_U2_PHY_ACR0, 0, HSTX_SRCAL_EN); | |
138 | + mdelay(1); | |
139 | + | |
140 | + /* Enable free run clock */ | |
141 | + phy_rmw32(phy, OFS_FM_MONR1, 0, FRCK_EN); | |
142 | + | |
143 | + /* Set cycle count = 0x400 */ | |
144 | + phy_rmw32(phy, OFS_FM_CR0, CYCLECNT_M, 0x400 << CYCLECNT_S); | |
145 | + | |
146 | + /* Enable frequency meter */ | |
147 | + phy_rmw32(phy, OFS_FM_CR0, 0, FREQDET_EN); | |
148 | + | |
149 | + /* Wait for FM detection done, set timeout to 10ms */ | |
150 | + for (i = 0; i < 10; i++) { | |
151 | + fmout = phy_r32(phy, OFS_FM_MONR0); | |
152 | + | |
153 | + if (fmout) | |
154 | + break; | |
155 | + | |
156 | + mdelay(1); | |
157 | + } | |
158 | + | |
159 | + /* Disable frequency meter */ | |
160 | + phy_rmw32(phy, OFS_FM_CR0, FREQDET_EN, 0); | |
161 | + | |
162 | + /* Disable free run clock */ | |
163 | + phy_rmw32(phy, OFS_FM_MONR1, FRCK_EN, 0); | |
164 | + | |
165 | + /* Disable HS TX SR calibration */ | |
166 | + phy_rmw32(phy, OFS_U2_PHY_ACR0, HSTX_SRCAL_EN, 0); | |
167 | + mdelay(1); | |
168 | + | |
169 | + if (fmout) { | |
170 | + /* | |
171 | + * set reg = (1024 / FM_OUT) * 25 * 0.028 | |
172 | + * (round to the nearest digits) | |
173 | + */ | |
174 | + tmp = (((1024 * 25 * U2_SR_COEF_7628) / fmout) + 500) / 1000; | |
175 | + } | |
176 | + | |
177 | + phy_rmw32(phy, OFS_U2_PHY_ACR0, HSTX_SRCTRL_M, | |
178 | + (tmp << HSTX_SRCTRL_S) & HSTX_SRCTRL_M); | |
179 | +} | |
180 | + | |
83 | 181 | static int mt76x8_usb_phy_power_on(struct phy *_phy) |
84 | 182 | { |
85 | 183 | struct mt76x8_usb_phy *phy = dev_get_priv(_phy->dev); |
86 | - u32 t; | |
87 | 184 | |
88 | - /* enable the phy */ | |
89 | - regmap_update_bits(phy->sysctl, RT_SYSC_REG_CLKCFG1, | |
90 | - phy->clk, phy->clk); | |
185 | + clk_enable(&phy->cg); | |
91 | 186 | |
92 | - /* setup host mode */ | |
93 | - regmap_update_bits(phy->sysctl, RT_SYSC_REG_SYSCFG1, | |
94 | - RT_SYSCFG1_USB0_HOST_MODE, | |
95 | - RT_SYSCFG1_USB0_HOST_MODE); | |
187 | + reset_deassert(&phy->rst_phy); | |
96 | 188 | |
97 | 189 | /* |
98 | 190 | * The SDK kernel had a delay of 100ms. however on device |
99 | 191 | |
... | ... | @@ -100,18 +192,9 @@ |
100 | 192 | */ |
101 | 193 | mdelay(10); |
102 | 194 | |
103 | - if (phy->base) | |
104 | - mt76x8_usb_phy_init(phy); | |
195 | + mt76x8_usb_phy_init(phy); | |
196 | + mt76x8_usb_phy_sr_calibrate(phy); | |
105 | 197 | |
106 | - /* print some status info */ | |
107 | - regmap_read(phy->sysctl, RT_SYSC_REG_USB_PHY_CFG, &t); | |
108 | - printf("remote usb device wakeup %s\n", | |
109 | - (t & UDEV_WAKEUP) ? "enabled" : "disabled"); | |
110 | - if (t & USB_PHY_UTMI_8B60M) | |
111 | - printf("UTMI 8bit 60MHz\n"); | |
112 | - else | |
113 | - printf("UTMI 16bit 30MHz\n"); | |
114 | - | |
115 | 198 | return 0; |
116 | 199 | } |
117 | 200 | |
118 | 201 | |
119 | 202 | |
120 | 203 | |
121 | 204 | |
... | ... | @@ -119,24 +202,30 @@ |
119 | 202 | { |
120 | 203 | struct mt76x8_usb_phy *phy = dev_get_priv(_phy->dev); |
121 | 204 | |
122 | - /* disable the phy */ | |
123 | - regmap_update_bits(phy->sysctl, RT_SYSC_REG_CLKCFG1, | |
124 | - phy->clk, 0); | |
205 | + clk_disable(&phy->cg); | |
125 | 206 | |
207 | + reset_assert(&phy->rst_phy); | |
208 | + | |
126 | 209 | return 0; |
127 | 210 | } |
128 | 211 | |
129 | 212 | static int mt76x8_usb_phy_probe(struct udevice *dev) |
130 | 213 | { |
131 | 214 | struct mt76x8_usb_phy *phy = dev_get_priv(dev); |
215 | + int ret; | |
132 | 216 | |
133 | - phy->sysctl = syscon_regmap_lookup_by_phandle(dev, "ralink,sysctl"); | |
134 | - if (IS_ERR(phy->sysctl)) | |
135 | - return PTR_ERR(phy->sysctl); | |
136 | - | |
137 | 217 | phy->base = dev_read_addr_ptr(dev); |
138 | 218 | if (!phy->base) |
139 | 219 | return -EINVAL; |
220 | + | |
221 | + /* clock gate */ | |
222 | + ret = clk_get_by_name(dev, "cg", &phy->cg); | |
223 | + if (ret) | |
224 | + return ret; | |
225 | + | |
226 | + ret = reset_get_by_name(dev, "phy", &phy->rst_phy); | |
227 | + if (ret) | |
228 | + return ret; | |
140 | 229 | |
141 | 230 | return 0; |
142 | 231 | } |