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 <libfdt.h> 28 #include <fdt_support.h> 29 30 int first_free_busno = 0; 31 32 #ifdef CONFIG_PCI1 33 static struct pci_controller pci1_hose; 34 #endif 35 #ifdef CONFIG_PCIE1 36 static struct pci_controller pcie1_hose; 37 #endif 38 #ifdef CONFIG_PCIE2 39 static struct pci_controller pcie2_hose; 40 #endif 41 #ifdef CONFIG_PCIE3 42 static struct pci_controller pcie3_hose; 43 #endif 44 45 #ifdef CONFIG_MPC8572 46 /* Correlate host/agent POR bits to usable info. Table 4-14 */ 47 struct host_agent_cfg_t { 48 uchar pcie_root[3]; 49 uchar rio_host; 50 } host_agent_cfg[8] = { 51 {{0, 0, 0}, 0}, 52 {{0, 1, 1}, 1}, 53 {{1, 0, 1}, 0}, 54 {{1, 1, 0}, 1}, 55 {{0, 0, 1}, 0}, 56 {{0, 1, 0}, 1}, 57 {{1, 0, 0}, 0}, 58 {{1, 1, 1}, 1} 59 }; 60 61 /* Correlate port width POR bits to usable info. Table 4-15 */ 62 struct io_port_cfg_t { 63 uchar pcie_width[3]; 64 uchar rio_width; 65 } io_port_cfg[16] = { 66 {{0, 0, 0}, 0}, 67 {{0, 0, 0}, 0}, 68 {{4, 0, 0}, 0}, 69 {{4, 4, 0}, 0}, 70 {{0, 0, 0}, 0}, 71 {{0, 0, 0}, 0}, 72 {{0, 0, 0}, 4}, 73 {{4, 2, 2}, 0}, 74 {{0, 0, 0}, 0}, 75 {{0, 0, 0}, 0}, 76 {{0, 0, 0}, 0}, 77 {{4, 0, 0}, 4}, 78 {{4, 0, 0}, 4}, 79 {{0, 0, 0}, 4}, 80 {{0, 0, 0}, 4}, 81 {{8, 0, 0}, 0}, 82 }; 83 #elif defined CONFIG_MPC8548 84 /* Correlate host/agent POR bits to usable info. Table 4-12 */ 85 struct host_agent_cfg_t { 86 uchar pci_host[2]; 87 uchar pcie_root[1]; 88 uchar rio_host; 89 } host_agent_cfg[8] = { 90 {{1, 1}, {0}, 0}, 91 {{1, 1}, {1}, 0}, 92 {{1, 1}, {0}, 1}, 93 {{0, 0}, {0}, 0}, /* reserved */ 94 {{0, 1}, {1}, 0}, 95 {{1, 1}, {1}, 0}, 96 {{0, 1}, {1}, 1}, 97 {{1, 1}, {1}, 1} 98 }; 99 100 /* Correlate port width POR bits to usable info. Table 4-13 */ 101 struct io_port_cfg_t { 102 uchar pcie_width[1]; 103 uchar rio_width; 104 } io_port_cfg[8] = { 105 {{0}, 0}, 106 {{0}, 0}, 107 {{0}, 0}, 108 {{4}, 4}, 109 {{4}, 4}, 110 {{0}, 4}, 111 {{0}, 4}, 112 {{8}, 0}, 113 }; 114 #elif defined CONFIG_MPC86xx 115 /* Correlate host/agent POR bits to usable info. Table 4-17 */ 116 struct host_agent_cfg_t { 117 uchar pcie_root[2]; 118 uchar rio_host; 119 } host_agent_cfg[8] = { 120 {{0, 0}, 0}, 121 {{1, 0}, 1}, 122 {{0, 1}, 0}, 123 {{1, 1}, 1} 124 }; 125 126 /* Correlate port width POR bits to usable info. Table 4-16 */ 127 struct io_port_cfg_t { 128 uchar pcie_width[2]; 129 uchar rio_width; 130 } io_port_cfg[16] = { 131 {{0, 0}, 0}, 132 {{0, 0}, 0}, 133 {{8, 0}, 0}, 134 {{8, 8}, 0}, 135 {{0, 0}, 0}, 136 {{8, 0}, 4}, 137 {{8, 0}, 4}, 138 {{8, 0}, 4}, 139 {{0, 0}, 0}, 140 {{0, 0}, 4}, 141 {{0, 0}, 4}, 142 {{0, 0}, 4}, 143 {{0, 0}, 0}, 144 {{0, 0}, 0}, 145 {{0, 8}, 0}, 146 {{8, 8}, 0}, 147 }; 148 #endif 149 150 /* 151 * 85xx and 86xx share naming conventions, but different layout. 152 * Correlate names to CPU-specific values to share common 153 * PCI code. 154 */ 155 #if defined(CONFIG_MPC85xx) 156 #define MPC8xxx_DEVDISR_PCIE1 MPC85xx_DEVDISR_PCIE 157 #define MPC8xxx_DEVDISR_PCIE2 MPC85xx_DEVDISR_PCIE2 158 #define MPC8xxx_DEVDISR_PCIE3 MPC85xx_DEVDISR_PCIE3 159 #define MPC8xxx_PORDEVSR_IO_SEL MPC85xx_PORDEVSR_IO_SEL 160 #define MPC8xxx_PORDEVSR_IO_SEL_SHIFT MPC85xx_PORDEVSR_IO_SEL_SHIFT 161 #define MPC8xxx_PORBMSR_HA MPC85xx_PORBMSR_HA 162 #define MPC8xxx_PORBMSR_HA_SHIFT MPC85xx_PORBMSR_HA_SHIFT 163 #elif defined(CONFIG_MPC86xx) 164 #define MPC8xxx_DEVDISR_PCIE1 MPC86xx_DEVDISR_PCIEX1 165 #define MPC8xxx_DEVDISR_PCIE2 MPC86xx_DEVDISR_PCIEX2 166 #define MPC8xxx_DEVDISR_PCIE3 0 /* 8641 doesn't have PCIe3 */ 167 #define MPC8xxx_PORDEVSR_IO_SEL MPC8641_PORDEVSR_IO_SEL 168 #define MPC8xxx_PORDEVSR_IO_SEL_SHIFT MPC8641_PORDEVSR_IO_SEL_SHIFT 169 #define MPC8xxx_PORBMSR_HA MPC8641_PORBMSR_HA 170 #define MPC8xxx_PORBMSR_HA_SHIFT MPC8641_PORBMSR_HA_SHIFT 171 #endif 172 173 void pci_init_board(void) 174 { 175 struct pci_controller *hose; 176 volatile ccsr_fsl_pci_t *pci; 177 int width; 178 int host; 179 #if defined(CONFIG_MPC85xx) 180 volatile ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); 181 #elif defined(CONFIG_MPC86xx) 182 immap_t *immap = (immap_t *)CONFIG_SYS_IMMR; 183 volatile ccsr_gur_t *gur = &immap->im_gur; 184 #endif 185 uint devdisr = gur->devdisr; 186 uint io_sel = (gur->pordevsr & MPC8xxx_PORDEVSR_IO_SEL) >> 187 MPC8xxx_PORDEVSR_IO_SEL_SHIFT; 188 uint host_agent = (gur->porbmsr & MPC8xxx_PORBMSR_HA) >> 189 MPC8xxx_PORBMSR_HA_SHIFT; 190 struct pci_region *r; 191 192 #ifdef CONFIG_PCI1 193 uint pci_spd_norm = (gur->pordevsr & MPC85xx_PORDEVSR_PCI1_SPD); 194 uint pci_32 = gur->pordevsr & MPC85xx_PORDEVSR_PCI1_PCI32; 195 uint pci_arb = gur->pordevsr & MPC85xx_PORDEVSR_PCI1_ARB; 196 uint pcix = gur->pordevsr & MPC85xx_PORDEVSR_PCI1; 197 uint freq = CONFIG_SYS_CLK_FREQ / 1000 / 1000; 198 199 width = 0; /* Silence compiler warning... */ 200 io_sel &= 0xf; /* Silence compiler warning... */ 201 pci = (ccsr_fsl_pci_t *) CONFIG_SYS_PCI1_ADDR; 202 hose = &pci1_hose; 203 host = host_agent_cfg[host_agent].pci_host[0]; 204 r = hose->regions; 205 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 /* inbound */ 217 r += fsl_pci_setup_inbound_windows(r); 218 219 /* outbound memory */ 220 pci_set_region(r++, 221 CONFIG_SYS_PCI1_MEM_BASE, 222 CONFIG_SYS_PCI1_MEM_PHYS, 223 CONFIG_SYS_PCI1_MEM_SIZE, 224 PCI_REGION_MEM); 225 226 /* outbound io */ 227 pci_set_region(r++, 228 CONFIG_SYS_PCI1_IO_BASE, 229 CONFIG_SYS_PCI1_IO_PHYS, 230 CONFIG_SYS_PCI1_IO_SIZE, 231 PCI_REGION_IO); 232 233 hose->region_count = r - hose->regions; 234 235 hose->first_busno = first_free_busno; 236 pci_setup_indirect(hose, (int)&pci->cfg_addr, 237 (int)&pci->cfg_data); 238 239 fsl_pci_init(hose); 240 241 /* Unlock inbound PCI configuration cycles */ 242 if (!host) 243 fsl_pci_config_unlock(hose); 244 245 first_free_busno = hose->last_busno + 1; 246 printf(" PCI1 on bus %02x - %02x\n", 247 hose->first_busno, hose->last_busno); 248 } else { 249 printf(" PCI1: disabled\n"); 250 } 251 #elif defined CONFIG_MPC8548 252 /* PCI1 not present on MPC8572 */ 253 gur->devdisr |= MPC85xx_DEVDISR_PCI1; /* disable */ 254 #endif 255 #ifdef CONFIG_PCIE1 256 pci = (ccsr_fsl_pci_t *) CONFIG_SYS_PCIE1_ADDR; 257 hose = &pcie1_hose; 258 host = host_agent_cfg[host_agent].pcie_root[0]; 259 width = io_port_cfg[io_sel].pcie_width[0]; 260 r = hose->regions; 261 262 if (width && !(devdisr & MPC8xxx_DEVDISR_PCIE1)) { 263 printf("\n PCIE1 connected as %s (x%d)", 264 host ? "Root Complex" : "End Point", width); 265 if (pci->pme_msg_det) { 266 pci->pme_msg_det = 0xffffffff; 267 debug(" with errors. Clearing. Now 0x%08x", 268 pci->pme_msg_det); 269 } 270 printf("\n"); 271 272 /* inbound */ 273 r += fsl_pci_setup_inbound_windows(r); 274 275 /* outbound memory */ 276 pci_set_region(r++, 277 CONFIG_SYS_PCIE1_MEM_BASE, 278 CONFIG_SYS_PCIE1_MEM_PHYS, 279 CONFIG_SYS_PCIE1_MEM_SIZE, 280 PCI_REGION_MEM); 281 282 /* outbound io */ 283 pci_set_region(r++, 284 CONFIG_SYS_PCIE1_IO_BASE, 285 CONFIG_SYS_PCIE1_IO_PHYS, 286 CONFIG_SYS_PCIE1_IO_SIZE, 287 PCI_REGION_IO); 288 289 hose->region_count = r - hose->regions; 290 291 hose->first_busno = first_free_busno; 292 pci_setup_indirect(hose, (int)&pci->cfg_addr, 293 (int) &pci->cfg_data); 294 295 fsl_pci_init(hose); 296 297 /* Unlock inbound PCI configuration cycles */ 298 if (!host) 299 fsl_pci_config_unlock(hose); 300 301 first_free_busno = hose->last_busno + 1; 302 printf(" PCIE1 on bus %02x - %02x\n", 303 hose->first_busno, hose->last_busno); 304 } 305 #else 306 gur->devdisr |= MPC8xxx_DEVDISR_PCIE1; /* disable */ 307 #endif /* CONFIG_PCIE1 */ 308 309 #ifdef CONFIG_PCIE2 310 pci = (ccsr_fsl_pci_t *) CONFIG_SYS_PCIE2_ADDR; 311 hose = &pcie2_hose; 312 host = host_agent_cfg[host_agent].pcie_root[1]; 313 width = io_port_cfg[io_sel].pcie_width[1]; 314 r = hose->regions; 315 316 if (width && !(devdisr & MPC8xxx_DEVDISR_PCIE2)) { 317 printf("\n PCIE2 connected as %s (x%d)", 318 host ? "Root Complex" : "End Point", width); 319 if (pci->pme_msg_det) { 320 pci->pme_msg_det = 0xffffffff; 321 debug(" with errors. Clearing. Now 0x%08x", 322 pci->pme_msg_det); 323 } 324 printf("\n"); 325 326 /* inbound */ 327 r += fsl_pci_setup_inbound_windows(r); 328 329 /* outbound memory */ 330 pci_set_region(r++, 331 CONFIG_SYS_PCIE2_MEM_BASE, 332 CONFIG_SYS_PCIE2_MEM_PHYS, 333 CONFIG_SYS_PCIE2_MEM_SIZE, 334 PCI_REGION_MEM); 335 336 /* outbound io */ 337 pci_set_region(r++, 338 CONFIG_SYS_PCIE2_IO_BASE, 339 CONFIG_SYS_PCIE2_IO_PHYS, 340 CONFIG_SYS_PCIE2_IO_SIZE, 341 PCI_REGION_IO); 342 343 hose->region_count = r - hose->regions; 344 345 hose->first_busno = first_free_busno; 346 pci_setup_indirect(hose, (int)&pci->cfg_addr, 347 (int)&pci->cfg_data); 348 349 fsl_pci_init(hose); 350 351 /* Unlock inbound PCI configuration cycles */ 352 if (!host) 353 fsl_pci_config_unlock(hose); 354 355 first_free_busno = hose->last_busno + 1; 356 printf(" PCIE2 on bus %02x - %02x\n", 357 hose->first_busno, hose->last_busno); 358 } 359 #else 360 gur->devdisr |= MPC8xxx_DEVDISR_PCIE2; /* disable */ 361 #endif /* CONFIG_PCIE2 */ 362 363 #ifdef CONFIG_PCIE3 364 pci = (ccsr_fsl_pci_t *) CONFIG_SYS_PCIE3_ADDR; 365 hose = &pcie3_hose; 366 host = host_agent_cfg[host_agent].pcie_root[2]; 367 width = io_port_cfg[io_sel].pcie_width[2]; 368 r = hose->regions; 369 370 if (width && !(devdisr & MPC8xxx_DEVDISR_PCIE3)) { 371 printf("\n PCIE3 connected as %s (x%d)", 372 host ? "Root Complex" : "End Point", width); 373 if (pci->pme_msg_det) { 374 pci->pme_msg_det = 0xffffffff; 375 debug(" with errors. Clearing. Now 0x%08x", 376 pci->pme_msg_det); 377 } 378 printf("\n"); 379 380 /* inbound */ 381 r += fsl_pci_setup_inbound_windows(r); 382 383 /* outbound memory */ 384 pci_set_region(r++, 385 CONFIG_SYS_PCIE3_MEM_BASE, 386 CONFIG_SYS_PCIE3_MEM_PHYS, 387 CONFIG_SYS_PCIE3_MEM_SIZE, 388 PCI_REGION_MEM); 389 390 /* outbound io */ 391 pci_set_region(r++, 392 CONFIG_SYS_PCIE3_IO_BASE, 393 CONFIG_SYS_PCIE3_IO_PHYS, 394 CONFIG_SYS_PCIE3_IO_SIZE, 395 PCI_REGION_IO); 396 397 hose->region_count = r - hose->regions; 398 399 hose->first_busno = first_free_busno; 400 pci_setup_indirect(hose, (int)&pci->cfg_addr, 401 (int)&pci->cfg_data); 402 403 fsl_pci_init(hose); 404 405 /* Unlock inbound PCI configuration cycles */ 406 if (!host) 407 fsl_pci_config_unlock(hose); 408 409 first_free_busno = hose->last_busno + 1; 410 printf(" PCIE3 on bus %02x - %02x\n", 411 hose->first_busno, hose->last_busno); 412 } 413 #else 414 gur->devdisr |= MPC8xxx_DEVDISR_PCIE3; /* disable */ 415 #endif /* CONFIG_PCIE3 */ 416 } 417 418 #if defined(CONFIG_OF_BOARD_SETUP) 419 void ft_board_pci_setup(void *blob, bd_t *bd) 420 { 421 /* TODO - make node name (eg pci0) dynamic */ 422 #ifdef CONFIG_PCI1 423 ft_fsl_pci_setup(blob, "pci0", &pci1_hose); 424 #endif 425 #ifdef CONFIG_PCIE1 426 ft_fsl_pci_setup(blob, "pci2", &pcie1_hose); 427 #endif 428 #ifdef CONFIG_PCIE2 429 ft_fsl_pci_setup(blob, "pci1", &pcie2_hose); 430 #endif 431 #ifdef CONFIG_PCIE3 432 ft_fsl_pci_setup(blob, "pci0", &pcie3_hose); 433 #endif 434 } 435 #endif /* CONFIG_OF_BOARD_SETUP */ 436