Add PCIe and reset related registers/bit fields for QCA, plus minor fixes
[oweals/u-boot_mod.git] / u-boot / board / ar7240 / common / ar7240_pci.c
1 /*****************************************************************************/\r
2 /*! file ap93_pci.c\r
3 ** /brief PCI support for AP91/93 board\r
4 **\r
5 **  This provides the support code required for PCI support on the AP91/93\r
6 **  board in the U-Boot environment.  This board is a Python based system\r
7 **  with a Merlin WLAN interface.  This file also contains the support\r
8 **  for initialization of the Merlin radios on the PCi bus, required for\r
9 **  pre-configuration for use by Linux.\r
10 **\r
11 **  Copyright (c) 2008 Atheros Communications Inc.  All rights reserved.\r
12 **\r
13 */\r
14 \r
15 #include <common.h>\r
16 #include <command.h>\r
17 #include <asm/mipsregs.h>\r
18 #include <asm/addrspace.h>\r
19 #include <config.h>\r
20 #include <version.h>\r
21 #include <pci.h>\r
22 #include "ar7240_soc.h"\r
23 \r
24 /*\r
25 ** PCI controller "hose" value\r
26 */\r
27 static int ar7240_local_write_config(int where, int size, uint32_t value){\r
28         ar7240_reg_wr((AR7240_PCI_CRP + where),value);\r
29         return(0);\r
30 }\r
31 \r
32 /*\r
33 ** We will use the ART configuration information stored in flash to initialize\r
34 ** these devices as required.\r
35 */\r
36 \r
37 // TODO: calibration data doesn't exist?\r
38 /*\r
39 void plat_dev_init(void){\r
40         u32 val;\r
41         u32 addr;\r
42         u32 BaseAddr = 0x10000000;\r
43         u32 CalAddr = WLANCAL;\r
44         volatile u16 *calData;\r
45         calData = (u16 *)CalAddr;\r
46 \r
47         if(calData[0] != 0xa55a && calData[0] != 0x5aa5){\r
48                 printf("BOARD IS NOT CALIBRATED!!!\n");\r
49                 return;\r
50         }\r
51 }\r
52 */\r
53 \r
54 /******************************************************************************/\r
55 /*!\r
56 **  \brief pci host initialization\r
57 **\r
58 **  Sets up the PCI controller on the host.  For AR7240 this may not be necessary,\r
59 **  but this function is required for board support.\r
60 **\r
61 ** We want a 1:1 mapping between PCI and DDR for inbound and outbound.\r
62 ** The PCI<---AHB decoding works as follows:\r
63 **\r
64 ** 8 registers in the DDR unit provide software configurable 32 bit offsets\r
65 ** for each of the eight 16MB PCI windows in the 128MB. The offsets will be\r
66 ** added to any address in the 16MB segment before being sent to the PCI unit.\r
67 **\r
68 ** Essentially  for any AHB address generated by the CPU,\r
69 ** 1. the MSB  four bits are stripped off, [31:28],\r
70 ** 2. Bit 27 is used to decide between the lower 128Mb (PCI) or the rest of\r
71 **    the AHB space\r
72 ** 3. Bits 26:24 are used to access one of the 8 window registers and are\r
73 **    masked off.\r
74 ** 4. If it is a PCI address, then the WINDOW offset in the WINDOW register\r
75 **    corresponding to the next 3 bits (bit 26:24) is ADDED to the address,\r
76 **    to generate the address to PCI unit.\r
77 **\r
78 **     eg. CPU address = 0x100000ff\r
79 **         window 0 offset = 0x10000000\r
80 **         This points to lowermost 16MB window in PCI space.\r
81 **         So the resulting address would be 0x000000ff+0x10000000\r
82 **         = 0x100000ff\r
83 **\r
84 **         eg2. CPU address = 0x120000ff\r
85 **         WINDOW 2 offset = 0x12000000\r
86 **         resulting address would be 0x000000ff+0x12000000\r
87 **                         = 0x120000ff\r
88 **\r
89 ** There is no translation for inbound access (PCI device as a master)\r
90 **\r
91 **  \return N/A\r
92 */\r
93 \r
94 /*\r
95 static int ar7240_pcibios_init(void){\r
96         if(is_ar9341()){\r
97                 return(0);\r
98         }\r
99 \r
100         if(((ar7240_reg_rd(AR7240_PCI_LCL_RESET)) & 0x1) == 0x0){\r
101                 printf("***** Warning *****: PCIe WLAN H/W not found !!!\n");\r
102                 return(0);\r
103         }\r
104 \r
105         return(1);\r
106 }\r
107 */\r
108 \r
109 #define pci_udelay(n)   do { uint32_t i; for(i = 0; i < ((n)/10); i++) udelay(10); } while(0)\r
110 \r
111 int pci_init_board(void){\r
112         uint32_t cmd = 0, reg_val;\r
113         \r
114         reg_val = ar7240_reg_rd(0xb804006c);\r
115         ar7240_reg_wr(0xb804006c, reg_val | 2);\r
116 \r
117         ar7240_reg_wr(0xb804000c, 1 << 2);\r
118 \r
119         pci_udelay(100000);\r
120 \r
121         /*\r
122         if((ar7240_reg_rd(WASP_BOOTSTRAP_REG) & WASP_REF_CLK_25) == 0){\r
123                 ar7240_reg_wr_nf(AR934X_PCIE_PLL_DITHER_DIV_MAX,\r
124                                                  PCIE_PLL_DITHER_DIV_MAX_EN_DITHER_SET(0) |\r
125                                                  PCIE_PLL_DITHER_DIV_MAX_USE_MAX_SET(1) |\r
126                                                  PCIE_PLL_DITHER_DIV_MAX_DIV_MAX_INT_SET(0x20) |\r
127                                                  PCIE_PLL_DITHER_DIV_MAX_DIV_MAX_FRAC_SET(0)\r
128                                                  );\r
129         } else {\r
130                 printf("%s: PCIe PLL not set for 40MHz refclk\n", __func__);\r
131         }\r
132         */\r
133 \r
134         ar7240_reg_rmw_set(AR7240_RESET, AR7240_RESET_PCIE);    // core in reset\r
135         pci_udelay(10000);\r
136         \r
137         ar7240_reg_rmw_set(AR7240_RESET, AR7240_RESET_PCIE_PHY);// phy in reset\r
138         pci_udelay(10000);\r
139         \r
140         ar7240_reg_rmw_clear(RST_MISC2_ADDRESS, RST_MISC2_PERSTN_RCPHY_SET(1)); // pci phy analog in reset\r
141         pci_udelay(10000);\r
142         \r
143         ar7240_reg_wr(0x180f0000, 0x1ffc0);                     // ltssm is disabled\r
144         pci_udelay(100);\r
145 \r
146         ar7240_reg_wr_nf(AR7240_PCI_LCL_RESET, 0);      // End point in reset\r
147         pci_udelay(100000);\r
148 \r
149         //ar7240_reg_rmw_clear(AR7240_RESET, AR7240_RESET_PCIE_PHY);\r
150 \r
151         /*\r
152         if((ar7240_reg_rd(AR7240_REV_ID) & 0xf) == 0){\r
153                 ar7240_reg_wr_nf(AR934X_PCIE_PLL_CONFIG,\r
154                                                  PCIE_PLL_CONFIG_REFDIV_SET(1) |\r
155                                                  PCIE_PLL_CONFIG_BYPASS_SET(1) |\r
156                                                  PCIE_PLL_CONFIG_PLLPWD_SET(1)\r
157                                                  );\r
158                 pci_udelay(10000);\r
159                 \r
160                 ar7240_reg_wr_nf(AR934X_PCIE_PLL_CONFIG,\r
161                                                  PCIE_PLL_CONFIG_REFDIV_SET(1) |\r
162                                                  PCIE_PLL_CONFIG_BYPASS_SET(1) |\r
163                                                  PCIE_PLL_CONFIG_PLLPWD_SET(0)\r
164                                                  );\r
165                 pci_udelay(1000);\r
166                 \r
167                 ar7240_reg_wr_nf(AR934X_PCIE_PLL_CONFIG,\r
168                                                  ar7240_reg_rd(AR934X_PCIE_PLL_CONFIG) &\r
169                                                  (~PCIE_PLL_CONFIG_BYPASS_SET(1))\r
170                                                  );\r
171                 pci_udelay(1000);\r
172         } else {\r
173         */\r
174                 ar7240_reg_wr_nf(0xb8116c04, (0x0 << 30) | (0x4 << 26) | (0x32 << 19) | (1 << 16) | (3 << 13) | (0x1e << 7));\r
175         pci_udelay(10000);\r
176                 \r
177                 ar7240_reg_wr_nf(0xb8116c08, (6 << 23));\r
178         pci_udelay(10000);\r
179                 \r
180                 ar7240_reg_wr_nf(0xb8050010, 0x40010800);\r
181                 pci_udelay(10000);\r
182                 \r
183                 ar7240_reg_wr_nf(0xb8050014, 0xc013fffe);\r
184                 pci_udelay(10000);\r
185                 \r
186                 ar7240_reg_wr_nf(0xb8050018, 0x00138000);\r
187                 pci_udelay(10000);\r
188                 \r
189                 ar7240_reg_wr_nf(0xb8050010, 0x00010800);\r
190                 pci_udelay(100000);\r
191                 \r
192                 ar7240_reg_wr_nf(0xb8050010, 0x00000800);\r
193                 pci_udelay(10000);\r
194         /*\r
195         }\r
196         */\r
197         \r
198         ar7240_reg_rmw_set(RST_MISC2_ADDRESS, RST_MISC2_PERSTN_RCPHY_SET(1)); // pci phy analog out of reset\r
199         pci_udelay(10000);\r
200 \r
201         ar7240_reg_rmw_clear(AR7240_RESET, AR7240_RESET_PCIE_PHY);      // phy out of reset\r
202         pci_udelay(10000);\r
203 \r
204         ar7240_reg_rmw_clear(AR7240_RESET, AR7240_RESET_PCIE);  // core out of reset\r
205         pci_udelay(1000);\r
206 \r
207         cmd =   PCI_COMMAND_MEMORY |\r
208                         PCI_COMMAND_MASTER |\r
209                         PCI_COMMAND_INVALIDATE |\r
210                         PCI_COMMAND_PARITY |\r
211                         PCI_COMMAND_SERR |\r
212                         PCI_COMMAND_FAST_BACK;\r
213 \r
214         ar7240_local_write_config(PCI_COMMAND, 4, cmd);         // pci cmd reg init\r
215         ar7240_local_write_config(0x20, 4, 0x1ff01000);         // membase setting\r
216         ar7240_local_write_config(0x24, 4, 0x1ff01000);         // prefetch membase setting\r
217 \r
218         //if((is_ar7241() || is_ar7242() || is_wasp())){\r
219                 ar7240_reg_wr(0x180f0000, 0x1ffc1);             // ltssm enable\r
220         //} else {\r
221         //      ar7240_reg_wr(0x180f0000, 0x1);\r
222         //}\r
223         pci_udelay(100000);\r
224 \r
225         ar7240_reg_wr_nf(AR7240_PCI_LCL_RESET, 4);              // EP out of reset\r
226         //pci_udelay(100000);\r
227 \r
228         /*\r
229          *  Delay increased from 100 to 1000, so as to\r
230          *  get the correct status from PCI LCL RESET register\r
231          */\r
232         // pci_udelay(100000);\r
233 \r
234         /*\r
235          * Check if the WLAN PCI-E H/W is present, If the\r
236          * WLAN H/W is not present, skip the PCI platform\r
237          * initialization code and return\r
238          */\r
239         //if(((ar7240_reg_rd(AR7240_PCI_LCL_RESET)) & 0x1) == 0x0){\r
240         //      printf("## Error: PCIe WLAN Module not found!\n");\r
241         //}\r
242 \r
243         //plat_dev_init();\r
244         \r
245         return(0);\r
246 }\r