1/****************************************************************************** 2** 3** FILE NAME : ifxmips_pcie_phy.c 4** PROJECT : IFX UEIP for VRX200 5** MODULES : PCIe PHY sub module 6** 7** DATE : 14 May 2009 8** AUTHOR : Lei Chuanhua 9** DESCRIPTION : PCIe Root Complex Driver 10** COPYRIGHT : Copyright (c) 2009 11** Infineon Technologies AG 12** Am Campeon 1-12, 85579 Neubiberg, Germany 13** 14** This program is free software; you can redistribute it and/or modify 15** it under the terms of the GNU General Public License as published by 16** the Free Software Foundation; either version 2 of the License, or 17** (at your option) any later version. 18** HISTORY 19** $Version $Date $Author $Comment 20** 0.0.1 14 May,2009 Lei Chuanhua Initial version 21*******************************************************************************/ 22/*! 23 \file ifxmips_pcie_phy.c 24 \ingroup IFX_PCIE 25 \brief PCIe PHY PLL register programming source file 26*/ 27#include <linux/types.h> 28#include <linux/kernel.h> 29#include <asm/paccess.h> 30#include <linux/delay.h> 31 32#include "pcie-lantiq.h" 33 34/* PCIe PDI only supports 16 bit operation */ 35 36#define IFX_PCIE_PHY_REG_WRITE16(__addr, __data) \ 37 ((*(volatile u16 *) (__addr)) = (__data)) 38 39#define IFX_PCIE_PHY_REG_READ16(__addr) \ 40 (*(volatile u16 *) (__addr)) 41 42#define IFX_PCIE_PHY_REG16(__addr) \ 43 (*(volatile u16 *) (__addr)) 44 45#define IFX_PCIE_PHY_REG(__reg, __value, __mask) do { \ 46 u16 read_data; \ 47 u16 write_data; \ 48 read_data = IFX_PCIE_PHY_REG_READ16((__reg)); \ 49 write_data = (read_data & ((u16)~(__mask))) | (((u16)(__value)) & ((u16)(__mask)));\ 50 IFX_PCIE_PHY_REG_WRITE16((__reg), write_data); \ 51} while (0) 52 53#define IFX_PCIE_PLL_TIMEOUT 1000 /* Tunnable */ 54 55static void 56pcie_phy_comm_setup(int pcie_port) 57{ 58 /* PLL Setting */ 59 IFX_PCIE_PHY_REG(PCIE_PHY_PLL_A_CTRL1(pcie_port), 0x120e, 0xFFFF); 60 61 /* increase the bias reference voltage */ 62 IFX_PCIE_PHY_REG(PCIE_PHY_PLL_A_CTRL2(pcie_port), 0x39D7, 0xFFFF); 63 IFX_PCIE_PHY_REG(PCIE_PHY_PLL_A_CTRL3(pcie_port), 0x0900, 0xFFFF); 64 65 /* Endcnt */ 66 IFX_PCIE_PHY_REG(PCIE_PHY_RX1_EI(pcie_port), 0x0004, 0xFFFF); 67 IFX_PCIE_PHY_REG(PCIE_PHY_RX1_A_CTRL(pcie_port), 0x6803, 0xFFFF); 68 69 /* force */ 70 IFX_PCIE_PHY_REG(PCIE_PHY_TX1_CTRL1(pcie_port), 0x0008, 0x0008); 71 72 /* predrv_ser_en */ 73 IFX_PCIE_PHY_REG(PCIE_PHY_TX1_A_CTRL2(pcie_port), 0x0706, 0xFFFF); 74 75 /* ctrl_lim */ 76 IFX_PCIE_PHY_REG(PCIE_PHY_TX1_CTRL3(pcie_port), 0x1FFF, 0xFFFF); 77 78 /* ctrl */ 79 IFX_PCIE_PHY_REG(PCIE_PHY_TX1_A_CTRL1(pcie_port), 0x0800, 0xFF00); 80 81 /* predrv_ser_en */ 82 IFX_PCIE_PHY_REG(PCIE_PHY_TX2_A_CTRL2(pcie_port), 0x4702, 0x7F00); 83 84 /* RTERM*/ 85 IFX_PCIE_PHY_REG(PCIE_PHY_TX1_CTRL2(pcie_port), 0x2e00, 0xFFFF); 86 87 /* Improved 100MHz clock output */ 88 IFX_PCIE_PHY_REG(PCIE_PHY_TX2_CTRL2(pcie_port), 0x3096, 0xFFFF); 89 IFX_PCIE_PHY_REG(PCIE_PHY_TX2_A_CTRL2(pcie_port), 0x4707, 0xFFFF); 90 91 /* Reduced CDR BW to avoid glitches */ 92 IFX_PCIE_PHY_REG(PCIE_PHY_RX1_CDR(pcie_port), 0x0235, 0xFFFF); 93} 94 95#ifdef CONFIG_IFX_PCIE_PHY_36MHZ_MODE 96static void 97pcie_phy_36mhz_mode_setup(int pcie_port) 98{ 99 IFX_PCIE_PRINT(PCIE_MSG_PHY, "%s pcie_port %d enter\n", __func__, pcie_port); 100 101 /* en_ext_mmd_div_ratio */ 102 IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL3(pcie_port), 0x0000, 0x0002); 103 104 /* ext_mmd_div_ratio*/ 105 IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL3(pcie_port), 0x0000, 0x0070); 106 107 /* pll_ensdm */ 108 IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL2(pcie_port), 0x0200, 0x0200); 109 110 /* en_const_sdm */ 111 IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL2(pcie_port), 0x0100, 0x0100); 112 113 /* mmd */ 114 IFX_PCIE_PHY_REG(PCIE_PHY_PLL_A_CTRL3(pcie_port), 0x2000, 0xe000); 115 116 /* lf_mode */ 117 IFX_PCIE_PHY_REG(PCIE_PHY_PLL_A_CTRL2(pcie_port), 0x0000, 0x4000); 118 119 /* const_sdm */ 120 IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL1(pcie_port), 0x38e4, 0xFFFF); 121 122 /* const sdm */ 123 IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL2(pcie_port), 0x00ee, 0x00FF); 124 125 /* pllmod */ 126 IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL7(pcie_port), 0x0002, 0xFFFF); 127 IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL6(pcie_port), 0x3a04, 0xFFFF); 128 IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL5(pcie_port), 0xfae3, 0xFFFF); 129 IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL4(pcie_port), 0x1b72, 0xFFFF); 130 131 IFX_PCIE_PRINT(PCIE_MSG_PHY, "%s pcie_port %d exit\n", __func__, pcie_port); 132} 133#endif /* CONFIG_IFX_PCIE_PHY_36MHZ_MODE */ 134 135#ifdef CONFIG_IFX_PCIE_PHY_36MHZ_SSC_MODE 136static void 137pcie_phy_36mhz_ssc_mode_setup(int pcie_port) 138{ 139 IFX_PCIE_PRINT(PCIE_MSG_PHY, "%s pcie_port %d enter\n", __func__, pcie_port); 140 141 /* PLL Setting */ 142 IFX_PCIE_PHY_REG(PCIE_PHY_PLL_A_CTRL1(pcie_port), 0x120e, 0xFFFF); 143 144 /* Increase the bias reference voltage */ 145 IFX_PCIE_PHY_REG(PCIE_PHY_PLL_A_CTRL2(pcie_port), 0x39D7, 0xFFFF); 146 IFX_PCIE_PHY_REG(PCIE_PHY_PLL_A_CTRL3(pcie_port), 0x0900, 0xFFFF); 147 148 /* Endcnt */ 149 IFX_PCIE_PHY_REG(PCIE_PHY_RX1_EI(pcie_port), 0x0004, 0xFFFF); 150 IFX_PCIE_PHY_REG(PCIE_PHY_RX1_A_CTRL(pcie_port), 0x6803, 0xFFFF); 151 152 /* Force */ 153 IFX_PCIE_PHY_REG(PCIE_PHY_TX1_CTRL1(pcie_port), 0x0008, 0x0008); 154 155 /* Predrv_ser_en */ 156 IFX_PCIE_PHY_REG(PCIE_PHY_TX1_A_CTRL2(pcie_port), 0x0706, 0xFFFF); 157 158 /* ctrl_lim */ 159 IFX_PCIE_PHY_REG(PCIE_PHY_TX1_CTRL3(pcie_port), 0x1FFF, 0xFFFF); 160 161 /* ctrl */ 162 IFX_PCIE_PHY_REG(PCIE_PHY_TX1_A_CTRL1(pcie_port), 0x0800, 0xFF00); 163 164 /* predrv_ser_en */ 165 IFX_PCIE_PHY_REG(PCIE_PHY_TX2_A_CTRL2(pcie_port), 0x4702, 0x7F00); 166 167 /* RTERM*/ 168 IFX_PCIE_PHY_REG(PCIE_PHY_TX1_CTRL2(pcie_port), 0x2e00, 0xFFFF); 169 170 /* en_ext_mmd_div_ratio */ 171 IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL3(pcie_port), 0x0000, 0x0002); 172 173 /* ext_mmd_div_ratio*/ 174 IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL3(pcie_port), 0x0000, 0x0070); 175 176 /* pll_ensdm */ 177 IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL2(pcie_port), 0x0400, 0x0400); 178 179 /* en_const_sdm */ 180 IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL2(pcie_port), 0x0200, 0x0200); 181 182 /* mmd */ 183 IFX_PCIE_PHY_REG(PCIE_PHY_PLL_A_CTRL3(pcie_port), 0x2000, 0xe000); 184 185 /* lf_mode */ 186 IFX_PCIE_PHY_REG(PCIE_PHY_PLL_A_CTRL2(pcie_port), 0x0000, 0x4000); 187 188 /* const_sdm */ 189 IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL1(pcie_port), 0x38e4, 0xFFFF); 190 191 IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL2(pcie_port), 0x0000, 0x0100); 192 /* const sdm */ 193 IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL2(pcie_port), 0x00ee, 0x00FF); 194 195 /* pllmod */ 196 IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL7(pcie_port), 0x0002, 0xFFFF); 197 IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL6(pcie_port), 0x3a04, 0xFFFF); 198 IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL5(pcie_port), 0xfae3, 0xFFFF); 199 IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL4(pcie_port), 0x1c72, 0xFFFF); 200 201 /* improved 100MHz clock output */ 202 IFX_PCIE_PHY_REG(PCIE_PHY_TX2_CTRL2(pcie_port), 0x3096, 0xFFFF); 203 IFX_PCIE_PHY_REG(PCIE_PHY_TX2_A_CTRL2(pcie_port), 0x4707, 0xFFFF); 204 205 /* reduced CDR BW to avoid glitches */ 206 IFX_PCIE_PHY_REG(PCIE_PHY_RX1_CDR(pcie_port), 0x0235, 0xFFFF); 207 208 IFX_PCIE_PRINT(PCIE_MSG_PHY, "%s pcie_port %d exit\n", __func__, pcie_port); 209} 210#endif /* CONFIG_IFX_PCIE_PHY_36MHZ_SSC_MODE */ 211 212#ifdef CONFIG_IFX_PCIE_PHY_25MHZ_MODE 213static void 214pcie_phy_25mhz_mode_setup(int pcie_port) 215{ 216 IFX_PCIE_PRINT(PCIE_MSG_PHY, "%s pcie_port %d enter\n", __func__, pcie_port); 217 /* en_const_sdm */ 218 IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL2(pcie_port), 0x0100, 0x0100); 219 220 /* pll_ensdm */ 221 IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL2(pcie_port), 0x0000, 0x0200); 222 223 /* en_ext_mmd_div_ratio*/ 224 IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL3(pcie_port), 0x0002, 0x0002); 225 226 /* ext_mmd_div_ratio*/ 227 IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL3(pcie_port), 0x0040, 0x0070); 228 229 /* mmd */ 230 IFX_PCIE_PHY_REG(PCIE_PHY_PLL_A_CTRL3(pcie_port), 0x6000, 0xe000); 231 232 /* lf_mode */ 233 IFX_PCIE_PHY_REG(PCIE_PHY_PLL_A_CTRL2(pcie_port), 0x4000, 0x4000); 234 235 IFX_PCIE_PRINT(PCIE_MSG_PHY, "%s pcie_port %d exit\n", __func__, pcie_port); 236} 237#endif /* CONFIG_IFX_PCIE_PHY_25MHZ_MODE */ 238 239#ifdef CONFIG_IFX_PCIE_PHY_100MHZ_MODE 240static void 241pcie_phy_100mhz_mode_setup(int pcie_port) 242{ 243 IFX_PCIE_PRINT(PCIE_MSG_PHY, "%s pcie_port %d enter\n", __func__, pcie_port); 244 /* en_ext_mmd_div_ratio */ 245 IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL3(pcie_port), 0x0000, 0x0002); 246 247 /* ext_mmd_div_ratio*/ 248 IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL3(pcie_port), 0x0000, 0x0070); 249 250 /* pll_ensdm */ 251 IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL2(pcie_port), 0x0200, 0x0200); 252 253 /* en_const_sdm */ 254 IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL2(pcie_port), 0x0100, 0x0100); 255 256 /* mmd */ 257 IFX_PCIE_PHY_REG(PCIE_PHY_PLL_A_CTRL3(pcie_port), 0x2000, 0xe000); 258 259 /* lf_mode */ 260 IFX_PCIE_PHY_REG(PCIE_PHY_PLL_A_CTRL2(pcie_port), 0x0000, 0x4000); 261 262 /* const_sdm */ 263 IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL1(pcie_port), 0x38e4, 0xFFFF); 264 265 /* const sdm */ 266 IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL2(pcie_port), 0x00ee, 0x00FF); 267 268 /* pllmod */ 269 IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL7(pcie_port), 0x0002, 0xFFFF); 270 IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL6(pcie_port), 0x3a04, 0xFFFF); 271 IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL5(pcie_port), 0xfae3, 0xFFFF); 272 IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL4(pcie_port), 0x1b72, 0xFFFF); 273 274 IFX_PCIE_PRINT(PCIE_MSG_PHY, "%s pcie_port %d exit\n", __func__, pcie_port); 275} 276#endif /* CONFIG_IFX_PCIE_PHY_100MHZ_MODE */ 277 278static int 279pcie_phy_wait_startup_ready(int pcie_port) 280{ 281 int i; 282 283 for (i = 0; i < IFX_PCIE_PLL_TIMEOUT; i++) { 284 if ((IFX_PCIE_PHY_REG16(PCIE_PHY_PLL_STATUS(pcie_port)) & 0x0040) != 0) { 285 break; 286 } 287 udelay(10); 288 } 289 if (i >= IFX_PCIE_PLL_TIMEOUT) { 290 printk(KERN_ERR "%s PLL Link timeout\n", __func__); 291 return -1; 292 } 293 return 0; 294} 295 296static void 297pcie_phy_load_enable(int pcie_port, int slice) 298{ 299 /* Set the load_en of tx/rx slice to '1' */ 300 switch (slice) { 301 case 1: 302 IFX_PCIE_PHY_REG(PCIE_PHY_TX1_CTRL1(pcie_port), 0x0010, 0x0010); 303 break; 304 case 2: 305 IFX_PCIE_PHY_REG(PCIE_PHY_TX2_CTRL1(pcie_port), 0x0010, 0x0010); 306 break; 307 case 3: 308 IFX_PCIE_PHY_REG(PCIE_PHY_RX1_CTRL1(pcie_port), 0x0002, 0x0002); 309 break; 310 } 311} 312 313static void 314pcie_phy_load_disable(int pcie_port, int slice) 315{ 316 /* set the load_en of tx/rx slice to '0' */ 317 switch (slice) { 318 case 1: 319 IFX_PCIE_PHY_REG(PCIE_PHY_TX1_CTRL1(pcie_port), 0x0000, 0x0010); 320 break; 321 case 2: 322 IFX_PCIE_PHY_REG(PCIE_PHY_TX2_CTRL1(pcie_port), 0x0000, 0x0010); 323 break; 324 case 3: 325 IFX_PCIE_PHY_REG(PCIE_PHY_RX1_CTRL1(pcie_port), 0x0000, 0x0002); 326 break; 327 } 328} 329 330static void pcie_phy_load_war(int pcie_port) 331{ 332 int slice; 333 334 for (slice = 1; slice < 4; slice++) { 335 pcie_phy_load_enable(pcie_port, slice); 336 udelay(1); 337 pcie_phy_load_disable(pcie_port, slice); 338 } 339} 340 341static void pcie_phy_tx2_modulation(int pcie_port) 342{ 343 IFX_PCIE_PHY_REG(PCIE_PHY_TX2_MOD1(pcie_port), 0x1FFE, 0xFFFF); 344 IFX_PCIE_PHY_REG(PCIE_PHY_TX2_MOD2(pcie_port), 0xFFFE, 0xFFFF); 345 IFX_PCIE_PHY_REG(PCIE_PHY_TX2_MOD3(pcie_port), 0x0601, 0xFFFF); 346 mdelay(1); 347 IFX_PCIE_PHY_REG(PCIE_PHY_TX2_MOD3(pcie_port), 0x0001, 0xFFFF); 348} 349 350static void pcie_phy_tx1_modulation(int pcie_port) 351{ 352 IFX_PCIE_PHY_REG(PCIE_PHY_TX1_MOD1(pcie_port), 0x1FFE, 0xFFFF); 353 IFX_PCIE_PHY_REG(PCIE_PHY_TX1_MOD2(pcie_port), 0xFFFE, 0xFFFF); 354 IFX_PCIE_PHY_REG(PCIE_PHY_TX1_MOD3(pcie_port), 0x0601, 0xFFFF); 355 mdelay(1); 356 IFX_PCIE_PHY_REG(PCIE_PHY_TX1_MOD3(pcie_port), 0x0001, 0xFFFF); 357} 358 359static void pcie_phy_tx_modulation_war(int pcie_port) 360{ 361 int i; 362#define PCIE_PHY_MODULATION_NUM 5 363 for (i = 0; i < PCIE_PHY_MODULATION_NUM; i++) { 364 pcie_phy_tx2_modulation(pcie_port); 365 pcie_phy_tx1_modulation(pcie_port); 366 } 367#undef PCIE_PHY_MODULATION_NUM 368} 369 370void pcie_phy_clock_mode_setup(int pcie_port) 371{ 372 pcie_pdi_big_endian(pcie_port); 373 374 /* Enable PDI to access PCIe PHY register */ 375 pcie_pdi_pmu_enable(pcie_port); 376 377 /* Configure PLL and PHY clock */ 378 pcie_phy_comm_setup(pcie_port); 379 380#ifdef CONFIG_IFX_PCIE_PHY_36MHZ_MODE 381 pcie_phy_36mhz_mode_setup(pcie_port); 382#elif defined(CONFIG_IFX_PCIE_PHY_36MHZ_SSC_MODE) 383 pcie_phy_36mhz_ssc_mode_setup(pcie_port); 384#elif defined(CONFIG_IFX_PCIE_PHY_25MHZ_MODE) 385 pcie_phy_25mhz_mode_setup(pcie_port); 386#elif defined (CONFIG_IFX_PCIE_PHY_100MHZ_MODE) 387 pcie_phy_100mhz_mode_setup(pcie_port); 388#else 389 #error "PCIE PHY Clock Mode must be chosen first!!!!" 390#endif /* CONFIG_IFX_PCIE_PHY_36MHZ_MODE */ 391 392 /* Enable PCIe PHY and make PLL setting take effect */ 393 pcie_phy_pmu_enable(pcie_port); 394 395 /* Check if we are in startup_ready status */ 396 pcie_phy_wait_startup_ready(pcie_port); 397 398 pcie_phy_load_war(pcie_port); 399 400 /* Apply TX modulation workarounds */ 401 pcie_phy_tx_modulation_war(pcie_port); 402 403#ifdef IFX_PCI_PHY_REG_DUMP 404 IFX_PCIE_PRINT(PCIE_MSG_PHY, "Modified PHY register dump\n"); 405 pcie_phy_reg_dump(pcie_port); 406#endif 407} 408 409