[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