13dd2db53SJon Loeliger /* 2d5c784edSZhao Chenhui * Copyright 2007,2009-2011 Freescale Semiconductor, Inc. 33dd2db53SJon Loeliger * 41a459660SWolfgang Denk * SPDX-License-Identifier: GPL-2.0+ 53dd2db53SJon Loeliger */ 6c9974ab0SJon Loeliger 73dd2db53SJon Loeliger #include <common.h> 83dd2db53SJon Loeliger #include <command.h> 93dd2db53SJon Loeliger #include <pci.h> 103dd2db53SJon Loeliger #include <asm/processor.h> 113dd2db53SJon Loeliger #include <asm/immap_86xx.h> 12c8514622SKumar Gala #include <asm/fsl_pci.h> 135614e71bSYork Sun #include <fsl_ddr_sdram.h> 145d27e02cSKumar Gala #include <asm/fsl_serdes.h> 15c9974ab0SJon Loeliger #include <i2c.h> 163dd2db53SJon Loeliger #include <asm/io.h> 171df170f8SJon Loeliger #include <libfdt.h> 181df170f8SJon Loeliger #include <fdt_support.h> 19a30a549aSJon Loeliger #include <spd_sdram.h> 2089973f8aSBen Warren #include <netdev.h> 213dd2db53SJon Loeliger 22*088454cdSSimon Glass DECLARE_GLOBAL_DATA_PTR; 23*088454cdSSimon Glass 243dd2db53SJon Loeliger void sdram_init(void); 254c77de3fSBecky Bruce phys_size_t fixed_sdram(void); 26e69e520fSTimur Tabi int mpc8610hpcd_diu_init(void); 27c9974ab0SJon Loeliger 283dd2db53SJon Loeliger 293dd2db53SJon Loeliger /* called before any console output */ 303dd2db53SJon Loeliger int board_early_init_f(void) 313dd2db53SJon Loeliger { 326d0f6bcfSJean-Christophe PLAGNIOL-VILLARD volatile immap_t *immap = (immap_t *)CONFIG_SYS_IMMR; 333dd2db53SJon Loeliger volatile ccsr_gur_t *gur = &immap->im_gur; 343dd2db53SJon Loeliger 35a877880cSYork Sun gur->gpiocr |= 0x88aa5500; /* DIU16, IR1, UART0, UART2 */ 36a877880cSYork Sun 37a877880cSYork Sun return 0; 38a877880cSYork Sun } 39a877880cSYork Sun 40a877880cSYork Sun int misc_init_r(void) 41a877880cSYork Sun { 42a877880cSYork Sun u8 tmp_val, version; 43048e7efeSKumar Gala u8 *pixis_base = (u8 *)PIXIS_BASE; 44a877880cSYork Sun 45a877880cSYork Sun /*Do not use 8259PIC*/ 46048e7efeSKumar Gala tmp_val = in_8(pixis_base + PIXIS_BRDCFG0); 47048e7efeSKumar Gala out_8(pixis_base + PIXIS_BRDCFG0, tmp_val | 0x80); 48a877880cSYork Sun 49a877880cSYork Sun /*For FPGA V7 or higher, set the IRQMAPSEL to 0 to use MAP0 interrupt*/ 50048e7efeSKumar Gala version = in_8(pixis_base + PIXIS_PVER); 51a877880cSYork Sun if(version >= 0x07) { 52048e7efeSKumar Gala tmp_val = in_8(pixis_base + PIXIS_BRDCFG0); 53048e7efeSKumar Gala out_8(pixis_base + PIXIS_BRDCFG0, tmp_val & 0xbf); 54a877880cSYork Sun } 55a877880cSYork Sun 56a877880cSYork Sun /* Using this for DIU init before the driver in linux takes over 57a877880cSYork Sun * Enable the TFP410 Encoder (I2C address 0x38) 58a877880cSYork Sun */ 59a877880cSYork Sun 60a877880cSYork Sun tmp_val = 0xBF; 61a877880cSYork Sun i2c_write(0x38, 0x08, 1, &tmp_val, sizeof(tmp_val)); 62a877880cSYork Sun /* Verify if enabled */ 63a877880cSYork Sun tmp_val = 0; 64a877880cSYork Sun i2c_read(0x38, 0x08, 1, &tmp_val, sizeof(tmp_val)); 657315ab22SMarek Vasut debug("DVI Encoder Read: 0x%02x\n", tmp_val); 66a877880cSYork Sun 67a877880cSYork Sun tmp_val = 0x10; 68a877880cSYork Sun i2c_write(0x38, 0x0A, 1, &tmp_val, sizeof(tmp_val)); 69a877880cSYork Sun /* Verify if enabled */ 70a877880cSYork Sun tmp_val = 0; 71a877880cSYork Sun i2c_read(0x38, 0x0A, 1, &tmp_val, sizeof(tmp_val)); 727315ab22SMarek Vasut debug("DVI Encoder Read: 0x%02x\n", tmp_val); 73a877880cSYork Sun 743dd2db53SJon Loeliger return 0; 753dd2db53SJon Loeliger } 763dd2db53SJon Loeliger 773dd2db53SJon Loeliger int checkboard(void) 783dd2db53SJon Loeliger { 796d0f6bcfSJean-Christophe PLAGNIOL-VILLARD volatile immap_t *immap = (immap_t *)CONFIG_SYS_IMMR; 803dd2db53SJon Loeliger volatile ccsr_local_mcm_t *mcm = &immap->im_local_mcm; 81048e7efeSKumar Gala u8 *pixis_base = (u8 *)PIXIS_BASE; 823dd2db53SJon Loeliger 8326fd33b9STimur Tabi printf ("Board: MPC8610HPCD, Sys ID: 0x%02x, " 8426fd33b9STimur Tabi "Sys Ver: 0x%02x, FPGA Ver: 0x%02x, ", 85048e7efeSKumar Gala in_8(pixis_base + PIXIS_ID), in_8(pixis_base + PIXIS_VER), 86048e7efeSKumar Gala in_8(pixis_base + PIXIS_PVER)); 873dd2db53SJon Loeliger 8826fd33b9STimur Tabi /* 8926fd33b9STimur Tabi * The MPC8610 HPCD workbook says that LBMAP=11 is the "normal" boot 9026fd33b9STimur Tabi * bank and LBMAP=00 is the alternate bank. However, the pixis 9126fd33b9STimur Tabi * altbank code can only set bits, not clear them, so we treat 00 as 9226fd33b9STimur Tabi * the normal bank and 11 as the alternate. 9326fd33b9STimur Tabi */ 9426fd33b9STimur Tabi switch (in_8(pixis_base + PIXIS_VBOOT) & 0xC0) { 9526fd33b9STimur Tabi case 0: 9626fd33b9STimur Tabi puts("vBank: Standard\n"); 9726fd33b9STimur Tabi break; 9826fd33b9STimur Tabi case 0x40: 9926fd33b9STimur Tabi puts("Promjet\n"); 10026fd33b9STimur Tabi break; 10126fd33b9STimur Tabi case 0x80: 10226fd33b9STimur Tabi puts("NAND\n"); 10326fd33b9STimur Tabi break; 10426fd33b9STimur Tabi case 0xC0: 10526fd33b9STimur Tabi puts("vBank: Alternate\n"); 10626fd33b9STimur Tabi break; 10726fd33b9STimur Tabi } 10826fd33b9STimur Tabi 1093dd2db53SJon Loeliger mcm->abcr |= 0x00010000; /* 0 */ 1103dd2db53SJon Loeliger mcm->hpmr3 = 0x80000008; /* 4c */ 1113dd2db53SJon Loeliger mcm->hpmr0 = 0; 1123dd2db53SJon Loeliger mcm->hpmr1 = 0; 1133dd2db53SJon Loeliger mcm->hpmr2 = 0; 1143dd2db53SJon Loeliger mcm->hpmr4 = 0; 1153dd2db53SJon Loeliger mcm->hpmr5 = 0; 1163dd2db53SJon Loeliger 1173dd2db53SJon Loeliger return 0; 1183dd2db53SJon Loeliger } 1193dd2db53SJon Loeliger 1203dd2db53SJon Loeliger 121*088454cdSSimon Glass int initdram(void) 1223dd2db53SJon Loeliger { 1234c77de3fSBecky Bruce phys_size_t dram_size = 0; 1243dd2db53SJon Loeliger 1253dd2db53SJon Loeliger #if defined(CONFIG_SPD_EEPROM) 12639aa1a73SJon Loeliger dram_size = fsl_ddr_sdram(); 1273dd2db53SJon Loeliger #else 1283dd2db53SJon Loeliger dram_size = fixed_sdram(); 1293dd2db53SJon Loeliger #endif 1303dd2db53SJon Loeliger 1319ff32d8cSTimur Tabi setup_ddr_bat(dram_size); 1329ff32d8cSTimur Tabi 13321cd5815SWolfgang Denk debug(" DDR: "); 134*088454cdSSimon Glass gd->ram_size = dram_size; 135*088454cdSSimon Glass 136*088454cdSSimon Glass return 0; 1373dd2db53SJon Loeliger } 1383dd2db53SJon Loeliger 1393dd2db53SJon Loeliger 1403dd2db53SJon Loeliger #if !defined(CONFIG_SPD_EEPROM) 1413dd2db53SJon Loeliger /* 1423dd2db53SJon Loeliger * Fixed sdram init -- doesn't use serial presence detect. 1433dd2db53SJon Loeliger */ 1443dd2db53SJon Loeliger 1454c77de3fSBecky Bruce phys_size_t fixed_sdram(void) 1463dd2db53SJon Loeliger { 1476d0f6bcfSJean-Christophe PLAGNIOL-VILLARD #if !defined(CONFIG_SYS_RAMBOOT) 1486d0f6bcfSJean-Christophe PLAGNIOL-VILLARD volatile immap_t *immap = (immap_t *)CONFIG_SYS_IMMR; 1499a17eb5bSYork Sun struct ccsr_ddr __iomem *ddr = &immap->im_ddr1; 1503dd2db53SJon Loeliger uint d_init; 1513dd2db53SJon Loeliger 1523dd2db53SJon Loeliger ddr->cs0_bnds = 0x0000001f; 1533dd2db53SJon Loeliger ddr->cs0_config = 0x80010202; 1543dd2db53SJon Loeliger 15545239cf4SKumar Gala ddr->timing_cfg_3 = 0x00000000; 1563dd2db53SJon Loeliger ddr->timing_cfg_0 = 0x00260802; 1573dd2db53SJon Loeliger ddr->timing_cfg_1 = 0x3935d322; 1583dd2db53SJon Loeliger ddr->timing_cfg_2 = 0x14904cc8; 159e7ee23ecSPeter Tyser ddr->sdram_mode = 0x00480432; 1603dd2db53SJon Loeliger ddr->sdram_mode_2 = 0x00000000; 1613dd2db53SJon Loeliger ddr->sdram_interval = 0x06180fff; /* 0x06180100; */ 1623dd2db53SJon Loeliger ddr->sdram_data_init = 0xDEADBEEF; 1633dd2db53SJon Loeliger ddr->sdram_clk_cntl = 0x03800000; 1643dd2db53SJon Loeliger ddr->sdram_cfg_2 = 0x04400010; 1653dd2db53SJon Loeliger 1663dd2db53SJon Loeliger #if defined(CONFIG_DDR_ECC) 1673dd2db53SJon Loeliger ddr->err_int_en = 0x0000000d; 1683dd2db53SJon Loeliger ddr->err_disable = 0x00000000; 1693dd2db53SJon Loeliger ddr->err_sbe = 0x00010000; 1703dd2db53SJon Loeliger #endif 1713dd2db53SJon Loeliger asm("sync;isync"); 1723dd2db53SJon Loeliger 1733dd2db53SJon Loeliger udelay(500); 1743dd2db53SJon Loeliger 175e7ee23ecSPeter Tyser ddr->sdram_cfg = 0xc3000000; /* 0xe3008000;*/ 1763dd2db53SJon Loeliger 1773dd2db53SJon Loeliger 1783dd2db53SJon Loeliger #if defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER) 1793dd2db53SJon Loeliger d_init = 1; 1803dd2db53SJon Loeliger debug("DDR - 1st controller: memory initializing\n"); 1813dd2db53SJon Loeliger /* 1823dd2db53SJon Loeliger * Poll until memory is initialized. 1833dd2db53SJon Loeliger * 512 Meg at 400 might hit this 200 times or so. 1843dd2db53SJon Loeliger */ 1853dd2db53SJon Loeliger while ((ddr->sdram_cfg_2 & (d_init << 4)) != 0) 1863dd2db53SJon Loeliger udelay(1000); 1873dd2db53SJon Loeliger 1883dd2db53SJon Loeliger debug("DDR: memory initialized\n\n"); 1893dd2db53SJon Loeliger asm("sync; isync"); 1903dd2db53SJon Loeliger udelay(500); 1913dd2db53SJon Loeliger #endif 1923dd2db53SJon Loeliger 1933dd2db53SJon Loeliger return 512 * 1024 * 1024; 1943dd2db53SJon Loeliger #endif 1956d0f6bcfSJean-Christophe PLAGNIOL-VILLARD return CONFIG_SYS_SDRAM_SIZE * 1024 * 1024; 1963dd2db53SJon Loeliger } 1973dd2db53SJon Loeliger 1983dd2db53SJon Loeliger #endif 1993dd2db53SJon Loeliger 2003dd2db53SJon Loeliger #if defined(CONFIG_PCI) 2013dd2db53SJon Loeliger /* 2023dd2db53SJon Loeliger * Initialize PCI Devices, report devices found. 2033dd2db53SJon Loeliger */ 2043dd2db53SJon Loeliger 2053dd2db53SJon Loeliger #ifndef CONFIG_PCI_PNP 2063dd2db53SJon Loeliger static struct pci_config_table pci_fsl86xxads_config_table[] = { 2073dd2db53SJon Loeliger {PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 2083dd2db53SJon Loeliger PCI_IDSEL_NUMBER, PCI_ANY_ID, 2093dd2db53SJon Loeliger pci_cfgfunc_config_device, {PCI_ENET0_IOADDR, 2103dd2db53SJon Loeliger PCI_ENET0_MEMADDR, 2113dd2db53SJon Loeliger PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER} }, 2123dd2db53SJon Loeliger {} 2133dd2db53SJon Loeliger }; 2143dd2db53SJon Loeliger #endif 2153dd2db53SJon Loeliger 2163dd2db53SJon Loeliger 217d5c784edSZhao Chenhui static struct pci_controller pci1_hose; 2183dd2db53SJon Loeliger #endif /* CONFIG_PCI */ 2193dd2db53SJon Loeliger 2203dd2db53SJon Loeliger void pci_init_board(void) 2213dd2db53SJon Loeliger { 2226d0f6bcfSJean-Christophe PLAGNIOL-VILLARD volatile immap_t *immap = (immap_t *) CONFIG_SYS_CCSRBAR; 2233dd2db53SJon Loeliger volatile ccsr_gur_t *gur = &immap->im_gur; 224b8526212SKumar Gala struct fsl_pci_info pci_info; 225e38cc2c7SWolfgang Denk u32 devdisr; 226b8526212SKumar Gala int first_free_busno; 227b8526212SKumar Gala int pci_agent; 2285e3d7050SKumar Gala 2295e3d7050SKumar Gala devdisr = in_be32(&gur->devdisr); 2303dd2db53SJon Loeliger 231b8526212SKumar Gala first_free_busno = fsl_pcie_init_board(0); 2323dd2db53SJon Loeliger 2333dd2db53SJon Loeliger #ifdef CONFIG_PCI1 2343dd2db53SJon Loeliger if (!(devdisr & MPC86xx_DEVDISR_PCI1)) { 235b8526212SKumar Gala SET_STD_PCI_INFO(pci_info, 1); 236b8526212SKumar Gala set_next_law(pci_info.mem_phys, 237b8526212SKumar Gala law_size_bits(pci_info.mem_size), pci_info.law); 238b8526212SKumar Gala set_next_law(pci_info.io_phys, 239b8526212SKumar Gala law_size_bits(pci_info.io_size), pci_info.law); 240b8526212SKumar Gala 241b8526212SKumar Gala pci_agent = fsl_setup_hose(&pci1_hose, pci_info.regs); 2428ca78f2cSPeter Tyser printf("PCI: connected to PCI slots as %s" \ 2435e3d7050SKumar Gala " (base address %lx)\n", 2443dd2db53SJon Loeliger pci_agent ? "Agent" : "Host", 245b8526212SKumar Gala pci_info.regs); 246d5c784edSZhao Chenhui #ifndef CONFIG_PCI_PNP 247d5c784edSZhao Chenhui pci1_hose.config_table = pci_mpc86xxcts_config_table; 248d5c784edSZhao Chenhui #endif 249b8526212SKumar Gala first_free_busno = fsl_pci_init_port(&pci_info, 2505e3d7050SKumar Gala &pci1_hose, first_free_busno); 2515e3d7050SKumar Gala } else { 2525e3d7050SKumar Gala printf("PCI: disabled\n"); 2533dd2db53SJon Loeliger } 2545e3d7050SKumar Gala 2555e3d7050SKumar Gala puts("\n"); 2565e3d7050SKumar Gala #else 2575e3d7050SKumar Gala setbits_be32(&gur->devdisr, MPC86xx_DEVDISR_PCI1); /* disable */ 2585e3d7050SKumar Gala #endif 259b8526212SKumar Gala 260b8526212SKumar Gala fsl_pcie_init_board(first_free_busno); 2613dd2db53SJon Loeliger } 2623dd2db53SJon Loeliger 2631df170f8SJon Loeliger #if defined(CONFIG_OF_BOARD_SETUP) 264e895a4b0SSimon Glass int ft_board_setup(void *blob, bd_t *bd) 2653dd2db53SJon Loeliger { 2668439f05cSPeter Tyser ft_cpu_setup(blob, bd); 2671df170f8SJon Loeliger 2686525d51fSKumar Gala FT_FSL_PCI_SETUP; 269e895a4b0SSimon Glass 270e895a4b0SSimon Glass return 0; 2711df170f8SJon Loeliger } 2723dd2db53SJon Loeliger #endif 2733dd2db53SJon Loeliger 2743dd2db53SJon Loeliger /* 2753dd2db53SJon Loeliger * get_board_sys_clk 2763dd2db53SJon Loeliger * Reads the FPGA on board for CONFIG_SYS_CLK_FREQ 2773dd2db53SJon Loeliger */ 2783dd2db53SJon Loeliger 2793dd2db53SJon Loeliger unsigned long 2803dd2db53SJon Loeliger get_board_sys_clk(ulong dummy) 2813dd2db53SJon Loeliger { 282a877880cSYork Sun u8 i; 2833dd2db53SJon Loeliger ulong val = 0; 284048e7efeSKumar Gala u8 *pixis_base = (u8 *)PIXIS_BASE; 2853dd2db53SJon Loeliger 286048e7efeSKumar Gala i = in_8(pixis_base + PIXIS_SPD); 2873dd2db53SJon Loeliger i &= 0x07; 2883dd2db53SJon Loeliger 2893dd2db53SJon Loeliger switch (i) { 2903dd2db53SJon Loeliger case 0: 2913dd2db53SJon Loeliger val = 33333000; 2923dd2db53SJon Loeliger break; 2933dd2db53SJon Loeliger case 1: 2943dd2db53SJon Loeliger val = 39999600; 2953dd2db53SJon Loeliger break; 2963dd2db53SJon Loeliger case 2: 2973dd2db53SJon Loeliger val = 49999500; 2983dd2db53SJon Loeliger break; 2993dd2db53SJon Loeliger case 3: 3003dd2db53SJon Loeliger val = 66666000; 3013dd2db53SJon Loeliger break; 3023dd2db53SJon Loeliger case 4: 3033dd2db53SJon Loeliger val = 83332500; 3043dd2db53SJon Loeliger break; 3053dd2db53SJon Loeliger case 5: 3063dd2db53SJon Loeliger val = 99999000; 3073dd2db53SJon Loeliger break; 3083dd2db53SJon Loeliger case 6: 3093dd2db53SJon Loeliger val = 133332000; 3103dd2db53SJon Loeliger break; 3113dd2db53SJon Loeliger case 7: 3123dd2db53SJon Loeliger val = 166665000; 3133dd2db53SJon Loeliger break; 3143dd2db53SJon Loeliger } 3153dd2db53SJon Loeliger 3163dd2db53SJon Loeliger return val; 3173dd2db53SJon Loeliger } 31865d3d99cSBen Warren 31965d3d99cSBen Warren int board_eth_init(bd_t *bis) 32065d3d99cSBen Warren { 32189973f8aSBen Warren return pci_eth_init(bis); 32265d3d99cSBen Warren } 3234ef630dfSPeter Tyser 3244ef630dfSPeter Tyser void board_reset(void) 3254ef630dfSPeter Tyser { 326048e7efeSKumar Gala u8 *pixis_base = (u8 *)PIXIS_BASE; 327048e7efeSKumar Gala 328048e7efeSKumar Gala out_8(pixis_base + PIXIS_RST, 0); 3294ef630dfSPeter Tyser 3304ef630dfSPeter Tyser while (1) 3314ef630dfSPeter Tyser ; 3324ef630dfSPeter Tyser } 333