diff --git a/arch/powerpc/cpu/ppc4xx/fdt.c b/arch/powerpc/cpu/ppc4xx/fdt.c index 15a184b5c6..e99b2b03dc 100644 --- a/arch/powerpc/cpu/ppc4xx/fdt.c +++ b/arch/powerpc/cpu/ppc4xx/fdt.c @@ -59,15 +59,15 @@ void __ft_board_setup(void *blob, bd_t *bd) *p++ = 0; *p++ = bxcr & EBC_BXCR_BAS_MASK; *p++ = EBC_BXCR_BANK_SIZE(bxcr); - -#ifdef CONFIG_FDT_FIXUP_NOR_FLASH_SIZE - /* Try to update reg property in nor flash node too */ - fdt_fixup_nor_flash_size(blob, i, - EBC_BXCR_BANK_SIZE(bxcr)); -#endif } } + +#ifdef CONFIG_FDT_FIXUP_NOR_FLASH_SIZE + /* Update reg property in all nor flash nodes too */ + fdt_fixup_nor_flash_size(blob); +#endif + /* Some 405 PPC's have EBC as direct PLB child in the dts */ if (fdt_path_offset(blob, ebc_path) < 0) strcpy(ebc_path, "/plb/ebc"); diff --git a/board/amcc/ebony/flash.c b/board/amcc/ebony/flash.c index 8fe3ba1b8f..79d2c4c307 100644 --- a/board/amcc/ebony/flash.c +++ b/board/amcc/ebony/flash.c @@ -34,6 +34,7 @@ #include #include #include +#include #undef DEBUG #ifdef DEBUG @@ -71,6 +72,36 @@ static unsigned long flash_addr_table[8][CONFIG_SYS_MAX_FLASH_BANKS] = { */ static ulong flash_get_size(vu_long * addr, flash_info_t * info); +/* + * Override the weak default mapping function with a board specific one + */ +u32 flash_get_bank_size(int cs, int idx) +{ + u8 reg = in_8((void *)CONFIG_SYS_FPGA_BASE); + + if ((reg & BOOT_SMALL_FLASH) && !(reg & FLASH_ONBD_N)) { + /* + * cs0: small flash (512KiB) + * cs2: 2 * big flash (2 * 2MiB) + */ + if (cs == 0) + return flash_info[2].size; + if (cs == 2) + return flash_info[0].size + flash_info[1].size; + } else { + /* + * cs0: 2 * big flash (2 * 2MiB) + * cs2: small flash (512KiB) + */ + if (cs == 0) + return flash_info[0].size + flash_info[1].size; + if (cs == 2) + return flash_info[2].size; + } + + return 0; +} + unsigned long flash_init(void) { unsigned long total_b = 0; diff --git a/common/fdt_support.c b/common/fdt_support.c index aef4fe23e0..6f32e3f68d 100644 --- a/common/fdt_support.c +++ b/common/fdt_support.c @@ -590,12 +590,31 @@ int fdt_pci_dma_ranges(void *blob, int phb_off, struct pci_controller *hose) { #endif #ifdef CONFIG_FDT_FIXUP_NOR_FLASH_SIZE +/* + * Provide a weak default function to return the flash bank size. + * There might be multiple non-identical flash chips connected to one + * chip-select, so we need to pass an index as well. + */ +u32 __flash_get_bank_size(int cs, int idx) +{ + extern flash_info_t flash_info[]; + + /* + * As default, a simple 1:1 mapping is provided. Boards with + * a different mapping need to supply a board specific mapping + * routine. + */ + return flash_info[cs].size; +} +u32 flash_get_bank_size(int cs, int idx) + __attribute__((weak, alias("__flash_get_bank_size"))); + /* * This function can be used to update the size in the "reg" property - * of the NOR FLASH device nodes. This is necessary for boards with + * of all NOR FLASH device nodes. This is necessary for boards with * non-fixed NOR FLASH sizes. */ -int fdt_fixup_nor_flash_size(void *blob, int cs, u32 size) +int fdt_fixup_nor_flash_size(void *blob) { char compat[][16] = { "cfi-flash", "jedec-flash" }; int off; @@ -607,19 +626,31 @@ int fdt_fixup_nor_flash_size(void *blob, int cs, u32 size) for (i = 0; i < 2; i++) { off = fdt_node_offset_by_compatible(blob, -1, compat[i]); while (off != -FDT_ERR_NOTFOUND) { + int idx; + /* - * Found one compatible node, now check if this one - * has the correct CS + * Found one compatible node, so fixup the size + * int its reg properties */ prop = fdt_get_property_w(blob, off, "reg", &len); if (prop) { - reg = (u32 *)&prop->data[0]; - if (reg[0] == cs) { - reg[2] = size; - fdt_setprop(blob, off, "reg", reg, - 3 * sizeof(u32)); + int tuple_size = 3 * sizeof(reg); - return 0; + /* + * There might be multiple reg-tuples, + * so loop through them all + */ + len /= tuple_size; + reg = (u32 *)&prop->data[0]; + for (idx = 0; idx < len; idx++) { + /* + * Update size in reg property + */ + reg[2] = flash_get_bank_size(reg[0], + idx); + fdt_setprop(blob, off, "reg", reg, + tuple_size); + reg += tuple_size; } } @@ -629,7 +660,7 @@ int fdt_fixup_nor_flash_size(void *blob, int cs, u32 size) } } - return -1; + return 0; } #endif diff --git a/include/configs/CATcenter.h b/include/configs/CATcenter.h index 229a5138e5..002435ec11 100644 --- a/include/configs/CATcenter.h +++ b/include/configs/CATcenter.h @@ -105,6 +105,7 @@ #define CONFIG_SYS_LOADS_BAUD_CHANGE 1 /* allow baudrate change */ +#define CONFIG_PPC4xx_EMAC #undef CONFIG_EXT_PHY #define CONFIG_NET_MULTI 1 @@ -398,6 +399,7 @@ * I2C EEPROM (CAT24WC16) for environment */ #define CONFIG_HARD_I2C /* I2c with hardware support */ +#define CONFIG_PPC4XX_I2C /* use PPC4xx driver */ #define CONFIG_SYS_I2C_SPEED 400000 /* I2C speed and slave address */ #define CONFIG_SYS_I2C_SLAVE 0x7F @@ -410,16 +412,6 @@ /* last 4 bits of the address */ #define CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS 10 /* and takes up to 10 msec */ -/*----------------------------------------------------------------------- - * Cache Configuration - */ -#define CONFIG_SYS_DCACHE_SIZE 16384 /* For AMCC 405 CPUs, older 405 ppc's */ - /* have only 8kB, 16kB is save here */ -#define CONFIG_SYS_CACHELINE_SIZE 32 /* ... */ -#if defined(CONFIG_CMD_KGDB) -#define CONFIG_SYS_CACHELINE_SHIFT 5 /* log base 2 of the above value */ -#endif - /* * Init Memory Controller: * @@ -570,17 +562,6 @@ #define DIMM_READ_ADDR 0xAB #define DIMM_WRITE_ADDR 0xAA -#define CPC0_PLLMR0 (CNTRL_DCR_BASE+0x0) /* PLL mode 0 register */ -#define CPC0_BOOT (CNTRL_DCR_BASE+0x1) /* Chip Clock Status register */ -#define CPC0_CR1 (CNTRL_DCR_BASE+0x2) /* Chip Control 1 register */ -#define CPC0_EPRCSR (CNTRL_DCR_BASE+0x3) /* EMAC PHY Rcv Clk Src register */ -#define CPC0_PLLMR1 (CNTRL_DCR_BASE+0x4) /* PLL mode 1 register */ -#define CPC0_UCR (CNTRL_DCR_BASE+0x5) /* UART Control register */ -#define CPC0_SRR (CNTRL_DCR_BASE+0x6) /* Soft Reset register */ -#define CPC0_JTAGID (CNTRL_DCR_BASE+0x7) /* JTAG ID register */ -#define CPC0_SPARE (CNTRL_DCR_BASE+0x8) /* Spare DCR */ -#define CPC0_PCI (CNTRL_DCR_BASE+0x9) /* PCI Control register */ - /* Defines for CPC0_PLLMR1 Register fields */ #define PLL_ACTIVE 0x80000000 #define CPC0_PLLMR1_SSCS 0x80000000 diff --git a/include/configs/acadia.h b/include/configs/acadia.h index bd3388f626..8b01c704fd 100644 --- a/include/configs/acadia.h +++ b/include/configs/acadia.h @@ -120,7 +120,13 @@ #define CONFIG_SYS_FLASH_EMPTY_INFO /* print 'E' for empty sector on flinfo */ #else -#define CONFIG_SYS_NO_FLASH 1 /* No NOR on Acadia when NAND-booting */ +/* + * No NOR-flash on Acadia when NAND-booting. We need to undef the + * NOR device-tree fixup code as well, since flash_info is not defined + * in this case. + */ +#define CONFIG_SYS_NO_FLASH 1 +#undef CONFIG_FDT_FIXUP_NOR_FLASH_SIZE #endif #ifdef CONFIG_ENV_IS_IN_FLASH diff --git a/include/fdt_support.h b/include/fdt_support.h index 871ef4524b..fd94929cef 100644 --- a/include/fdt_support.h +++ b/include/fdt_support.h @@ -79,7 +79,7 @@ void ft_pci_setup(void *blob, bd_t *bd); void set_working_fdt_addr(void *addr); int fdt_resize(void *blob); -int fdt_fixup_nor_flash_size(void *blob, int cs, u32 size); +int fdt_fixup_nor_flash_size(void *blob); void fdt_fixup_mtdparts(void *fdt, void *node_info, int node_info_size); void fdt_del_node_and_alias(void *blob, const char *alias); diff --git a/include/ppc4xx.h b/include/ppc4xx.h index ee30a4ca3d..5238d04aa7 100644 --- a/include/ppc4xx.h +++ b/include/ppc4xx.h @@ -99,6 +99,16 @@ #endif /* 440EP/EPX 440GR/GRX 440SP/SPE 460EX/GT/SX 405EX*/ +/* + * Define ns16550 register offset for all PPC4xx SoC's. Some + * mostly FPGA based PPC4xx implementations use a different + * offset. So let's give them a chance to define their offset + * in the board config header. + */ +#if !defined(CONFIG_SYS_NS16550_REG_SIZE) +#define CONFIG_SYS_NS16550_REG_SIZE 1 +#endif + #if defined(CONFIG_440) #include #else diff --git a/post/cpu/ppc4xx/uart.c b/post/cpu/ppc4xx/uart.c index be217fcf8d..6b61cc191e 100644 --- a/post/cpu/ppc4xx/uart.c +++ b/post/cpu/ppc4xx/uart.c @@ -4,6 +4,8 @@ * * Author: Igor Lisitsin * + * Copyright 2010, Stefan Roese, DENX Software Engineering, sr@denx.de + * * See file CREDITS for list of people who contributed to this * project. * @@ -24,6 +26,9 @@ */ #include +#include +#include +#include /* * UART test @@ -119,33 +124,24 @@ #define UDIV_MAX 32 #endif -#define UART_RBR 0x00 -#define UART_THR 0x00 -#define UART_IER 0x01 -#define UART_IIR 0x02 -#define UART_FCR 0x02 -#define UART_LCR 0x03 -#define UART_MCR 0x04 -#define UART_LSR 0x05 -#define UART_MSR 0x06 -#define UART_SCR 0x07 -#define UART_DLL 0x00 -#define UART_DLM 0x01 - -/* - * Line Status Register. - */ -#define asyncLSRDataReady1 0x01 -#define asyncLSROverrunError1 0x02 -#define asyncLSRParityError1 0x04 -#define asyncLSRFramingError1 0x08 -#define asyncLSRBreakInterrupt1 0x10 -#define asyncLSRTxHoldEmpty1 0x20 -#define asyncLSRTxShiftEmpty1 0x40 -#define asyncLSRRxFifoError1 0x80 - DECLARE_GLOBAL_DATA_PTR; +static void uart_post_init_common(struct NS16550 *com_port, unsigned short bdiv) +{ + volatile char val; + + out_8(&com_port->lcr, 0x80); /* set DLAB bit */ + out_8(&com_port->dll, bdiv); /* set baudrate divisor */ + out_8(&com_port->dlm, bdiv >> 8); /* set baudrate divisor */ + out_8(&com_port->lcr, 0x03); /* clear DLAB; set 8 bits, no parity */ + out_8(&com_port->fcr, 0x00); /* disable FIFO */ + out_8(&com_port->mcr, 0x10); /* enable loopback mode */ + val = in_8(&com_port->lsr); /* clear line status */ + val = in_8(&com_port->rbr); /* read receive buffer */ + out_8(&com_port->scr, 0x00); /* set scratchpad */ + out_8(&com_port->ier, 0x00); /* set interrupt enable reg */ +} + #if defined(CONFIG_440) || defined(CONFIG_405EX) #if !defined(CONFIG_SYS_EXT_SERIAL_CLOCK) static void serial_divs (int baudrate, unsigned long *pudiv, @@ -190,19 +186,18 @@ static void serial_divs (int baudrate, unsigned long *pudiv, } #endif -static int uart_post_init (unsigned long dev_base) +static int uart_post_init (struct NS16550 *com_port) { unsigned long reg = 0; unsigned long udiv; unsigned short bdiv; - volatile char val; #ifdef CONFIG_SYS_EXT_SERIAL_CLOCK unsigned long tmp; #endif int i; for (i = 0; i < 3500; i++) { - if (in8 (dev_base + UART_LSR) & asyncLSRTxHoldEmpty1) + if (in_8(&com_port->lsr) & UART_LSR_THRE) break; udelay (100); } @@ -239,34 +234,24 @@ static int uart_post_init (unsigned long dev_base) MTREG(UART3_SDR, reg); #endif - out8(dev_base + UART_LCR, 0x80); /* set DLAB bit */ - out8(dev_base + UART_DLL, bdiv); /* set baudrate divisor */ - out8(dev_base + UART_DLM, bdiv >> 8); /* set baudrate divisor */ - out8(dev_base + UART_LCR, 0x03); /* clear DLAB; set 8 bits, no parity */ - out8(dev_base + UART_FCR, 0x00); /* disable FIFO */ - out8(dev_base + UART_MCR, 0x10); /* enable loopback mode */ - val = in8(dev_base + UART_LSR); /* clear line status */ - val = in8(dev_base + UART_RBR); /* read receive buffer */ - out8(dev_base + UART_SCR, 0x00); /* set scratchpad */ - out8(dev_base + UART_IER, 0x00); /* set interrupt enable reg */ + uart_post_init_common(com_port, bdiv); return 0; } #else /* CONFIG_440 */ -static int uart_post_init (unsigned long dev_base) +static int uart_post_init (struct NS16550 *com_port) { unsigned long reg; unsigned long tmp; unsigned long clk; unsigned long udiv; unsigned short bdiv; - volatile char val; int i; for (i = 0; i < 3500; i++) { - if (in8 (dev_base + UART_LSR) & asyncLSRTxHoldEmpty1) + if (in_8(&com_port->lsr) & UART_LSR_THRE) break; udelay (100); } @@ -309,59 +294,51 @@ static int uart_post_init (unsigned long dev_base) bdiv = (clk + tmp / 2) / tmp; #endif /* CONFIG_405EZ */ - out8(dev_base + UART_LCR, 0x80); /* set DLAB bit */ - out8(dev_base + UART_DLL, bdiv); /* set baudrate divisor */ - out8(dev_base + UART_DLM, bdiv >> 8); /* set baudrate divisor */ - out8(dev_base + UART_LCR, 0x03); /* clear DLAB; set 8 bits, no parity */ - out8(dev_base + UART_FCR, 0x00); /* disable FIFO */ - out8(dev_base + UART_MCR, 0x10); /* enable loopback mode */ - val = in8(dev_base + UART_LSR); /* clear line status */ - val = in8(dev_base + UART_RBR); /* read receive buffer */ - out8(dev_base + UART_SCR, 0x00); /* set scratchpad */ - out8(dev_base + UART_IER, 0x00); /* set interrupt enable reg */ + uart_post_init_common(com_port, bdiv); - return (0); + return 0; } #endif /* CONFIG_440 */ -static void uart_post_putc (unsigned long dev_base, char c) +static void uart_post_putc (struct NS16550 *com_port, char c) { int i; - out8 (dev_base + UART_THR, c); /* put character out */ + out_8(&com_port->thr, c); /* put character out */ /* Wait for transfer completion */ for (i = 0; i < 3500; i++) { - if (in8 (dev_base + UART_LSR) & asyncLSRTxHoldEmpty1) + if (in_8(&com_port->lsr) & UART_LSR_THRE) break; udelay (100); } } -static int uart_post_getc (unsigned long dev_base) +static int uart_post_getc (struct NS16550 *com_port) { int i; /* Wait for character available */ for (i = 0; i < 3500; i++) { - if (in8 (dev_base + UART_LSR) & asyncLSRDataReady1) + if (in_8(&com_port->lsr) & UART_LSR_DR) break; udelay (100); } - return 0xff & in8 (dev_base + UART_RBR); + + return 0xff & in_8(&com_port->rbr); } -static int test_ctlr (unsigned long dev_base, int index) +static int test_ctlr (struct NS16550 *com_port, int index) { int res = -1; char test_str[] = "*** UART Test String ***\r\n"; int i; - uart_post_init (dev_base); + uart_post_init (com_port); for (i = 0; i < sizeof (test_str) - 1; i++) { - uart_post_putc (dev_base, test_str[i]); - if (uart_post_getc (dev_base) != test_str[i]) + uart_post_putc (com_port, test_str[i]); + if (uart_post_getc (com_port) != test_str[i]) goto done; } res = 0; @@ -377,8 +354,8 @@ int uart_post_test (int flags) int i, res = 0; static unsigned long base[] = CONFIG_SYS_POST_UART_TABLE; - for (i = 0; i < sizeof (base) / sizeof (base[0]); i++) { - if (test_ctlr (base[i], i)) + for (i = 0; i < ARRAY_SIZE(base); i++) { + if (test_ctlr((struct NS16550 *)base[i], i)) res = -1; } serial_reinit_all ();