.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
---|
1 | 2 | /* |
---|
2 | 3 | * phy-ti-pipe3 - PIPE3 PHY driver. |
---|
3 | 4 | * |
---|
4 | 5 | * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com |
---|
5 | | - * This program is free software; you can redistribute it and/or modify |
---|
6 | | - * it under the terms of the GNU General Public License as published by |
---|
7 | | - * the Free Software Foundation; either version 2 of the License, or |
---|
8 | | - * (at your option) any later version. |
---|
9 | | - * |
---|
10 | 6 | * Author: Kishon Vijay Abraham I <kishon@ti.com> |
---|
11 | | - * |
---|
12 | | - * This program is distributed in the hope that it will be useful, |
---|
13 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
14 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
15 | | - * GNU General Public License for more details. |
---|
16 | | - * |
---|
17 | 7 | */ |
---|
18 | 8 | |
---|
19 | 9 | #include <linux/module.h> |
---|
.. | .. |
---|
56 | 46 | |
---|
57 | 47 | #define SATA_PLL_SOFT_RESET BIT(18) |
---|
58 | 48 | |
---|
59 | | -#define PIPE3_PHY_PWRCTL_CLK_CMD_MASK 0x003FC000 |
---|
| 49 | +#define PIPE3_PHY_PWRCTL_CLK_CMD_MASK GENMASK(21, 14) |
---|
60 | 50 | #define PIPE3_PHY_PWRCTL_CLK_CMD_SHIFT 14 |
---|
61 | 51 | |
---|
62 | | -#define PIPE3_PHY_PWRCTL_CLK_FREQ_MASK 0xFFC00000 |
---|
| 52 | +#define PIPE3_PHY_PWRCTL_CLK_FREQ_MASK GENMASK(31, 22) |
---|
63 | 53 | #define PIPE3_PHY_PWRCTL_CLK_FREQ_SHIFT 22 |
---|
64 | 54 | |
---|
65 | | -#define PIPE3_PHY_TX_RX_POWERON 0x3 |
---|
66 | | -#define PIPE3_PHY_TX_RX_POWEROFF 0x0 |
---|
| 55 | +#define PIPE3_PHY_RX_POWERON (0x1 << PIPE3_PHY_PWRCTL_CLK_CMD_SHIFT) |
---|
| 56 | +#define PIPE3_PHY_TX_POWERON (0x2 << PIPE3_PHY_PWRCTL_CLK_CMD_SHIFT) |
---|
67 | 57 | |
---|
68 | 58 | #define PCIE_PCS_MASK 0xFF0000 |
---|
69 | 59 | #define PCIE_PCS_DELAY_COUNT_SHIFT 0x10 |
---|
70 | 60 | |
---|
71 | | -#define PCIEPHYRX_ANA_PROGRAMMABILITY 0x0000000C |
---|
| 61 | +#define PIPE3_PHY_RX_ANA_PROGRAMMABILITY 0x0000000C |
---|
72 | 62 | #define INTERFACE_MASK GENMASK(31, 27) |
---|
73 | 63 | #define INTERFACE_SHIFT 27 |
---|
| 64 | +#define INTERFACE_MODE_USBSS BIT(4) |
---|
| 65 | +#define INTERFACE_MODE_SATA_1P5 BIT(3) |
---|
| 66 | +#define INTERFACE_MODE_SATA_3P0 BIT(2) |
---|
| 67 | +#define INTERFACE_MODE_PCIE BIT(0) |
---|
| 68 | + |
---|
74 | 69 | #define LOSD_MASK GENMASK(17, 14) |
---|
75 | 70 | #define LOSD_SHIFT 14 |
---|
76 | 71 | #define MEM_PLLDIV GENMASK(6, 5) |
---|
77 | 72 | |
---|
78 | | -#define PCIEPHYRX_TRIM 0x0000001C |
---|
79 | | -#define MEM_DLL_TRIM_SEL GENMASK(31, 30) |
---|
| 73 | +#define PIPE3_PHY_RX_TRIM 0x0000001C |
---|
| 74 | +#define MEM_DLL_TRIM_SEL_MASK GENMASK(31, 30) |
---|
80 | 75 | #define MEM_DLL_TRIM_SHIFT 30 |
---|
81 | 76 | |
---|
82 | | -#define PCIEPHYRX_DLL 0x00000024 |
---|
83 | | -#define MEM_DLL_PHINT_RATE GENMASK(31, 30) |
---|
| 77 | +#define PIPE3_PHY_RX_DLL 0x00000024 |
---|
| 78 | +#define MEM_DLL_PHINT_RATE_MASK GENMASK(31, 30) |
---|
| 79 | +#define MEM_DLL_PHINT_RATE_SHIFT 30 |
---|
84 | 80 | |
---|
85 | | -#define PCIEPHYRX_DIGITAL_MODES 0x00000028 |
---|
| 81 | +#define PIPE3_PHY_RX_DIGITAL_MODES 0x00000028 |
---|
| 82 | +#define MEM_HS_RATE_MASK GENMASK(28, 27) |
---|
| 83 | +#define MEM_HS_RATE_SHIFT 27 |
---|
| 84 | +#define MEM_OVRD_HS_RATE BIT(26) |
---|
| 85 | +#define MEM_OVRD_HS_RATE_SHIFT 26 |
---|
86 | 86 | #define MEM_CDR_FASTLOCK BIT(23) |
---|
87 | | -#define MEM_CDR_LBW GENMASK(22, 21) |
---|
88 | | -#define MEM_CDR_STEPCNT GENMASK(20, 19) |
---|
| 87 | +#define MEM_CDR_FASTLOCK_SHIFT 23 |
---|
| 88 | +#define MEM_CDR_LBW_MASK GENMASK(22, 21) |
---|
| 89 | +#define MEM_CDR_LBW_SHIFT 21 |
---|
| 90 | +#define MEM_CDR_STEPCNT_MASK GENMASK(20, 19) |
---|
| 91 | +#define MEM_CDR_STEPCNT_SHIFT 19 |
---|
89 | 92 | #define MEM_CDR_STL_MASK GENMASK(18, 16) |
---|
90 | 93 | #define MEM_CDR_STL_SHIFT 16 |
---|
91 | 94 | #define MEM_CDR_THR_MASK GENMASK(15, 13) |
---|
92 | 95 | #define MEM_CDR_THR_SHIFT 13 |
---|
93 | 96 | #define MEM_CDR_THR_MODE BIT(12) |
---|
94 | | -#define MEM_CDR_CDR_2NDO_SDM_MODE BIT(11) |
---|
95 | | -#define MEM_OVRD_HS_RATE BIT(26) |
---|
| 97 | +#define MEM_CDR_THR_MODE_SHIFT 12 |
---|
| 98 | +#define MEM_CDR_2NDO_SDM_MODE BIT(11) |
---|
| 99 | +#define MEM_CDR_2NDO_SDM_MODE_SHIFT 11 |
---|
96 | 100 | |
---|
97 | | -#define PCIEPHYRX_EQUALIZER 0x00000038 |
---|
98 | | -#define MEM_EQLEV GENMASK(31, 16) |
---|
99 | | -#define MEM_EQFTC GENMASK(15, 11) |
---|
100 | | -#define MEM_EQCTL GENMASK(10, 7) |
---|
| 101 | +#define PIPE3_PHY_RX_EQUALIZER 0x00000038 |
---|
| 102 | +#define MEM_EQLEV_MASK GENMASK(31, 16) |
---|
| 103 | +#define MEM_EQLEV_SHIFT 16 |
---|
| 104 | +#define MEM_EQFTC_MASK GENMASK(15, 11) |
---|
| 105 | +#define MEM_EQFTC_SHIFT 11 |
---|
| 106 | +#define MEM_EQCTL_MASK GENMASK(10, 7) |
---|
101 | 107 | #define MEM_EQCTL_SHIFT 7 |
---|
102 | 108 | #define MEM_OVRD_EQLEV BIT(2) |
---|
| 109 | +#define MEM_OVRD_EQLEV_SHIFT 2 |
---|
103 | 110 | #define MEM_OVRD_EQFTC BIT(1) |
---|
| 111 | +#define MEM_OVRD_EQFTC_SHIFT 1 |
---|
| 112 | + |
---|
| 113 | +#define SATA_PHY_RX_IO_AND_A2D_OVERRIDES 0x44 |
---|
| 114 | +#define MEM_CDR_LOS_SOURCE_MASK GENMASK(10, 9) |
---|
| 115 | +#define MEM_CDR_LOS_SOURCE_SHIFT 9 |
---|
104 | 116 | |
---|
105 | 117 | /* |
---|
106 | 118 | * This is an Empirical value that works, need to confirm the actual |
---|
.. | .. |
---|
109 | 121 | */ |
---|
110 | 122 | #define PLL_IDLE_TIME 100 /* in milliseconds */ |
---|
111 | 123 | #define PLL_LOCK_TIME 100 /* in milliseconds */ |
---|
| 124 | + |
---|
| 125 | +enum pipe3_mode { PIPE3_MODE_PCIE = 1, |
---|
| 126 | + PIPE3_MODE_SATA, |
---|
| 127 | + PIPE3_MODE_USBSS }; |
---|
112 | 128 | |
---|
113 | 129 | struct pipe3_dpll_params { |
---|
114 | 130 | u16 m; |
---|
.. | .. |
---|
121 | 137 | struct pipe3_dpll_map { |
---|
122 | 138 | unsigned long rate; |
---|
123 | 139 | struct pipe3_dpll_params params; |
---|
| 140 | +}; |
---|
| 141 | + |
---|
| 142 | +struct pipe3_settings { |
---|
| 143 | + u8 ana_interface; |
---|
| 144 | + u8 ana_losd; |
---|
| 145 | + u8 dig_fastlock; |
---|
| 146 | + u8 dig_lbw; |
---|
| 147 | + u8 dig_stepcnt; |
---|
| 148 | + u8 dig_stl; |
---|
| 149 | + u8 dig_thr; |
---|
| 150 | + u8 dig_thr_mode; |
---|
| 151 | + u8 dig_2ndo_sdm_mode; |
---|
| 152 | + u8 dig_hs_rate; |
---|
| 153 | + u8 dig_ovrd_hs_rate; |
---|
| 154 | + u8 dll_trim_sel; |
---|
| 155 | + u8 dll_phint_rate; |
---|
| 156 | + u8 eq_lev; |
---|
| 157 | + u8 eq_ftc; |
---|
| 158 | + u8 eq_ctl; |
---|
| 159 | + u8 eq_ovrd_lev; |
---|
| 160 | + u8 eq_ovrd_ftc; |
---|
124 | 161 | }; |
---|
125 | 162 | |
---|
126 | 163 | struct ti_pipe3 { |
---|
.. | .. |
---|
141 | 178 | unsigned int power_reg; /* power reg. index within syscon */ |
---|
142 | 179 | unsigned int pcie_pcs_reg; /* pcs reg. index in syscon */ |
---|
143 | 180 | bool sata_refclk_enabled; |
---|
| 181 | + enum pipe3_mode mode; |
---|
| 182 | + struct pipe3_settings settings; |
---|
144 | 183 | }; |
---|
145 | 184 | |
---|
146 | 185 | static struct pipe3_dpll_map dpll_map_usb[] = { |
---|
.. | .. |
---|
161 | 200 | {26000000, {750, 12, 4, 6, 0} }, /* 26 MHz */ |
---|
162 | 201 | {38400000, {625, 15, 4, 6, 0} }, /* 38.4 MHz */ |
---|
163 | 202 | { }, /* Terminator */ |
---|
| 203 | +}; |
---|
| 204 | + |
---|
| 205 | +struct pipe3_data { |
---|
| 206 | + enum pipe3_mode mode; |
---|
| 207 | + struct pipe3_dpll_map *dpll_map; |
---|
| 208 | + struct pipe3_settings settings; |
---|
| 209 | +}; |
---|
| 210 | + |
---|
| 211 | +static struct pipe3_data data_usb = { |
---|
| 212 | + .mode = PIPE3_MODE_USBSS, |
---|
| 213 | + .dpll_map = dpll_map_usb, |
---|
| 214 | + .settings = { |
---|
| 215 | + /* DRA75x TRM Table 26-17 Preferred USB3_PHY_RX SCP Register Settings */ |
---|
| 216 | + .ana_interface = INTERFACE_MODE_USBSS, |
---|
| 217 | + .ana_losd = 0xa, |
---|
| 218 | + .dig_fastlock = 1, |
---|
| 219 | + .dig_lbw = 3, |
---|
| 220 | + .dig_stepcnt = 0, |
---|
| 221 | + .dig_stl = 0x3, |
---|
| 222 | + .dig_thr = 1, |
---|
| 223 | + .dig_thr_mode = 1, |
---|
| 224 | + .dig_2ndo_sdm_mode = 0, |
---|
| 225 | + .dig_hs_rate = 0, |
---|
| 226 | + .dig_ovrd_hs_rate = 1, |
---|
| 227 | + .dll_trim_sel = 0x2, |
---|
| 228 | + .dll_phint_rate = 0x3, |
---|
| 229 | + .eq_lev = 0, |
---|
| 230 | + .eq_ftc = 0, |
---|
| 231 | + .eq_ctl = 0x9, |
---|
| 232 | + .eq_ovrd_lev = 0, |
---|
| 233 | + .eq_ovrd_ftc = 0, |
---|
| 234 | + }, |
---|
| 235 | +}; |
---|
| 236 | + |
---|
| 237 | +static struct pipe3_data data_sata = { |
---|
| 238 | + .mode = PIPE3_MODE_SATA, |
---|
| 239 | + .dpll_map = dpll_map_sata, |
---|
| 240 | + .settings = { |
---|
| 241 | + /* DRA75x TRM Table 26-9 Preferred SATA_PHY_RX SCP Register Settings */ |
---|
| 242 | + .ana_interface = INTERFACE_MODE_SATA_3P0, |
---|
| 243 | + .ana_losd = 0x5, |
---|
| 244 | + .dig_fastlock = 1, |
---|
| 245 | + .dig_lbw = 3, |
---|
| 246 | + .dig_stepcnt = 0, |
---|
| 247 | + .dig_stl = 0x3, |
---|
| 248 | + .dig_thr = 1, |
---|
| 249 | + .dig_thr_mode = 1, |
---|
| 250 | + .dig_2ndo_sdm_mode = 0, |
---|
| 251 | + .dig_hs_rate = 0, /* Not in TRM preferred settings */ |
---|
| 252 | + .dig_ovrd_hs_rate = 0, /* Not in TRM preferred settings */ |
---|
| 253 | + .dll_trim_sel = 0x1, |
---|
| 254 | + .dll_phint_rate = 0x2, /* for 1.5 GHz DPLL clock */ |
---|
| 255 | + .eq_lev = 0, |
---|
| 256 | + .eq_ftc = 0x1f, |
---|
| 257 | + .eq_ctl = 0, |
---|
| 258 | + .eq_ovrd_lev = 1, |
---|
| 259 | + .eq_ovrd_ftc = 1, |
---|
| 260 | + }, |
---|
| 261 | +}; |
---|
| 262 | + |
---|
| 263 | +static struct pipe3_data data_pcie = { |
---|
| 264 | + .mode = PIPE3_MODE_PCIE, |
---|
| 265 | + .settings = { |
---|
| 266 | + /* DRA75x TRM Table 26-62 Preferred PCIe_PHY_RX SCP Register Settings */ |
---|
| 267 | + .ana_interface = INTERFACE_MODE_PCIE, |
---|
| 268 | + .ana_losd = 0xa, |
---|
| 269 | + .dig_fastlock = 1, |
---|
| 270 | + .dig_lbw = 3, |
---|
| 271 | + .dig_stepcnt = 0, |
---|
| 272 | + .dig_stl = 0x3, |
---|
| 273 | + .dig_thr = 1, |
---|
| 274 | + .dig_thr_mode = 1, |
---|
| 275 | + .dig_2ndo_sdm_mode = 0, |
---|
| 276 | + .dig_hs_rate = 0, |
---|
| 277 | + .dig_ovrd_hs_rate = 0, |
---|
| 278 | + .dll_trim_sel = 0x2, |
---|
| 279 | + .dll_phint_rate = 0x3, |
---|
| 280 | + .eq_lev = 0, |
---|
| 281 | + .eq_ftc = 0x1f, |
---|
| 282 | + .eq_ctl = 1, |
---|
| 283 | + .eq_ovrd_lev = 0, |
---|
| 284 | + .eq_ovrd_ftc = 0, |
---|
| 285 | + }, |
---|
164 | 286 | }; |
---|
165 | 287 | |
---|
166 | 288 | static inline u32 ti_pipe3_readl(void __iomem *addr, unsigned offset) |
---|
.. | .. |
---|
196 | 318 | |
---|
197 | 319 | static int ti_pipe3_power_off(struct phy *x) |
---|
198 | 320 | { |
---|
199 | | - u32 val; |
---|
200 | 321 | int ret; |
---|
201 | 322 | struct ti_pipe3 *phy = phy_get_drvdata(x); |
---|
202 | 323 | |
---|
.. | .. |
---|
205 | 326 | return 0; |
---|
206 | 327 | } |
---|
207 | 328 | |
---|
208 | | - val = PIPE3_PHY_TX_RX_POWEROFF << PIPE3_PHY_PWRCTL_CLK_CMD_SHIFT; |
---|
209 | | - |
---|
210 | 329 | ret = regmap_update_bits(phy->phy_power_syscon, phy->power_reg, |
---|
211 | | - PIPE3_PHY_PWRCTL_CLK_CMD_MASK, val); |
---|
| 330 | + PIPE3_PHY_PWRCTL_CLK_CMD_MASK, 0); |
---|
212 | 331 | return ret; |
---|
213 | 332 | } |
---|
| 333 | + |
---|
| 334 | +static void ti_pipe3_calibrate(struct ti_pipe3 *phy); |
---|
214 | 335 | |
---|
215 | 336 | static int ti_pipe3_power_on(struct phy *x) |
---|
216 | 337 | { |
---|
217 | 338 | u32 val; |
---|
218 | 339 | u32 mask; |
---|
219 | | - int ret; |
---|
220 | 340 | unsigned long rate; |
---|
221 | 341 | struct ti_pipe3 *phy = phy_get_drvdata(x); |
---|
| 342 | + bool rx_pending = false; |
---|
222 | 343 | |
---|
223 | 344 | if (!phy->phy_power_syscon) { |
---|
224 | 345 | omap_control_phy_power(phy->control_dev, 1); |
---|
.. | .. |
---|
231 | 352 | return -EINVAL; |
---|
232 | 353 | } |
---|
233 | 354 | rate = rate / 1000000; |
---|
234 | | - mask = OMAP_CTRL_PIPE3_PHY_PWRCTL_CLK_CMD_MASK | |
---|
235 | | - OMAP_CTRL_PIPE3_PHY_PWRCTL_CLK_FREQ_MASK; |
---|
236 | | - val = PIPE3_PHY_TX_RX_POWERON << PIPE3_PHY_PWRCTL_CLK_CMD_SHIFT; |
---|
237 | | - val |= rate << OMAP_CTRL_PIPE3_PHY_PWRCTL_CLK_FREQ_SHIFT; |
---|
| 355 | + mask = OMAP_CTRL_PIPE3_PHY_PWRCTL_CLK_FREQ_MASK; |
---|
| 356 | + val = rate << OMAP_CTRL_PIPE3_PHY_PWRCTL_CLK_FREQ_SHIFT; |
---|
| 357 | + regmap_update_bits(phy->phy_power_syscon, phy->power_reg, |
---|
| 358 | + mask, val); |
---|
| 359 | + /* |
---|
| 360 | + * For PCIe, TX and RX must be powered on simultaneously. |
---|
| 361 | + * For USB and SATA, TX must be powered on before RX |
---|
| 362 | + */ |
---|
| 363 | + mask = OMAP_CTRL_PIPE3_PHY_PWRCTL_CLK_CMD_MASK; |
---|
| 364 | + if (phy->mode == PIPE3_MODE_SATA || phy->mode == PIPE3_MODE_USBSS) { |
---|
| 365 | + val = PIPE3_PHY_TX_POWERON; |
---|
| 366 | + rx_pending = true; |
---|
| 367 | + } else { |
---|
| 368 | + val = PIPE3_PHY_TX_POWERON | PIPE3_PHY_RX_POWERON; |
---|
| 369 | + } |
---|
238 | 370 | |
---|
239 | | - ret = regmap_update_bits(phy->phy_power_syscon, phy->power_reg, |
---|
240 | | - mask, val); |
---|
241 | | - return ret; |
---|
| 371 | + regmap_update_bits(phy->phy_power_syscon, phy->power_reg, |
---|
| 372 | + mask, val); |
---|
| 373 | + |
---|
| 374 | + if (rx_pending) { |
---|
| 375 | + val = PIPE3_PHY_TX_POWERON | PIPE3_PHY_RX_POWERON; |
---|
| 376 | + regmap_update_bits(phy->phy_power_syscon, phy->power_reg, |
---|
| 377 | + mask, val); |
---|
| 378 | + } |
---|
| 379 | + |
---|
| 380 | + if (phy->mode == PIPE3_MODE_PCIE) |
---|
| 381 | + ti_pipe3_calibrate(phy); |
---|
| 382 | + |
---|
| 383 | + return 0; |
---|
242 | 384 | } |
---|
243 | 385 | |
---|
244 | 386 | static int ti_pipe3_dpll_wait_lock(struct ti_pipe3 *phy) |
---|
.. | .. |
---|
300 | 442 | static void ti_pipe3_calibrate(struct ti_pipe3 *phy) |
---|
301 | 443 | { |
---|
302 | 444 | u32 val; |
---|
| 445 | + struct pipe3_settings *s = &phy->settings; |
---|
303 | 446 | |
---|
304 | | - val = ti_pipe3_readl(phy->phy_rx, PCIEPHYRX_ANA_PROGRAMMABILITY); |
---|
| 447 | + val = ti_pipe3_readl(phy->phy_rx, PIPE3_PHY_RX_ANA_PROGRAMMABILITY); |
---|
305 | 448 | val &= ~(INTERFACE_MASK | LOSD_MASK | MEM_PLLDIV); |
---|
306 | | - val |= (0x1 << INTERFACE_SHIFT | 0xA << LOSD_SHIFT); |
---|
307 | | - ti_pipe3_writel(phy->phy_rx, PCIEPHYRX_ANA_PROGRAMMABILITY, val); |
---|
| 449 | + val |= (s->ana_interface << INTERFACE_SHIFT | s->ana_losd << LOSD_SHIFT); |
---|
| 450 | + ti_pipe3_writel(phy->phy_rx, PIPE3_PHY_RX_ANA_PROGRAMMABILITY, val); |
---|
308 | 451 | |
---|
309 | | - val = ti_pipe3_readl(phy->phy_rx, PCIEPHYRX_DIGITAL_MODES); |
---|
310 | | - val &= ~(MEM_CDR_STEPCNT | MEM_CDR_STL_MASK | MEM_CDR_THR_MASK | |
---|
311 | | - MEM_CDR_CDR_2NDO_SDM_MODE | MEM_OVRD_HS_RATE); |
---|
312 | | - val |= (MEM_CDR_FASTLOCK | MEM_CDR_LBW | 0x3 << MEM_CDR_STL_SHIFT | |
---|
313 | | - 0x1 << MEM_CDR_THR_SHIFT | MEM_CDR_THR_MODE); |
---|
314 | | - ti_pipe3_writel(phy->phy_rx, PCIEPHYRX_DIGITAL_MODES, val); |
---|
| 452 | + val = ti_pipe3_readl(phy->phy_rx, PIPE3_PHY_RX_DIGITAL_MODES); |
---|
| 453 | + val &= ~(MEM_HS_RATE_MASK | MEM_OVRD_HS_RATE | MEM_CDR_FASTLOCK | |
---|
| 454 | + MEM_CDR_LBW_MASK | MEM_CDR_STEPCNT_MASK | MEM_CDR_STL_MASK | |
---|
| 455 | + MEM_CDR_THR_MASK | MEM_CDR_THR_MODE | MEM_CDR_2NDO_SDM_MODE); |
---|
| 456 | + val |= s->dig_hs_rate << MEM_HS_RATE_SHIFT | |
---|
| 457 | + s->dig_ovrd_hs_rate << MEM_OVRD_HS_RATE_SHIFT | |
---|
| 458 | + s->dig_fastlock << MEM_CDR_FASTLOCK_SHIFT | |
---|
| 459 | + s->dig_lbw << MEM_CDR_LBW_SHIFT | |
---|
| 460 | + s->dig_stepcnt << MEM_CDR_STEPCNT_SHIFT | |
---|
| 461 | + s->dig_stl << MEM_CDR_STL_SHIFT | |
---|
| 462 | + s->dig_thr << MEM_CDR_THR_SHIFT | |
---|
| 463 | + s->dig_thr_mode << MEM_CDR_THR_MODE_SHIFT | |
---|
| 464 | + s->dig_2ndo_sdm_mode << MEM_CDR_2NDO_SDM_MODE_SHIFT; |
---|
| 465 | + ti_pipe3_writel(phy->phy_rx, PIPE3_PHY_RX_DIGITAL_MODES, val); |
---|
315 | 466 | |
---|
316 | | - val = ti_pipe3_readl(phy->phy_rx, PCIEPHYRX_TRIM); |
---|
317 | | - val &= ~MEM_DLL_TRIM_SEL; |
---|
318 | | - val |= 0x2 << MEM_DLL_TRIM_SHIFT; |
---|
319 | | - ti_pipe3_writel(phy->phy_rx, PCIEPHYRX_TRIM, val); |
---|
| 467 | + val = ti_pipe3_readl(phy->phy_rx, PIPE3_PHY_RX_TRIM); |
---|
| 468 | + val &= ~MEM_DLL_TRIM_SEL_MASK; |
---|
| 469 | + val |= s->dll_trim_sel << MEM_DLL_TRIM_SHIFT; |
---|
| 470 | + ti_pipe3_writel(phy->phy_rx, PIPE3_PHY_RX_TRIM, val); |
---|
320 | 471 | |
---|
321 | | - val = ti_pipe3_readl(phy->phy_rx, PCIEPHYRX_DLL); |
---|
322 | | - val |= MEM_DLL_PHINT_RATE; |
---|
323 | | - ti_pipe3_writel(phy->phy_rx, PCIEPHYRX_DLL, val); |
---|
| 472 | + val = ti_pipe3_readl(phy->phy_rx, PIPE3_PHY_RX_DLL); |
---|
| 473 | + val &= ~MEM_DLL_PHINT_RATE_MASK; |
---|
| 474 | + val |= s->dll_phint_rate << MEM_DLL_PHINT_RATE_SHIFT; |
---|
| 475 | + ti_pipe3_writel(phy->phy_rx, PIPE3_PHY_RX_DLL, val); |
---|
324 | 476 | |
---|
325 | | - val = ti_pipe3_readl(phy->phy_rx, PCIEPHYRX_EQUALIZER); |
---|
326 | | - val &= ~(MEM_EQLEV | MEM_EQCTL | MEM_OVRD_EQLEV | MEM_OVRD_EQFTC); |
---|
327 | | - val |= MEM_EQFTC | 0x1 << MEM_EQCTL_SHIFT; |
---|
328 | | - ti_pipe3_writel(phy->phy_rx, PCIEPHYRX_EQUALIZER, val); |
---|
| 477 | + val = ti_pipe3_readl(phy->phy_rx, PIPE3_PHY_RX_EQUALIZER); |
---|
| 478 | + val &= ~(MEM_EQLEV_MASK | MEM_EQFTC_MASK | MEM_EQCTL_MASK | |
---|
| 479 | + MEM_OVRD_EQLEV | MEM_OVRD_EQFTC); |
---|
| 480 | + val |= s->eq_lev << MEM_EQLEV_SHIFT | |
---|
| 481 | + s->eq_ftc << MEM_EQFTC_SHIFT | |
---|
| 482 | + s->eq_ctl << MEM_EQCTL_SHIFT | |
---|
| 483 | + s->eq_ovrd_lev << MEM_OVRD_EQLEV_SHIFT | |
---|
| 484 | + s->eq_ovrd_ftc << MEM_OVRD_EQFTC_SHIFT; |
---|
| 485 | + ti_pipe3_writel(phy->phy_rx, PIPE3_PHY_RX_EQUALIZER, val); |
---|
| 486 | + |
---|
| 487 | + if (phy->mode == PIPE3_MODE_SATA) { |
---|
| 488 | + val = ti_pipe3_readl(phy->phy_rx, |
---|
| 489 | + SATA_PHY_RX_IO_AND_A2D_OVERRIDES); |
---|
| 490 | + val &= ~MEM_CDR_LOS_SOURCE_MASK; |
---|
| 491 | + ti_pipe3_writel(phy->phy_rx, SATA_PHY_RX_IO_AND_A2D_OVERRIDES, |
---|
| 492 | + val); |
---|
| 493 | + } |
---|
329 | 494 | } |
---|
330 | 495 | |
---|
331 | 496 | static int ti_pipe3_init(struct phy *x) |
---|
.. | .. |
---|
340 | 505 | * as recommended in AM572x TRM SPRUHZ6, section 18.5.2.2, table |
---|
341 | 506 | * 18-1804. |
---|
342 | 507 | */ |
---|
343 | | - if (of_device_is_compatible(phy->dev->of_node, "ti,phy-pipe3-pcie")) { |
---|
| 508 | + if (phy->mode == PIPE3_MODE_PCIE) { |
---|
344 | 509 | if (!phy->pcs_syscon) { |
---|
345 | 510 | omap_control_pcie_pcs(phy->control_dev, 0x96); |
---|
346 | 511 | return 0; |
---|
.. | .. |
---|
349 | 514 | val = 0x96 << OMAP_CTRL_PCIE_PCS_DELAY_COUNT_SHIFT; |
---|
350 | 515 | ret = regmap_update_bits(phy->pcs_syscon, phy->pcie_pcs_reg, |
---|
351 | 516 | PCIE_PCS_MASK, val); |
---|
352 | | - if (ret) |
---|
353 | | - return ret; |
---|
354 | | - |
---|
355 | | - ti_pipe3_calibrate(phy); |
---|
356 | | - |
---|
357 | | - return 0; |
---|
| 517 | + return ret; |
---|
358 | 518 | } |
---|
359 | 519 | |
---|
360 | 520 | /* Bring it out of IDLE if it is IDLE */ |
---|
.. | .. |
---|
367 | 527 | |
---|
368 | 528 | /* SATA has issues if re-programmed when locked */ |
---|
369 | 529 | val = ti_pipe3_readl(phy->pll_ctrl_base, PLL_STATUS); |
---|
370 | | - if ((val & PLL_LOCK) && of_device_is_compatible(phy->dev->of_node, |
---|
371 | | - "ti,phy-pipe3-sata")) |
---|
| 530 | + if ((val & PLL_LOCK) && phy->mode == PIPE3_MODE_SATA) |
---|
372 | 531 | return ret; |
---|
373 | 532 | |
---|
374 | 533 | /* Program the DPLL */ |
---|
.. | .. |
---|
377 | 536 | ti_pipe3_disable_clocks(phy); |
---|
378 | 537 | return -EINVAL; |
---|
379 | 538 | } |
---|
| 539 | + |
---|
| 540 | + ti_pipe3_calibrate(phy); |
---|
380 | 541 | |
---|
381 | 542 | return ret; |
---|
382 | 543 | } |
---|
.. | .. |
---|
390 | 551 | /* If dpll_reset_syscon is not present we wont power down SATA DPLL |
---|
391 | 552 | * due to Errata i783 |
---|
392 | 553 | */ |
---|
393 | | - if (of_device_is_compatible(phy->dev->of_node, "ti,phy-pipe3-sata") && |
---|
394 | | - !phy->dpll_reset_syscon) |
---|
| 554 | + if (phy->mode == PIPE3_MODE_SATA && !phy->dpll_reset_syscon) |
---|
395 | 555 | return 0; |
---|
396 | 556 | |
---|
397 | 557 | /* PCIe doesn't have internal DPLL */ |
---|
398 | | - if (!of_device_is_compatible(phy->dev->of_node, "ti,phy-pipe3-pcie")) { |
---|
| 558 | + if (phy->mode != PIPE3_MODE_PCIE) { |
---|
399 | 559 | /* Put DPLL in IDLE mode */ |
---|
400 | 560 | val = ti_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2); |
---|
401 | 561 | val |= PLL_IDLE; |
---|
.. | .. |
---|
418 | 578 | } |
---|
419 | 579 | |
---|
420 | 580 | /* i783: SATA needs control bit toggle after PLL unlock */ |
---|
421 | | - if (of_device_is_compatible(phy->dev->of_node, "ti,phy-pipe3-sata")) { |
---|
| 581 | + if (phy->mode == PIPE3_MODE_SATA) { |
---|
422 | 582 | regmap_update_bits(phy->dpll_reset_syscon, phy->dpll_reset_reg, |
---|
423 | 583 | SATA_PLL_SOFT_RESET, SATA_PLL_SOFT_RESET); |
---|
424 | 584 | regmap_update_bits(phy->dpll_reset_syscon, phy->dpll_reset_reg, |
---|
.. | .. |
---|
443 | 603 | { |
---|
444 | 604 | struct clk *clk; |
---|
445 | 605 | struct device *dev = phy->dev; |
---|
446 | | - struct device_node *node = dev->of_node; |
---|
447 | 606 | |
---|
448 | 607 | phy->refclk = devm_clk_get(dev, "refclk"); |
---|
449 | 608 | if (IS_ERR(phy->refclk)) { |
---|
.. | .. |
---|
451 | 610 | /* older DTBs have missing refclk in SATA PHY |
---|
452 | 611 | * so don't bail out in case of SATA PHY. |
---|
453 | 612 | */ |
---|
454 | | - if (!of_device_is_compatible(node, "ti,phy-pipe3-sata")) |
---|
| 613 | + if (phy->mode != PIPE3_MODE_SATA) |
---|
455 | 614 | return PTR_ERR(phy->refclk); |
---|
456 | 615 | } |
---|
457 | 616 | |
---|
458 | | - if (!of_device_is_compatible(node, "ti,phy-pipe3-sata")) { |
---|
| 617 | + if (phy->mode != PIPE3_MODE_SATA) { |
---|
459 | 618 | phy->wkupclk = devm_clk_get(dev, "wkupclk"); |
---|
460 | 619 | if (IS_ERR(phy->wkupclk)) { |
---|
461 | 620 | dev_err(dev, "unable to get wkupclk\n"); |
---|
.. | .. |
---|
465 | 624 | phy->wkupclk = ERR_PTR(-ENODEV); |
---|
466 | 625 | } |
---|
467 | 626 | |
---|
468 | | - if (!of_device_is_compatible(node, "ti,phy-pipe3-pcie") || |
---|
469 | | - phy->phy_power_syscon) { |
---|
| 627 | + if (phy->mode != PIPE3_MODE_PCIE || phy->phy_power_syscon) { |
---|
470 | 628 | phy->sys_clk = devm_clk_get(dev, "sysclk"); |
---|
471 | 629 | if (IS_ERR(phy->sys_clk)) { |
---|
472 | 630 | dev_err(dev, "unable to get sysclk\n"); |
---|
.. | .. |
---|
474 | 632 | } |
---|
475 | 633 | } |
---|
476 | 634 | |
---|
477 | | - if (of_device_is_compatible(node, "ti,phy-pipe3-pcie")) { |
---|
| 635 | + if (phy->mode == PIPE3_MODE_PCIE) { |
---|
478 | 636 | clk = devm_clk_get(dev, "dpll_ref"); |
---|
479 | 637 | if (IS_ERR(clk)) { |
---|
480 | 638 | dev_err(dev, "unable to get dpll ref clk\n"); |
---|
.. | .. |
---|
546 | 704 | phy->control_dev = &control_pdev->dev; |
---|
547 | 705 | } |
---|
548 | 706 | |
---|
549 | | - if (of_device_is_compatible(node, "ti,phy-pipe3-pcie")) { |
---|
| 707 | + if (phy->mode == PIPE3_MODE_PCIE) { |
---|
550 | 708 | phy->pcs_syscon = syscon_regmap_lookup_by_phandle(node, |
---|
551 | 709 | "syscon-pcs"); |
---|
552 | 710 | if (IS_ERR(phy->pcs_syscon)) { |
---|
.. | .. |
---|
564 | 722 | } |
---|
565 | 723 | } |
---|
566 | 724 | |
---|
567 | | - if (of_device_is_compatible(node, "ti,phy-pipe3-sata")) { |
---|
| 725 | + if (phy->mode == PIPE3_MODE_SATA) { |
---|
568 | 726 | phy->dpll_reset_syscon = syscon_regmap_lookup_by_phandle(node, |
---|
569 | 727 | "syscon-pllreset"); |
---|
570 | 728 | if (IS_ERR(phy->dpll_reset_syscon)) { |
---|
.. | .. |
---|
589 | 747 | { |
---|
590 | 748 | struct resource *res; |
---|
591 | 749 | struct device *dev = phy->dev; |
---|
592 | | - struct device_node *node = dev->of_node; |
---|
593 | 750 | struct platform_device *pdev = to_platform_device(dev); |
---|
594 | | - |
---|
595 | | - if (!of_device_is_compatible(node, "ti,phy-pipe3-pcie")) |
---|
596 | | - return 0; |
---|
597 | 751 | |
---|
598 | 752 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, |
---|
599 | 753 | "phy_rx"); |
---|
.. | .. |
---|
611 | 765 | static int ti_pipe3_get_pll_base(struct ti_pipe3 *phy) |
---|
612 | 766 | { |
---|
613 | 767 | struct resource *res; |
---|
614 | | - const struct of_device_id *match; |
---|
615 | 768 | struct device *dev = phy->dev; |
---|
616 | | - struct device_node *node = dev->of_node; |
---|
617 | 769 | struct platform_device *pdev = to_platform_device(dev); |
---|
618 | 770 | |
---|
619 | | - if (of_device_is_compatible(node, "ti,phy-pipe3-pcie")) |
---|
| 771 | + if (phy->mode == PIPE3_MODE_PCIE) |
---|
620 | 772 | return 0; |
---|
621 | | - |
---|
622 | | - match = of_match_device(ti_pipe3_id_table, dev); |
---|
623 | | - if (!match) |
---|
624 | | - return -EINVAL; |
---|
625 | | - |
---|
626 | | - phy->dpll_map = (struct pipe3_dpll_map *)match->data; |
---|
627 | | - if (!phy->dpll_map) { |
---|
628 | | - dev_err(dev, "no DPLL data\n"); |
---|
629 | | - return -EINVAL; |
---|
630 | | - } |
---|
631 | 773 | |
---|
632 | 774 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, |
---|
633 | 775 | "pll_ctrl"); |
---|
.. | .. |
---|
640 | 782 | struct ti_pipe3 *phy; |
---|
641 | 783 | struct phy *generic_phy; |
---|
642 | 784 | struct phy_provider *phy_provider; |
---|
643 | | - struct device_node *node = pdev->dev.of_node; |
---|
644 | 785 | struct device *dev = &pdev->dev; |
---|
645 | 786 | int ret; |
---|
| 787 | + const struct of_device_id *match; |
---|
| 788 | + struct pipe3_data *data; |
---|
646 | 789 | |
---|
647 | 790 | phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL); |
---|
648 | 791 | if (!phy) |
---|
649 | 792 | return -ENOMEM; |
---|
650 | 793 | |
---|
651 | | - phy->dev = dev; |
---|
| 794 | + match = of_match_device(ti_pipe3_id_table, dev); |
---|
| 795 | + if (!match) |
---|
| 796 | + return -EINVAL; |
---|
| 797 | + |
---|
| 798 | + data = (struct pipe3_data *)match->data; |
---|
| 799 | + if (!data) { |
---|
| 800 | + dev_err(dev, "no driver data\n"); |
---|
| 801 | + return -EINVAL; |
---|
| 802 | + } |
---|
| 803 | + |
---|
| 804 | + phy->dev = dev; |
---|
| 805 | + phy->mode = data->mode; |
---|
| 806 | + phy->dpll_map = data->dpll_map; |
---|
| 807 | + phy->settings = data->settings; |
---|
652 | 808 | |
---|
653 | 809 | ret = ti_pipe3_get_pll_base(phy); |
---|
654 | 810 | if (ret) |
---|
.. | .. |
---|
672 | 828 | /* |
---|
673 | 829 | * Prevent auto-disable of refclk for SATA PHY due to Errata i783 |
---|
674 | 830 | */ |
---|
675 | | - if (of_device_is_compatible(node, "ti,phy-pipe3-sata")) { |
---|
| 831 | + if (phy->mode == PIPE3_MODE_SATA) { |
---|
676 | 832 | if (!IS_ERR(phy->refclk)) { |
---|
677 | 833 | clk_prepare_enable(phy->refclk); |
---|
678 | 834 | phy->sata_refclk_enabled = true; |
---|
.. | .. |
---|
693 | 849 | |
---|
694 | 850 | static int ti_pipe3_remove(struct platform_device *pdev) |
---|
695 | 851 | { |
---|
| 852 | + struct ti_pipe3 *phy = platform_get_drvdata(pdev); |
---|
| 853 | + |
---|
| 854 | + if (phy->mode == PIPE3_MODE_SATA) { |
---|
| 855 | + clk_disable_unprepare(phy->refclk); |
---|
| 856 | + phy->sata_refclk_enabled = false; |
---|
| 857 | + } |
---|
696 | 858 | pm_runtime_disable(&pdev->dev); |
---|
697 | 859 | |
---|
698 | 860 | return 0; |
---|
.. | .. |
---|
743 | 905 | { |
---|
744 | 906 | if (!IS_ERR(phy->wkupclk)) |
---|
745 | 907 | clk_disable_unprepare(phy->wkupclk); |
---|
746 | | - if (!IS_ERR(phy->refclk)) { |
---|
| 908 | + if (!IS_ERR(phy->refclk)) |
---|
747 | 909 | clk_disable_unprepare(phy->refclk); |
---|
748 | | - /* |
---|
749 | | - * SATA refclk needs an additional disable as we left it |
---|
750 | | - * on in probe to avoid Errata i783 |
---|
751 | | - */ |
---|
752 | | - if (phy->sata_refclk_enabled) { |
---|
753 | | - clk_disable_unprepare(phy->refclk); |
---|
754 | | - phy->sata_refclk_enabled = false; |
---|
755 | | - } |
---|
756 | | - } |
---|
757 | | - |
---|
758 | 910 | if (!IS_ERR(phy->div_clk)) |
---|
759 | 911 | clk_disable_unprepare(phy->div_clk); |
---|
760 | 912 | } |
---|
.. | .. |
---|
762 | 914 | static const struct of_device_id ti_pipe3_id_table[] = { |
---|
763 | 915 | { |
---|
764 | 916 | .compatible = "ti,phy-usb3", |
---|
765 | | - .data = dpll_map_usb, |
---|
| 917 | + .data = &data_usb, |
---|
766 | 918 | }, |
---|
767 | 919 | { |
---|
768 | 920 | .compatible = "ti,omap-usb3", |
---|
769 | | - .data = dpll_map_usb, |
---|
| 921 | + .data = &data_usb, |
---|
770 | 922 | }, |
---|
771 | 923 | { |
---|
772 | 924 | .compatible = "ti,phy-pipe3-sata", |
---|
773 | | - .data = dpll_map_sata, |
---|
| 925 | + .data = &data_sata, |
---|
774 | 926 | }, |
---|
775 | 927 | { |
---|
776 | 928 | .compatible = "ti,phy-pipe3-pcie", |
---|
| 929 | + .data = &data_pcie, |
---|
777 | 930 | }, |
---|
778 | 931 | {} |
---|
779 | 932 | }; |
---|