[U-Boot] [PATCH] ppc4xx: Add 405EP based PMC405DE board
Stefan Roese
sr at denx.de
Wed Jul 15 07:03:22 CEST 2009
On Monday 13 July 2009 15:24:18 Matthias Fuchs wrote:
> Signed-off-by: Matthias Fuchs <matthias.fuchs at esd.eu>
Thanks. Looks good. Only some nitpicking comments (coding-style) below.
> +++ b/board/esd/pmc405de/pmc405de.c
> @@ -0,0 +1,587 @@
> +/*
> + * (C) Copyright 2009
> + * Matthias Fuchs, esd gmbh germany, matthias.fuchs at esd.eu
> + *
> + * 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>
> +#include <libfdt.h>
> +#include <fdt_support.h>
> +#include <asm/processor.h>
> +#include <asm/io.h>
> +#include <asm/4xx_pci.h>
> +#include <command.h>
> +#include <malloc.h>
> +
> +#define CPLD_VERSION (CONFIG_SYS_CPLD_BASE + 0)
> +#define CPLD_VERSION_MASK 0x0f
> +#define CPLD_STATUS (CONFIG_SYS_CPLD_BASE + 4)
> +#define CPLD_CONTROL (CONFIG_SYS_CPLD_BASE + 8)
> +#define CPLD_CONTROL_POSTLED_N 0x01
> +#define CPLD_CONTROL_POSTLED_GATE 0x02
> +#define CPLD_CONTROL_RESETOUT_N 0x40
> +#define CPLD_CONTROL_RESETOUT_N_GATE 0x80
> +
> +DECLARE_GLOBAL_DATA_PTR;
> +
> +extern void __ft_board_setup(void *blob, bd_t *bd);
> +extern void pll_write(u32 a, u32 b);
> +
> +static int wait_for_pci_ready_done;
> +
> +static int is_monarch(void);
> +static int pci_is_66mhz(void);
> +static int board_revision(void);
> +static int cpld_revision(void);
> +
> +int board_early_init_f(void)
> +{
> + u32 pllmr0, pllmr1;
> +
> + /*
> + * check M66EN and patch PLB:PCI divider for 66MHz PCI
> + *
> + * fCPU==333MHz && fPCI==66MHz (PLBDiv==3 && M66EN==1): PLB/PCI=1
> + * fCPU==333MHz && fPCI==33MHz (PLBDiv==3 && M66EN==0): PLB/PCI=2
> + * fCPU==133|266MHz && fPCI==66MHz (PLBDiv==1|2 && M66EN==1): PLB/PCI=2
> + * fCPU==133|266MHz && fPCI==33MHz (PLBDiv==1|2 && M66EN==0): PLB/PCI=3
> + *
> + * finally call pll_write() which will do a chip reset
> + * and never return.
> + */
> + pllmr0 = mfdcr(CPC0_PLLMR0);
> + pllmr1 = mfdcr(CPC0_PLLMR1);
> +
> + if ((pllmr0 & PLLMR0_CPU_TO_PLB_MASK) == PLLMR0_CPU_PLB_DIV_3) {
> + /* fCPU=333MHz, fPLB=111MHz */
> + if (pci_is_66mhz()) {
> + if ((pllmr0 & PLLMR0_PCI_TO_PLB_MASK) !=
> + PLLMR0_PCI_PLB_DIV_1) {
> + pll_write((pllmr0 & ~PLLMR0_PCI_TO_PLB_MASK) |
> + PLLMR0_PCI_PLB_DIV_1, pllmr1);
> + }
> + } else {
> + if ((pllmr0 & PLLMR0_PCI_TO_PLB_MASK) !=
> + PLLMR0_PCI_PLB_DIV_2) {
> + pll_write((pllmr0 & ~PLLMR0_PCI_TO_PLB_MASK) |
> + PLLMR0_PCI_PLB_DIV_2, pllmr1);
> + }
> + }
> + } else {
> + /* fCPU=133|266MHz, fPLB=133MHz */
> + if (pci_is_66mhz()) {
> + if ((pllmr0 & PLLMR0_PCI_TO_PLB_MASK) !=
> + PLLMR0_PCI_PLB_DIV_2) {
> + pll_write((pllmr0 & ~PLLMR0_PCI_TO_PLB_MASK) |
> + PLLMR0_PCI_PLB_DIV_2, pllmr1);
> + }
> + } else {
> + if ((pllmr0 & PLLMR0_PCI_TO_PLB_MASK) !=
> + PLLMR0_PCI_PLB_DIV_3) {
> + pll_write((pllmr0 & ~PLLMR0_PCI_TO_PLB_MASK) |
> + PLLMR0_PCI_PLB_DIV_3, pllmr1);
> + }
> + }
> + }
> +
> + /*
> + * IRQ 25 (EXT IRQ 0) PCI-INTA#; active low; level sensitive
> + * IRQ 26 (EXT IRQ 1) PCI-INTB#; active low; level sensitive
> + * IRQ 27 (EXT IRQ 2) PCI-INTC#; active low; level sensitive
> + * IRQ 28 (EXT IRQ 3) PCI-INTD#; active low; level sensitive
> + * IRQ 29 (EXT IRQ 4) ETH0-PHY-IRQ#; active low; level sensitive
> + * IRQ 30 (EXT IRQ 5) ETH1-PHY-IRQ#; active low; level sensitive
> + * IRQ 31 (EXT IRQ 6) PLD-IRQ#; active low; level sensitive
> + */
> + mtdcr(uicsr, 0xFFFFFFFF); /* clear all ints */
> + mtdcr(uicer, 0x00000000); /* disable all ints */
> + mtdcr(uiccr, 0x00000000); /* set all to be non-critical*/
> + mtdcr(uicpr, 0xFFFFFF80); /* set int polarities */
> + mtdcr(uictr, 0x10000000); /* set int trigger levels */
> + mtdcr(uicvcr, 0x00000001); /* set vect base=0, INT0 highest prio */
> + mtdcr(uicsr, 0xFFFFFFFF); /* clear all ints */
> +
> + /*
> + * EBC Configuration Register:
> + * - set ready timeout to 512 ebc-clks -> ca. 15 us
> + * - EBC lines are always driven
> + */
> + mtebc (epcr, 0xa8400000);
Please remove this space before "(" here.
> +
> + return 0;
> +}
> +
> +int misc_init_r(void)
> +{
> + int i;
> +
> + if (!is_monarch()) {
> + /* PCI configuration done: release EREADY */
> + out_be32((void*)GPIO0_OR,
> + in_be32((void*)GPIO0_OR) | CONFIG_SYS_GPIO_EREADY);
> + out_be32((void*)GPIO0_TCR,
> + in_be32((void*)GPIO0_TCR) | CONFIG_SYS_GPIO_EREADY);
> + }
> +
> + /* turn off POST LED */
> + out_8((void*)CPLD_CONTROL,
> + CPLD_CONTROL_POSTLED_N | CPLD_CONTROL_POSTLED_GATE);
> +
> + /* turn on LEDs: RUN, A, B */
> + out_be32((void*)GPIO0_OR,
> + in_be32((void*)GPIO0_OR) &
> + ~(CONFIG_SYS_GPIO_LEDRUN_N |
> + CONFIG_SYS_GPIO_LEDA_N |
> + CONFIG_SYS_GPIO_LEDB_N));
> +
> + for (i=0; i < 200; i++)
> + udelay(1000);
> +
> + /* turn off LEDs: A, B */
> + out_be32((void*)GPIO0_OR,
> + in_be32((void*)GPIO0_OR) |
> + (CONFIG_SYS_GPIO_LEDA_N |
> + CONFIG_SYS_GPIO_LEDB_N));
> +
> + return (0);
> +}
> +
> +static int is_monarch(void)
> +{
> + if (in_be32((void*)GPIO0_IR) & CONFIG_SYS_GPIO_MONARCH_N)
> + return 0;
> + return 1;
> +}
> +
> +static int pci_is_66mhz(void)
> +{
> + if (in_be32((void*)GPIO0_IR) & CONFIG_SYS_GPIO_M66EN)
> + return 1;
> + return 0;
> +}
> +
> +static int board_revision(void)
> +{
> + return ((in_be32((void*)GPIO0_IR) & CONFIG_SYS_GPIO_HWREV_MASK) >>
> + CONFIG_SYS_GPIO_HWREV_SHIFT);
> +}
> +
> +static int cpld_revision(void)
> +{
> + return ((in_8((void*)CPLD_VERSION) & CPLD_VERSION_MASK));
> +}
> +
> +/*
> + * Check Board Identity
> + */
> +int checkboard(void)
> +{
> + puts("Board: esd GmbH - PMC-CPU/405-DE");
> +
> + gd->board_type = board_revision();
> + printf(", Rev 1.%ld, ", gd->board_type);
> +
> + if (!is_monarch())
> + puts("non-");
> +
> + printf("monarch, PCI=%s MHz, PLD-Rev 1.%d\n",
> + pci_is_66mhz() ? "66" : "33", cpld_revision());
> +
> + return 0;
> +}
> +
> +
> +static void wait_for_pci_ready(void)
> +{
> + int i;
> + char *s = getenv("pcidelay");
> +
> + /* only wait once */
> + if (wait_for_pci_ready_done)
> + return;
> +
> + /*
> + * We have our own handling of the pcidelay variable.
> + * Using CONFIG_PCI_BOOTDELAY enables pausing for host
> + * and adapter devices. For adapter devices we do not
> + * want this.
> + */
> + if (s) {
> + int ms = simple_strtoul(s, NULL, 10);
> + printf("PCI: Waiting for %d ms\n", ms);
> + for (i=0; i<ms; i++)
> + udelay(1000);
> + }
> +
> + if (!(in_be32((void*)GPIO0_IR) & CONFIG_SYS_GPIO_EREADY)) {
> + printf("PCI: Waiting for EREADY (CTRL-C to skip) ... ");
> + while (1) {
> + if (ctrlc()) {
> + puts("abort\n");
> + break;
> + }
> + if (in_be32((void*)GPIO0_IR) & CONFIG_SYS_GPIO_EREADY) {
> + printf("done\n");
> + break;
> + }
> + }
> + }
> +
> + wait_for_pci_ready_done = 1;
> +}
> +
> +/*
> + * Overwrite weak is_pci_host()
> + *
> + * This routine is called to determine if a pci scan should be
> + * performed. With various hardware environments (especially cPCI and
> + * PPMC) it's insufficient to depend on the state of the arbiter enable
> + * bit in the strap register, or generic host/adapter assumptions.
> + *
> + * Return 0 for adapter mode, non-zero for host (monarch) mode.
> + */
> +int is_pci_host(struct pci_controller *hose)
> +{
> + char *s;
> +
> + if (!is_monarch()) {
> + /*
> + * Overwrite PCI identification when running in
> + * non-monarch mode
> + * This should be moved into pci_target_init()
> + * when it is sometimes available for 405 CPUs
> + */
> + pci_write_config_word(PCIDEVID_405GP,
> + PCI_SUBSYSTEM_ID,
> + CONFIG_SYS_PCI_SUBSYS_ID_NONMONARCH);
> + pci_write_config_word(PCIDEVID_405GP,
> + PCI_CLASS_SUB_CODE,
> + CONFIG_SYS_PCI_CLASSCODE_NONMONARCH);
> + }
> +
> + s = getenv("pciscan");
> + if (s == NULL)
> + if (is_monarch()) {
> + wait_for_pci_ready();
> + return 1;
> + } else
> + return 0;
> + else if (!strcmp(s, "yes"))
> + return 1;
This "if/else" statements should have braces ({) since it's not a single-line
statement.
Best regards,
Stefan
=====================================================================
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-0 Fax: +49-8142-66989-80 Email: office at denx.de
=====================================================================
More information about the U-Boot
mailing list