1 /******************************************************************************
3 ** FILE NAME : ifxmips_pcie_phy.c
4 ** PROJECT : IFX UEIP for VRX200
5 ** MODULES : PCIe PHY sub module
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
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.
19 ** $Version $Date $Author $Comment
20 ** 0.0.1 14 May,2009 Lei Chuanhua Initial version
21 *******************************************************************************/
23 \file ifxmips_pcie_phy.c
25 \brief PCIe PHY PLL register programming source file
27 #include <linux/types.h>
28 #include <linux/kernel.h>
29 #include <asm/paccess.h>
30 #include <linux/delay.h>
32 #include "pcie-lantiq.h"
34 /* PCIe PDI only supports 16 bit operation */
36 #define IFX_PCIE_PHY_REG_WRITE16(__addr, __data) \
37 ((*(volatile u16 *) (__addr)) = (__data))
39 #define IFX_PCIE_PHY_REG_READ16(__addr) \
40 (*(volatile u16 *) (__addr))
42 #define IFX_PCIE_PHY_REG16(__addr) \
43 (*(volatile u16 *) (__addr))
45 #define IFX_PCIE_PHY_REG(__reg, __value, __mask) do { \
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); \
53 #define IFX_PCIE_PLL_TIMEOUT 1000 /* Tunnable */
56 pcie_phy_comm_setup(int pcie_port)
59 IFX_PCIE_PHY_REG(PCIE_PHY_PLL_A_CTRL1(pcie_port), 0x120e, 0xFFFF);
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);
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);
70 IFX_PCIE_PHY_REG(PCIE_PHY_TX1_CTRL1(pcie_port), 0x0008, 0x0008);
73 IFX_PCIE_PHY_REG(PCIE_PHY_TX1_A_CTRL2(pcie_port), 0x0706, 0xFFFF);
76 IFX_PCIE_PHY_REG(PCIE_PHY_TX1_CTRL3(pcie_port), 0x1FFF, 0xFFFF);
79 IFX_PCIE_PHY_REG(PCIE_PHY_TX1_A_CTRL1(pcie_port), 0x0800, 0xFF00);
82 IFX_PCIE_PHY_REG(PCIE_PHY_TX2_A_CTRL2(pcie_port), 0x4702, 0x7F00);
85 IFX_PCIE_PHY_REG(PCIE_PHY_TX1_CTRL2(pcie_port), 0x2e00, 0xFFFF);
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);
91 /* Reduced CDR BW to avoid glitches */
92 IFX_PCIE_PHY_REG(PCIE_PHY_RX1_CDR(pcie_port), 0x0235, 0xFFFF);
95 #ifdef CONFIG_IFX_PCIE_PHY_36MHZ_MODE
97 pcie_phy_36mhz_mode_setup(int pcie_port)
99 IFX_PCIE_PRINT(PCIE_MSG_PHY, "%s pcie_port %d enter\n", __func__, pcie_port);
101 /* en_ext_mmd_div_ratio */
102 IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL3(pcie_port), 0x0000, 0x0002);
104 /* ext_mmd_div_ratio*/
105 IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL3(pcie_port), 0x0000, 0x0070);
108 IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL2(pcie_port), 0x0200, 0x0200);
111 IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL2(pcie_port), 0x0100, 0x0100);
114 IFX_PCIE_PHY_REG(PCIE_PHY_PLL_A_CTRL3(pcie_port), 0x2000, 0xe000);
117 IFX_PCIE_PHY_REG(PCIE_PHY_PLL_A_CTRL2(pcie_port), 0x0000, 0x4000);
120 IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL1(pcie_port), 0x38e4, 0xFFFF);
123 IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL2(pcie_port), 0x00ee, 0x00FF);
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);
131 IFX_PCIE_PRINT(PCIE_MSG_PHY, "%s pcie_port %d exit\n", __func__, pcie_port);
133 #endif /* CONFIG_IFX_PCIE_PHY_36MHZ_MODE */
135 #ifdef CONFIG_IFX_PCIE_PHY_36MHZ_SSC_MODE
137 pcie_phy_36mhz_ssc_mode_setup(int pcie_port)
139 IFX_PCIE_PRINT(PCIE_MSG_PHY, "%s pcie_port %d enter\n", __func__, pcie_port);
142 IFX_PCIE_PHY_REG(PCIE_PHY_PLL_A_CTRL1(pcie_port), 0x120e, 0xFFFF);
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);
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);
153 IFX_PCIE_PHY_REG(PCIE_PHY_TX1_CTRL1(pcie_port), 0x0008, 0x0008);
156 IFX_PCIE_PHY_REG(PCIE_PHY_TX1_A_CTRL2(pcie_port), 0x0706, 0xFFFF);
159 IFX_PCIE_PHY_REG(PCIE_PHY_TX1_CTRL3(pcie_port), 0x1FFF, 0xFFFF);
162 IFX_PCIE_PHY_REG(PCIE_PHY_TX1_A_CTRL1(pcie_port), 0x0800, 0xFF00);
165 IFX_PCIE_PHY_REG(PCIE_PHY_TX2_A_CTRL2(pcie_port), 0x4702, 0x7F00);
168 IFX_PCIE_PHY_REG(PCIE_PHY_TX1_CTRL2(pcie_port), 0x2e00, 0xFFFF);
170 /* en_ext_mmd_div_ratio */
171 IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL3(pcie_port), 0x0000, 0x0002);
173 /* ext_mmd_div_ratio*/
174 IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL3(pcie_port), 0x0000, 0x0070);
177 IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL2(pcie_port), 0x0400, 0x0400);
180 IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL2(pcie_port), 0x0200, 0x0200);
183 IFX_PCIE_PHY_REG(PCIE_PHY_PLL_A_CTRL3(pcie_port), 0x2000, 0xe000);
186 IFX_PCIE_PHY_REG(PCIE_PHY_PLL_A_CTRL2(pcie_port), 0x0000, 0x4000);
189 IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL1(pcie_port), 0x38e4, 0xFFFF);
191 IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL2(pcie_port), 0x0000, 0x0100);
193 IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL2(pcie_port), 0x00ee, 0x00FF);
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);
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);
205 /* reduced CDR BW to avoid glitches */
206 IFX_PCIE_PHY_REG(PCIE_PHY_RX1_CDR(pcie_port), 0x0235, 0xFFFF);
208 IFX_PCIE_PRINT(PCIE_MSG_PHY, "%s pcie_port %d exit\n", __func__, pcie_port);
210 #endif /* CONFIG_IFX_PCIE_PHY_36MHZ_SSC_MODE */
212 #ifdef CONFIG_IFX_PCIE_PHY_25MHZ_MODE
214 pcie_phy_25mhz_mode_setup(int pcie_port)
216 IFX_PCIE_PRINT(PCIE_MSG_PHY, "%s pcie_port %d enter\n", __func__, pcie_port);
218 IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL2(pcie_port), 0x0100, 0x0100);
221 IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL2(pcie_port), 0x0000, 0x0200);
223 /* en_ext_mmd_div_ratio*/
224 IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL3(pcie_port), 0x0002, 0x0002);
226 /* ext_mmd_div_ratio*/
227 IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL3(pcie_port), 0x0040, 0x0070);
230 IFX_PCIE_PHY_REG(PCIE_PHY_PLL_A_CTRL3(pcie_port), 0x6000, 0xe000);
233 IFX_PCIE_PHY_REG(PCIE_PHY_PLL_A_CTRL2(pcie_port), 0x4000, 0x4000);
235 IFX_PCIE_PRINT(PCIE_MSG_PHY, "%s pcie_port %d exit\n", __func__, pcie_port);
237 #endif /* CONFIG_IFX_PCIE_PHY_25MHZ_MODE */
239 #ifdef CONFIG_IFX_PCIE_PHY_100MHZ_MODE
241 pcie_phy_100mhz_mode_setup(int pcie_port)
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);
247 /* ext_mmd_div_ratio*/
248 IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL3(pcie_port), 0x0000, 0x0070);
251 IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL2(pcie_port), 0x0200, 0x0200);
254 IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL2(pcie_port), 0x0100, 0x0100);
257 IFX_PCIE_PHY_REG(PCIE_PHY_PLL_A_CTRL3(pcie_port), 0x2000, 0xe000);
260 IFX_PCIE_PHY_REG(PCIE_PHY_PLL_A_CTRL2(pcie_port), 0x0000, 0x4000);
263 IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL1(pcie_port), 0x38e4, 0xFFFF);
266 IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL2(pcie_port), 0x00ee, 0x00FF);
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);
274 IFX_PCIE_PRINT(PCIE_MSG_PHY, "%s pcie_port %d exit\n", __func__, pcie_port);
276 #endif /* CONFIG_IFX_PCIE_PHY_100MHZ_MODE */
279 pcie_phy_wait_startup_ready(int pcie_port)
283 for (i = 0; i < IFX_PCIE_PLL_TIMEOUT; i++) {
284 if ((IFX_PCIE_PHY_REG16(PCIE_PHY_PLL_STATUS(pcie_port)) & 0x0040) != 0) {
289 if (i >= IFX_PCIE_PLL_TIMEOUT) {
290 printk(KERN_ERR "%s PLL Link timeout\n", __func__);
297 pcie_phy_load_enable(int pcie_port, int slice)
299 /* Set the load_en of tx/rx slice to '1' */
302 IFX_PCIE_PHY_REG(PCIE_PHY_TX1_CTRL1(pcie_port), 0x0010, 0x0010);
305 IFX_PCIE_PHY_REG(PCIE_PHY_TX2_CTRL1(pcie_port), 0x0010, 0x0010);
308 IFX_PCIE_PHY_REG(PCIE_PHY_RX1_CTRL1(pcie_port), 0x0002, 0x0002);
314 pcie_phy_load_disable(int pcie_port, int slice)
316 /* set the load_en of tx/rx slice to '0' */
319 IFX_PCIE_PHY_REG(PCIE_PHY_TX1_CTRL1(pcie_port), 0x0000, 0x0010);
322 IFX_PCIE_PHY_REG(PCIE_PHY_TX2_CTRL1(pcie_port), 0x0000, 0x0010);
325 IFX_PCIE_PHY_REG(PCIE_PHY_RX1_CTRL1(pcie_port), 0x0000, 0x0002);
330 static void pcie_phy_load_war(int pcie_port)
334 for (slice = 1; slice < 4; slice++) {
335 pcie_phy_load_enable(pcie_port, slice);
337 pcie_phy_load_disable(pcie_port, slice);
341 static void pcie_phy_tx2_modulation(int pcie_port)
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);
347 IFX_PCIE_PHY_REG(PCIE_PHY_TX2_MOD3(pcie_port), 0x0001, 0xFFFF);
350 static void pcie_phy_tx1_modulation(int pcie_port)
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);
356 IFX_PCIE_PHY_REG(PCIE_PHY_TX1_MOD3(pcie_port), 0x0001, 0xFFFF);
359 static void pcie_phy_tx_modulation_war(int pcie_port)
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);
367 #undef PCIE_PHY_MODULATION_NUM
370 void pcie_phy_clock_mode_setup(int pcie_port)
372 pcie_pdi_big_endian(pcie_port);
374 /* Enable PDI to access PCIe PHY register */
375 pcie_pdi_pmu_enable(pcie_port);
377 /* Configure PLL and PHY clock */
378 pcie_phy_comm_setup(pcie_port);
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);
389 #error "PCIE PHY Clock Mode must be chosen first!!!!"
390 #endif /* CONFIG_IFX_PCIE_PHY_36MHZ_MODE */
392 /* Enable PCIe PHY and make PLL setting take effect */
393 pcie_phy_pmu_enable(pcie_port);
395 /* Check if we are in startup_ready status */
396 pcie_phy_wait_startup_ready(pcie_port);
398 pcie_phy_load_war(pcie_port);
400 /* Apply TX modulation workarounds */
401 pcie_phy_tx_modulation_war(pcie_port);
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);