1 /* 2 * Copyright 2008 Extreme Engineering Solutions, Inc. 3 * Copyright 2007-2008 Freescale Semiconductor, Inc. 4 * 5 * See file CREDITS for list of people who contributed to this 6 * project. 7 * 8 * This program is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU General Public License as 10 * published by the Free Software Foundation; either version 2 of 11 * the License, or (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 21 * MA 02111-1307 USA 22 */ 23 24 #include <common.h> 25 #include <pci.h> 26 #include <asm/fsl_pci.h> 27 #include <asm/io.h> 28 #include <libfdt.h> 29 #include <fdt_support.h> 30 31 int first_free_busno = 0; 32 33 #ifdef CONFIG_PCI1 34 static struct pci_controller pci1_hose; 35 #endif 36 #ifdef CONFIG_PCIE1 37 static struct pci_controller pcie1_hose; 38 #endif 39 #ifdef CONFIG_PCIE2 40 static struct pci_controller pcie2_hose; 41 #endif 42 #ifdef CONFIG_PCIE3 43 static struct pci_controller pcie3_hose; 44 #endif 45 46 #ifdef CONFIG_MPC8572 47 /* Correlate host/agent POR bits to usable info. Table 4-14 */ 48 struct host_agent_cfg_t { 49 uchar pcie_root[3]; 50 uchar rio_host; 51 } host_agent_cfg[8] = { 52 {{0, 0, 0}, 0}, 53 {{0, 1, 1}, 1}, 54 {{1, 0, 1}, 0}, 55 {{1, 1, 0}, 1}, 56 {{0, 0, 1}, 0}, 57 {{0, 1, 0}, 1}, 58 {{1, 0, 0}, 0}, 59 {{1, 1, 1}, 1} 60 }; 61 62 /* Correlate port width POR bits to usable info. Table 4-15 */ 63 struct io_port_cfg_t { 64 uchar pcie_width[3]; 65 uchar rio_width; 66 } io_port_cfg[16] = { 67 {{0, 0, 0}, 0}, 68 {{0, 0, 0}, 0}, 69 {{4, 0, 0}, 0}, 70 {{4, 4, 0}, 0}, 71 {{0, 0, 0}, 0}, 72 {{0, 0, 0}, 0}, 73 {{0, 0, 0}, 4}, 74 {{4, 2, 2}, 0}, 75 {{0, 0, 0}, 0}, 76 {{0, 0, 0}, 0}, 77 {{0, 0, 0}, 0}, 78 {{4, 0, 0}, 4}, 79 {{4, 0, 0}, 4}, 80 {{0, 0, 0}, 4}, 81 {{0, 0, 0}, 4}, 82 {{8, 0, 0}, 0}, 83 }; 84 #elif defined CONFIG_MPC8548 85 /* Correlate host/agent POR bits to usable info. Table 4-12 */ 86 struct host_agent_cfg_t { 87 uchar pci_host[2]; 88 uchar pcie_root[1]; 89 uchar rio_host; 90 } host_agent_cfg[8] = { 91 {{1, 1}, {0}, 0}, 92 {{1, 1}, {1}, 0}, 93 {{1, 1}, {0}, 1}, 94 {{0, 0}, {0}, 0}, /* reserved */ 95 {{0, 1}, {1}, 0}, 96 {{1, 1}, {1}, 0}, 97 {{0, 1}, {1}, 1}, 98 {{1, 1}, {1}, 1} 99 }; 100 101 /* Correlate port width POR bits to usable info. Table 4-13 */ 102 struct io_port_cfg_t { 103 uchar pcie_width[1]; 104 uchar rio_width; 105 } io_port_cfg[8] = { 106 {{0}, 0}, 107 {{0}, 0}, 108 {{0}, 0}, 109 {{4}, 4}, 110 {{4}, 4}, 111 {{0}, 4}, 112 {{0}, 4}, 113 {{8}, 0}, 114 }; 115 #elif defined CONFIG_MPC86xx 116 /* Correlate host/agent POR bits to usable info. Table 4-17 */ 117 struct host_agent_cfg_t { 118 uchar pcie_root[2]; 119 uchar rio_host; 120 } host_agent_cfg[8] = { 121 {{0, 0}, 0}, 122 {{1, 0}, 1}, 123 {{0, 1}, 0}, 124 {{1, 1}, 1} 125 }; 126 127 /* Correlate port width POR bits to usable info. Table 4-16 */ 128 struct io_port_cfg_t { 129 uchar pcie_width[2]; 130 uchar rio_width; 131 } io_port_cfg[16] = { 132 {{0, 0}, 0}, 133 {{0, 0}, 0}, 134 {{8, 0}, 0}, 135 {{8, 8}, 0}, 136 {{0, 0}, 0}, 137 {{8, 0}, 4}, 138 {{8, 0}, 4}, 139 {{8, 0}, 4}, 140 {{0, 0}, 0}, 141 {{0, 0}, 4}, 142 {{0, 0}, 4}, 143 {{0, 0}, 4}, 144 {{0, 0}, 0}, 145 {{0, 0}, 0}, 146 {{0, 8}, 0}, 147 {{8, 8}, 0}, 148 }; 149 #endif 150 151 /* 152 * 85xx and 86xx share naming conventions, but different layout. 153 * Correlate names to CPU-specific values to share common 154 * PCI code. 155 */ 156 #if defined(CONFIG_MPC85xx) 157 #define MPC8xxx_DEVDISR_PCIE1 MPC85xx_DEVDISR_PCIE 158 #define MPC8xxx_DEVDISR_PCIE2 MPC85xx_DEVDISR_PCIE2 159 #define MPC8xxx_DEVDISR_PCIE3 MPC85xx_DEVDISR_PCIE3 160 #define MPC8xxx_PORDEVSR_IO_SEL MPC85xx_PORDEVSR_IO_SEL 161 #define MPC8xxx_PORDEVSR_IO_SEL_SHIFT MPC85xx_PORDEVSR_IO_SEL_SHIFT 162 #define MPC8xxx_PORBMSR_HA MPC85xx_PORBMSR_HA 163 #define MPC8xxx_PORBMSR_HA_SHIFT MPC85xx_PORBMSR_HA_SHIFT 164 #elif defined(CONFIG_MPC86xx) 165 #define MPC8xxx_DEVDISR_PCIE1 MPC86xx_DEVDISR_PCIEX1 166 #define MPC8xxx_DEVDISR_PCIE2 MPC86xx_DEVDISR_PCIEX2 167 #define MPC8xxx_DEVDISR_PCIE3 0 /* 8641 doesn't have PCIe3 */ 168 #define MPC8xxx_PORDEVSR_IO_SEL MPC8641_PORDEVSR_IO_SEL 169 #define MPC8xxx_PORDEVSR_IO_SEL_SHIFT MPC8641_PORDEVSR_IO_SEL_SHIFT 170 #define MPC8xxx_PORBMSR_HA MPC8641_PORBMSR_HA 171 #define MPC8xxx_PORBMSR_HA_SHIFT MPC8641_PORBMSR_HA_SHIFT 172 #endif 173 174 void pci_init_board(void) 175 { 176 struct pci_controller *hose; 177 volatile ccsr_fsl_pci_t *pci; 178 int width; 179 int host; 180 #if defined(CONFIG_MPC85xx) 181 volatile ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); 182 #elif defined(CONFIG_MPC86xx) 183 immap_t *immap = (immap_t *)CONFIG_SYS_IMMR; 184 volatile ccsr_gur_t *gur = &immap->im_gur; 185 #endif 186 uint devdisr = in_be32(&gur->devdisr); 187 uint io_sel = (in_be32(&gur->pordevsr) & MPC8xxx_PORDEVSR_IO_SEL) >> 188 MPC8xxx_PORDEVSR_IO_SEL_SHIFT; 189 uint host_agent = (in_be32(&gur->porbmsr) & MPC8xxx_PORBMSR_HA) >> 190 MPC8xxx_PORBMSR_HA_SHIFT; 191 struct pci_region *r; 192 193 #ifdef CONFIG_PCI1 194 uint pci_spd_norm = in_be32(&gur->pordevsr) & MPC85xx_PORDEVSR_PCI1_SPD; 195 uint pci_32 = in_be32(&gur->pordevsr) & MPC85xx_PORDEVSR_PCI1_PCI32; 196 uint pci_arb = in_be32(&gur->pordevsr) & MPC85xx_PORDEVSR_PCI1_ARB; 197 uint pcix = in_be32(&gur->pordevsr) & MPC85xx_PORDEVSR_PCI1; 198 uint freq = CONFIG_SYS_CLK_FREQ / 1000 / 1000; 199 200 width = 0; /* Silence compiler warning... */ 201 io_sel &= 0xf; /* Silence compiler warning... */ 202 pci = (ccsr_fsl_pci_t *) CONFIG_SYS_PCI1_ADDR; 203 hose = &pci1_hose; 204 host = host_agent_cfg[host_agent].pci_host[0]; 205 r = hose->regions; 206 207 if (!(devdisr & MPC85xx_DEVDISR_PCI1)) { 208 printf("\n PCI1: %d bit %s, %s %d MHz, %s, %s\n", 209 pci_32 ? 32 : 64, 210 pcix ? "PCIX" : "PCI", 211 pci_spd_norm ? ">=" : "<=", 212 pcix ? freq * 2 : freq, 213 host ? "host" : "agent", 214 pci_arb ? "arbiter" : "external-arbiter"); 215 216 /* outbound memory */ 217 pci_set_region(r++, 218 CONFIG_SYS_PCI1_MEM_BASE, 219 CONFIG_SYS_PCI1_MEM_PHYS, 220 CONFIG_SYS_PCI1_MEM_SIZE, 221 PCI_REGION_MEM); 222 223 /* outbound io */ 224 pci_set_region(r++, 225 CONFIG_SYS_PCI1_IO_BASE, 226 CONFIG_SYS_PCI1_IO_PHYS, 227 CONFIG_SYS_PCI1_IO_SIZE, 228 PCI_REGION_IO); 229 230 hose->region_count = r - hose->regions; 231 232 hose->first_busno = first_free_busno; 233 234 fsl_pci_init(hose, (u32)&pci->cfg_addr, (u32)&pci->cfg_data); 235 236 /* Unlock inbound PCI configuration cycles */ 237 if (!host) 238 fsl_pci_config_unlock(hose); 239 240 first_free_busno = hose->last_busno + 1; 241 printf(" PCI1 on bus %02x - %02x\n", 242 hose->first_busno, hose->last_busno); 243 } else { 244 printf(" PCI1: disabled\n"); 245 } 246 #elif defined CONFIG_MPC8548 247 /* PCI1 not present on MPC8572 */ 248 setbits_be32(&gur->devdisr, MPC85xx_DEVDISR_PCI1); 249 #endif 250 #ifdef CONFIG_PCIE1 251 pci = (ccsr_fsl_pci_t *) CONFIG_SYS_PCIE1_ADDR; 252 hose = &pcie1_hose; 253 host = host_agent_cfg[host_agent].pcie_root[0]; 254 width = io_port_cfg[io_sel].pcie_width[0]; 255 r = hose->regions; 256 257 if (width && !(devdisr & MPC8xxx_DEVDISR_PCIE1)) { 258 printf("\n PCIE1 connected as %s (x%d)", 259 host ? "Root Complex" : "Endpoint", width); 260 if (in_be32(&pci->pme_msg_det)) { 261 out_be32(&pci->pme_msg_det, 0xffffffff); 262 debug(" with errors. Clearing. Now 0x%08x", 263 in_be32(&pci->pme_msg_det)); 264 } 265 printf("\n"); 266 267 /* outbound memory */ 268 pci_set_region(r++, 269 CONFIG_SYS_PCIE1_MEM_BASE, 270 CONFIG_SYS_PCIE1_MEM_PHYS, 271 CONFIG_SYS_PCIE1_MEM_SIZE, 272 PCI_REGION_MEM); 273 274 /* outbound io */ 275 pci_set_region(r++, 276 CONFIG_SYS_PCIE1_IO_BASE, 277 CONFIG_SYS_PCIE1_IO_PHYS, 278 CONFIG_SYS_PCIE1_IO_SIZE, 279 PCI_REGION_IO); 280 281 hose->region_count = r - hose->regions; 282 283 hose->first_busno = first_free_busno; 284 285 fsl_pci_init(hose, (u32)&pci->cfg_addr, (u32)&pci->cfg_data); 286 287 /* Unlock inbound PCI configuration cycles */ 288 if (!host) 289 fsl_pci_config_unlock(hose); 290 291 first_free_busno = hose->last_busno + 1; 292 printf(" PCIE1 on bus %02x - %02x\n", 293 hose->first_busno, hose->last_busno); 294 } 295 #else 296 setbits_be32(&gur->devdisr, MPC8xxx_DEVDISR_PCIE1); 297 #endif /* CONFIG_PCIE1 */ 298 299 #ifdef CONFIG_PCIE2 300 pci = (ccsr_fsl_pci_t *) CONFIG_SYS_PCIE2_ADDR; 301 hose = &pcie2_hose; 302 host = host_agent_cfg[host_agent].pcie_root[1]; 303 width = io_port_cfg[io_sel].pcie_width[1]; 304 r = hose->regions; 305 306 if (width && !(devdisr & MPC8xxx_DEVDISR_PCIE2)) { 307 printf("\n PCIE2 connected as %s (x%d)", 308 host ? "Root Complex" : "Endpoint", width); 309 if (in_be32(&pci->pme_msg_det)) { 310 out_be32(&pci->pme_msg_det, 0xffffffff); 311 debug(" with errors. Clearing. Now 0x%08x", 312 in_be32(&pci->pme_msg_det)); 313 } 314 printf("\n"); 315 316 /* outbound memory */ 317 pci_set_region(r++, 318 CONFIG_SYS_PCIE2_MEM_BASE, 319 CONFIG_SYS_PCIE2_MEM_PHYS, 320 CONFIG_SYS_PCIE2_MEM_SIZE, 321 PCI_REGION_MEM); 322 323 /* outbound io */ 324 pci_set_region(r++, 325 CONFIG_SYS_PCIE2_IO_BASE, 326 CONFIG_SYS_PCIE2_IO_PHYS, 327 CONFIG_SYS_PCIE2_IO_SIZE, 328 PCI_REGION_IO); 329 330 hose->region_count = r - hose->regions; 331 332 hose->first_busno = first_free_busno; 333 334 fsl_pci_init(hose, (u32)&pci->cfg_addr, (u32)&pci->cfg_data); 335 336 /* Unlock inbound PCI configuration cycles */ 337 if (!host) 338 fsl_pci_config_unlock(hose); 339 340 first_free_busno = hose->last_busno + 1; 341 printf(" PCIE2 on bus %02x - %02x\n", 342 hose->first_busno, hose->last_busno); 343 } 344 #else 345 setbits_be32(&gur->devdisr, MPC8xxx_DEVDISR_PCIE2); 346 #endif /* CONFIG_PCIE2 */ 347 348 #ifdef CONFIG_PCIE3 349 pci = (ccsr_fsl_pci_t *) CONFIG_SYS_PCIE3_ADDR; 350 hose = &pcie3_hose; 351 host = host_agent_cfg[host_agent].pcie_root[2]; 352 width = io_port_cfg[io_sel].pcie_width[2]; 353 r = hose->regions; 354 355 if (width && !(devdisr & MPC8xxx_DEVDISR_PCIE3)) { 356 printf("\n PCIE3 connected as %s (x%d)", 357 host ? "Root Complex" : "Endpoint", width); 358 if (in_be32(&pci->pme_msg_det)) { 359 out_be32(&pci->pme_msg_det, 0xffffffff); 360 debug(" with errors. Clearing. Now 0x%08x", 361 in_be32(&pci->pme_msg_det)); 362 } 363 printf("\n"); 364 365 /* outbound memory */ 366 pci_set_region(r++, 367 CONFIG_SYS_PCIE3_MEM_BASE, 368 CONFIG_SYS_PCIE3_MEM_PHYS, 369 CONFIG_SYS_PCIE3_MEM_SIZE, 370 PCI_REGION_MEM); 371 372 /* outbound io */ 373 pci_set_region(r++, 374 CONFIG_SYS_PCIE3_IO_BASE, 375 CONFIG_SYS_PCIE3_IO_PHYS, 376 CONFIG_SYS_PCIE3_IO_SIZE, 377 PCI_REGION_IO); 378 379 hose->region_count = r - hose->regions; 380 381 hose->first_busno = first_free_busno; 382 383 fsl_pci_init(hose, (u32)&pci->cfg_addr, (u32)&pci->cfg_data); 384 385 /* Unlock inbound PCI configuration cycles */ 386 if (!host) 387 fsl_pci_config_unlock(hose); 388 389 first_free_busno = hose->last_busno + 1; 390 printf(" PCIE3 on bus %02x - %02x\n", 391 hose->first_busno, hose->last_busno); 392 } 393 #else 394 setbits_be32(&gur->devdisr, MPC8xxx_DEVDISR_PCIE3); 395 #endif /* CONFIG_PCIE3 */ 396 } 397 398 #if defined(CONFIG_OF_BOARD_SETUP) 399 void ft_board_pci_setup(void *blob, bd_t *bd) 400 { 401 FT_FSL_PCI_SETUP; 402 } 403 #endif /* CONFIG_OF_BOARD_SETUP */ 404