1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright (C) 2006-2009 Freescale Semiconductor, Inc. 4 */ 5 6 #include <asm/mmu.h> 7 #include <asm/io.h> 8 #include <common.h> 9 #include <mpc83xx.h> 10 #include <pci.h> 11 #include <i2c.h> 12 #include <fdt_support.h> 13 #include <asm/fsl_i2c.h> 14 #include <asm/fsl_mpc83xx_serdes.h> 15 16 static struct pci_region pci_regions[] = { 17 { 18 bus_start: CONFIG_SYS_PCI_MEM_BASE, 19 phys_start: CONFIG_SYS_PCI_MEM_PHYS, 20 size: CONFIG_SYS_PCI_MEM_SIZE, 21 flags: PCI_REGION_MEM | PCI_REGION_PREFETCH 22 }, 23 { 24 bus_start: CONFIG_SYS_PCI_MMIO_BASE, 25 phys_start: CONFIG_SYS_PCI_MMIO_PHYS, 26 size: CONFIG_SYS_PCI_MMIO_SIZE, 27 flags: PCI_REGION_MEM 28 }, 29 { 30 bus_start: CONFIG_SYS_PCI_IO_BASE, 31 phys_start: CONFIG_SYS_PCI_IO_PHYS, 32 size: CONFIG_SYS_PCI_IO_SIZE, 33 flags: PCI_REGION_IO 34 } 35 }; 36 37 static struct pci_region pcie_regions_0[] = { 38 { 39 .bus_start = CONFIG_SYS_PCIE1_MEM_BASE, 40 .phys_start = CONFIG_SYS_PCIE1_MEM_PHYS, 41 .size = CONFIG_SYS_PCIE1_MEM_SIZE, 42 .flags = PCI_REGION_MEM, 43 }, 44 { 45 .bus_start = CONFIG_SYS_PCIE1_IO_BASE, 46 .phys_start = CONFIG_SYS_PCIE1_IO_PHYS, 47 .size = CONFIG_SYS_PCIE1_IO_SIZE, 48 .flags = PCI_REGION_IO, 49 }, 50 }; 51 52 static struct pci_region pcie_regions_1[] = { 53 { 54 .bus_start = CONFIG_SYS_PCIE2_MEM_BASE, 55 .phys_start = CONFIG_SYS_PCIE2_MEM_PHYS, 56 .size = CONFIG_SYS_PCIE2_MEM_SIZE, 57 .flags = PCI_REGION_MEM, 58 }, 59 { 60 .bus_start = CONFIG_SYS_PCIE2_IO_BASE, 61 .phys_start = CONFIG_SYS_PCIE2_IO_PHYS, 62 .size = CONFIG_SYS_PCIE2_IO_SIZE, 63 .flags = PCI_REGION_IO, 64 }, 65 }; 66 67 static int is_pex_x2(void) 68 { 69 const char *pex_x2 = env_get("pex_x2"); 70 71 if (pex_x2 && !strcmp(pex_x2, "yes")) 72 return 1; 73 return 0; 74 } 75 76 void pci_init_board(void) 77 { 78 volatile immap_t *immr = (volatile immap_t *)CONFIG_SYS_IMMR; 79 volatile sysconf83xx_t *sysconf = &immr->sysconf; 80 volatile clk83xx_t *clk = (volatile clk83xx_t *)&immr->clk; 81 volatile law83xx_t *pci_law = immr->sysconf.pcilaw; 82 volatile law83xx_t *pcie_law = sysconf->pcielaw; 83 struct pci_region *reg[] = { pci_regions }; 84 struct pci_region *pcie_reg[] = { pcie_regions_0, pcie_regions_1, }; 85 u32 spridr = in_be32(&immr->sysconf.spridr); 86 int pex2 = is_pex_x2(); 87 88 if (board_pci_host_broken()) 89 goto skip_pci; 90 91 /* Enable all 5 PCI_CLK_OUTPUTS */ 92 clk->occr |= 0xf8000000; 93 udelay(2000); 94 95 /* Configure PCI Local Access Windows */ 96 pci_law[0].bar = CONFIG_SYS_PCI_MEM_PHYS & LAWBAR_BAR; 97 pci_law[0].ar = LBLAWAR_EN | LBLAWAR_512MB; 98 99 pci_law[1].bar = CONFIG_SYS_PCI_IO_PHYS & LAWBAR_BAR; 100 pci_law[1].ar = LBLAWAR_EN | LBLAWAR_1MB; 101 102 udelay(2000); 103 104 mpc83xx_pci_init(1, reg); 105 skip_pci: 106 /* There is no PEX in MPC8379 parts. */ 107 if (PARTID_NO_E(spridr) == SPR_8379) 108 return; 109 110 if (pex2) 111 fsl_setup_serdes(CONFIG_FSL_SERDES2, FSL_SERDES_PROTO_PEX_X2, 112 FSL_SERDES_CLK_100, FSL_SERDES_VDD_1V); 113 else 114 fsl_setup_serdes(CONFIG_FSL_SERDES2, FSL_SERDES_PROTO_PEX, 115 FSL_SERDES_CLK_100, FSL_SERDES_VDD_1V); 116 117 /* Configure the clock for PCIE controller */ 118 clrsetbits_be32(&clk->sccr, SCCR_PCIEXP1CM | SCCR_PCIEXP2CM, 119 SCCR_PCIEXP1CM_1 | SCCR_PCIEXP2CM_1); 120 121 /* Deassert the resets in the control register */ 122 out_be32(&sysconf->pecr1, 0xE0008000); 123 if (!pex2) 124 out_be32(&sysconf->pecr2, 0xE0008000); 125 udelay(2000); 126 127 /* Configure PCI Express Local Access Windows */ 128 out_be32(&pcie_law[0].bar, CONFIG_SYS_PCIE1_BASE & LAWBAR_BAR); 129 out_be32(&pcie_law[0].ar, LBLAWAR_EN | LBLAWAR_512MB); 130 131 out_be32(&pcie_law[1].bar, CONFIG_SYS_PCIE2_BASE & LAWBAR_BAR); 132 out_be32(&pcie_law[1].ar, LBLAWAR_EN | LBLAWAR_512MB); 133 134 mpc83xx_pcie_init(pex2 ? 1 : 2, pcie_reg); 135 } 136 137 void ft_pcie_fixup(void *blob, bd_t *bd) 138 { 139 const char *status = "disabled (PCIE1 is x2)"; 140 141 if (!is_pex_x2()) 142 return; 143 144 do_fixup_by_path(blob, "pci2", "status", status, 145 strlen(status) + 1, 1); 146 } 147