1 /* 2 * Copyright (C) 2007 Freescale Semiconductor, Inc. 3 * 4 * Author: Scott Wood <scottwood@freescale.com> 5 * Dave Liu <daveliu@freescale.com> 6 * 7 * SPDX-License-Identifier: GPL-2.0+ 8 */ 9 10 #include <common.h> 11 #include <hwconfig.h> 12 #include <i2c.h> 13 #include <linux/libfdt.h> 14 #include <fdt_support.h> 15 #include <pci.h> 16 #include <mpc83xx.h> 17 #include <netdev.h> 18 #include <asm/io.h> 19 #include <ns16550.h> 20 #include <nand.h> 21 22 DECLARE_GLOBAL_DATA_PTR; 23 24 int board_early_init_f(void) 25 { 26 volatile immap_t *im = (immap_t *)CONFIG_SYS_IMMR; 27 28 if (im->pmc.pmccr1 & PMCCR1_POWER_OFF) 29 gd->flags |= GD_FLG_SILENT; 30 31 return 0; 32 } 33 34 #ifndef CONFIG_NAND_SPL 35 36 static u8 read_board_info(void) 37 { 38 u8 val8; 39 i2c_set_bus_num(0); 40 41 if (i2c_read(CONFIG_SYS_I2C_PCF8574A_ADDR, 0, 0, &val8, 1) == 0) 42 return val8; 43 else 44 return 0; 45 } 46 47 int checkboard(void) 48 { 49 static const char * const rev_str[] = { 50 "0.0", 51 "0.1", 52 "1.0", 53 "1.1", 54 "<unknown>", 55 }; 56 u8 info; 57 int i; 58 59 info = read_board_info(); 60 i = (!info) ? 4: info & 0x03; 61 62 printf("Board: Freescale MPC8315ERDB Rev %s\n", rev_str[i]); 63 64 return 0; 65 } 66 67 static struct pci_region pci_regions[] = { 68 { 69 bus_start: CONFIG_SYS_PCI_MEM_BASE, 70 phys_start: CONFIG_SYS_PCI_MEM_PHYS, 71 size: CONFIG_SYS_PCI_MEM_SIZE, 72 flags: PCI_REGION_MEM | PCI_REGION_PREFETCH 73 }, 74 { 75 bus_start: CONFIG_SYS_PCI_MMIO_BASE, 76 phys_start: CONFIG_SYS_PCI_MMIO_PHYS, 77 size: CONFIG_SYS_PCI_MMIO_SIZE, 78 flags: PCI_REGION_MEM 79 }, 80 { 81 bus_start: CONFIG_SYS_PCI_IO_BASE, 82 phys_start: CONFIG_SYS_PCI_IO_PHYS, 83 size: CONFIG_SYS_PCI_IO_SIZE, 84 flags: PCI_REGION_IO 85 } 86 }; 87 88 static struct pci_region pcie_regions_0[] = { 89 { 90 .bus_start = CONFIG_SYS_PCIE1_MEM_BASE, 91 .phys_start = CONFIG_SYS_PCIE1_MEM_PHYS, 92 .size = CONFIG_SYS_PCIE1_MEM_SIZE, 93 .flags = PCI_REGION_MEM, 94 }, 95 { 96 .bus_start = CONFIG_SYS_PCIE1_IO_BASE, 97 .phys_start = CONFIG_SYS_PCIE1_IO_PHYS, 98 .size = CONFIG_SYS_PCIE1_IO_SIZE, 99 .flags = PCI_REGION_IO, 100 }, 101 }; 102 103 static struct pci_region pcie_regions_1[] = { 104 { 105 .bus_start = CONFIG_SYS_PCIE2_MEM_BASE, 106 .phys_start = CONFIG_SYS_PCIE2_MEM_PHYS, 107 .size = CONFIG_SYS_PCIE2_MEM_SIZE, 108 .flags = PCI_REGION_MEM, 109 }, 110 { 111 .bus_start = CONFIG_SYS_PCIE2_IO_BASE, 112 .phys_start = CONFIG_SYS_PCIE2_IO_PHYS, 113 .size = CONFIG_SYS_PCIE2_IO_SIZE, 114 .flags = PCI_REGION_IO, 115 }, 116 }; 117 118 void pci_init_board(void) 119 { 120 volatile immap_t *immr = (volatile immap_t *)CONFIG_SYS_IMMR; 121 volatile sysconf83xx_t *sysconf = &immr->sysconf; 122 volatile clk83xx_t *clk = (volatile clk83xx_t *)&immr->clk; 123 volatile law83xx_t *pci_law = immr->sysconf.pcilaw; 124 volatile law83xx_t *pcie_law = sysconf->pcielaw; 125 struct pci_region *reg[] = { pci_regions }; 126 struct pci_region *pcie_reg[] = { pcie_regions_0, pcie_regions_1, }; 127 128 /* Enable all 3 PCI_CLK_OUTPUTs. */ 129 clk->occr |= 0xe0000000; 130 131 /* 132 * Configure PCI Local Access Windows 133 */ 134 pci_law[0].bar = CONFIG_SYS_PCI_MEM_PHYS & LAWBAR_BAR; 135 pci_law[0].ar = LBLAWAR_EN | LBLAWAR_512MB; 136 137 pci_law[1].bar = CONFIG_SYS_PCI_IO_PHYS & LAWBAR_BAR; 138 pci_law[1].ar = LBLAWAR_EN | LBLAWAR_1MB; 139 140 mpc83xx_pci_init(1, reg); 141 142 /* Configure the clock for PCIE controller */ 143 clrsetbits_be32(&clk->sccr, SCCR_PCIEXP1CM | SCCR_PCIEXP2CM, 144 SCCR_PCIEXP1CM_1 | SCCR_PCIEXP2CM_1); 145 146 /* Deassert the resets in the control register */ 147 out_be32(&sysconf->pecr1, 0xE0008000); 148 out_be32(&sysconf->pecr2, 0xE0008000); 149 udelay(2000); 150 151 /* Configure PCI Express Local Access Windows */ 152 out_be32(&pcie_law[0].bar, CONFIG_SYS_PCIE1_BASE & LAWBAR_BAR); 153 out_be32(&pcie_law[0].ar, LBLAWAR_EN | LBLAWAR_512MB); 154 155 out_be32(&pcie_law[1].bar, CONFIG_SYS_PCIE2_BASE & LAWBAR_BAR); 156 out_be32(&pcie_law[1].ar, LBLAWAR_EN | LBLAWAR_512MB); 157 158 mpc83xx_pcie_init(2, pcie_reg); 159 } 160 161 #if defined(CONFIG_OF_BOARD_SETUP) 162 void fdt_tsec1_fixup(void *fdt, bd_t *bd) 163 { 164 const char disabled[] = "disabled"; 165 const char *path; 166 int ret; 167 168 if (hwconfig_arg_cmp("board_type", "tsec1")) { 169 return; 170 } else if (!hwconfig_arg_cmp("board_type", "ulpi")) { 171 printf("NOTICE: No or unknown board_type hwconfig specified.\n" 172 " Assuming board with TSEC1.\n"); 173 return; 174 } 175 176 ret = fdt_path_offset(fdt, "/aliases"); 177 if (ret < 0) { 178 printf("WARNING: can't find /aliases node\n"); 179 return; 180 } 181 182 path = fdt_getprop(fdt, ret, "ethernet0", NULL); 183 if (!path) { 184 printf("WARNING: can't find ethernet0 alias\n"); 185 return; 186 } 187 188 do_fixup_by_path(fdt, path, "status", disabled, sizeof(disabled), 1); 189 } 190 191 int ft_board_setup(void *blob, bd_t *bd) 192 { 193 ft_cpu_setup(blob, bd); 194 #ifdef CONFIG_PCI 195 ft_pci_setup(blob, bd); 196 #endif 197 fsl_fdt_fixup_dr_usb(blob, bd); 198 fdt_tsec1_fixup(blob, bd); 199 200 return 0; 201 } 202 #endif 203 204 int board_eth_init(bd_t *bis) 205 { 206 cpu_eth_init(bis); /* Initialize TSECs first */ 207 return pci_eth_init(bis); 208 } 209 210 #else /* CONFIG_NAND_SPL */ 211 212 int checkboard(void) 213 { 214 puts("Board: Freescale MPC8315ERDB\n"); 215 return 0; 216 } 217 218 void board_init_f(ulong bootflag) 219 { 220 board_early_init_f(); 221 NS16550_init((NS16550_t)(CONFIG_SYS_IMMR + 0x4500), 222 CONFIG_SYS_NS16550_CLK / 16 / CONFIG_BAUDRATE); 223 puts("NAND boot... "); 224 timer_init(); 225 dram_init(); 226 relocate_code(CONFIG_SYS_NAND_U_BOOT_RELOC + 0x10000, (gd_t *)gd, 227 CONFIG_SYS_NAND_U_BOOT_RELOC); 228 } 229 230 void board_init_r(gd_t *gd, ulong dest_addr) 231 { 232 nand_boot(); 233 } 234 235 void putc(char c) 236 { 237 if (gd->flags & GD_FLG_SILENT) 238 return; 239 240 if (c == '\n') 241 NS16550_putc((NS16550_t)(CONFIG_SYS_IMMR + 0x4500), '\r'); 242 243 NS16550_putc((NS16550_t)(CONFIG_SYS_IMMR + 0x4500), c); 244 } 245 246 #endif /* CONFIG_NAND_SPL */ 247