| .. | .. |
|---|
| 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 | }; |
|---|