119580e66SDave Liu /* 29993e196SKim Phillips * Copyright (C) 2006-2009 Freescale Semiconductor, Inc. 319580e66SDave Liu * 419580e66SDave Liu * See file CREDITS for list of people who contributed to this 519580e66SDave Liu * project. 619580e66SDave Liu * 719580e66SDave Liu * This program is free software; you can redistribute it and/or 819580e66SDave Liu * modify it under the terms of the GNU General Public License as 919580e66SDave Liu * published by the Free Software Foundation; either version 2 of 1019580e66SDave Liu * the License, or (at your option) any later version. 1119580e66SDave Liu */ 1219580e66SDave Liu 1319580e66SDave Liu #include <asm/mmu.h> 1419580e66SDave Liu #include <asm/io.h> 1519580e66SDave Liu #include <common.h> 1619580e66SDave Liu #include <mpc83xx.h> 1719580e66SDave Liu #include <pci.h> 1819580e66SDave Liu #include <i2c.h> 198b34557cSAnton Vorontsov #include <fdt_support.h> 2019580e66SDave Liu #include <asm/fsl_i2c.h> 217e1afb62SKumar Gala #include <asm/fsl_mpc83xx_serdes.h> 2219580e66SDave Liu 2319580e66SDave Liu static struct pci_region pci_regions[] = { 2419580e66SDave Liu { 256d0f6bcfSJean-Christophe PLAGNIOL-VILLARD bus_start: CONFIG_SYS_PCI_MEM_BASE, 266d0f6bcfSJean-Christophe PLAGNIOL-VILLARD phys_start: CONFIG_SYS_PCI_MEM_PHYS, 276d0f6bcfSJean-Christophe PLAGNIOL-VILLARD size: CONFIG_SYS_PCI_MEM_SIZE, 2819580e66SDave Liu flags: PCI_REGION_MEM | PCI_REGION_PREFETCH 2919580e66SDave Liu }, 3019580e66SDave Liu { 316d0f6bcfSJean-Christophe PLAGNIOL-VILLARD bus_start: CONFIG_SYS_PCI_MMIO_BASE, 326d0f6bcfSJean-Christophe PLAGNIOL-VILLARD phys_start: CONFIG_SYS_PCI_MMIO_PHYS, 336d0f6bcfSJean-Christophe PLAGNIOL-VILLARD size: CONFIG_SYS_PCI_MMIO_SIZE, 3419580e66SDave Liu flags: PCI_REGION_MEM 3519580e66SDave Liu }, 3619580e66SDave Liu { 376d0f6bcfSJean-Christophe PLAGNIOL-VILLARD bus_start: CONFIG_SYS_PCI_IO_BASE, 386d0f6bcfSJean-Christophe PLAGNIOL-VILLARD phys_start: CONFIG_SYS_PCI_IO_PHYS, 396d0f6bcfSJean-Christophe PLAGNIOL-VILLARD size: CONFIG_SYS_PCI_IO_SIZE, 4019580e66SDave Liu flags: PCI_REGION_IO 4119580e66SDave Liu } 4219580e66SDave Liu }; 4319580e66SDave Liu 448b34557cSAnton Vorontsov static struct pci_region pcie_regions_0[] = { 458b34557cSAnton Vorontsov { 468b34557cSAnton Vorontsov .bus_start = CONFIG_SYS_PCIE1_MEM_BASE, 478b34557cSAnton Vorontsov .phys_start = CONFIG_SYS_PCIE1_MEM_PHYS, 488b34557cSAnton Vorontsov .size = CONFIG_SYS_PCIE1_MEM_SIZE, 498b34557cSAnton Vorontsov .flags = PCI_REGION_MEM, 508b34557cSAnton Vorontsov }, 518b34557cSAnton Vorontsov { 528b34557cSAnton Vorontsov .bus_start = CONFIG_SYS_PCIE1_IO_BASE, 538b34557cSAnton Vorontsov .phys_start = CONFIG_SYS_PCIE1_IO_PHYS, 548b34557cSAnton Vorontsov .size = CONFIG_SYS_PCIE1_IO_SIZE, 558b34557cSAnton Vorontsov .flags = PCI_REGION_IO, 568b34557cSAnton Vorontsov }, 578b34557cSAnton Vorontsov }; 588b34557cSAnton Vorontsov 598b34557cSAnton Vorontsov static struct pci_region pcie_regions_1[] = { 608b34557cSAnton Vorontsov { 618b34557cSAnton Vorontsov .bus_start = CONFIG_SYS_PCIE2_MEM_BASE, 628b34557cSAnton Vorontsov .phys_start = CONFIG_SYS_PCIE2_MEM_PHYS, 638b34557cSAnton Vorontsov .size = CONFIG_SYS_PCIE2_MEM_SIZE, 648b34557cSAnton Vorontsov .flags = PCI_REGION_MEM, 658b34557cSAnton Vorontsov }, 668b34557cSAnton Vorontsov { 678b34557cSAnton Vorontsov .bus_start = CONFIG_SYS_PCIE2_IO_BASE, 688b34557cSAnton Vorontsov .phys_start = CONFIG_SYS_PCIE2_IO_PHYS, 698b34557cSAnton Vorontsov .size = CONFIG_SYS_PCIE2_IO_SIZE, 708b34557cSAnton Vorontsov .flags = PCI_REGION_IO, 718b34557cSAnton Vorontsov }, 728b34557cSAnton Vorontsov }; 738b34557cSAnton Vorontsov 748b34557cSAnton Vorontsov static int is_pex_x2(void) 758b34557cSAnton Vorontsov { 768b34557cSAnton Vorontsov const char *pex_x2 = getenv("pex_x2"); 778b34557cSAnton Vorontsov 788b34557cSAnton Vorontsov if (pex_x2 && !strcmp(pex_x2, "yes")) 798b34557cSAnton Vorontsov return 1; 808b34557cSAnton Vorontsov return 0; 818b34557cSAnton Vorontsov } 828b34557cSAnton Vorontsov 8319580e66SDave Liu void pci_init_board(void) 8419580e66SDave Liu { 856d0f6bcfSJean-Christophe PLAGNIOL-VILLARD volatile immap_t *immr = (volatile immap_t *)CONFIG_SYS_IMMR; 868b34557cSAnton Vorontsov volatile sysconf83xx_t *sysconf = &immr->sysconf; 8719580e66SDave Liu volatile clk83xx_t *clk = (volatile clk83xx_t *)&immr->clk; 8819580e66SDave Liu volatile law83xx_t *pci_law = immr->sysconf.pcilaw; 898b34557cSAnton Vorontsov volatile law83xx_t *pcie_law = sysconf->pcielaw; 9019580e66SDave Liu struct pci_region *reg[] = { pci_regions }; 918b34557cSAnton Vorontsov struct pci_region *pcie_reg[] = { pcie_regions_0, pcie_regions_1, }; 928b34557cSAnton Vorontsov u32 spridr = in_be32(&immr->sysconf.spridr); 938b34557cSAnton Vorontsov int pex2 = is_pex_x2(); 9419580e66SDave Liu 9500f7bbaeSAnton Vorontsov if (board_pci_host_broken()) 968b34557cSAnton Vorontsov goto skip_pci; 9700f7bbaeSAnton Vorontsov 9819580e66SDave Liu /* Enable all 5 PCI_CLK_OUTPUTS */ 9919580e66SDave Liu clk->occr |= 0xf8000000; 10019580e66SDave Liu udelay(2000); 10119580e66SDave Liu 10219580e66SDave Liu /* Configure PCI Local Access Windows */ 1036d0f6bcfSJean-Christophe PLAGNIOL-VILLARD pci_law[0].bar = CONFIG_SYS_PCI_MEM_PHYS & LAWBAR_BAR; 10419580e66SDave Liu pci_law[0].ar = LBLAWAR_EN | LBLAWAR_512MB; 10519580e66SDave Liu 1066d0f6bcfSJean-Christophe PLAGNIOL-VILLARD pci_law[1].bar = CONFIG_SYS_PCI_IO_PHYS & LAWBAR_BAR; 10719580e66SDave Liu pci_law[1].ar = LBLAWAR_EN | LBLAWAR_1MB; 10819580e66SDave Liu 10919580e66SDave Liu udelay(2000); 11019580e66SDave Liu 111*6aa3d3bfSPeter Tyser mpc83xx_pci_init(1, reg); 1128b34557cSAnton Vorontsov skip_pci: 1138b34557cSAnton Vorontsov /* There is no PEX in MPC8379 parts. */ 1148b34557cSAnton Vorontsov if (PARTID_NO_E(spridr) == SPR_8379) 1158b34557cSAnton Vorontsov return; 1168b34557cSAnton Vorontsov 1177e2ec1deSAnton Vorontsov if (pex2) 1187e2ec1deSAnton Vorontsov fsl_setup_serdes(CONFIG_FSL_SERDES2, FSL_SERDES_PROTO_PEX_X2, 1197e2ec1deSAnton Vorontsov FSL_SERDES_CLK_100, FSL_SERDES_VDD_1V); 1207e2ec1deSAnton Vorontsov else 1217e2ec1deSAnton Vorontsov fsl_setup_serdes(CONFIG_FSL_SERDES2, FSL_SERDES_PROTO_PEX, 1227e2ec1deSAnton Vorontsov FSL_SERDES_CLK_100, FSL_SERDES_VDD_1V); 1237e2ec1deSAnton Vorontsov 1248b34557cSAnton Vorontsov /* Configure the clock for PCIE controller */ 1258b34557cSAnton Vorontsov clrsetbits_be32(&clk->sccr, SCCR_PCIEXP1CM | SCCR_PCIEXP2CM, 1268b34557cSAnton Vorontsov SCCR_PCIEXP1CM_1 | SCCR_PCIEXP2CM_1); 1278b34557cSAnton Vorontsov 1288b34557cSAnton Vorontsov /* Deassert the resets in the control register */ 1298b34557cSAnton Vorontsov out_be32(&sysconf->pecr1, 0xE0008000); 1308b34557cSAnton Vorontsov if (!pex2) 1318b34557cSAnton Vorontsov out_be32(&sysconf->pecr2, 0xE0008000); 1328b34557cSAnton Vorontsov udelay(2000); 1338b34557cSAnton Vorontsov 1348b34557cSAnton Vorontsov /* Configure PCI Express Local Access Windows */ 1358b34557cSAnton Vorontsov out_be32(&pcie_law[0].bar, CONFIG_SYS_PCIE1_BASE & LAWBAR_BAR); 1368b34557cSAnton Vorontsov out_be32(&pcie_law[0].ar, LBLAWAR_EN | LBLAWAR_512MB); 1378b34557cSAnton Vorontsov 1388b34557cSAnton Vorontsov out_be32(&pcie_law[1].bar, CONFIG_SYS_PCIE2_BASE & LAWBAR_BAR); 1398b34557cSAnton Vorontsov out_be32(&pcie_law[1].ar, LBLAWAR_EN | LBLAWAR_512MB); 1408b34557cSAnton Vorontsov 1418b34557cSAnton Vorontsov mpc83xx_pcie_init(pex2 ? 1 : 2, pcie_reg, 0); 1428b34557cSAnton Vorontsov } 1438b34557cSAnton Vorontsov 1448b34557cSAnton Vorontsov void ft_pcie_fixup(void *blob, bd_t *bd) 1458b34557cSAnton Vorontsov { 1468b34557cSAnton Vorontsov const char *status = "disabled (PCIE1 is x2)"; 1478b34557cSAnton Vorontsov 1488b34557cSAnton Vorontsov if (!is_pex_x2()) 1498b34557cSAnton Vorontsov return; 1508b34557cSAnton Vorontsov 1518b34557cSAnton Vorontsov do_fixup_by_path(blob, "pci2", "status", status, 1528b34557cSAnton Vorontsov strlen(status) + 1, 1); 15319580e66SDave Liu } 154