diff options
Diffstat (limited to 'board/mvblm7/pci.c')
-rw-r--r-- | board/mvblm7/pci.c | 133 |
1 files changed, 133 insertions, 0 deletions
diff --git a/board/mvblm7/pci.c b/board/mvblm7/pci.c new file mode 100644 index 0000000..ef34a6b --- /dev/null +++ b/board/mvblm7/pci.c @@ -0,0 +1,133 @@ +/* + * Copyright (C) Freescale Semiconductor, Inc. 2006. All rights reserved. + * + * (C) Copyright 2008 + * Andre Schwarz, Matrix Vision GmbH, andre.schwarz@matrix-vision.de + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#if defined(CONFIG_OF_LIBFDT) +#include <libfdt.h> +#endif +#include <pci.h> +#include <mpc83xx.h> +#include <fpga.h> +#include "mvblm7.h" +#include "fpga.h" + +DECLARE_GLOBAL_DATA_PTR; + +int mvblm7_load_fpga(void) +{ + size_t data_size = 0; + void *fpga_data = NULL; + char *datastr = getenv("fpgadata"); + char *sizestr = getenv("fpgadatasize"); + + if (datastr) + fpga_data = (void *)simple_strtoul(datastr, NULL, 16); + if (sizestr) + data_size = (size_t)simple_strtoul(sizestr, NULL, 16); + + return fpga_load(0, fpga_data, data_size); +} + +static struct pci_region pci_regions[] = { + { + bus_start: CFG_PCI1_MEM_BASE, + phys_start: CFG_PCI1_MEM_PHYS, + size: CFG_PCI1_MEM_SIZE, + flags: PCI_REGION_MEM | PCI_REGION_PREFETCH + }, + { + bus_start: CFG_PCI1_MMIO_BASE, + phys_start: CFG_PCI1_MMIO_PHYS, + size: CFG_PCI1_MMIO_SIZE, + flags: PCI_REGION_MEM + }, + { + bus_start: CFG_PCI1_IO_BASE, + phys_start: CFG_PCI1_IO_PHYS, + size: CFG_PCI1_IO_SIZE, + flags: PCI_REGION_IO + } +}; + +void pci_init_board(void) +{ + char *s; + int i; + int warmboot; + int load_fpga; + volatile immap_t *immr; + volatile pcictrl83xx_t *pci_ctrl; + volatile gpio83xx_t *gpio; + volatile clk83xx_t *clk; + volatile law83xx_t *pci_law; + struct pci_region *reg[] = { pci_regions }; + + load_fpga = 1; + immr = (immap_t *) CFG_IMMR; + clk = (clk83xx_t *) &immr->clk; + pci_ctrl = immr->pci_ctrl; + pci_law = immr->sysconf.pcilaw; + gpio = (volatile gpio83xx_t *)&immr->gpio[0]; + + s = getenv("skip_fpga"); + if (s) { + printf("found 'skip_fpga' -> FPGA _not_ loaded !\n"); + load_fpga = 0; + } + + gpio->dat = MV_GPIO_DAT; + gpio->odr = MV_GPIO_ODE; + if (load_fpga) + gpio->dir = MV_GPIO_OUT; + else + gpio->dir = MV_GPIO_OUT & ~(FPGA_DIN|FPGA_CCLK); + + printf("SICRH / SICRL : 0x%08x / 0x%08x\n", immr->sysconf.sicrh, + immr->sysconf.sicrl); + + mvblm7_init_fpga(); + if (load_fpga) + mvblm7_load_fpga(); + + /* Enable PCI_CLK_OUTPUTs 0 and 1 with 1:1 clocking */ + clk->occr = 0xc0000000; + + pci_ctrl[0].gcr = 0; + udelay(2000); + pci_ctrl[0].gcr = 1; + + for (i = 0; i < 1000; ++i) + udelay(1000); + + pci_law[0].bar = CFG_PCI1_MEM_PHYS & LAWBAR_BAR; + pci_law[0].ar = LBLAWAR_EN | LBLAWAR_1GB; + + pci_law[1].bar = CFG_PCI1_IO_PHYS & LAWBAR_BAR; + pci_law[1].ar = LBLAWAR_EN | LBLAWAR_1MB; + + warmboot = gd->bd->bi_bootflags & BOOTFLAG_WARM; + + mpc83xx_pci_init(1, reg, warmboot); +} |