Channagoud Kadabi | 1f24f8a | 2015-02-11 15:43:10 -0800 | [diff] [blame] | 1 | /* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. |
Channagoud Kadabi | aab99d4 | 2014-02-04 15:45:56 -0800 | [diff] [blame] | 2 | |
| 3 | * Redistribution and use in source and binary forms, with or without |
| 4 | * modification, are permitted provided that the following conditions are |
| 5 | * met: |
| 6 | * * Redistributions of source code must retain the above copyright |
| 7 | * notice, this list of conditions and the following disclaimer. |
| 8 | * * Redistributions in binary form must reproduce the above |
| 9 | * copyright notice, this list of conditions and the following |
| 10 | * disclaimer in the documentation and/or other materials provided |
| 11 | * with the distribution. |
| 12 | * * Neither the name of The Linux Foundation. nor the names of its |
| 13 | * contributors may be used to endorse or promote products derived |
| 14 | * from this software without specific prior written permission. |
| 15 | * |
| 16 | * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED |
| 17 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
| 18 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT |
| 19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS |
| 20 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
| 21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
| 22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR |
| 23 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, |
| 24 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE |
| 25 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN |
| 26 | * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 27 | */ |
| 28 | |
Channagoud Kadabi | b3d7f1f | 2014-04-22 15:02:51 -0700 | [diff] [blame] | 29 | #include <sys/types.h> |
Channagoud Kadabi | aab99d4 | 2014-02-04 15:45:56 -0800 | [diff] [blame] | 30 | #include <stdint.h> |
| 31 | #include <platform/clock.h> |
| 32 | #include <platform/iomap.h> |
| 33 | #include <qmp_phy.h> |
| 34 | #include <reg.h> |
| 35 | #include <bits.h> |
Channagoud Kadabi | a39da8b | 2014-04-03 15:34:43 -0700 | [diff] [blame] | 36 | #include <clock.h> |
| 37 | #include <debug.h> |
Veera Sundaram Sankaran | 0018151 | 2014-12-09 11:23:39 -0800 | [diff] [blame] | 38 | #include <qtimer.h> |
Channagoud Kadabi | e35356f | 2015-08-05 18:06:38 -0700 | [diff] [blame] | 39 | #include <platform.h> |
Channagoud Kadabi | 0a98d00 | 2015-10-07 11:57:53 -0700 | [diff] [blame] | 40 | #include <target.h> |
Channagoud Kadabi | a39da8b | 2014-04-03 15:34:43 -0700 | [diff] [blame] | 41 | |
| 42 | #define HS_PHY_COMMON_CTRL 0xEC |
| 43 | #define USE_CORECLK BIT(14) |
| 44 | #define PLLBTUNE BIT(15) |
| 45 | #define FSEL (0x7 << 4) |
| 46 | #define DIS_RETENTION BIT(18) |
Channagoud Kadabi | b3d7f1f | 2014-04-22 15:02:51 -0700 | [diff] [blame] | 47 | #define QMP_PHY_MAX_TIMEOUT 1000 |
| 48 | #define PHYSTATUS BIT(6) |
Channagoud Kadabi | aab99d4 | 2014-02-04 15:45:56 -0800 | [diff] [blame] | 49 | |
Channagoud Kadabi | 1f24f8a | 2015-02-11 15:43:10 -0800 | [diff] [blame] | 50 | static bool hsonly_mode; |
| 51 | |
Channagoud Kadabi | 6a1b8ba | 2015-04-28 17:14:32 -0700 | [diff] [blame] | 52 | /* Override values for QMP 2.0 V1 devices */ |
| 53 | struct qmp_reg qmp_override_pll_rev2[] = |
| 54 | { |
| 55 | {0x124, 0x1C}, /* USB3PHY_QSERDES_COM_VCO_TUNE_CTRL */ |
| 56 | {0x12C, 0x3F}, /* USB3PHY_QSERDES_COM_VCO_TUNE1_MODE0 */ |
| 57 | {0x130, 0x01}, /* USB3PHY_QSERDES_COM_VCO_TUNE2_MODE0 */ |
| 58 | {0x6c4, 0x13}, /* USB3_PHY_FLL_CNTRL2 */ |
| 59 | }; |
| 60 | |
| 61 | /* QMP settings for 2.0 QMP V2 HW */ |
| 62 | struct qmp_reg qmp_settings_rev2[] = |
Channagoud Kadabi | 662a7fa | 2014-11-17 17:24:27 -0800 | [diff] [blame] | 63 | { |
| 64 | {0xAC, 0x14}, /* QSERDES_COM_SYSCLK_EN_SEL */ |
| 65 | {0x34, 0x08}, /* QSERDES_COM_BIAS_EN_CLKBUFLR_EN */ |
| 66 | {0x174, 0x30}, /* QSERDES_COM_CLK_SELECT */ |
Channagoud Kadabi | 662a7fa | 2014-11-17 17:24:27 -0800 | [diff] [blame] | 67 | {0x194, 0x06}, /* QSERDES_COM_CMN_CONFIG */ |
| 68 | {0x19c, 0x01}, /* QSERDES_COM_SVS_MODE_CLK_SEL */ |
Channagoud Kadabi | e35356f | 2015-08-05 18:06:38 -0700 | [diff] [blame] | 69 | {0x178, 0x00}, /* QSERDES_COM_HSCLK_SEL */ |
Channagoud Kadabi | 6a1b8ba | 2015-04-28 17:14:32 -0700 | [diff] [blame] | 70 | {0x70, 0x0F}, /* USB3PHY_QSERDES_COM_BG_TRIM */ |
| 71 | {0x48, 0x0F}, /* USB3PHY_QSERDES_COM_PLL_IVCO */ |
| 72 | {0x3C, 0x04}, /* QSERDES_COM_SYS_CLK_CTRL */ |
| 73 | |
Channagoud Kadabi | 6a1b8ba | 2015-04-28 17:14:32 -0700 | [diff] [blame] | 74 | /* PLL & Loop filter settings */ |
Channagoud Kadabi | 662a7fa | 2014-11-17 17:24:27 -0800 | [diff] [blame] | 75 | {0xd0, 0x82}, /* QSERDES_COM_DEC_START_MODE0 */ |
| 76 | {0xdc, 0x55}, /* QSERDES_COM_DIV_FRAC_START1_MODE0 */ |
| 77 | {0xe0, 0x55}, /* QSERDES_COM_DIV_FRAC_START2_MODE0 */ |
| 78 | {0xe4, 0x03}, /* QSERDES_COM_DIV_FRAC_START3_MODE0 */ |
| 79 | {0x78, 0x0b}, /* QSERDES_COM_CP_CTRL_MODE0 */ |
| 80 | {0x84, 0x16}, /* QSERDES_COM_PLL_RCTRL_MODE0 */ |
| 81 | {0x90, 0x28}, /* QSERDES_COM_PLL_CCTRL_MODE0 */ |
| 82 | {0x108, 0x80}, /* QSERDES_COM_INTEGLOOP_GAIN0_MODE0 */ |
Channagoud Kadabi | 6a1b8ba | 2015-04-28 17:14:32 -0700 | [diff] [blame] | 83 | {0x124, 0x00}, /* QSERDES_COM_VCO_TUNE_CTRL */ |
Channagoud Kadabi | 662a7fa | 2014-11-17 17:24:27 -0800 | [diff] [blame] | 84 | {0x4c, 0x15}, /* QSERDES_COM_LOCK_CMP1_MODE0 */ |
| 85 | {0x50, 0x34}, /* QSERDES_COM_LOCK_CMP2_MODE0 */ |
| 86 | {0x54, 0x00}, /* QSERDES_COM_LOCK_CMP3_MODE0 */ |
Channagoud Kadabi | 662a7fa | 2014-11-17 17:24:27 -0800 | [diff] [blame] | 87 | {0x18c, 0x00}, /* QSERDES_COM_CORE_CLK_EN */ |
Channagoud Kadabi | 662a7fa | 2014-11-17 17:24:27 -0800 | [diff] [blame] | 88 | {0xcc, 0x00}, /* QSERDES_COM_LOCK_CMP_CFG */ |
Channagoud Kadabi | 6a1b8ba | 2015-04-28 17:14:32 -0700 | [diff] [blame] | 89 | {0x0C, 0x0A}, /* QSERDES_COM_BG_TIMER */ |
Channagoud Kadabi | 662a7fa | 2014-11-17 17:24:27 -0800 | [diff] [blame] | 90 | {0x128, 0x00}, /* QSERDES_COM_VCO_TUNE_MAP */ |
| 91 | {0xc, 0x0a}, /* QSERDES_COM_BG_TIMER */ |
Channagoud Kadabi | 6a1b8ba | 2015-04-28 17:14:32 -0700 | [diff] [blame] | 92 | |
| 93 | /* SSC settings */ |
Channagoud Kadabi | 662a7fa | 2014-11-17 17:24:27 -0800 | [diff] [blame] | 94 | {0x10, 0x01}, /* QSERDES_COM_SSC_EN_CENTER */ |
| 95 | {0x1c, 0x31}, /* QSERDES_COM_SSC_PER1 */ |
| 96 | {0x20, 0x01}, /* QSERDES_COM_SSC_PER2 */ |
| 97 | {0x14, 0x00}, /* QSERDES_COM_SSC_ADJ_PER1 */ |
| 98 | {0x18, 0x00}, /* QSERDES_COM_SSC_ADJ_PER2 */ |
| 99 | {0x24, 0xde}, /* QSERDES_COM_SSC_STEP_SIZE1 */ |
| 100 | {0x28, 0x07}, /* QSERDES_COM_SSC_STEP_SIZE2 */ |
Channagoud Kadabi | 6a1b8ba | 2015-04-28 17:14:32 -0700 | [diff] [blame] | 101 | |
| 102 | /* Rx Settings */ |
Channagoud Kadabi | 662a7fa | 2014-11-17 17:24:27 -0800 | [diff] [blame] | 103 | {0x440, 0x0b}, /* QSERDES_RX_UCDR_FASTLOCK_FO_GAIN */ |
Channagoud Kadabi | 6a1b8ba | 2015-04-28 17:14:32 -0700 | [diff] [blame] | 104 | {0x41C, 0x04}, /* QSERDES_RX_UCDR_SO_GAIN */ |
| 105 | {0x4d8, 0x02}, /* QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2 */ |
| 106 | {0x4dc, 0x4c}, /* QSERDES_RX_RX_EQU_ADAPTOR_CNTRL3 */ |
| 107 | {0x4e0, 0xbb}, /* QSERDES_RX_RX_EQU_ADAPTOR_CNTRL4 */ |
Channagoud Kadabi | 662a7fa | 2014-11-17 17:24:27 -0800 | [diff] [blame] | 108 | {0x508, 0x77}, /* QSERDES_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1 */ |
| 109 | {0x50c, 0x80}, /* QSERDES_RX_RX_OFFSET_ADAPTOR_CNTRL2 */ |
Channagoud Kadabi | 6a1b8ba | 2015-04-28 17:14:32 -0700 | [diff] [blame] | 110 | {0x514, 0x03}, /* QSERDES_RX_SIGDET_CNTRL */ |
Channagoud Kadabi | 6b141f8 | 2015-09-24 15:39:08 -0700 | [diff] [blame] | 111 | {0x518, 0x18}, /* QSERDES_RX_SIGDET_LVL */ |
Channagoud Kadabi | 662a7fa | 2014-11-17 17:24:27 -0800 | [diff] [blame] | 112 | {0x51c, 0x16}, /* QSERDES_RX_SIGDET_DEGLITCH_CNTRL */ |
Channagoud Kadabi | 6a1b8ba | 2015-04-28 17:14:32 -0700 | [diff] [blame] | 113 | |
| 114 | /* Tx settings */ |
Channagoud Kadabi | 662a7fa | 2014-11-17 17:24:27 -0800 | [diff] [blame] | 115 | {0x268, 0x45}, /* QSERDES_TX_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN */ |
| 116 | {0x2ac, 0x12}, /* QSERDES_TX_RCV_DETECT_LVL_2 */ |
Channagoud Kadabi | 6a1b8ba | 2015-04-28 17:14:32 -0700 | [diff] [blame] | 117 | {0x294, 0x06}, /* QSERDES_TX_LANE_MODE */ |
| 118 | |
| 119 | /* FLL settings */ |
Channagoud Kadabi | 662a7fa | 2014-11-17 17:24:27 -0800 | [diff] [blame] | 120 | {0x6c4, 0x03}, /* USB3_PHY_FLL_CNTRL2 */ |
| 121 | {0x6c0, 0x02}, /* USB3_PHY_FLL_CNTRL1 */ |
| 122 | {0x6c8, 0x09}, /* USB3_PHY_FLL_CNT_VAL_L */ |
| 123 | {0x6cc, 0x42}, /* USB3_PHY_FLL_CNT_VAL_H_TOL */ |
| 124 | {0x6d0, 0x85}, /* USB3_PHY_FLL_MAN_CODE */ |
Channagoud Kadabi | 6a1b8ba | 2015-04-28 17:14:32 -0700 | [diff] [blame] | 125 | |
| 126 | /* Lock Det Settings */ |
Channagoud Kadabi | 662a7fa | 2014-11-17 17:24:27 -0800 | [diff] [blame] | 127 | {0x680, 0xd1}, /* USB3_PHY_LOCK_DETECT_CONFIG1 */ |
| 128 | {0x684, 0x1f}, /* USB3_PHY_LOCK_DETECT_CONFIG2 */ |
| 129 | {0x688, 0x47}, /* USB3_PHY_LOCK_DETECT_CONFIG3 */ |
| 130 | {0x664, 0x08}, /* USB3_PHY_POWER_STATE_CONFIG2 */ |
Channagoud Kadabi | 662a7fa | 2014-11-17 17:24:27 -0800 | [diff] [blame] | 131 | {0x608, 0x03}, /* USB3_PHY_START_CONTROL */ |
Channagoud Kadabi | 6a1b8ba | 2015-04-28 17:14:32 -0700 | [diff] [blame] | 132 | {0x600, 0x00}, /* USB3_PHY_SW_RESET */ |
Channagoud Kadabi | 662a7fa | 2014-11-17 17:24:27 -0800 | [diff] [blame] | 133 | }; |
| 134 | |
Channagoud Kadabi | e35356f | 2015-08-05 18:06:38 -0700 | [diff] [blame] | 135 | #if PLATFORM_USE_QMP_MISC |
| 136 | struct qmp_reg qmp_misc_settings_rev2[] = |
| 137 | { |
| 138 | {0x178, 0x01}, /* QSERDES_COM_HSCLK_SEL */ |
Channagoud Kadabi | 6b141f8 | 2015-09-24 15:39:08 -0700 | [diff] [blame] | 139 | {0x518, 0x1B}, /* QSERDES_RX_SIGDET_LVL */ |
Channagoud Kadabi | e35356f | 2015-08-05 18:06:38 -0700 | [diff] [blame] | 140 | {0xC4, 0x15}, /* USB3PHY_QSERDES_COM_RESCODE_DIV_NUM */ |
| 141 | {0x1B8, 0x1F}, /* QSERDES_COM_CMN_MISC2 */ |
| 142 | }; |
| 143 | #endif |
| 144 | |
Channagoud Kadabi | 0b13ba5 | 2014-05-12 18:08:33 -0700 | [diff] [blame] | 145 | __WEAK uint32_t target_override_pll() |
| 146 | { |
| 147 | return 0; |
| 148 | } |
| 149 | |
Channagoud Kadabi | 662a7fa | 2014-11-17 17:24:27 -0800 | [diff] [blame] | 150 | __WEAK uint32_t platform_get_qmp_rev() |
| 151 | { |
| 152 | return 0x10000000; |
| 153 | } |
| 154 | |
| 155 | /* USB3.0 QMP phy reset */ |
| 156 | static void qmp_phy_qmp_reset(void) |
Channagoud Kadabi | aab99d4 | 2014-02-04 15:45:56 -0800 | [diff] [blame] | 157 | { |
Channagoud Kadabi | a39da8b | 2014-04-03 15:34:43 -0700 | [diff] [blame] | 158 | int ret = 0; |
Channagoud Kadabi | aab99d4 | 2014-02-04 15:45:56 -0800 | [diff] [blame] | 159 | uint32_t val; |
Channagoud Kadabi | b3d7f1f | 2014-04-22 15:02:51 -0700 | [diff] [blame] | 160 | bool phy_com_reset = false; |
Channagoud Kadabi | aab99d4 | 2014-02-04 15:45:56 -0800 | [diff] [blame] | 161 | |
Channagoud Kadabi | a39da8b | 2014-04-03 15:34:43 -0700 | [diff] [blame] | 162 | struct clk *usb2b_clk = NULL; |
| 163 | struct clk *usb_pipe_clk = NULL; |
| 164 | struct clk *phy_com_clk = NULL; |
| 165 | struct clk *phy_clk = NULL; |
Channagoud Kadabi | aab99d4 | 2014-02-04 15:45:56 -0800 | [diff] [blame] | 166 | |
Channagoud Kadabi | b3d7f1f | 2014-04-22 15:02:51 -0700 | [diff] [blame] | 167 | /* Look if phy com clock is present */ |
| 168 | phy_com_clk = clk_get("usb30_phy_com_reset"); |
| 169 | if (phy_com_clk) |
| 170 | phy_com_reset = true; |
| 171 | |
Channagoud Kadabi | a39da8b | 2014-04-03 15:34:43 -0700 | [diff] [blame] | 172 | usb2b_clk = clk_get("usb2b_phy_sleep_clk"); |
| 173 | ASSERT(usb2b_clk); |
Channagoud Kadabi | aab99d4 | 2014-02-04 15:45:56 -0800 | [diff] [blame] | 174 | |
Channagoud Kadabi | a39da8b | 2014-04-03 15:34:43 -0700 | [diff] [blame] | 175 | phy_clk = clk_get("usb30_phy_reset"); |
| 176 | ASSERT(phy_clk); |
| 177 | |
| 178 | usb_pipe_clk = clk_get("usb30_pipe_clk"); |
| 179 | ASSERT(usb_pipe_clk); |
| 180 | |
| 181 | /* ASSERT */ |
| 182 | ret = clk_reset(usb2b_clk, CLK_RESET_ASSERT); |
| 183 | if (ret) |
| 184 | { |
| 185 | dprintf(CRITICAL, "Failed to assert usb2b_phy_clk\n"); |
| 186 | return; |
| 187 | } |
| 188 | |
Channagoud Kadabi | b3d7f1f | 2014-04-22 15:02:51 -0700 | [diff] [blame] | 189 | if (phy_com_reset) |
Channagoud Kadabi | a39da8b | 2014-04-03 15:34:43 -0700 | [diff] [blame] | 190 | { |
Channagoud Kadabi | b3d7f1f | 2014-04-22 15:02:51 -0700 | [diff] [blame] | 191 | ret = clk_reset(phy_com_clk, CLK_RESET_ASSERT); |
| 192 | if (ret) |
| 193 | { |
| 194 | dprintf(CRITICAL, "Failed to assert phy_com_clk\n"); |
| 195 | goto deassert_usb2b_clk; |
| 196 | } |
Channagoud Kadabi | a39da8b | 2014-04-03 15:34:43 -0700 | [diff] [blame] | 197 | } |
| 198 | |
| 199 | ret = clk_reset(phy_clk, CLK_RESET_ASSERT); |
| 200 | if (ret) |
| 201 | { |
| 202 | dprintf(CRITICAL, "Failed to assert phy_clk\n"); |
| 203 | goto deassert_phy_com_clk; |
| 204 | } |
| 205 | |
| 206 | ret = clk_reset(usb_pipe_clk, CLK_RESET_ASSERT); |
| 207 | if (ret) |
| 208 | { |
| 209 | dprintf(CRITICAL, "Failed to assert usb_pipe_clk\n"); |
| 210 | goto deassert_phy_clk; |
| 211 | } |
| 212 | |
| 213 | udelay(100); |
| 214 | |
| 215 | /* DEASSERT */ |
| 216 | ret = clk_reset(usb_pipe_clk, CLK_RESET_DEASSERT); |
| 217 | if (ret) |
| 218 | dprintf(CRITICAL, "Failed to deassert usb_pipe_clk\n"); |
| 219 | |
| 220 | deassert_phy_clk: |
| 221 | ret = clk_reset(phy_clk, CLK_RESET_DEASSERT); |
| 222 | if (ret) |
| 223 | dprintf(CRITICAL, "Failed to deassert phy_clk\n"); |
| 224 | |
| 225 | deassert_phy_com_clk: |
Channagoud Kadabi | b3d7f1f | 2014-04-22 15:02:51 -0700 | [diff] [blame] | 226 | if (phy_com_reset) |
| 227 | { |
| 228 | ret = clk_reset(phy_com_clk, CLK_RESET_DEASSERT); |
| 229 | if (ret) |
| 230 | dprintf(CRITICAL, "Failed to deassert phy_com_clk\n"); |
| 231 | } |
Channagoud Kadabi | a39da8b | 2014-04-03 15:34:43 -0700 | [diff] [blame] | 232 | |
| 233 | deassert_usb2b_clk: |
| 234 | ret = clk_reset(usb2b_clk, CLK_RESET_DEASSERT); |
| 235 | if (ret) |
| 236 | dprintf(CRITICAL, "Failed to deassert usb2b_phy_clk\n"); |
| 237 | |
| 238 | /* Override the phy common control values */ |
| 239 | val = readl(MSM_USB30_QSCRATCH_BASE + HS_PHY_COMMON_CTRL); |
| 240 | val |= USE_CORECLK | PLLBTUNE; |
| 241 | val &= ~FSEL; |
| 242 | val &= ~DIS_RETENTION; |
| 243 | writel(val, MSM_USB30_QSCRATCH_BASE + HS_PHY_COMMON_CTRL); |
Channagoud Kadabi | aab99d4 | 2014-02-04 15:45:56 -0800 | [diff] [blame] | 244 | } |
| 245 | |
Channagoud Kadabi | c4b752c | 2014-12-22 12:06:27 -0800 | [diff] [blame] | 246 | /* USB3.0 QMP phy reset */ |
| 247 | void usb30_qmp_phy_reset(void) |
| 248 | { |
| 249 | #if USB_RESET_FROM_CLK |
| 250 | clock_reset_usb_phy(); |
| 251 | #else |
| 252 | qmp_phy_qmp_reset(); |
| 253 | #endif |
| 254 | } |
| 255 | |
Channagoud Kadabi | aab99d4 | 2014-02-04 15:45:56 -0800 | [diff] [blame] | 256 | /* USB 3.0 phy init: HPG for QMP phy*/ |
| 257 | void usb30_qmp_phy_init() |
| 258 | { |
Channagoud Kadabi | b3d7f1f | 2014-04-22 15:02:51 -0700 | [diff] [blame] | 259 | int timeout = QMP_PHY_MAX_TIMEOUT; |
Channagoud Kadabi | 662a7fa | 2014-11-17 17:24:27 -0800 | [diff] [blame] | 260 | uint32_t phy_status = 0; |
| 261 | uint32_t qmp_reg_size; |
| 262 | uint32_t i; |
| 263 | |
Channagoud Kadabi | 0a98d00 | 2015-10-07 11:57:53 -0700 | [diff] [blame] | 264 | |
| 265 | #if USE_TARGET_QMP_SETTINGS |
| 266 | struct qmp_reg *target_qmp_settings = NULL; |
| 267 | qmp_reg_size = target_get_qmp_regsize(); |
| 268 | target_qmp_settings = target_get_qmp_settings(); |
| 269 | if (qmp_reg_size && target_qmp_settings) |
| 270 | { |
| 271 | for (i = 0 ; i < qmp_reg_size; i++) |
| 272 | { |
| 273 | /* As per the hw document we need to add a delay of 1 ms after setting |
| 274 | * QSERDES_COM_RESETSM_CNTRL2 and before setting QSERDES_COM_CMN_CONFIG */ |
| 275 | if (i == 7) |
| 276 | mdelay(1); |
| 277 | writel(target_qmp_settings[i].val, QMP_PHY_BASE + target_qmp_settings[i].off); |
| 278 | } |
| 279 | goto phy_status; |
| 280 | } |
| 281 | #endif |
| 282 | |
| 283 | uint32_t rev_id = platform_get_qmp_rev(); |
Channagoud Kadabi | b3d7f1f | 2014-04-22 15:02:51 -0700 | [diff] [blame] | 284 | |
Channagoud Kadabi | aab99d4 | 2014-02-04 15:45:56 -0800 | [diff] [blame] | 285 | /* Sequence as per HPG */ |
Channagoud Kadabi | aab99d4 | 2014-02-04 15:45:56 -0800 | [diff] [blame] | 286 | writel(0x01, QMP_PHY_BASE + PCIE_USB3_PHY_POWER_DOWN_CONTROL); |
Channagoud Kadabi | 0b13ba5 | 2014-05-12 18:08:33 -0700 | [diff] [blame] | 287 | |
Channagoud Kadabi | 662a7fa | 2014-11-17 17:24:27 -0800 | [diff] [blame] | 288 | if (rev_id >= 0x20000000) |
| 289 | { |
Channagoud Kadabi | 6a1b8ba | 2015-04-28 17:14:32 -0700 | [diff] [blame] | 290 | qmp_reg_size = sizeof(qmp_settings_rev2) / sizeof(struct qmp_reg); |
Channagoud Kadabi | 662a7fa | 2014-11-17 17:24:27 -0800 | [diff] [blame] | 291 | for (i = 0 ; i < qmp_reg_size; i++) |
Channagoud Kadabi | 6a1b8ba | 2015-04-28 17:14:32 -0700 | [diff] [blame] | 292 | writel(qmp_settings_rev2[i].val, QMP_PHY_BASE + qmp_settings_rev2[i].off); |
| 293 | |
Channagoud Kadabi | e35356f | 2015-08-05 18:06:38 -0700 | [diff] [blame] | 294 | #if PLATFORM_USE_QMP_MISC |
| 295 | if (platform_use_qmp_misc_settings()) |
| 296 | for (i = 0; i < ARRAY_SIZE(qmp_misc_settings_rev2); i++) |
| 297 | writel(qmp_misc_settings_rev2[i].val, QMP_PHY_BASE + qmp_misc_settings_rev2[i].off); |
| 298 | #endif |
Channagoud Kadabi | 6a1b8ba | 2015-04-28 17:14:32 -0700 | [diff] [blame] | 299 | if (target_override_pll()) |
| 300 | { |
| 301 | qmp_reg_size = sizeof(qmp_override_pll_rev2) / sizeof(struct qmp_reg); |
| 302 | for (i = 0 ; i < qmp_reg_size; i++) |
| 303 | writel(qmp_override_pll_rev2[i].val, QMP_PHY_BASE + qmp_override_pll_rev2[i].off); |
| 304 | } |
Channagoud Kadabi | 662a7fa | 2014-11-17 17:24:27 -0800 | [diff] [blame] | 305 | } |
Channagoud Kadabi | 0b13ba5 | 2014-05-12 18:08:33 -0700 | [diff] [blame] | 306 | else |
Channagoud Kadabi | 662a7fa | 2014-11-17 17:24:27 -0800 | [diff] [blame] | 307 | { |
| 308 | writel(0x08, QMP_PHY_BASE + QSERDES_COM_SYSCLK_EN_SEL_TXBAND); |
Channagoud Kadabi | aab99d4 | 2014-02-04 15:45:56 -0800 | [diff] [blame] | 309 | |
Channagoud Kadabi | 662a7fa | 2014-11-17 17:24:27 -0800 | [diff] [blame] | 310 | if (target_override_pll()) |
| 311 | writel(0xE1, QMP_PHY_BASE + QSERDES_COM_PLL_VCOTAIL_EN); |
Channagoud Kadabi | aab99d4 | 2014-02-04 15:45:56 -0800 | [diff] [blame] | 312 | |
Channagoud Kadabi | 662a7fa | 2014-11-17 17:24:27 -0800 | [diff] [blame] | 313 | writel(0x82, QMP_PHY_BASE + QSERDES_COM_DEC_START1); |
| 314 | writel(0x03, QMP_PHY_BASE + QSERDES_COM_DEC_START2); |
| 315 | writel(0xD5, QMP_PHY_BASE + QSERDES_COM_DIV_FRAC_START1); |
| 316 | writel(0xAA, QMP_PHY_BASE + QSERDES_COM_DIV_FRAC_START2); |
| 317 | writel(0x4D, QMP_PHY_BASE + QSERDES_COM_DIV_FRAC_START3); |
| 318 | writel(0x01, QMP_PHY_BASE + QSERDES_COM_PLLLOCK_CMP_EN); |
| 319 | writel(0x2B, QMP_PHY_BASE + QSERDES_COM_PLLLOCK_CMP1); |
| 320 | writel(0x68, QMP_PHY_BASE + QSERDES_COM_PLLLOCK_CMP2); |
| 321 | writel(0x7C, QMP_PHY_BASE + QSERDES_COM_PLL_CRCTRL); |
| 322 | writel(0x02, QMP_PHY_BASE + QSERDES_COM_PLL_CP_SETI); |
| 323 | writel(0x1F, QMP_PHY_BASE + QSERDES_COM_PLL_IP_SETP); |
| 324 | writel(0x0F, QMP_PHY_BASE + QSERDES_COM_PLL_CP_SETP); |
| 325 | writel(0x01, QMP_PHY_BASE + QSERDES_COM_PLL_IP_SETI); |
| 326 | writel(0x0F, QMP_PHY_BASE + QSERDES_COM_IE_TRIM); |
| 327 | writel(0x0F, QMP_PHY_BASE + QSERDES_COM_IP_TRIM); |
| 328 | writel(0x46, QMP_PHY_BASE + QSERDES_COM_PLL_CNTRL); |
| 329 | |
| 330 | /* CDR Settings */ |
| 331 | writel(0xDA, QMP_PHY_BASE + QSERDES_RX_CDR_CONTROL1); |
| 332 | writel(0x42, QMP_PHY_BASE + QSERDES_RX_CDR_CONTROL2); |
| 333 | |
| 334 | /* Calibration Settings */ |
| 335 | writel(0x90, QMP_PHY_BASE + QSERDES_COM_RESETSM_CNTRL); |
| 336 | if (target_override_pll()) |
| 337 | writel(0x07, QMP_PHY_BASE + QSERDES_COM_RESETSM_CNTRL2); |
| 338 | else |
| 339 | writel(0x05, QMP_PHY_BASE + QSERDES_COM_RESETSM_CNTRL2); |
| 340 | |
| 341 | writel(0x20, QMP_PHY_BASE + QSERDES_COM_RES_CODE_START_SEG1); |
| 342 | writel(0x77, QMP_PHY_BASE + QSERDES_COM_RES_CODE_CAL_CSR); |
| 343 | writel(0x15, QMP_PHY_BASE + QSERDES_COM_RES_TRIM_CONTROL); |
| 344 | writel(0x03, QMP_PHY_BASE + QSERDES_TX_RCV_DETECT_LVL); |
| 345 | writel(0x02, QMP_PHY_BASE + QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2); |
| 346 | writel(0x6C, QMP_PHY_BASE + QSERDES_RX_RX_EQU_ADAPTOR_CNTRL3); |
| 347 | writel(0xC7, QMP_PHY_BASE + QSERDES_RX_RX_EQU_ADAPTOR_CNTRL4); |
| 348 | writel(0x40, QMP_PHY_BASE + QSERDES_RX_SIGDET_ENABLES); |
| 349 | writel(0x73, QMP_PHY_BASE + QSERDES_RX_SIGDET_CNTRL); |
| 350 | writel(0x06, QMP_PHY_BASE + QSERDES_RX_SIGDET_DEGLITCH_CNTRL); |
| 351 | writel(0x48, QMP_PHY_BASE + PCIE_USB3_PHY_RX_IDLE_DTCT_CNTRL); |
| 352 | writel(0x01, QMP_PHY_BASE + QSERDES_COM_SSC_EN_CENTER); |
| 353 | writel(0x02, QMP_PHY_BASE + QSERDES_COM_SSC_ADJ_PER1); |
| 354 | writel(0x31, QMP_PHY_BASE + QSERDES_COM_SSC_PER1); |
| 355 | writel(0x01, QMP_PHY_BASE + QSERDES_COM_SSC_PER2); |
| 356 | writel(0x19, QMP_PHY_BASE + QSERDES_COM_SSC_STEP_SIZE1); |
| 357 | writel(0x19, QMP_PHY_BASE + QSERDES_COM_SSC_STEP_SIZE2); |
| 358 | writel(0x08, QMP_PHY_BASE + PCIE_USB3_PHY_POWER_STATE_CONFIG2); |
| 359 | |
| 360 | writel(0x00, QMP_PHY_BASE + PCIE_USB3_PHY_SW_RESET); |
| 361 | writel(0x03, QMP_PHY_BASE + PCIE_USB3_PHY_START); |
| 362 | } |
Channagoud Kadabi | aab99d4 | 2014-02-04 15:45:56 -0800 | [diff] [blame] | 363 | |
Channagoud Kadabi | 0a98d00 | 2015-10-07 11:57:53 -0700 | [diff] [blame] | 364 | #if USE_TARGET_QMP_SETTINGS |
| 365 | phy_status: |
| 366 | #endif |
Channagoud Kadabi | 662a7fa | 2014-11-17 17:24:27 -0800 | [diff] [blame] | 367 | |
Channagoud Kadabi | 0a98d00 | 2015-10-07 11:57:53 -0700 | [diff] [blame] | 368 | /* For future targets defined USB3_PHY_STATUS in the iomap.h |
| 369 | * Initial version of driver was written thinking phy_status register |
| 370 | * address would not change, but the address keeps changing for every chip |
| 371 | * so better get the address from iomap amd keep the backward compatibility |
| 372 | */ |
| 373 | #if USB3_PHY_STATUS |
| 374 | phy_status = USB3_PHY_STATUS; |
| 375 | #else |
| 376 | if (rev_id >= 0x20000000) |
| 377 | phy_status = QMP_PHY_BASE + 0x77c; |
| 378 | else |
| 379 | phy_status = QMP_PHY_BASE + 0x728; |
| 380 | #endif |
| 381 | |
| 382 | while ((readl(phy_status) & PHYSTATUS)) |
Channagoud Kadabi | 7bc9edb | 2014-06-01 19:01:12 -0700 | [diff] [blame] | 383 | { |
| 384 | udelay(1); |
| 385 | timeout--; |
| 386 | if (!timeout) |
| 387 | { |
Channagoud Kadabi | 1f24f8a | 2015-02-11 15:43:10 -0800 | [diff] [blame] | 388 | dprintf(CRITICAL, "QMP phy initialization failed, fallback to HighSpeed only mode\n"); |
| 389 | hsonly_mode = true; |
Channagoud Kadabi | 7bc9edb | 2014-06-01 19:01:12 -0700 | [diff] [blame] | 390 | return; |
| 391 | } |
| 392 | } |
Channagoud Kadabi | 1f24f8a | 2015-02-11 15:43:10 -0800 | [diff] [blame] | 393 | |
| 394 | clock_bumpup_pipe3_clk(); |
| 395 | } |
| 396 | |
| 397 | bool use_hsonly_mode() |
| 398 | { |
| 399 | return hsonly_mode; |
Channagoud Kadabi | aab99d4 | 2014-02-04 15:45:56 -0800 | [diff] [blame] | 400 | } |