Commit 4cce51141f2d65e3a76b618159cc96dda099810e

Authored by Weijie Gao
Committed by Daniel Schwierzeck
1 parent 6658ebc96a

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

... ... @@ -200,6 +200,7 @@
200 200 config MT76X8_USB_PHY
201 201 bool "MediaTek MT76x8 (7628/88) USB PHY support"
202 202 depends on PHY
  203 + depends on SOC_MT7628
203 204 help
204 205 Support the USB PHY in MT76x8 SoCs
205 206  
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 }