diff options
Diffstat (limited to 'arch')
72 files changed, 1781 insertions, 1665 deletions
diff --git a/arch/arm/cpu/arm1176/bcm2835/Makefile b/arch/arm/cpu/arm1176/bcm2835/Makefile index 4ea6d6b89ff..95da6a822a1 100644 --- a/arch/arm/cpu/arm1176/bcm2835/Makefile +++ b/arch/arm/cpu/arm1176/bcm2835/Makefile @@ -17,7 +17,7 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(SOC).o SOBJS := lowlevel_init.o -COBJS := reset.o timer.o +COBJS := init.o reset.o timer.o SRCS := $(SOBJS:.o=.c) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) diff --git a/arch/arm/cpu/arm1176/bcm2835/init.c b/arch/arm/cpu/arm1176/bcm2835/init.c new file mode 100644 index 00000000000..e90d3bba1f9 --- /dev/null +++ b/arch/arm/cpu/arm1176/bcm2835/init.c @@ -0,0 +1,24 @@ +/* + * (C) Copyright 2012 Stephen Warren + * + * 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 + * version 2 as published by the Free Software Foundation. + * + * 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. + */ + +#include <common.h> + +int arch_cpu_init(void) +{ + icache_enable(); + + return 0; +} diff --git a/arch/arm/cpu/arm1176/cpu.c b/arch/arm/cpu/arm1176/cpu.c index 532a90b546f..c0fd114e163 100644 --- a/arch/arm/cpu/arm1176/cpu.c +++ b/arch/arm/cpu/arm1176/cpu.c @@ -65,10 +65,3 @@ static void cache_flush (void) /* mem barrier to sync things */ asm ("mcr p15, 0, %0, c7, c10, 4": :"r" (0)); } - -int arch_cpu_init(void) -{ - icache_enable(); - - return 0; -} diff --git a/arch/arm/cpu/arm926ejs/davinci/Makefile b/arch/arm/cpu/arm926ejs/davinci/Makefile index c91928e71d2..dec7bfbfaa4 100644 --- a/arch/arm/cpu/arm926ejs/davinci/Makefile +++ b/arch/arm/cpu/arm926ejs/davinci/Makefile @@ -37,7 +37,7 @@ COBJS-$(CONFIG_SOC_DA850) += da850_pinmux.o COBJS-$(CONFIG_DRIVER_TI_EMAC) += lxt972.o dp83848.o et1011c.o ksz8873.o ifdef CONFIG_SPL_BUILD -COBJS-y += spl.o +COBJS-$(CONFIG_SPL_FRAMEWORK) += spl.o COBJS-$(CONFIG_SOC_DM365) += dm365_lowlevel.o COBJS-$(CONFIG_SOC_DA8XX) += da850_lowlevel.o endif diff --git a/arch/arm/cpu/arm926ejs/davinci/config.mk b/arch/arm/cpu/arm926ejs/davinci/config.mk new file mode 100644 index 00000000000..745231547d8 --- /dev/null +++ b/arch/arm/cpu/arm926ejs/davinci/config.mk @@ -0,0 +1,16 @@ +# +# Copyright (C) 2012, Texas Instruments, Incorporated - http://www.ti.com/ +# +# 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 "as is" WITHOUT ANY WARRANTY of any +# kind, whether express or implied; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +ifndef CONFIG_SPL_BUILD +ALL-$(CONFIG_SPL_FRAMEWORK) += $(obj)u-boot.ais +endif diff --git a/arch/arm/cpu/arm926ejs/davinci/spl.c b/arch/arm/cpu/arm926ejs/davinci/spl.c index 03c85c87fba..714fa928465 100644 --- a/arch/arm/cpu/arm926ejs/davinci/spl.c +++ b/arch/arm/cpu/arm926ejs/davinci/spl.c @@ -21,6 +21,8 @@ * MA 02111-1307 USA */ #include <common.h> +#include <config.h> +#include <spl.h> #include <asm/u-boot.h> #include <asm/utils.h> #include <nand.h> @@ -30,15 +32,9 @@ #include <spi_flash.h> #include <mmc.h> -#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT - DECLARE_GLOBAL_DATA_PTR; -/* Define global data structure pointer to it*/ -static gd_t gdata __attribute__ ((section(".data"))); -static bd_t bdata __attribute__ ((section(".data"))); - -#else +#ifndef CONFIG_SPL_LIBCOMMON_SUPPORT void puts(const char *str) { while (*str) @@ -52,53 +48,49 @@ void putc(char c) NS16550_putc((NS16550_t)(CONFIG_SYS_NS16550_COM1), c); } - #endif /* CONFIG_SPL_LIBCOMMON_SUPPORT */ -inline void hang(void) -{ - puts("### ERROR ### Please RESET the board ###\n"); - for (;;) - ; -} - void board_init_f(ulong dummy) { + /* First, setup our stack pointer. */ + asm volatile("mov sp, %0\n" : : "r"(CONFIG_SPL_STACK)); + + /* Second, perform our low-level init. */ #ifdef CONFIG_SOC_DM365 dm36x_lowlevel_init(0); #endif #ifdef CONFIG_SOC_DA8XX arch_cpu_init(); #endif - relocate_code(CONFIG_SPL_STACK, NULL, CONFIG_SPL_TEXT_BASE); -} -void board_init_r(gd_t *id, ulong dummy) -{ -#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT - mem_malloc_init(CONFIG_SYS_TEXT_BASE - CONFIG_SYS_MALLOC_LEN, - CONFIG_SYS_MALLOC_LEN); + /* Third, we clear the BSS. */ + memset(__bss_start, 0, __bss_end__ - __bss_start); + /* Finally, setup gd and move to the next step. */ gd = &gdata; - gd->bd = &bdata; - gd->flags |= GD_FLG_RELOC; - gd->baudrate = CONFIG_BAUDRATE; - serial_init(); /* serial communications setup */ - gd->have_console = 1; + board_init_r(NULL, 0); +} -#endif +void spl_board_init(void) +{ + preloader_console_init(); +} -#ifdef CONFIG_SPL_NAND_LOAD - nand_init(); - puts("Nand boot...\n"); - nand_boot(); -#endif -#ifdef CONFIG_SPL_SPI_LOAD - puts("SPI boot...\n"); - spi_boot(); -#endif -#ifdef CONFIG_SPL_MMC_LOAD - puts("MMC boot...\n"); - spl_mmc_load(); +u32 spl_boot_mode(void) +{ + return MMCSD_MODE_RAW; +} + +u32 spl_boot_device(void) +{ +#ifdef CONFIG_SPL_NAND_SIMPLE + return BOOT_DEVICE_NAND; +#elif defined(CONFIG_SPL_SPI_LOAD) + return BOOT_DEVICE_SPI; +#elif defined(CONFIG_SPL_MMC_LOAD) + return BOOT_DEVICE_MMC1; +#else + puts("Unknown boot device\n"); + hang(); #endif } diff --git a/arch/arm/cpu/arm926ejs/start.S b/arch/arm/cpu/arm926ejs/start.S index 6f05f1ac49c..521d46290cf 100644 --- a/arch/arm/cpu/arm926ejs/start.S +++ b/arch/arm/cpu/arm926ejs/start.S @@ -215,6 +215,7 @@ call_board_init_f: /*------------------------------------------------------------------------------*/ +#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_NAND_SPL) /* * void relocate_code (addr_sp, gd, addr_moni) * @@ -344,6 +345,7 @@ _rel_dyn_end_ofs: .word __rel_dyn_end - _start _dynsym_start_ofs: .word __dynsym_start - _start +#endif /* ************************************************************************* diff --git a/arch/arm/cpu/armv7/am33xx/board.c b/arch/arm/cpu/armv7/am33xx/board.c index ecc26717cda..978b184fb22 100644 --- a/arch/arm/cpu/armv7/am33xx/board.c +++ b/arch/arm/cpu/armv7/am33xx/board.c @@ -18,6 +18,7 @@ #include <common.h> #include <errno.h> +#include <spl.h> #include <asm/arch/cpu.h> #include <asm/arch/hardware.h> #include <asm/arch/omap.h> @@ -27,7 +28,6 @@ #include <asm/arch/mmc_host_def.h> #include <asm/arch/sys_proto.h> #include <asm/io.h> -#include <asm/omap_common.h> #include <asm/emif.h> #include <asm/gpio.h> #include <i2c.h> @@ -166,6 +166,8 @@ void s_init(void) regVal |= UART_SMART_IDLE_EN; writel(regVal, &uart_base->uartsyscfg); + gd = &gdata; + preloader_console_init(); /* Initalize the board header */ diff --git a/arch/arm/cpu/armv7/omap-common/Makefile b/arch/arm/cpu/armv7/omap-common/Makefile index d37b22d98a8..1f2fa027c8f 100644 --- a/arch/arm/cpu/armv7/omap-common/Makefile +++ b/arch/arm/cpu/armv7/omap-common/Makefile @@ -42,19 +42,6 @@ COBJS += boot-common.o SOBJS += lowlevel_init.o endif -ifdef CONFIG_SPL_BUILD -COBJS += spl.o -ifdef CONFIG_SPL_NAND_SUPPORT -COBJS += spl_nand.o -endif -ifdef CONFIG_SPL_MMC_SUPPORT -COBJS += spl_mmc.o -endif -ifdef CONFIG_SPL_YMODEM_SUPPORT -COBJS += spl_ymodem.o -endif -endif - ifndef CONFIG_SPL_BUILD ifneq ($(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX),) COBJS += mem-common.o diff --git a/arch/arm/cpu/armv7/omap-common/boot-common.c b/arch/arm/cpu/armv7/omap-common/boot-common.c index f211f7670c6..0f19141cc23 100644 --- a/arch/arm/cpu/armv7/omap-common/boot-common.c +++ b/arch/arm/cpu/armv7/omap-common/boot-common.c @@ -17,8 +17,10 @@ */ #include <common.h> +#include <spl.h> #include <asm/omap_common.h> #include <asm/arch/omap.h> +#include <asm/arch/mmc_host_def.h> /* * This is used to verify if the configuration header @@ -37,13 +39,34 @@ struct omap_boot_parameters boot_params __attribute__ ((section(".data"))); */ u32 omap_bootmode = MMCSD_MODE_FAT; -u32 omap_boot_device(void) +u32 spl_boot_device(void) { return (u32) (boot_params.omap_bootdevice); } -u32 omap_boot_mode(void) +u32 spl_boot_mode(void) { return omap_bootmode; } + +void spl_board_init(void) +{ +#ifdef CONFIG_SPL_NAND_SUPPORT + gpmc_init(); +#endif +} + +int board_mmc_init(bd_t *bis) +{ + switch (spl_boot_device()) { + case BOOT_DEVICE_MMC1: + omap_mmc_init(0, 0, 0); + break; + case BOOT_DEVICE_MMC2: + case BOOT_DEVICE_MMC2_2: + omap_mmc_init(1, 0, 0); + break; + } + return 0; +} #endif diff --git a/arch/arm/cpu/armv7/omap-common/hwinit-common.c b/arch/arm/cpu/armv7/omap-common/hwinit-common.c index 459ebb55e57..9ef10bdf2da 100644 --- a/arch/arm/cpu/armv7/omap-common/hwinit-common.c +++ b/arch/arm/cpu/armv7/omap-common/hwinit-common.c @@ -28,10 +28,10 @@ * MA 02111-1307 USA */ #include <common.h> +#include <spl.h> #include <asm/arch/sys_proto.h> #include <asm/sizes.h> #include <asm/emif.h> -#include <asm/omap_common.h> DECLARE_GLOBAL_DATA_PTR; @@ -92,6 +92,11 @@ static void init_boot_params(void) { boot_params_ptr = (u32 *) &boot_params; } + +void spl_display_print(void) +{ + omap_rev_string(); +} #endif /* @@ -119,6 +124,9 @@ void s_init(void) set_mux_conf_regs(); #ifdef CONFIG_SPL_BUILD setup_clocks_for_console(); + + gd = &gdata; + preloader_console_init(); do_io_settings(); #endif diff --git a/arch/arm/cpu/armv7/omap-common/lowlevel_init.S b/arch/arm/cpu/armv7/omap-common/lowlevel_init.S index 1ece073630a..9766563d02d 100644 --- a/arch/arm/cpu/armv7/omap-common/lowlevel_init.S +++ b/arch/arm/cpu/armv7/omap-common/lowlevel_init.S @@ -52,18 +52,18 @@ ENTRY(save_boot_params) ldr r1, =boot_params str r0, [r1] #ifdef CONFIG_SPL_BUILD - /* Store the boot device in omap_boot_device */ + /* Store the boot device in spl_boot_device */ ldrb r2, [r0, #BOOT_DEVICE_OFFSET] @ r1 <- value of boot device and r2, #BOOT_DEVICE_MASK ldr r3, =boot_params - strb r2, [r3, #BOOT_DEVICE_OFFSET] @ omap_boot_device <- r1 + strb r2, [r3, #BOOT_DEVICE_OFFSET] @ spl_boot_device <- r1 /* boot mode is passed only for devices that can raw/fat mode */ cmp r2, #2 blt 2f cmp r2, #7 bgt 2f - /* Store the boot mode (raw/FAT) in omap_boot_mode */ + /* Store the boot mode (raw/FAT) in omap_bootmode */ ldr r2, [r0, #DEV_DESC_PTR_OFFSET] @ get the device descriptor ptr ldr r2, [r2, #DEV_DATA_PTR_OFFSET] @ get the pDeviceData ptr ldr r2, [r2, #BOOT_MODE_OFFSET] @ get the boot mode diff --git a/arch/arm/cpu/armv7/omap-common/spl.c b/arch/arm/cpu/armv7/omap-common/spl.c deleted file mode 100644 index 4d1ac85d009..00000000000 --- a/arch/arm/cpu/armv7/omap-common/spl.c +++ /dev/null @@ -1,228 +0,0 @@ -/* - * (C) Copyright 2010 - * Texas Instruments, <www.ti.com> - * - * Aneesh V <aneesh@ti.com> - * - * 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 <asm/u-boot.h> -#include <asm/utils.h> -#include <asm/arch/sys_proto.h> -#include <nand.h> -#include <mmc.h> -#include <fat.h> -#include <version.h> -#include <asm/omap_common.h> -#include <asm/arch/mmc_host_def.h> -#include <i2c.h> -#include <image.h> -#include <malloc.h> -#include <linux/compiler.h> - -DECLARE_GLOBAL_DATA_PTR; - -u32* boot_params_ptr = NULL; -struct spl_image_info spl_image; - -/* Define global data structure pointer to it*/ -static gd_t gdata __attribute__ ((section(".data"))); -static bd_t bdata __attribute__ ((section(".data"))); - -inline void hang(void) -{ - puts("### ERROR ### Please RESET the board ###\n"); - for (;;) - ; -} - -void board_init_f(ulong dummy) -{ - /* - * We call relocate_code() with relocation target same as the - * CONFIG_SYS_SPL_TEXT_BASE. This will result in relocation getting - * skipped. Instead, only .bss initialization will happen. That's - * all we need - */ - debug(">>board_init_f()\n"); - relocate_code(CONFIG_SPL_STACK, &gdata, CONFIG_SPL_TEXT_BASE); -} - -/* - * Default function to determine if u-boot or the OS should - * be started. This implementation always returns 1. - * - * Please implement your own board specific funcion to do this. - * - * RETURN - * 0 to not start u-boot - * positive if u-boot should start - */ -#ifdef CONFIG_SPL_OS_BOOT -__weak int spl_start_uboot(void) -{ - printf("SPL: Please implement spl_start_uboot() for your board\n"); - printf("SPL: Direct Linux boot not active!\n"); - return 1; -} -#endif - -void spl_parse_image_header(const struct image_header *header) -{ - u32 header_size = sizeof(struct image_header); - - if (__be32_to_cpu(header->ih_magic) == IH_MAGIC) { - spl_image.size = __be32_to_cpu(header->ih_size) + header_size; - spl_image.entry_point = __be32_to_cpu(header->ih_load); - /* Load including the header */ - spl_image.load_addr = spl_image.entry_point - header_size; - spl_image.os = header->ih_os; - spl_image.name = (const char *)&header->ih_name; - debug("spl: payload image: %s load addr: 0x%x size: %d\n", - spl_image.name, spl_image.load_addr, spl_image.size); - } else { - /* Signature not found - assume u-boot.bin */ - printf("mkimage signature not found - ih_magic = %x\n", - header->ih_magic); - debug("Assuming u-boot.bin ..\n"); - /* Let's assume U-Boot will not be more than 200 KB */ - spl_image.size = 200 * 1024; - spl_image.entry_point = CONFIG_SYS_TEXT_BASE; - spl_image.load_addr = CONFIG_SYS_TEXT_BASE; - spl_image.os = IH_OS_U_BOOT; - spl_image.name = "U-Boot"; - } -} - -/* - * This function jumps to an image with argument. Normally an FDT or ATAGS - * image. - * arg: Pointer to paramter image in RAM - */ -#ifdef CONFIG_SPL_OS_BOOT -static void __noreturn jump_to_image_linux(void *arg) -{ - debug("Entering kernel arg pointer: 0x%p\n", arg); - typedef void (*image_entry_arg_t)(int, int, void *) - __attribute__ ((noreturn)); - image_entry_arg_t image_entry = - (image_entry_arg_t) spl_image.entry_point; - cleanup_before_linux(); - image_entry(0, CONFIG_MACH_TYPE, arg); -} -#endif - -static void __noreturn jump_to_image_no_args(void) -{ - typedef void __noreturn (*image_entry_noargs_t)(u32 *); - image_entry_noargs_t image_entry = - (image_entry_noargs_t) spl_image.entry_point; - - debug("image entry point: 0x%X\n", spl_image.entry_point); - /* Pass the saved boot_params from rom code */ -#if defined(CONFIG_VIRTIO) || defined(CONFIG_ZEBU) - image_entry = (image_entry_noargs_t)0x80100000; -#endif - u32 boot_params_ptr_addr = (u32)&boot_params_ptr; - image_entry((u32 *)boot_params_ptr_addr); -} - -void board_init_r(gd_t *id, ulong dummy) -{ - u32 boot_device; - debug(">>spl:board_init_r()\n"); - - mem_malloc_init(CONFIG_SYS_SPL_MALLOC_START, - CONFIG_SYS_SPL_MALLOC_SIZE); - -#ifdef CONFIG_SPL_BOARD_INIT - spl_board_init(); -#endif - - boot_device = omap_boot_device(); - debug("boot device - %d\n", boot_device); - switch (boot_device) { -#ifdef CONFIG_SPL_MMC_SUPPORT - case BOOT_DEVICE_MMC1: - case BOOT_DEVICE_MMC2: - case BOOT_DEVICE_MMC2_2: - spl_mmc_load_image(); - break; -#endif -#ifdef CONFIG_SPL_NAND_SUPPORT - case BOOT_DEVICE_NAND: - spl_nand_load_image(); - break; -#endif -#ifdef CONFIG_SPL_YMODEM_SUPPORT - case BOOT_DEVICE_UART: - spl_ymodem_load_image(); - break; -#endif - default: - printf("SPL: Un-supported Boot Device - %d!!!\n", boot_device); - hang(); - break; - } - - switch (spl_image.os) { - case IH_OS_U_BOOT: - debug("Jumping to U-Boot\n"); - jump_to_image_no_args(); - break; -#ifdef CONFIG_SPL_OS_BOOT - case IH_OS_LINUX: - debug("Jumping to Linux\n"); - spl_board_prepare_for_linux(); - jump_to_image_linux((void *)CONFIG_SYS_SPL_ARGS_ADDR); - break; -#endif - default: - puts("Unsupported OS image.. Jumping nevertheless..\n"); - jump_to_image_no_args(); - } -} - -/* This requires UART clocks to be enabled */ -void preloader_console_init(void) -{ - const char *u_boot_rev = U_BOOT_VERSION; - - gd = &gdata; - gd->bd = &bdata; - gd->flags |= GD_FLG_RELOC; - gd->baudrate = CONFIG_BAUDRATE; - - serial_init(); /* serial communications setup */ - - gd->have_console = 1; - - /* Avoid a second "U-Boot" coming from this string */ - u_boot_rev = &u_boot_rev[7]; - - printf("\nU-Boot SPL %s (%s - %s)\n", u_boot_rev, U_BOOT_DATE, - U_BOOT_TIME); - omap_rev_string(); -} - -void __weak omap_rev_string() -{ - printf("Texas Instruments Revision detection unimplemented\n"); -} diff --git a/arch/arm/cpu/armv7/omap-common/spl_mmc.c b/arch/arm/cpu/armv7/omap-common/spl_mmc.c deleted file mode 100644 index 2f921bb07d4..00000000000 --- a/arch/arm/cpu/armv7/omap-common/spl_mmc.c +++ /dev/null @@ -1,150 +0,0 @@ -/* - * (C) Copyright 2010 - * Texas Instruments, <www.ti.com> - * - * Aneesh V <aneesh@ti.com> - * - * 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 <asm/u-boot.h> -#include <asm/utils.h> -#include <asm/arch/sys_proto.h> -#include <mmc.h> -#include <fat.h> -#include <version.h> -#include <asm/omap_common.h> -#include <asm/arch/mmc_host_def.h> - -DECLARE_GLOBAL_DATA_PTR; - -#ifdef CONFIG_GENERIC_MMC -int board_mmc_init(bd_t *bis) -{ - switch (omap_boot_device()) { - case BOOT_DEVICE_MMC1: - omap_mmc_init(0, 0, 0); - break; - case BOOT_DEVICE_MMC2: - case BOOT_DEVICE_MMC2_2: - omap_mmc_init(1, 0, 0); - break; - } - return 0; -} -#endif - -static void mmc_load_image_raw(struct mmc *mmc) -{ - u32 image_size_sectors, err; - const struct image_header *header; - - header = (struct image_header *)(CONFIG_SYS_TEXT_BASE - - sizeof(struct image_header)); - - /* read image header to find the image size & load address */ - err = mmc->block_dev.block_read(0, - CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR, 1, - (void *)header); - - if (err <= 0) - goto end; - - spl_parse_image_header(header); - - /* convert size to sectors - round up */ - image_size_sectors = (spl_image.size + MMCSD_SECTOR_SIZE - 1) / - MMCSD_SECTOR_SIZE; - - /* Read the header too to avoid extra memcpy */ - err = mmc->block_dev.block_read(0, - CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR, - image_size_sectors, (void *)spl_image.load_addr); - -end: - if (err <= 0) { - printf("spl: mmc blk read err - %d\n", err); - hang(); - } -} - -static void mmc_load_image_fat(struct mmc *mmc) -{ - s32 err; - struct image_header *header; - - header = (struct image_header *)(CONFIG_SYS_TEXT_BASE - - sizeof(struct image_header)); - - err = fat_register_device(&mmc->block_dev, - CONFIG_SYS_MMC_SD_FAT_BOOT_PARTITION); - if (err) { - printf("spl: fat register err - %d\n", err); - hang(); - } - - err = file_fat_read(CONFIG_SPL_FAT_LOAD_PAYLOAD_NAME, - (u8 *)header, sizeof(struct image_header)); - if (err <= 0) - goto end; - - spl_parse_image_header(header); - - err = file_fat_read(CONFIG_SPL_FAT_LOAD_PAYLOAD_NAME, - (u8 *)spl_image.load_addr, 0); - -end: - if (err <= 0) { - printf("spl: error reading image %s, err - %d\n", - CONFIG_SPL_FAT_LOAD_PAYLOAD_NAME, err); - hang(); - } -} - -void spl_mmc_load_image(void) -{ - struct mmc *mmc; - int err; - u32 boot_mode; - - mmc_initialize(gd->bd); - /* We register only one device. So, the dev id is always 0 */ - mmc = find_mmc_device(0); - if (!mmc) { - puts("spl: mmc device not found!!\n"); - hang(); - } - - err = mmc_init(mmc); - if (err) { - printf("spl: mmc init failed: err - %d\n", err); - hang(); - } - boot_mode = omap_boot_mode(); - if (boot_mode == MMCSD_MODE_RAW) { - debug("boot mode - RAW\n"); - mmc_load_image_raw(mmc); - } else if (boot_mode == MMCSD_MODE_FAT) { - debug("boot mode - FAT\n"); - mmc_load_image_fat(mmc); - } else { - puts("spl: wrong MMC boot mode\n"); - hang(); - } -} diff --git a/arch/arm/cpu/armv7/omap-common/spl_nand.c b/arch/arm/cpu/armv7/omap-common/spl_nand.c deleted file mode 100644 index 8cf55c9a1c8..00000000000 --- a/arch/arm/cpu/armv7/omap-common/spl_nand.c +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (C) 2011 - * Corscience GmbH & Co. KG - Simon Schwarz <schwarz@corscience.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> -#include <asm/u-boot.h> -#include <asm/utils.h> -#include <asm/arch/sys_proto.h> -#include <asm/io.h> -#include <nand.h> -#include <version.h> -#include <asm/omap_common.h> - -void spl_nand_load_image(void) -{ - struct image_header *header; - int *src __attribute__((unused)); - int *dst __attribute__((unused)); - - switch (omap_boot_mode()) { - case NAND_MODE_HW_ECC: - debug("spl: nand - using hw ecc\n"); - gpmc_init(); - nand_init(); - break; - default: - puts("spl: ERROR: This bootmode is not implemented - hanging"); - hang(); - } - - /*use CONFIG_SYS_TEXT_BASE as temporary storage area */ - header = (struct image_header *)(CONFIG_SYS_TEXT_BASE); -#ifdef CONFIG_SPL_OS_BOOT - if (!spl_start_uboot()) { - /* - * load parameter image - * load to temp position since nand_spl_load_image reads - * a whole block which is typically larger than - * CONFIG_CMD_SPL_WRITE_SIZE therefore may overwrite - * following sections like BSS - */ - nand_spl_load_image(CONFIG_CMD_SPL_NAND_OFS, - CONFIG_CMD_SPL_WRITE_SIZE, - (void *)CONFIG_SYS_TEXT_BASE); - /* copy to destintion */ - for (dst = (int *)CONFIG_SYS_SPL_ARGS_ADDR, - src = (int *)CONFIG_SYS_TEXT_BASE; - src < (int *)(CONFIG_SYS_TEXT_BASE + - CONFIG_CMD_SPL_WRITE_SIZE); - src++, dst++) { - writel(readl(src), dst); - } - - /* load linux */ - nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS, - CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); - spl_parse_image_header(header); - if (header->ih_os == IH_OS_LINUX) { - /* happy - was a linux */ - nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS, - spl_image.size, (void *)spl_image.load_addr); - nand_deselect(); - return; - } else { - printf("The Expected Linux image was not" - "found. Please check your NAND" - "configuration.\n"); - printf("Trying to start u-boot now...\n"); - } - } -#endif -#ifdef CONFIG_NAND_ENV_DST - nand_spl_load_image(CONFIG_ENV_OFFSET, - CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); - spl_parse_image_header(header); - nand_spl_load_image(CONFIG_ENV_OFFSET, spl_image.size, - (void *)spl_image.load_addr); -#ifdef CONFIG_ENV_OFFSET_REDUND - nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, - CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); - spl_parse_image_header(header); - nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, spl_image.size, - (void *)spl_image.load_addr); -#endif -#endif - /* Load u-boot */ - nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, - CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); - spl_parse_image_header(header); - nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, - spl_image.size, (void *)spl_image.load_addr); - nand_deselect(); -} diff --git a/arch/arm/cpu/armv7/omap-common/spl_ymodem.c b/arch/arm/cpu/armv7/omap-common/spl_ymodem.c deleted file mode 100644 index 47663f7edf4..00000000000 --- a/arch/arm/cpu/armv7/omap-common/spl_ymodem.c +++ /dev/null @@ -1,76 +0,0 @@ -/* - * (C) Copyright 2000-2004 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * (C) Copyright 2011 - * Texas Instruments, <www.ti.com> - * - * Matt Porter <mporter@ti.com> - * - * 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 <xyzModem.h> -#include <asm/u-boot.h> -#include <asm/utils.h> -#include <asm/arch/sys_proto.h> -#include <asm/omap_common.h> - -#define BUF_SIZE 1024 - -static int getcymodem(void) { - if (tstc()) - return (getc()); - return -1; -} - -void spl_ymodem_load_image(void) -{ - int size = 0; - int err; - int res; - int ret; - connection_info_t info; - char buf[BUF_SIZE]; - ulong store_addr = ~0; - ulong addr = 0; - - info.mode = xyzModem_ymodem; - ret = xyzModem_stream_open(&info, &err); - - if (!ret) { - while ((res = - xyzModem_stream_read(buf, BUF_SIZE, &err)) > 0) { - if (addr == 0) - spl_parse_image_header((struct image_header *)buf); - store_addr = addr + spl_image.load_addr; - size += res; - addr += res; - memcpy((char *)(store_addr), buf, res); - } - } else { - printf("spl: ymodem err - %s\n", xyzModem_error(err)); - hang(); - } - - xyzModem_stream_close(&err); - xyzModem_stream_terminate(false, &getcymodem); - - printf("Loaded %d bytes\n", size); -} diff --git a/arch/arm/cpu/armv7/omap-common/u-boot-spl.lds b/arch/arm/cpu/armv7/omap-common/u-boot-spl.lds index 8867e0604db..1d8efb213bf 100644 --- a/arch/arm/cpu/armv7/omap-common/u-boot-spl.lds +++ b/arch/arm/cpu/armv7/omap-common/u-boot-spl.lds @@ -37,9 +37,9 @@ SECTIONS { .text : { - __start = .; - arch/arm/cpu/armv7/start.o (.text) - *(.text*) + __start = .; + arch/arm/cpu/armv7/start.o (.text) + *(.text*) } >.sram . = ALIGN(4); diff --git a/arch/arm/cpu/armv7/omap3/board.c b/arch/arm/cpu/armv7/omap3/board.c index f2e52e9ce1b..9cee1d9b490 100644 --- a/arch/arm/cpu/armv7/omap3/board.c +++ b/arch/arm/cpu/armv7/omap3/board.c @@ -33,6 +33,7 @@ * MA 02111-1307 USA */ #include <common.h> +#include <spl.h> #include <asm/io.h> #include <asm/arch/sys_proto.h> #include <asm/arch/mem.h> @@ -40,9 +41,12 @@ #include <asm/armv7.h> #include <asm/arch/gpio.h> #include <asm/omap_common.h> +#include <asm/arch/mmc_host_def.h> #include <i2c.h> #include <linux/compiler.h> +DECLARE_GLOBAL_DATA_PTR; + /* Declarations */ extern omap3_sysinfo sysinfo; static void omap3_setup_aux_cr(void); @@ -69,30 +73,44 @@ const struct gpio_bank *const omap_gpio_bank = gpio_bank_34xx; u32 omap3_boot_device = BOOT_DEVICE_NAND; /* auto boot mode detection is not possible for OMAP3 - hard code */ -u32 omap_boot_mode(void) +u32 spl_boot_mode(void) { - switch (omap_boot_device()) { + switch (spl_boot_device()) { case BOOT_DEVICE_MMC2: return MMCSD_MODE_RAW; case BOOT_DEVICE_MMC1: return MMCSD_MODE_FAT; break; - case BOOT_DEVICE_NAND: - return NAND_MODE_HW_ECC; - break; default: puts("spl: ERROR: unknown device - can't select boot mode\n"); hang(); } } -u32 omap_boot_device(void) +u32 spl_boot_device(void) { return omap3_boot_device; } +int board_mmc_init(bd_t *bis) +{ + switch (spl_boot_device()) { + case BOOT_DEVICE_MMC1: + omap_mmc_init(0, 0, 0); + break; + case BOOT_DEVICE_MMC2: + case BOOT_DEVICE_MMC2_2: + omap_mmc_init(1, 0, 0); + break; + } + return 0; +} + void spl_board_init(void) { +#ifdef CONFIG_SPL_NAND_SUPPORT + gpmc_init(); +#endif #ifdef CONFIG_SPL_I2C_SUPPORT i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); #endif @@ -236,6 +254,8 @@ void s_init(void) #endif #ifdef CONFIG_SPL_BUILD + gd = &gdata; + preloader_console_init(); timer_init(); diff --git a/arch/arm/cpu/armv7/start.S b/arch/arm/cpu/armv7/start.S index 32658eb7a53..f26308df16c 100644 --- a/arch/arm/cpu/armv7/start.S +++ b/arch/arm/cpu/armv7/start.S @@ -164,6 +164,7 @@ call_board_init_f: /*------------------------------------------------------------------------------*/ +#ifndef CONFIG_SPL_BUILD /* * void relocate_code (addr_sp, gd, addr_moni) * @@ -194,7 +195,6 @@ copy_loop: cmp r0, r2 /* until source end address [r2] */ blo copy_loop -#ifndef CONFIG_SPL_BUILD /* * fix .rel.dyn relocations */ @@ -241,20 +241,12 @@ _rel_dyn_end_ofs: _dynsym_start_ofs: .word __dynsym_start - _start -#endif /* #ifndef CONFIG_SPL_BUILD */ - clear_bss: -#ifdef CONFIG_SPL_BUILD - /* No relocation for SPL */ - ldr r0, =__bss_start - ldr r1, =__bss_end__ -#else ldr r0, _bss_start_ofs ldr r1, _bss_end_ofs mov r4, r6 /* reloc addr */ add r0, r0, r4 add r1, r1, r4 -#endif mov r2, #0x00000000 /* clear */ clbss_l:cmp r0, r1 /* clear loop... */ @@ -281,12 +273,10 @@ jump_2_ram: * Move vector table */ #if !defined(CONFIG_TEGRA20) -#if !(defined(CONFIG_OMAP44XX) && defined(CONFIG_SPL_BUILD)) /* Set vector address in CP15 VBAR register */ ldr r0, =_start add r0, r0, r9 mcr p15, 0, r0, c12, c0, 0 @Set VBAR -#endif #endif /* !Tegra20 */ ldr r0, _board_init_r_ofs @@ -302,6 +292,7 @@ jump_2_ram: _board_init_r_ofs: .word board_init_r - _start ENDPROC(relocate_code) +#endif /************************************************************************* * diff --git a/arch/arm/include/asm/arch-am33xx/spl.h b/arch/arm/include/asm/arch-am33xx/spl.h new file mode 100644 index 00000000000..70f521d2697 --- /dev/null +++ b/arch/arm/include/asm/arch-am33xx/spl.h @@ -0,0 +1,31 @@ +/* + * (C) Copyright 2012 + * Texas Instruments, <www.ti.com> + * + * 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 + */ +#ifndef _ASM_ARCH_SPL_H_ +#define _ASM_SPL_H_ + +#define BOOT_DEVICE_NAND 5 +#define BOOT_DEVICE_MMC1 8 +#define BOOT_DEVICE_MMC2 9 /* eMMC or daughter card */ +#define BOOT_DEVICE_UART 65 +#define BOOT_DEVICE_MMC2_2 0xFF +#endif diff --git a/arch/arm/include/asm/arch-davinci/spl.h b/arch/arm/include/asm/arch-davinci/spl.h new file mode 100644 index 00000000000..fb01db02cf3 --- /dev/null +++ b/arch/arm/include/asm/arch-davinci/spl.h @@ -0,0 +1,32 @@ +/* + * (C) Copyright 2012 + * Texas Instruments, <www.ti.com> + * + * 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 + */ +#ifndef _ASM_ARCH_SPL_H_ +#define _ASM_SPL_H_ + +#define BOOT_DEVICE_NAND 1 +#define BOOT_DEVICE_SPI 2 +#define BOOT_DEVICE_MMC1 3 +#define BOOT_DEVICE_MMC2 4 /* dummy */ +#define BOOT_DEVICE_MMC2_2 5 /* dummy */ + +#endif diff --git a/arch/arm/include/asm/arch-omap3/spl.h b/arch/arm/include/asm/arch-omap3/spl.h new file mode 100644 index 00000000000..404e16a5a06 --- /dev/null +++ b/arch/arm/include/asm/arch-omap3/spl.h @@ -0,0 +1,34 @@ +/* + * (C) Copyright 2012 + * Texas Instruments, <www.ti.com> + * + * 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 + */ +#ifndef _ASM_ARCH_SPL_H_ +#define _ASM_SPL_H_ + +#define BOOT_DEVICE_NONE 0 +#define BOOT_DEVICE_XIP 1 +#define BOOT_DEVICE_NAND 2 +#define BOOT_DEVICE_ONE_NAND 3 +#define BOOT_DEVICE_MMC2 5 /*emmc*/ +#define BOOT_DEVICE_MMC1 6 +#define BOOT_DEVICE_XIPWAIT 7 +#define BOOT_DEVICE_MMC2_2 0xFF +#endif diff --git a/arch/arm/include/asm/arch-omap4/spl.h b/arch/arm/include/asm/arch-omap4/spl.h new file mode 100644 index 00000000000..cec84dc548c --- /dev/null +++ b/arch/arm/include/asm/arch-omap4/spl.h @@ -0,0 +1,35 @@ +/* + * (C) Copyright 2012 + * Texas Instruments, <www.ti.com> + * + * 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 + */ +#ifndef _ASM_ARCH_SPL_H_ +#define _ASM_SPL_H_ + +#define BOOT_DEVICE_NONE 0 +#define BOOT_DEVICE_XIP 1 +#define BOOT_DEVICE_XIPWAIT 2 +#define BOOT_DEVICE_NAND 3 +#define BOOT_DEVICE_ONE_NAND 4 +#define BOOT_DEVICE_MMC1 5 +#define BOOT_DEVICE_MMC2 6 +#define BOOT_DEVICE_MMC2_2 0xFF + +#endif diff --git a/arch/arm/include/asm/arch-omap4/sys_proto.h b/arch/arm/include/asm/arch-omap4/sys_proto.h index d633573c258..b48f81dc336 100644 --- a/arch/arm/include/asm/arch-omap4/sys_proto.h +++ b/arch/arm/include/asm/arch-omap4/sys_proto.h @@ -42,7 +42,6 @@ void sr32(void *, u32, u32, u32); u32 wait_on_value(u32, u32, void *, u32); void sdelay(unsigned long); void set_pl310_ctrl_reg(u32 val); -void omap_rev_string(void); void setup_clocks_for_console(void); void prcm_init(void); void bypass_dpll(u32 *const base); diff --git a/arch/arm/include/asm/arch-omap5/spl.h b/arch/arm/include/asm/arch-omap5/spl.h new file mode 100644 index 00000000000..d125c61f4c1 --- /dev/null +++ b/arch/arm/include/asm/arch-omap5/spl.h @@ -0,0 +1,35 @@ +/* + * (C) Copyright 2012 + * Texas Instruments, <www.ti.com> + * + * 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 + */ +#ifndef _ASM_ARCH_SPL_H_ +#define _ASM_SPL_H_ + +#define BOOT_DEVICE_NONE 0 +#define BOOT_DEVICE_XIP 1 +#define BOOT_DEVICE_XIPWAIT 2 +#define BOOT_DEVICE_NAND 3 +#define BOOT_DEVICE_ONE_NAND 4 +#define BOOT_DEVICE_MMC1 5 +#define BOOT_DEVICE_MMC2 6 +#define BOOT_DEVICE_MMC2_2 7 + +#endif diff --git a/arch/arm/include/asm/arch-omap5/sys_proto.h b/arch/arm/include/asm/arch-omap5/sys_proto.h index 74feb90277c..72e9df7881e 100644 --- a/arch/arm/include/asm/arch-omap5/sys_proto.h +++ b/arch/arm/include/asm/arch-omap5/sys_proto.h @@ -42,7 +42,6 @@ void set_muxconf_regs_non_essential(void); void sr32(void *, u32, u32, u32); u32 wait_on_value(u32, u32, void *, u32); void sdelay(unsigned long); -void omap_rev_string(void); void setup_clocks_for_console(void); void prcm_init(void); void bypass_dpll(u32 *const base); diff --git a/arch/arm/include/asm/omap_common.h b/arch/arm/include/asm/omap_common.h index 71ef9b077f4..2a40b898e35 100644 --- a/arch/arm/include/asm/omap_common.h +++ b/arch/arm/include/asm/omap_common.h @@ -34,83 +34,6 @@ #define OMAP_INIT_CONTEXT_UBOOT_AFTER_SPL 2 #define OMAP_INIT_CONTEXT_UBOOT_AFTER_CH 3 -void preloader_console_init(void); - -/* Boot device */ -#ifdef CONFIG_OMAP54XX -#define BOOT_DEVICE_NONE 0 -#define BOOT_DEVICE_XIP 1 -#define BOOT_DEVICE_XIPWAIT 2 -#define BOOT_DEVICE_NAND 3 -#define BOOT_DEVICE_ONE_NAND 4 -#define BOOT_DEVICE_MMC1 5 -#define BOOT_DEVICE_MMC2 6 -#define BOOT_DEVICE_MMC2_2 7 -#elif defined(CONFIG_OMAP44XX) /* OMAP4 */ -#define BOOT_DEVICE_NONE 0 -#define BOOT_DEVICE_XIP 1 -#define BOOT_DEVICE_XIPWAIT 2 -#define BOOT_DEVICE_NAND 3 -#define BOOT_DEVICE_ONE_NAND 4 -#define BOOT_DEVICE_MMC1 5 -#define BOOT_DEVICE_MMC2 6 -#define BOOT_DEVICE_MMC2_2 0xFF -#elif defined(CONFIG_OMAP34XX) /* OMAP3 */ -#define BOOT_DEVICE_NONE 0 -#define BOOT_DEVICE_XIP 1 -#define BOOT_DEVICE_NAND 2 -#define BOOT_DEVICE_ONE_NAND 3 -#define BOOT_DEVICE_MMC2 5 /*emmc*/ -#define BOOT_DEVICE_MMC1 6 -#define BOOT_DEVICE_XIPWAIT 7 -#define BOOT_DEVICE_MMC2_2 0xFF -#elif defined(CONFIG_AM33XX) /* AM33XX */ -#define BOOT_DEVICE_NAND 5 -#define BOOT_DEVICE_MMC1 8 -#define BOOT_DEVICE_MMC2 9 /* eMMC or daughter card */ -#define BOOT_DEVICE_UART 65 -#define BOOT_DEVICE_MMC2_2 0xFF -#endif - -/* Boot type */ -#define MMCSD_MODE_UNDEFINED 0 -#define MMCSD_MODE_RAW 1 -#define MMCSD_MODE_FAT 2 -#define NAND_MODE_HW_ECC 3 - -struct spl_image_info { - const char *name; - u8 os; - u32 load_addr; - u32 entry_point; - u32 size; -}; - -extern struct spl_image_info spl_image; - -extern u32* boot_params_ptr; -u32 omap_boot_device(void); -u32 omap_boot_mode(void); - -/* SPL common function s*/ -void spl_parse_image_header(const struct image_header *header); -void omap_rev_string(void); -void spl_board_prepare_for_linux(void); -int spl_start_uboot(void); - -/* NAND SPL functions */ -void spl_nand_load_image(void); - -/* MMC SPL functions */ -void spl_mmc_load_image(void); - -/* YMODEM SPL functions */ -void spl_ymodem_load_image(void); - -#ifdef CONFIG_SPL_BOARD_INIT -void spl_board_init(void); -#endif - static inline u32 omap_revision(void) { extern u32 *const omap_si_rev; diff --git a/arch/arm/include/asm/spl.h b/arch/arm/include/asm/spl.h new file mode 100644 index 00000000000..62011aaada4 --- /dev/null +++ b/arch/arm/include/asm/spl.h @@ -0,0 +1,34 @@ +/* + * (C) Copyright 2012 + * Texas Instruments, <www.ti.com> + * + * 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 + */ +#ifndef _ASM_SPL_H_ +#define _ASM_SPL_H_ + +/* Platform-specific defines */ +#include <asm/arch/spl.h> + +/* Linker symbols. */ +extern char __bss_start[], __bss_end__[]; + +extern gd_t gdata; + +#endif diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile index bd3b77f2e65..3422ac1c5fc 100644 --- a/arch/arm/lib/Makefile +++ b/arch/arm/lib/Makefile @@ -44,6 +44,8 @@ COBJS-y += interrupts.o COBJS-y += reset.o SOBJS-$(CONFIG_USE_ARCH_MEMSET) += memset.o SOBJS-$(CONFIG_USE_ARCH_MEMCPY) += memcpy.o +else +COBJS-$(CONFIG_SPL_FRAMEWORK) += spl.o endif COBJS-y += cache.o diff --git a/arch/arm/lib/spl.c b/arch/arm/lib/spl.c new file mode 100644 index 00000000000..f568f619cb0 --- /dev/null +++ b/arch/arm/lib/spl.c @@ -0,0 +1,72 @@ +/* + * (C) Copyright 2010-2012 + * Texas Instruments, <www.ti.com> + * + * Aneesh V <aneesh@ti.com> + * Tom Rini <trini@ti.com> + * + * 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 <config.h> +#include <spl.h> +#include <image.h> +#include <linux/compiler.h> + +/* Pointer to as well as the global data structure for SPL */ +DECLARE_GLOBAL_DATA_PTR; +gd_t gdata __attribute__ ((section(".data"))); + +/* + * In the context of SPL, board_init_f must ensure that any clocks/etc for + * DDR are enabled, ensure that the stack pointer is valid, clear the BSS + * and call board_init_f. We provide this version by default but mark it + * as __weak to allow for platforms to do this in their own way if needed. + */ +void __weak board_init_f(ulong dummy) +{ + /* Set the stack pointer. */ + asm volatile("mov sp, %0\n" : : "r"(CONFIG_SPL_STACK)); + + /* Clear the BSS. */ + memset(__bss_start, 0, __bss_end__ - __bss_start); + + /* Set global data pointer. */ + gd = &gdata; + + board_init_r(NULL, 0); +} + +/* + * This function jumps to an image with argument. Normally an FDT or ATAGS + * image. + * arg: Pointer to paramter image in RAM + */ +#ifdef CONFIG_SPL_OS_BOOT +void __noreturn jump_to_image_linux(void *arg) +{ + debug("Entering kernel arg pointer: 0x%p\n", arg); + typedef void (*image_entry_arg_t)(int, int, void *) + __attribute__ ((noreturn)); + image_entry_arg_t image_entry = + (image_entry_arg_t) spl_image.entry_point; + cleanup_before_linux(); + image_entry(0, CONFIG_MACH_TYPE, arg); +} +#endif diff --git a/arch/avr32/lib/board.c b/arch/avr32/lib/board.c index d7a64b48727..9d3b76e15ae 100644 --- a/arch/avr32/lib/board.c +++ b/arch/avr32/lib/board.c @@ -250,7 +250,6 @@ void board_init_f(ulong board_type) void board_init_r(gd_t *new_gd, ulong dest_addr) { - extern void malloc_bin_reloc (void); #ifndef CONFIG_ENV_IS_NOWHERE extern char * env_name_spec; #endif diff --git a/arch/m68k/lib/board.c b/arch/m68k/lib/board.c index 65a8595c2bd..2add630abb4 100644 --- a/arch/m68k/lib/board.c +++ b/arch/m68k/lib/board.c @@ -389,7 +389,6 @@ void board_init_r (gd_t *id, ulong dest_addr) { char *s; bd_t *bd; - extern void malloc_bin_reloc (void); #ifndef CONFIG_ENV_IS_NOWHERE extern char * env_name_spec; diff --git a/arch/mips/lib/board.c b/arch/mips/lib/board.c index 62d47a8bf0b..b14b33efcd0 100644 --- a/arch/mips/lib/board.c +++ b/arch/mips/lib/board.c @@ -248,7 +248,6 @@ void board_init_r(gd_t *id, ulong dest_addr) #ifndef CONFIG_SYS_NO_FLASH ulong size; #endif - extern void malloc_bin_reloc(void); #ifndef CONFIG_ENV_IS_NOWHERE extern char *env_name_spec; #endif diff --git a/arch/nds32/lib/board.c b/arch/nds32/lib/board.c index 2164a505f6e..17d3ee071f1 100644 --- a/arch/nds32/lib/board.c +++ b/arch/nds32/lib/board.c @@ -306,8 +306,6 @@ void board_init_r(gd_t *id, ulong dest_addr) bd_t *bd; ulong malloc_start; - extern void malloc_bin_reloc(void); - gd = id; bd = gd->bd; diff --git a/arch/powerpc/cpu/mpc85xx/Makefile b/arch/powerpc/cpu/mpc85xx/Makefile index 34f6c546984..33e93c88d72 100644 --- a/arch/powerpc/cpu/mpc85xx/Makefile +++ b/arch/powerpc/cpu/mpc85xx/Makefile @@ -55,8 +55,6 @@ COBJS-$(CONFIG_P1011) += ddr-gen3.o COBJS-$(CONFIG_P1012) += ddr-gen3.o COBJS-$(CONFIG_P1013) += ddr-gen3.o COBJS-$(CONFIG_P1014) += ddr-gen3.o -COBJS-$(CONFIG_P1015) += ddr-gen3.o -COBJS-$(CONFIG_P1016) += ddr-gen3.o COBJS-$(CONFIG_P1020) += ddr-gen3.o COBJS-$(CONFIG_P1021) += ddr-gen3.o COBJS-$(CONFIG_P1022) += ddr-gen3.o @@ -64,10 +62,8 @@ COBJS-$(CONFIG_P1024) += ddr-gen3.o COBJS-$(CONFIG_P1025) += ddr-gen3.o COBJS-$(CONFIG_P2010) += ddr-gen3.o COBJS-$(CONFIG_P2020) += ddr-gen3.o -COBJS-$(CONFIG_PPC_P2040) += ddr-gen3.o COBJS-$(CONFIG_PPC_P2041) += ddr-gen3.o COBJS-$(CONFIG_PPC_P3041) += ddr-gen3.o -COBJS-$(CONFIG_PPC_P3060) += ddr-gen3.o COBJS-$(CONFIG_PPC_P4080) += ddr-gen3.o COBJS-$(CONFIG_PPC_P5020) += ddr-gen3.o COBJS-$(CONFIG_BSC9131) += ddr-gen3.o @@ -80,10 +76,8 @@ COBJS-$(CONFIG_PCI) += pci.o COBJS-$(CONFIG_SYS_DPAA_QBMAN) += portals.o # various SoC specific assignments -COBJS-$(CONFIG_PPC_P2040) += p2041_ids.o COBJS-$(CONFIG_PPC_P2041) += p2041_ids.o COBJS-$(CONFIG_PPC_P3041) += p3041_ids.o -COBJS-$(CONFIG_PPC_P3060) += p3060_ids.o COBJS-$(CONFIG_PPC_P4080) += p4080_ids.o COBJS-$(CONFIG_PPC_P5020) += p5020_ids.o @@ -103,8 +97,6 @@ COBJS-$(CONFIG_P1011) += p1021_serdes.o COBJS-$(CONFIG_P1012) += p1021_serdes.o COBJS-$(CONFIG_P1013) += p1022_serdes.o COBJS-$(CONFIG_P1014) += p1010_serdes.o -COBJS-$(CONFIG_P1015) += p1021_serdes.o -COBJS-$(CONFIG_P1016) += p1021_serdes.o COBJS-$(CONFIG_P1017) += p1023_serdes.o COBJS-$(CONFIG_P1020) += p1021_serdes.o COBJS-$(CONFIG_P1021) += p1021_serdes.o @@ -114,10 +106,8 @@ COBJS-$(CONFIG_P1024) += p1021_serdes.o COBJS-$(CONFIG_P1025) += p1021_serdes.o COBJS-$(CONFIG_P2010) += p2020_serdes.o COBJS-$(CONFIG_P2020) += p2020_serdes.o -COBJS-$(CONFIG_PPC_P2040) += p2041_serdes.o COBJS-$(CONFIG_PPC_P2041) += p2041_serdes.o COBJS-$(CONFIG_PPC_P3041) += p3041_serdes.o -COBJS-$(CONFIG_PPC_P3060) += p3060_serdes.o COBJS-$(CONFIG_PPC_P4080) += p4080_serdes.o COBJS-$(CONFIG_PPC_P5020) += p5020_serdes.o diff --git a/arch/powerpc/cpu/mpc85xx/cmd_errata.c b/arch/powerpc/cpu/mpc85xx/cmd_errata.c index 4e1a54ad0c5..e8989bdf459 100644 --- a/arch/powerpc/cpu/mpc85xx/cmd_errata.c +++ b/arch/powerpc/cpu/mpc85xx/cmd_errata.c @@ -27,6 +27,9 @@ static int do_errata(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { +#ifdef CONFIG_SYS_FSL_ERRATUM_NMG_CPU_A011 + extern int enable_cpu_a011_workaround; +#endif __maybe_unused u32 svr = get_svr(); #if defined(CONFIG_FSL_SATA_V2) && defined(CONFIG_FSL_SATA_ERRATUM_A001) @@ -56,8 +59,9 @@ static int do_errata(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) /* * NMG_CPU_A011 applies to P4080 rev 1.0, 2.0, fixed in 3.0 * also applies to P3041 rev 1.0, 1.1, P2041 rev 1.0, 1.1 + * The SVR has been checked by cpu_init_r(). */ - if (SVR_SOC_VER(svr) != SVR_P4080 || SVR_MAJ(svr) < 3) + if (enable_cpu_a011_workaround) puts("Work-around for Erratum CPU-A011 enabled\n"); #endif #if defined(CONFIG_SYS_FSL_ERRATUM_CPU_A003999) @@ -120,6 +124,9 @@ static int do_errata(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) if ((SVR_MAJ(svr) == 1) || IS_SVR_REV(svr, 2, 0)) puts("Work-around for Erratum NMG ETSEC129 enabled\n"); #endif +#ifdef CONFIG_SYS_FSL_ERRATUM_A004510 + puts("Work-around for Erratum A004510 enabled\n"); +#endif return 0; } diff --git a/arch/powerpc/cpu/mpc85xx/cpu.c b/arch/powerpc/cpu/mpc85xx/cpu.c index c1815e8860d..5ddb29435c1 100644 --- a/arch/powerpc/cpu/mpc85xx/cpu.c +++ b/arch/powerpc/cpu/mpc85xx/cpu.c @@ -117,6 +117,9 @@ int checkcpu (void) case PVR_VER_E5500: puts("E5500"); break; + case PVR_VER_E6500: + puts("E6500"); + break; default: puts("Unknown"); break; @@ -427,11 +430,21 @@ static void dump_spd_ddr_reg(void) case 0: ddr[i] = (void *)CONFIG_SYS_MPC85xx_DDR_ADDR; break; -#ifdef CONFIG_SYS_MPC85xx_DDR2_ADDR +#if defined(CONFIG_SYS_MPC85xx_DDR2_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 1) case 1: ddr[i] = (void *)CONFIG_SYS_MPC85xx_DDR2_ADDR; break; #endif +#if defined(CONFIG_SYS_MPC85xx_DDR3_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 2) + case 2: + ddr[i] = (void *)CONFIG_SYS_MPC85xx_DDR3_ADDR; + break; +#endif +#if defined(CONFIG_SYS_MPC85xx_DDR4_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 3) + case 3: + ddr[i] = (void *)CONFIG_SYS_MPC85xx_DDR4_ADDR; + break; +#endif default: printf("%s unexpected controller number = %u\n", __func__, i); diff --git a/arch/powerpc/cpu/mpc85xx/cpu_init.c b/arch/powerpc/cpu/mpc85xx/cpu_init.c index fc6c2877d25..afb56719da2 100644 --- a/arch/powerpc/cpu/mpc85xx/cpu_init.c +++ b/arch/powerpc/cpu/mpc85xx/cpu_init.c @@ -38,6 +38,7 @@ #include <asm/fsl_law.h> #include <asm/fsl_serdes.h> #include <asm/fsl_srio.h> +#include <hwconfig.h> #include <linux/compiler.h> #include "mp.h" #ifdef CONFIG_SYS_QE_FMAN_FW_IN_NAND @@ -311,11 +312,41 @@ int cpu_init_r(void) #if defined(CONFIG_SYS_P4080_ERRATUM_CPU22) || \ defined(CONFIG_SYS_FSL_ERRATUM_NMG_CPU_A011) /* + * CPU22 and NMG_CPU_A011 share the same workaround. * CPU22 applies to P4080 rev 1.0, 2.0, fixed in 3.0 * NMG_CPU_A011 applies to P4080 rev 1.0, 2.0, fixed in 3.0 - * also applies to P3041 rev 1.0, 1.1, P2041 rev 1.0, 1.1 + * also applies to P3041 rev 1.0, 1.1, P2041 rev 1.0, 1.1, both + * fixed in 2.0. NMG_CPU_A011 is activated by default and can + * be disabled by hwconfig with syntax: + * + * fsl_cpu_a011:disable */ - if (SVR_SOC_VER(svr) != SVR_P4080 || SVR_MAJ(svr) < 3) { + extern int enable_cpu_a011_workaround; +#ifdef CONFIG_SYS_P4080_ERRATUM_CPU22 + enable_cpu_a011_workaround = (SVR_MAJ(svr) < 3); +#else + char buffer[HWCONFIG_BUFFER_SIZE]; + char *buf = NULL; + int n, res; + + n = getenv_f("hwconfig", buffer, sizeof(buffer)); + if (n > 0) + buf = buffer; + + res = hwconfig_arg_cmp_f("fsl_cpu_a011", "disable", buf); + if (res > 0) + enable_cpu_a011_workaround = 0; + else { + if (n >= HWCONFIG_BUFFER_SIZE) { + printf("fsl_cpu_a011 was not found. hwconfig variable " + "may be too long\n"); + } + enable_cpu_a011_workaround = + (SVR_SOC_VER(svr) == SVR_P4080 && SVR_MAJ(svr) < 3) || + (SVR_SOC_VER(svr) != SVR_P4080 && SVR_MAJ(svr) < 2); + } +#endif + if (enable_cpu_a011_workaround) { flush_dcache(); mtspr(L1CSR2, (mfspr(L1CSR2) | L1CSR2_DCWS)); sync(); @@ -447,11 +478,18 @@ skip_l2: #ifdef CONFIG_SYS_SRIO srio_init(); -#ifdef CONFIG_SRIOBOOT_MASTER - srio_boot_master(); -#ifdef CONFIG_SRIOBOOT_SLAVE_HOLDOFF - srio_boot_master_release_slave(); -#endif +#ifdef CONFIG_FSL_CORENET + char *s = getenv("bootmaster"); + if (s) { + if (!strcmp(s, "SRIO1")) { + srio_boot_master(1); + srio_boot_master_release_slave(1); + } + if (!strcmp(s, "SRIO2")) { + srio_boot_master(2); + srio_boot_master_release_slave(2); + } + } #endif #endif diff --git a/arch/powerpc/cpu/mpc85xx/ddr-gen3.c b/arch/powerpc/cpu/mpc85xx/ddr-gen3.c index 81961def1b7..ca4ed626457 100644 --- a/arch/powerpc/cpu/mpc85xx/ddr-gen3.c +++ b/arch/powerpc/cpu/mpc85xx/ddr-gen3.c @@ -1,5 +1,5 @@ /* - * Copyright 2008-2011 Freescale Semiconductor, Inc. + * Copyright 2008-2012 Freescale Semiconductor, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -32,9 +32,21 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs, case 0: ddr = (void *)CONFIG_SYS_MPC85xx_DDR_ADDR; break; +#if defined(CONFIG_SYS_MPC85xx_DDR2_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 1) case 1: ddr = (void *)CONFIG_SYS_MPC85xx_DDR2_ADDR; break; +#endif +#if defined(CONFIG_SYS_MPC85xx_DDR3_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 2) + case 2: + ddr = (void *)CONFIG_SYS_MPC85xx_DDR3_ADDR; + break; +#endif +#if defined(CONFIG_SYS_MPC85xx_DDR4_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 3) + case 3: + ddr = (void *)CONFIG_SYS_MPC85xx_DDR4_ADDR; + break; +#endif default: printf("%s unexpected ctrl_num = %u\n", __FUNCTION__, ctrl_num); return; @@ -43,6 +55,7 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs, out_be32(&ddr->eor, regs->ddr_eor); #ifdef CONFIG_SYS_FSL_ERRATUM_DDR111_DDR134 + debug("Workaround for ERRATUM_DDR111_DDR134\n"); for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) { cs_sa = (regs->cs[i].bnds >> 16) & 0xfff; cs_ea = regs->cs[i].bnds & 0xfff; @@ -115,8 +128,12 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs, out_be32(&ddr->ddr_cdr2, regs->ddr_cdr2); out_be32(&ddr->err_disable, regs->err_disable); out_be32(&ddr->err_int_en, regs->err_int_en); - for (i = 0; i < 32; i++) - out_be32(&ddr->debug[i], regs->debug[i]); + for (i = 0; i < 32; i++) { + if (regs->debug[i]) { + debug("Write to debug_%d as %08x\n", i+1, regs->debug[i]); + out_be32(&ddr->debug[i], regs->debug[i]); + } + } #ifdef CONFIG_SYS_FSL_ERRATUM_DDR_A003474 out_be32(&ddr->debug[12], 0x00000015); @@ -128,6 +145,7 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs, temp_sdram_cfg &= ~(SDRAM_CFG_MEM_EN); out_be32(&ddr->sdram_cfg, temp_sdram_cfg); #ifdef CONFIG_SYS_FSL_ERRATUM_DDR_A003 + debug("Workaround for ERRATUM_DDR_A003\n"); if (regs->ddr_sdram_rcw_2 & 0x00f00000) { out_be32(&ddr->timing_cfg_2, regs->timing_cfg_2 & 0xf07fffff); out_be32(&ddr->debug[2], 0x00000400); @@ -209,6 +227,7 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs, * This erratum does not affect DDR3 mode, only for DDR2 mode. */ #ifdef CONFIG_SYS_FSL_ERRATUM_DDR_115 + debug("Workaround for ERRATUM_DDR_115\n"); if ((((in_be32(&ddr->sdram_cfg) >> 24) & 0x7) == SDRAM_TYPE_DDR2) && in_be32(&ddr->sdram_cfg) & 0x80000) { /* set DEBUG_1[31] */ @@ -216,6 +235,7 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs, } #endif #ifdef CONFIG_SYS_FSL_ERRATUM_DDR111_DDR134 + debug("Workaround for ERRATUM_DDR111_DDR134\n"); /* * This is the combined workaround for DDR111 and DDR134 * following the published errata for MPC8572 diff --git a/arch/powerpc/cpu/mpc85xx/fdt.c b/arch/powerpc/cpu/mpc85xx/fdt.c index 21c3ad49bfb..a0a9b4c5ae9 100644 --- a/arch/powerpc/cpu/mpc85xx/fdt.c +++ b/arch/powerpc/cpu/mpc85xx/fdt.c @@ -57,8 +57,9 @@ void ft_fixup_cpu(void *blob, u64 memory_limit) u32 *reg = (u32 *)fdt_getprop(blob, off, "reg", 0); if (reg) { - u64 val = *reg * SIZE_BOOT_ENTRY + spin_tbl_addr; - val = cpu_to_fdt32(val); + u32 phys_cpu_id = thread_to_core(*reg); + u64 val = phys_cpu_id * SIZE_BOOT_ENTRY + spin_tbl_addr; + val = cpu_to_fdt64(val); if (*reg == id) { fdt_setprop_string(blob, off, "status", "okay"); @@ -534,7 +535,7 @@ void fdt_fixup_fman_firmware(void *blob) #define fdt_fixup_fman_firmware(x) #endif -#if defined(CONFIG_PPC_P4080) || defined(CONFIG_PPC_P3060) +#if defined(CONFIG_PPC_P4080) static void fdt_fixup_usb(void *fdt) { ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); diff --git a/arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c b/arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c index 4b52dad56ce..2a680603697 100644 --- a/arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c +++ b/arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c @@ -46,8 +46,6 @@ static u32 serdes_prtcl_map; -#define HWCONFIG_BUFFER_SIZE 128 - #ifdef DEBUG static const char *serdes_prtcl_str[] = { [NONE] = "NA", @@ -68,6 +66,7 @@ static const char *serdes_prtcl_str[] = { [SGMII_FM2_DTSEC2] = "SGMII_FM2_DTSEC2", [SGMII_FM2_DTSEC3] = "SGMII_FM2_DTSEC3", [SGMII_FM2_DTSEC4] = "SGMII_FM2_DTSEC4", + [SGMII_FM2_DTSEC5] = "SGMII_FM2_DTSEC5", [XAUI_FM1] = "XAUI_FM1", [XAUI_FM2] = "XAUI_FM2", [AURORA] = "DEBUG", @@ -658,6 +657,7 @@ void fsl_serdes_init(void) case SGMII_FM2_DTSEC2: case SGMII_FM2_DTSEC3: case SGMII_FM2_DTSEC4: + case SGMII_FM2_DTSEC5: case XAUI_FM1: case XAUI_FM2: case SRIO1: @@ -717,6 +717,10 @@ void fsl_serdes_init(void) serdes8_devdisr2 |= FSL_CORENET_DEVDISR2_FM2 | FSL_CORENET_DEVDISR2_DTSEC2_4; break; + case SGMII_FM2_DTSEC5: + serdes8_devdisr2 |= FSL_CORENET_DEVDISR2_FM2 | + FSL_CORENET_DEVDISR2_DTSEC2_5; + break; case XAUI_FM1: serdes8_devdisr2 |= FSL_CORENET_DEVDISR2_FM1 | FSL_CORENET_DEVDISR2_10GEC1; diff --git a/arch/powerpc/cpu/mpc85xx/p3060_ids.c b/arch/powerpc/cpu/mpc85xx/p3060_ids.c deleted file mode 100644 index d32142f6369..00000000000 --- a/arch/powerpc/cpu/mpc85xx/p3060_ids.c +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright 2011 Freescale Semiconductor, Inc. - * - * 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 <asm/fsl_portals.h> -#include <asm/fsl_liodn.h> - -#ifdef CONFIG_SYS_DPAA_QBMAN -struct qportal_info qp_info[CONFIG_SYS_QMAN_NUM_PORTALS] = { - /* dqrr liodn, frame data liodn, liodn off, sdest */ - SET_QP_INFO( 1, 2, 1, 0), - SET_QP_INFO( 3, 4, 2, 1), - SET_QP_INFO( 5, 6, 3, 2), - SET_QP_INFO( 7, 8, 4, 3), - SET_QP_INFO( 9, 10, 5, 4), - SET_QP_INFO(11, 12, 6, 5), - SET_QP_INFO(13, 14, 7, 6), - SET_QP_INFO(15, 16, 8, 7), - SET_QP_INFO(17, 18, 9, 0), /* for now sdest to 0 */ - SET_QP_INFO(19, 20, 10, 0), /* for now sdest to 0 */ -}; -#endif - -struct srio_liodn_id_table srio_liodn_tbl[] = { - SET_SRIO_LIODN_1(1, 198), - SET_SRIO_LIODN_1(2, 199), -}; -int srio_liodn_tbl_sz = ARRAY_SIZE(srio_liodn_tbl); - -struct liodn_id_table liodn_tbl[] = { - SET_USB_LIODN(1, "fsl-usb2-mph", 127), - SET_USB_LIODN(2, "fsl-usb2-dr", 157), - - SET_PCI_LIODN("fsl,qoriq-pcie-v2.2", 1, 193), - SET_PCI_LIODN("fsl,qoriq-pcie-v2.2", 2, 194), - - SET_DMA_LIODN(1, 196), - SET_DMA_LIODN(2, 197), - - SET_GUTS_LIODN("fsl,srio-rmu", 200, rmuliodnr, 0xd3000), - -#ifdef CONFIG_SYS_DPAA_QBMAN - SET_QMAN_LIODN(31), - SET_BMAN_LIODN(32), -#endif - SET_PME_LIODN(128), -}; -int liodn_tbl_sz = ARRAY_SIZE(liodn_tbl); - -#ifdef CONFIG_SYS_DPAA_FMAN -struct liodn_id_table fman1_liodn_tbl[] = { - SET_FMAN_RX_1G_LIODN(1, 0, 11), - SET_FMAN_RX_1G_LIODN(1, 1, 12), - SET_FMAN_RX_1G_LIODN(1, 2, 13), - SET_FMAN_RX_1G_LIODN(1, 3, 14), -}; -int fman1_liodn_tbl_sz = ARRAY_SIZE(fman1_liodn_tbl); - -#if (CONFIG_SYS_NUM_FMAN == 2) -struct liodn_id_table fman2_liodn_tbl[] = { - SET_FMAN_RX_1G_LIODN(2, 0, 16), - SET_FMAN_RX_1G_LIODN(2, 1, 17), - SET_FMAN_RX_1G_LIODN(2, 2, 18), - SET_FMAN_RX_1G_LIODN(2, 3, 19), -}; -int fman2_liodn_tbl_sz = ARRAY_SIZE(fman2_liodn_tbl); -#endif -#endif - -struct liodn_id_table sec_liodn_tbl[] = { - SET_SEC_JR_LIODN_ENTRY(0, 146, 154), - SET_SEC_JR_LIODN_ENTRY(1, 147, 155), - SET_SEC_JR_LIODN_ENTRY(2, 178, 186), - SET_SEC_JR_LIODN_ENTRY(3, 179, 187), - SET_SEC_RTIC_LIODN_ENTRY(a, 144), - SET_SEC_RTIC_LIODN_ENTRY(b, 145), - SET_SEC_RTIC_LIODN_ENTRY(c, 176), - SET_SEC_RTIC_LIODN_ENTRY(d, 177), - SET_SEC_DECO_LIODN_ENTRY(0, 129, 161), - SET_SEC_DECO_LIODN_ENTRY(1, 130, 162), - SET_SEC_DECO_LIODN_ENTRY(2, 131, 163), - SET_SEC_DECO_LIODN_ENTRY(3, 132, 164), - SET_SEC_DECO_LIODN_ENTRY(4, 133, 165), -}; -int sec_liodn_tbl_sz = ARRAY_SIZE(sec_liodn_tbl); - -struct liodn_id_table liodn_bases[] = { - [FSL_HW_PORTAL_SEC] = SET_LIODN_BASE_2(96, 106), -#ifdef CONFIG_SYS_DPAA_FMAN - [FSL_HW_PORTAL_FMAN1] = SET_LIODN_BASE_1(32), -#if (CONFIG_SYS_NUM_FMAN == 2) - [FSL_HW_PORTAL_FMAN2] = SET_LIODN_BASE_1(64), -#endif -#endif -#ifdef CONFIG_SYS_DPAA_PME - [FSL_HW_PORTAL_PME] = SET_LIODN_BASE_2(116, 133), -#endif -}; diff --git a/arch/powerpc/cpu/mpc85xx/p3060_serdes.c b/arch/powerpc/cpu/mpc85xx/p3060_serdes.c deleted file mode 100644 index e720dcf6bd3..00000000000 --- a/arch/powerpc/cpu/mpc85xx/p3060_serdes.c +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright 2011 Freescale Semiconductor, Inc. - * - * 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 <asm/io.h> -#include <asm/fsl_serdes.h> -#include <asm/processor.h> -#include <asm/io.h> -#include "fsl_corenet_serdes.h" - -static u8 serdes_cfg_tbl[][SRDS_MAX_LANES] = { - [0x03] = {PCIE1, PCIE1, PCIE1, PCIE1, PCIE2, PCIE2, PCIE2, PCIE2, - SGMII_FM2_DTSEC4, SGMII_FM1_DTSEC4, SGMII_FM2_DTSEC1, - SGMII_FM1_DTSEC1, SGMII_FM2_DTSEC2, SGMII_FM1_DTSEC2, - NONE, NONE, AURORA, AURORA}, - [0x06] = {PCIE1, PCIE1, PCIE1, PCIE1, NONE, NONE, SGMII_FM2_DTSEC3, - SGMII_FM1_DTSEC3, SGMII_FM2_DTSEC4, SGMII_FM1_DTSEC4, - SGMII_FM2_DTSEC1, SGMII_FM1_DTSEC1, SGMII_FM2_DTSEC2, - SGMII_FM1_DTSEC2, NONE, NONE, AURORA, AURORA}, - [0x16] = {SRIO2, SRIO2, SRIO2, SRIO2, SRIO1, SRIO1, SRIO1, SRIO1, - AURORA, AURORA, SGMII_FM2_DTSEC1, SGMII_FM1_DTSEC1, - SGMII_FM2_DTSEC2, SGMII_FM1_DTSEC2, SGMII_FM2_DTSEC3, - SGMII_FM1_DTSEC3, SGMII_FM2_DTSEC4, SGMII_FM1_DTSEC4}, - [0x19] = {SRIO2, SRIO2, SRIO2, SRIO2, SRIO1, SRIO1, SRIO1, SRIO1, - AURORA, AURORA, PCIE2, PCIE2, PCIE2, PCIE2, SGMII_FM2_DTSEC3, - SGMII_FM1_DTSEC3, SGMII_FM2_DTSEC4, SGMII_FM1_DTSEC4}, - [0x1c] = {NONE, NONE, SRIO1, SRIO2, NONE, NONE, NONE, NONE, - AURORA, AURORA, SGMII_FM2_DTSEC1, SGMII_FM1_DTSEC1, - SGMII_FM2_DTSEC2, SGMII_FM1_DTSEC2, SGMII_FM2_DTSEC3, - SGMII_FM1_DTSEC3, SGMII_FM2_DTSEC4, SGMII_FM1_DTSEC4}, -}; - -enum srds_prtcl serdes_get_prtcl(int cfg, int lane) -{ - if (!serdes_lane_enabled(lane)) - return NONE; - - return serdes_cfg_tbl[cfg][lane]; -} - -int is_serdes_prtcl_valid(u32 prtcl) -{ - int i; - - if (prtcl > ARRAY_SIZE(serdes_cfg_tbl)) - return 0; - - for (i = 0; i < SRDS_MAX_LANES; i++) { - if (serdes_cfg_tbl[prtcl][i] != NONE) - return 1; - } - - return 0; -} - -void soc_serdes_init(void) -{ - /* - * On the P3060 the devdisr2 register does not correctly reflect - * the state of the MACs based on the RCW fields. So disable the MACs - * based on the srds_prtcl and ec1, ec2, ec3 fields - */ - - ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); - u32 devdisr2 = in_be32(&gur->devdisr2); - u32 rcwsr11 = in_be32(&gur->rcwsr[11]); - - /* NOTE: Leave FM1-1,FM1-2 alone for MDIO access */ - - if (!is_serdes_configured(SGMII_FM1_DTSEC3)) - devdisr2 |= FSL_CORENET_DEVDISR2_DTSEC1_3; - - if (!is_serdes_configured(SGMII_FM1_DTSEC4)) - devdisr2 |= FSL_CORENET_DEVDISR2_DTSEC1_4; - - if (!is_serdes_configured(SGMII_FM2_DTSEC1)) - devdisr2 |= FSL_CORENET_DEVDISR2_DTSEC2_1; - - if (!is_serdes_configured(SGMII_FM2_DTSEC2)) - devdisr2 |= FSL_CORENET_DEVDISR2_DTSEC2_2; - - if (!is_serdes_configured(SGMII_FM2_DTSEC3)) - devdisr2 |= FSL_CORENET_DEVDISR2_DTSEC2_3; - - if (!is_serdes_configured(SGMII_FM2_DTSEC4)) - devdisr2 |= FSL_CORENET_DEVDISR2_DTSEC2_4; - - if ((rcwsr11 & FSL_CORENET_RCWSR11_EC2) == - FSL_CORENET_RCWSR11_EC2_FM1_DTSEC2) { - devdisr2 &= ~FSL_CORENET_DEVDISR2_DTSEC1_2; - } - - if ((rcwsr11 & FSL_CORENET_RCWSR11_EC2) == - FSL_CORENET_RCWSR11_EC2_FM2_DTSEC1) { - devdisr2 &= ~FSL_CORENET_DEVDISR2_DTSEC2_1; - } - - out_be32(&gur->devdisr2, devdisr2); -} diff --git a/arch/powerpc/cpu/mpc85xx/release.S b/arch/powerpc/cpu/mpc85xx/release.S index 1860684c11a..22e73e06610 100644 --- a/arch/powerpc/cpu/mpc85xx/release.S +++ b/arch/powerpc/cpu/mpc85xx/release.S @@ -1,5 +1,5 @@ /* - * Copyright 2008-2011 Freescale Semiconductor, Inc. + * Copyright 2008-2012 Freescale Semiconductor, Inc. * Kumar Gala <kumar.gala@freescale.com> * * See file CREDITS for list of people who contributed to this @@ -74,6 +74,33 @@ __secondary_start_page: mtspr 977,r3 #endif +#ifdef CONFIG_SYS_FSL_ERRATUM_A004510 + mfspr r3,SPRN_SVR + rlwinm r3,r3,0,0xff + li r4,CONFIG_SYS_FSL_ERRATUM_A004510_SVR_REV + cmpw r3,r4 + beq 1f + +#ifdef CONFIG_SYS_FSL_ERRATUM_A004510_SVR_REV2 + li r4,CONFIG_SYS_FSL_ERRATUM_A004510_SVR_REV2 + cmpw r3,r4 + beq 1f +#endif + + /* Not a supported revision affected by erratum */ + b 2f + +1: /* Erratum says set bits 55:60 to 001001 */ + msync + isync + mfspr r3,976 + li r4,0x48 + rlwimi r3,r4,0,0x1f8 + mtspr 976,r3 + isync +2: +#endif + /* Enable branch prediction */ lis r3,BUCSR_ENABLE@h ori r3,r3,BUCSR_ENABLE@l @@ -128,7 +155,27 @@ __secondary_start_page: /* r10 has the base address for the entry */ mfspr r0,SPRN_PIR -#ifdef CONFIG_E500MC +#if defined(CONFIG_E6500) +/* + * PIR definition for E6500 + * 0-17 Reserved (logic 0s) + * 8-19 CHIP_ID, 2’b00 - SoC 1 + * all others - reserved + * 20-24 CLUSTER_ID 5’b00000 - CCM 1 + * all others - reserved + * 25-26 CORE_CLUSTER_ID 2’b00 - cluster 1 + * 2’b01 - cluster 2 + * 2’b10 - cluster 3 + * 2’b11 - cluster 4 + * 27-28 CORE_ID 2’b00 - core 0 + * 2’b01 - core 1 + * 2’b10 - core 2 + * 2’b11 - core 3 + * 29-31 THREAD_ID 3’b000 - thread 0 + * 3’b001 - thread 1 + */ + rlwinm r4,r0,29,25,31 +#elif defined(CONFIG_E500MC) rlwinm r4,r0,27,27,31 #else mr r4,r0 @@ -143,6 +190,25 @@ __secondary_start_page: mtspr L1CSR2,r8 #endif +#ifdef CONFIG_E6500 + mfspr r0,SPRN_PIR + /* + * core 0 thread 0: pir reset value 0x00, new pir 0 + * core 0 thread 1: pir reset value 0x01, new pir 1 + * core 1 thread 0: pir reset value 0x08, new pir 2 + * core 1 thread 1: pir reset value 0x09, new pir 3 + * core 2 thread 0: pir reset value 0x10, new pir 4 + * core 2 thread 1: pir reset value 0x11, new pir 5 + * etc. + * + * Only thread 0 of each core will be running, updating PIR doesn't + * need to deal with the thread bits. + */ + rlwinm r4,r0,30,24,30 +#endif + + mtspr SPRN_PIR,r4 /* write to PIR register */ + #if defined(CONFIG_SYS_P4080_ERRATUM_CPU22) || \ defined(CONFIG_SYS_FSL_ERRATUM_NMG_CPU_A011) /* @@ -163,6 +229,12 @@ __secondary_start_page: cmpw r3,r5 bge 2f 1: +#ifdef CONFIG_SYS_FSL_ERRATUM_NMG_CPU_A011 + lis r3,toreset(enable_cpu_a011_workaround)@ha + lwz r3,toreset(enable_cpu_a011_workaround)@l(r3) + cmpwi r3,0 + beq 2f +#endif mfspr r3,L1CSR2 oris r3,r3,(L1CSR2_DCWS)@h mtspr L1CSR2,r3 @@ -220,7 +292,7 @@ __secondary_start_page: /* setup the entry */ li r3,0 li r8,1 - stw r0,ENTRY_PIR(r10) + stw r4,ENTRY_PIR(r10) stw r3,ENTRY_ADDR_UPPER(r10) stw r8,ENTRY_ADDR_LOWER(r10) stw r3,ENTRY_R3_UPPER(r10) @@ -346,6 +418,15 @@ __bootpg_addr: __spin_table: .space CONFIG_MAX_CPUS*ENTRY_SIZE + /* + * This variable is set by cpu_init_r() after parsing hwconfig + * to enable workaround for erratum NMG_CPU_A011. + */ + .align L1_CACHE_SHIFT + .global enable_cpu_a011_workaround +enable_cpu_a011_workaround: + .long 1 + /* Fill in the empty space. The actual reset vector is * the last word of the page */ __secondary_start_code_end: diff --git a/arch/powerpc/cpu/mpc85xx/speed.c b/arch/powerpc/cpu/mpc85xx/speed.c index ce475324550..abfeb268d4d 100644 --- a/arch/powerpc/cpu/mpc85xx/speed.c +++ b/arch/powerpc/cpu/mpc85xx/speed.c @@ -186,8 +186,7 @@ void get_sys_info (sys_info_t * sysInfo) #endif #ifdef CONFIG_QE -#if defined(CONFIG_P1012) || defined(CONFIG_P1016) || \ - defined(CONFIG_P1021) || defined(CONFIG_P1025) +#if defined(CONFIG_P1012) || defined(CONFIG_P1021) || defined(CONFIG_P1025) sysInfo->freqQE = sysInfo->freqSystemBus; #else qe_ratio = ((gur->porpllsr) & MPC85xx_PORPLLSR_QE_RATIO) diff --git a/arch/powerpc/cpu/mpc85xx/start.S b/arch/powerpc/cpu/mpc85xx/start.S index 6aabc30c283..9e04257d2ca 100644 --- a/arch/powerpc/cpu/mpc85xx/start.S +++ b/arch/powerpc/cpu/mpc85xx/start.S @@ -86,6 +86,35 @@ _start_e500: li r1,MSR_DE mtmsr r1 +#ifdef CONFIG_SYS_FSL_ERRATUM_A004510 + mfspr r3,SPRN_SVR + rlwinm r3,r3,0,0xff + li r4,CONFIG_SYS_FSL_ERRATUM_A004510_SVR_REV + cmpw r3,r4 + beq 1f + +#ifdef CONFIG_SYS_FSL_ERRATUM_A004510_SVR_REV2 + li r4,CONFIG_SYS_FSL_ERRATUM_A004510_SVR_REV2 + cmpw r3,r4 + beq 1f +#endif + + /* Not a supported revision affected by erratum */ + li r27,0 + b 2f + +1: li r27,1 /* Remember for later that we have the erratum */ + /* Erratum says set bits 55:60 to 001001 */ + msync + isync + mfspr r3,976 + li r4,0x48 + rlwimi r3,r4,0,0x1f8 + mtspr 976,r3 + isync +2: +#endif + #if defined(CONFIG_SECURE_BOOT) && defined(CONFIG_E500MC) /* ISBC uses L2 as stack. * Disable L2 cache here so that u-boot can enable it later @@ -406,12 +435,11 @@ l2_disabled: * Search for the TLB that covers the code we're executing, and shrink it * so that it covers only this 4K page. That will ensure that any other * TLB we create won't interfere with it. We assume that the TLB exists, - * which is why we don't check the Valid bit of MAS1. + * which is why we don't check the Valid bit of MAS1. We also assume + * it is in TLB1. * * This is necessary, for example, when booting from the on-chip ROM, * which (oddly) creates a single 4GB TLB that covers CCSR and DDR. - * If we don't shrink this TLB now, then we'll accidentally delete it - * in "purge_old_ccsr_tlb" below. */ bl nexti /* Find our address */ nexti: mflr r1 /* R1 = our PC */ @@ -421,11 +449,15 @@ nexti: mflr r1 /* R1 = our PC */ msync tlbsx 0, r1 /* This must succeed */ + mfspr r14, MAS0 /* Save ESEL for later */ + rlwinm r14, r14, 16, 0xfff + /* Set the size of the TLB to 4KB */ mfspr r3, MAS1 li r2, 0xF00 andc r3, r3, r2 /* Clear the TSIZE bits */ ori r3, r3, MAS1_TSIZE(BOOKE_PAGESZ_4K)@l + oris r3, r3, MAS1_IPROT@h mtspr MAS1, r3 /* @@ -440,6 +472,14 @@ nexti: mflr r1 /* R1 = our PC */ mfspr r2, MAS2 andc r2, r2, r3 or r2, r2, r1 +#ifdef CONFIG_SYS_FSL_ERRATUM_A004510 + cmpwi r27,0 + beq 1f + andi. r15, r2, MAS2_I|MAS2_G /* save the old I/G for later */ + rlwinm r2, r2, 0, ~MAS2_I + ori r2, r2, MAS2_G +1: +#endif mtspr MAS2, r2 /* Set the EPN to our PC base address */ mfspr r2, MAS3 @@ -452,6 +492,39 @@ nexti: mflr r1 /* R1 = our PC */ tlbwe /* + * Clear out any other TLB entries that may exist, to avoid conflicts. + * Our TLB entry is in r14. + */ + li r0, TLBIVAX_ALL | TLBIVAX_TLB0 + tlbivax 0, r0 + tlbsync + + mfspr r4, SPRN_TLB1CFG + rlwinm r4, r4, 0, TLBnCFG_NENTRY_MASK + + li r3, 0 + mtspr MAS1, r3 +1: cmpw r3, r14 +#if defined(CONFIG_SYS_PPC_E500_DEBUG_TLB) && !defined(CONFIG_NAND_SPL) + cmpwi cr1, r3, CONFIG_SYS_PPC_E500_DEBUG_TLB + cror cr0*4+eq, cr0*4+eq, cr1*4+eq +#endif + rlwinm r5, r3, 16, MAS0_ESEL_MSK + addi r3, r3, 1 + beq 2f /* skip the entry we're executing from */ + + oris r5, r5, MAS0_TLBSEL(1)@h + mtspr MAS0, r5 + + isync + tlbwe + isync + msync + +2: cmpw r3, r4 + blt 1b + +/* * Relocate CCSR, if necessary. We relocate CCSR if (obviously) the default * location is not where we want it. This typically happens on a 36-bit * system, where we want to move CCSR to near the top of 36-bit address space. @@ -469,41 +542,15 @@ nexti: mflr r1 /* R1 = our PC */ #error "CONFIG_SYS_CCSRBAR_PHYS_HIGH and CONFIG_SYS_CCSRBAR_PHYS_LOW) must be defined." #endif -purge_old_ccsr_tlb: - lis r8, CONFIG_SYS_CCSRBAR@h - ori r8, r8, CONFIG_SYS_CCSRBAR@l - lis r9, (CONFIG_SYS_CCSRBAR + 0x1000)@h - ori r9, r9, (CONFIG_SYS_CCSRBAR + 0x1000)@l - - /* - * In a multi-stage boot (e.g. NAND boot), a previous stage may have - * created a TLB for CCSR, which will interfere with our relocation - * code. Since we're going to create a new TLB for CCSR anyway, - * it should be safe to delete this old TLB here. We have to search - * for it, though. - */ - - li r1, 0 - mtspr MAS6, r1 /* Search the current address space and PID */ - isync - msync - tlbsx 0, r8 - mfspr r1, MAS1 - andis. r2, r1, MAS1_VALID@h /* Check for the Valid bit */ - beq 1f /* Skip if no TLB found */ - - rlwinm r1, r1, 0, 1, 31 /* Clear Valid bit */ - mtspr MAS1, r1 - isync - msync - tlbwe -1: - create_ccsr_new_tlb: /* * Create a TLB for the new location of CCSR. Register R8 is reserved * for the virtual address of this TLB (CONFIG_SYS_CCSRBAR). */ + lis r8, CONFIG_SYS_CCSRBAR@h + ori r8, r8, CONFIG_SYS_CCSRBAR@l + lis r9, (CONFIG_SYS_CCSRBAR + 0x1000)@h + ori r9, r9, (CONFIG_SYS_CCSRBAR + 0x1000)@l lis r0, FSL_BOOKE_MAS0(0, 0, 0)@h ori r0, r0, FSL_BOOKE_MAS0(0, 0, 0)@l lis r1, FSL_BOOKE_MAS1(1, 0, 0, 0, BOOKE_PAGESZ_4K)@h @@ -719,6 +766,253 @@ delete_temp_tlbs: tlbwe #endif /* #if (CONFIG_SYS_CCSRBAR_DEFAULT != CONFIG_SYS_CCSRBAR_PHYS) */ +#ifdef CONFIG_SYS_FSL_ERRATUM_A004510 +#define DCSR_LAWBARH0 (CONFIG_SYS_CCSRBAR + 0x1000) +#define LAW_SIZE_1M 0x13 +#define DCSRBAR_LAWAR (LAW_EN | (0x1d << 20) | LAW_SIZE_1M) + + cmpwi r27,0 + beq 9f + + /* + * Create a TLB entry for CCSR + * + * We're executing out of TLB1 entry in r14, and that's the only + * TLB entry that exists. To allocate some TLB entries for our + * own use, flip a bit high enough that we won't flip it again + * via incrementing. + */ + + xori r8, r14, 32 + lis r0, MAS0_TLBSEL(1)@h + rlwimi r0, r8, 16, MAS0_ESEL_MSK + lis r1, FSL_BOOKE_MAS1(1, 1, 0, 0, BOOKE_PAGESZ_16M)@h + ori r1, r1, FSL_BOOKE_MAS1(1, 1, 0, 0, BOOKE_PAGESZ_16M)@l + lis r7, CONFIG_SYS_CCSRBAR@h + ori r7, r7, CONFIG_SYS_CCSRBAR@l + ori r2, r7, MAS2_I|MAS2_G + lis r3, FSL_BOOKE_MAS3(CONFIG_SYS_CCSRBAR_PHYS_LOW, 0, (MAS3_SW|MAS3_SR))@h + ori r3, r3, FSL_BOOKE_MAS3(CONFIG_SYS_CCSRBAR_PHYS_LOW, 0, (MAS3_SW|MAS3_SR))@l + lis r4, CONFIG_SYS_CCSRBAR_PHYS_HIGH@h + ori r4, r4, CONFIG_SYS_CCSRBAR_PHYS_HIGH@l + mtspr MAS0, r0 + mtspr MAS1, r1 + mtspr MAS2, r2 + mtspr MAS3, r3 + mtspr MAS7, r4 + isync + tlbwe + isync + msync + + /* Map DCSR temporarily to physical address zero */ + li r0, 0 + lis r3, DCSRBAR_LAWAR@h + ori r3, r3, DCSRBAR_LAWAR@l + + stw r0, 0xc00(r7) /* LAWBARH0 */ + stw r0, 0xc04(r7) /* LAWBARL0 */ + sync + stw r3, 0xc08(r7) /* LAWAR0 */ + + /* Read back from LAWAR to ensure the update is complete. */ + lwz r3, 0xc08(r7) /* LAWAR0 */ + isync + + /* Create a TLB entry for DCSR at zero */ + + addi r9, r8, 1 + lis r0, MAS0_TLBSEL(1)@h + rlwimi r0, r9, 16, MAS0_ESEL_MSK + lis r1, FSL_BOOKE_MAS1(1, 1, 0, 0, BOOKE_PAGESZ_1M)@h + ori r1, r1, FSL_BOOKE_MAS1(1, 1, 0, 0, BOOKE_PAGESZ_1M)@l + li r6, 0 /* DCSR effective address */ + ori r2, r6, MAS2_I|MAS2_G + li r3, MAS3_SW|MAS3_SR + li r4, 0 + mtspr MAS0, r0 + mtspr MAS1, r1 + mtspr MAS2, r2 + mtspr MAS3, r3 + mtspr MAS7, r4 + isync + tlbwe + isync + msync + + /* enable the timebase */ +#define CTBENR 0xe2084 + li r3, 1 + addis r4, r7, CTBENR@ha + stw r3, CTBENR@l(r4) + lwz r3, CTBENR@l(r4) + twi 0,r3,0 + isync + + .macro erratum_set_ccsr offset value + addis r3, r7, \offset@ha + lis r4, \value@h + addi r3, r3, \offset@l + ori r4, r4, \value@l + bl erratum_set_value + .endm + + .macro erratum_set_dcsr offset value + addis r3, r6, \offset@ha + lis r4, \value@h + addi r3, r3, \offset@l + ori r4, r4, \value@l + bl erratum_set_value + .endm + + erratum_set_dcsr 0xb0e08 0xe0201800 + erratum_set_dcsr 0xb0e18 0xe0201800 + erratum_set_dcsr 0xb0e38 0xe0400000 + erratum_set_dcsr 0xb0008 0x00900000 + erratum_set_dcsr 0xb0e40 0xe00a0000 + erratum_set_ccsr 0x18600 CONFIG_SYS_FSL_CORENET_SNOOPVEC_COREONLY + erratum_set_ccsr 0x10f00 0x415e5000 + erratum_set_ccsr 0x11f00 0x415e5000 + + /* Make temp mapping uncacheable again, if it was initially */ + bl 2f +2: mflr r3 + tlbsx 0, r3 + mfspr r4, MAS2 + rlwimi r4, r15, 0, MAS2_I + rlwimi r4, r15, 0, MAS2_G + mtspr MAS2, r4 + isync + tlbwe + isync + msync + + /* Clear the cache */ + lis r3,(L1CSR1_ICFI|L1CSR1_ICLFR)@h + ori r3,r3,(L1CSR1_ICFI|L1CSR1_ICLFR)@l + sync + isync + mtspr SPRN_L1CSR1,r3 + isync +2: sync + mfspr r4,SPRN_L1CSR1 + and. r4,r4,r3 + bne 2b + + lis r3,(L1CSR1_CPE|L1CSR1_ICE)@h + ori r3,r3,(L1CSR1_CPE|L1CSR1_ICE)@l + sync + isync + mtspr SPRN_L1CSR1,r3 + isync +2: sync + mfspr r4,SPRN_L1CSR1 + and. r4,r4,r3 + beq 2b + + /* Remove temporary mappings */ + lis r0, MAS0_TLBSEL(1)@h + rlwimi r0, r9, 16, MAS0_ESEL_MSK + li r3, 0 + mtspr MAS0, r0 + mtspr MAS1, r3 + isync + tlbwe + isync + msync + + li r3, 0 + stw r3, 0xc08(r7) /* LAWAR0 */ + lwz r3, 0xc08(r7) + isync + + lis r0, MAS0_TLBSEL(1)@h + rlwimi r0, r8, 16, MAS0_ESEL_MSK + li r3, 0 + mtspr MAS0, r0 + mtspr MAS1, r3 + isync + tlbwe + isync + msync + + b 9f + + /* r3 = addr, r4 = value, clobbers r5, r11, r12 */ +erratum_set_value: + /* Lock two cache lines into I-Cache */ + sync + mfspr r11, SPRN_L1CSR1 + rlwinm r11, r11, 0, ~L1CSR1_ICUL + sync + isync + mtspr SPRN_L1CSR1, r11 + isync + + mflr r12 + bl 5f +5: mflr r5 + addi r5, r5, 2f - 5b + icbtls 0, 0, r5 + addi r5, r5, 64 + + sync + mfspr r11, SPRN_L1CSR1 +3: andi. r11, r11, L1CSR1_ICUL + bne 3b + + icbtls 0, 0, r5 + addi r5, r5, 64 + + sync + mfspr r11, SPRN_L1CSR1 +3: andi. r11, r11, L1CSR1_ICUL + bne 3b + + b 2f + .align 6 + /* Inside a locked cacheline, wait a while, write, then wait a while */ +2: sync + + mfspr r5, SPRN_TBRL + addis r11, r5, 0x10000@h /* wait 65536 timebase ticks */ +4: mfspr r5, SPRN_TBRL + subf. r5, r5, r11 + bgt 4b + + stw r4, 0(r3) + + mfspr r5, SPRN_TBRL + addis r11, r5, 0x10000@h /* wait 65536 timebase ticks */ +4: mfspr r5, SPRN_TBRL + subf. r5, r5, r11 + bgt 4b + + sync + + /* + * Fill out the rest of this cache line and the next with nops, + * to ensure that nothing outside the locked area will be + * fetched due to a branch. + */ + .rept 19 + nop + .endr + + sync + mfspr r11, SPRN_L1CSR1 + rlwinm r11, r11, 0, ~L1CSR1_ICUL + sync + isync + mtspr SPRN_L1CSR1, r11 + isync + + mtlr r12 + blr + +9: +#endif + create_init_ram_area: lis r6,FSL_BOOKE_MAS0(1, 15, 0)@h ori r6,r6,FSL_BOOKE_MAS0(1, 15, 0)@l @@ -855,18 +1149,12 @@ version_string: .globl _start_cont _start_cont: /* Setup the stack in initial RAM,could be L2-as-SRAM or L1 dcache*/ - lis r1,CONFIG_SYS_INIT_RAM_ADDR@h - ori r1,r1,CONFIG_SYS_INIT_SP_OFFSET@l - + lis r3,(CONFIG_SYS_INIT_RAM_ADDR)@h + ori r3,r3,((CONFIG_SYS_INIT_SP_OFFSET-16)&~0xf)@l /* Align to 16 */ li r0,0 - stwu r0,-4(r1) - stwu r0,-4(r1) /* Terminate call chain */ - - stwu r1,-8(r1) /* Save back chain and move SP */ - lis r0,RESET_VECTOR@h /* Address of reset vector */ - ori r0,r0,RESET_VECTOR@l - stwu r1,-8(r1) /* Save back chain and move SP */ - stw r0,+12(r1) /* Save return addr (underflow vect) */ + stw r0,0(r3) /* Terminate Back Chain */ + stw r0,+4(r3) /* NULL return address. */ + mr r1,r3 /* Transfer to SP(r1) */ GET_GOT bl cpu_init_early_f diff --git a/arch/powerpc/cpu/mpc8xxx/cpu.c b/arch/powerpc/cpu/mpc8xxx/cpu.c index cbc674211aa..78a8f926b38 100644 --- a/arch/powerpc/cpu/mpc8xxx/cpu.c +++ b/arch/powerpc/cpu/mpc8xxx/cpu.c @@ -57,8 +57,6 @@ struct cpu_type cpu_type_list [] = { CPU_TYPE_ENTRY(P1012, P1012, 1), CPU_TYPE_ENTRY(P1013, P1013, 1), CPU_TYPE_ENTRY(P1014, P1014, 1), - CPU_TYPE_ENTRY(P1015, P1015, 1), - CPU_TYPE_ENTRY(P1016, P1016, 1), CPU_TYPE_ENTRY(P1017, P1017, 1), CPU_TYPE_ENTRY(P1020, P1020, 2), CPU_TYPE_ENTRY(P1021, P1021, 2), @@ -71,7 +69,6 @@ struct cpu_type cpu_type_list [] = { CPU_TYPE_ENTRY(P2040, P2040, 4), CPU_TYPE_ENTRY(P2041, P2041, 4), CPU_TYPE_ENTRY(P3041, P3041, 4), - CPU_TYPE_ENTRY_MASK(P3060, P3060, 6, 0xf3), CPU_TYPE_ENTRY(P4040, P4040, 4), CPU_TYPE_ENTRY(P4080, P4080, 8), CPU_TYPE_ENTRY(P5010, P5010, 1), @@ -85,7 +82,39 @@ struct cpu_type cpu_type_list [] = { #endif }; -struct cpu_type cpu_type_unknown = CPU_TYPE_ENTRY(Unknown, Unknown, 1); +#ifdef CONFIG_SYS_FSL_QORIQ_CHASSIS2 +u32 compute_ppc_cpumask(void) +{ + ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); + int i = 0, count = 0; + u32 cluster, mask = 0; + + do { + int j; + cluster = in_be32(&gur->tp_cluster[i++].lower); + for (j = 0; j < 4; j++) { + u32 idx = (cluster >> (j*8)) & TP_CLUSTER_INIT_MASK; + u32 type = in_be32(&gur->tp_ityp[idx]); + + if (type & TP_ITYP_AV) { + if (TP_ITYP_TYPE(type) == TP_ITYP_TYPE_PPC) + mask |= 1 << count; + } + count++; + } + } while ((cluster & TP_CLUSTER_EOC) != TP_CLUSTER_EOC); + + return mask; +} +#else /* CONFIG_SYS_FSL_QORIQ_CHASSIS2 */ +/* + * Before chassis genenration 2, the cpumask should be hard-coded. + * In case of cpu type unknown or cpumask unset, use 1 as fail save. + */ +#define compute_ppc_cpumask() 1 +#endif /* CONFIG_SYS_FSL_QORIQ_CHASSIS2 */ + +struct cpu_type cpu_type_unknown = CPU_TYPE_ENTRY(Unknown, Unknown, 0); struct cpu_type *identify_cpu(u32 ver) { @@ -113,6 +142,9 @@ u32 cpu_mask() return ((in_be32(&pic->frr) & MPC8xxx_PICFRR_NCPU_MASK) >> MPC8xxx_PICFRR_NCPU_SHIFT) + 1; + if (cpu->num_cores == 0) + return compute_ppc_cpumask(); + return cpu->mask; } @@ -120,13 +152,14 @@ u32 cpu_mask() * Return the number of cores on this SOC. */ int cpu_numcores() { - ccsr_pic_t __iomem *pic = (void *)CONFIG_SYS_MPC8xxx_PIC_ADDR; struct cpu_type *cpu = gd->cpu; - /* better to query feature reporting register than just assume 1 */ - if (cpu == &cpu_type_unknown) - return ((in_be32(&pic->frr) & MPC8xxx_PICFRR_NCPU_MASK) >> - MPC8xxx_PICFRR_NCPU_SHIFT) + 1; + /* + * Report # of cores in terms of the cpu_mask if we haven't + * figured out how many there are yet + */ + if (cpu->num_cores == 0) + return hweight32(cpu_mask()); return cpu->num_cores; } @@ -138,9 +171,7 @@ int cpu_numcores() { */ int is_core_valid(unsigned int core) { - struct cpu_type *cpu = gd->cpu; - - return !!((1 << core) & cpu->mask); + return !!((1 << core) & cpu_mask()); } int probecpu (void) @@ -156,6 +187,19 @@ int probecpu (void) return 0; } +/* Once in memory, compute mask & # cores once and save them off */ +int fixup_cpu(void) +{ + struct cpu_type *cpu = gd->cpu; + + if (cpu->num_cores == 0) { + cpu->mask = cpu_mask(); + cpu->num_cores = cpu_numcores(); + } + + return 0; +} + /* * Initializes on-chip ethernet controllers. * to override, implement board_eth_init() diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c b/arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c index 2067d53ad28..2592873c9f0 100644 --- a/arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c +++ b/arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c @@ -1,5 +1,5 @@ /* - * Copyright 2008-2011 Freescale Semiconductor, Inc. + * Copyright 2008-2012 Freescale Semiconductor, Inc. * * 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 @@ -151,8 +151,19 @@ static void set_csn_config(int dimm_number, int i, fsl_ddr_cfg_regs_t *ddr, if (dimm_params[dimm_number].n_ranks > 0) { go_config = 1; /* These fields only available in CS0_CONFIG */ - intlv_en = popts->memctl_interleaving; - intlv_ctl = popts->memctl_interleaving_mode; + if (!popts->memctl_interleaving) + break; + switch (popts->memctl_interleaving_mode) { + case FSL_DDR_CACHE_LINE_INTERLEAVING: + case FSL_DDR_PAGE_INTERLEAVING: + case FSL_DDR_BANK_INTERLEAVING: + case FSL_DDR_SUPERBANK_INTERLEAVING: + intlv_en = popts->memctl_interleaving; + intlv_ctl = popts->memctl_interleaving_mode; + break; + default: + break; + } } break; case 1: @@ -302,29 +313,41 @@ static void set_timing_cfg_0(fsl_ddr_cfg_regs_t *ddr, /* DDR SDRAM Timing Configuration 3 (TIMING_CFG_3) */ static void set_timing_cfg_3(fsl_ddr_cfg_regs_t *ddr, + const memctl_options_t *popts, const common_timing_params_t *common_dimm, unsigned int cas_latency) { + /* Extended precharge to activate interval (tRP) */ + unsigned int ext_pretoact = 0; /* Extended Activate to precharge interval (tRAS) */ unsigned int ext_acttopre = 0; - unsigned int ext_refrec; /* Extended refresh recovery time (tRFC) */ - unsigned int ext_caslat = 0; /* Extended MCAS latency from READ cmd */ - unsigned int cntl_adj = 0; /* Control Adjust */ - - /* If the tRAS > 19 MCLK, we use the ext mode */ - if (picos_to_mclk(common_dimm->tRAS_ps) > 0x13) - ext_acttopre = 1; - + /* Extended activate to read/write interval (tRCD) */ + unsigned int ext_acttorw = 0; + /* Extended refresh recovery time (tRFC) */ + unsigned int ext_refrec; + /* Extended MCAS latency from READ cmd */ + unsigned int ext_caslat = 0; + /* Extended last data to precharge interval (tWR) */ + unsigned int ext_wrrec = 0; + /* Control Adjust */ + unsigned int cntl_adj = 0; + + ext_pretoact = picos_to_mclk(common_dimm->tRP_ps) >> 4; + ext_acttopre = picos_to_mclk(common_dimm->tRAS_ps) >> 4; + ext_acttorw = picos_to_mclk(common_dimm->tRCD_ps) >> 4; + ext_caslat = (2 * cas_latency - 1) >> 4; ext_refrec = (picos_to_mclk(common_dimm->tRFC_ps) - 8) >> 4; - - /* If the CAS latency more than 8, use the ext mode */ - if (cas_latency > 8) - ext_caslat = 1; + /* ext_wrrec only deals with 16 clock and above, or 14 with OTF */ + ext_wrrec = (picos_to_mclk(common_dimm->tWR_ps) + + (popts->OTF_burst_chop_en ? 2 : 0)) >> 4; ddr->timing_cfg_3 = (0 - | ((ext_acttopre & 0x1) << 24) - | ((ext_refrec & 0xF) << 16) - | ((ext_caslat & 0x1) << 12) + | ((ext_pretoact & 0x1) << 28) + | ((ext_acttopre & 0x2) << 24) + | ((ext_acttorw & 0x1) << 22) + | ((ext_refrec & 0x1F) << 16) + | ((ext_caslat & 0x3) << 12) + | ((ext_wrrec & 0x1) << 8) | ((cntl_adj & 0x7) << 0) ); debug("FSLDDR: timing_cfg_3 = 0x%08x\n", ddr->timing_cfg_3); @@ -386,15 +409,16 @@ static void set_timing_cfg_1(fsl_ddr_cfg_regs_t *ddr, * we need set extend bit for it at * TIMING_CFG_3[EXT_CASLAT] */ - if (cas_latency > 8) - cas_latency -= 8; caslat_ctrl = 2 * cas_latency - 1; #endif refrec_ctrl = picos_to_mclk(common_dimm->tRFC_ps) - 8; wrrec_mclk = picos_to_mclk(common_dimm->tWR_ps); - wrrec_mclk = wrrec_table[wrrec_mclk - 1]; + if (wrrec_mclk > 16) + printf("Error: WRREC doesn't support more than 16 clocks\n"); + else + wrrec_mclk = wrrec_table[wrrec_mclk - 1]; if (popts->OTF_burst_chop_en) wrrec_mclk += 2; @@ -825,7 +849,7 @@ static void set_ddr_sdram_mode(fsl_ddr_cfg_regs_t *ddr, /* Mode Register - MR0 */ unsigned int dll_on; /* DLL control for precharge PD, 0=off, 1=on */ - unsigned int wr; /* Write Recovery */ + unsigned int wr = 0; /* Write Recovery */ unsigned int dll_rst; /* DLL Reset */ unsigned int mode; /* Normal=0 or Test=1 */ unsigned int caslat = 4;/* CAS# latency, default set as 6 cycles */ @@ -885,24 +909,37 @@ static void set_ddr_sdram_mode(fsl_ddr_cfg_regs_t *ddr, dll_on = 1; wr_mclk = (common_dimm->tWR_ps + mclk_ps - 1) / mclk_ps; - wr = wr_table[wr_mclk - 5]; + if (wr_mclk <= 16) { + wr = wr_table[wr_mclk - 5]; + } else { + printf("Error: unsupported write recovery for mode register " + "wr_mclk = %d\n", wr_mclk); + } dll_rst = 0; /* dll no reset */ mode = 0; /* normal mode */ /* look up table to get the cas latency bits */ - if (cas_latency >= 5 && cas_latency <= 11) { - unsigned char cas_latency_table[7] = { + if (cas_latency >= 5 && cas_latency <= 16) { + unsigned char cas_latency_table[] = { 0x2, /* 5 clocks */ 0x4, /* 6 clocks */ 0x6, /* 7 clocks */ 0x8, /* 8 clocks */ 0xa, /* 9 clocks */ 0xc, /* 10 clocks */ - 0xe /* 11 clocks */ + 0xe, /* 11 clocks */ + 0x1, /* 12 clocks */ + 0x3, /* 13 clocks */ + 0x5, /* 14 clocks */ + 0x7, /* 15 clocks */ + 0x9, /* 16 clocks */ }; caslat = cas_latency_table[cas_latency - 5]; + } else { + printf("Error: unsupported cas latency for mode register\n"); } + bt = 0; /* Nibble sequential */ switch (popts->burst_length) { @@ -930,6 +967,7 @@ static void set_ddr_sdram_mode(fsl_ddr_cfg_regs_t *ddr, | ((mode & 0x1) << 7) | (((caslat >> 1) & 0x7) << 4) | ((bt & 0x1) << 3) + | ((caslat & 1) << 2) | ((bl & 0x3) << 0) ); @@ -1399,73 +1437,37 @@ compute_fsl_memctl_config_regs(const memctl_options_t *popts, /* Chip Select Memory Bounds (CSn_BNDS) */ for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) { - unsigned long long ea = 0, sa = 0; + unsigned long long ea, sa; unsigned int cs_per_dimm = CONFIG_CHIP_SELECTS_PER_CTRL / CONFIG_DIMM_SLOTS_PER_CTLR; unsigned int dimm_number = i / cs_per_dimm; unsigned long long rank_density - = dimm_params[dimm_number].rank_density; + = dimm_params[dimm_number].rank_density >> dbw_cap_adj; - if (((i == 1) && (popts->ba_intlv_ctl & FSL_DDR_CS0_CS1)) || - ((i == 2) && (popts->ba_intlv_ctl & 0x04)) || - ((i == 3) && (popts->ba_intlv_ctl & FSL_DDR_CS2_CS3))) { - /* - * Don't set up boundaries for unused CS - * cs1 for cs0_cs1, cs0_cs1_and_cs2_cs3, cs0_cs1_cs2_cs3 - * cs2 for cs0_cs1_cs2_cs3 - * cs3 for cs2_cs3, cs0_cs1_and_cs2_cs3, cs0_cs1_cs2_cs3 - * But we need to set the ODT_RD_CFG and - * ODT_WR_CFG for CS1_CONFIG here. - */ - set_csn_config(dimm_number, i, ddr, popts, dimm_params); - continue; - } if (dimm_params[dimm_number].n_ranks == 0) { debug("Skipping setup of CS%u " "because n_ranks on DIMM %u is 0\n", i, dimm_number); continue; } - if (popts->memctl_interleaving && popts->ba_intlv_ctl) { - /* - * This works superbank 2CS - * There are 2 or more memory controllers configured - * identically, memory is interleaved between them, - * and each controller uses rank interleaving within - * itself. Therefore the starting and ending address - * on each controller is twice the amount present on - * each controller. If any CS is not included in the - * interleaving, the memory on that CS is not accssible - * and the total memory size is reduced. The CS is also - * disabled. - */ - unsigned long long ctlr_density = 0; + if (popts->memctl_interleaving) { switch (popts->ba_intlv_ctl & FSL_DDR_CS0_CS1_CS2_CS3) { + case FSL_DDR_CS0_CS1_CS2_CS3: + break; case FSL_DDR_CS0_CS1: case FSL_DDR_CS0_CS1_AND_CS2_CS3: - ctlr_density = dimm_params[0].rank_density * 2; if (i > 1) cs_en = 0; break; case FSL_DDR_CS2_CS3: - ctlr_density = dimm_params[0].rank_density; + default: if (i > 0) cs_en = 0; break; - case FSL_DDR_CS0_CS1_CS2_CS3: - /* - * The four CS interleaving should have been verified by - * populate_memctl_options() - */ - ctlr_density = dimm_params[0].rank_density * 4; - break; - default: - break; } - ea = (CONFIG_NUM_DDR_CONTROLLERS * - (ctlr_density >> dbw_cap_adj)) - 1; - } - else if (!popts->memctl_interleaving && popts->ba_intlv_ctl) { + sa = common_dimm->base_address; + ea = common_dimm->total_mem - 1; + } else if (!popts->memctl_interleaving) { /* * If memory interleaving between controllers is NOT * enabled, the starting address for each memory @@ -1477,49 +1479,40 @@ compute_fsl_memctl_config_regs(const memctl_options_t *popts, */ switch (popts->ba_intlv_ctl & FSL_DDR_CS0_CS1_CS2_CS3) { case FSL_DDR_CS0_CS1_CS2_CS3: - /* CS0+CS1+CS2+CS3 interleaving, only CS0_CNDS - * needs to be set. - */ sa = common_dimm->base_address; - ea = sa + (4 * (rank_density >> dbw_cap_adj))-1; + ea = common_dimm->total_mem - 1; break; case FSL_DDR_CS0_CS1_AND_CS2_CS3: - /* CS0+CS1 and CS2+CS3 interleaving, CS0_CNDS - * and CS2_CNDS need to be set. - */ - if ((i == 2) && (dimm_number == 0)) { + if ((i >= 2) && (dimm_number == 0)) { sa = dimm_params[dimm_number].base_address + - 2 * (rank_density >> dbw_cap_adj); - ea = sa + 2 * (rank_density >> dbw_cap_adj) - 1; + 2 * rank_density; + ea = sa + 2 * rank_density - 1; } else { sa = dimm_params[dimm_number].base_address; - ea = sa + (2 * (rank_density >> - dbw_cap_adj)) - 1; + ea = sa + 2 * rank_density - 1; } break; case FSL_DDR_CS0_CS1: - /* CS0+CS1 interleaving, CS0_CNDS needs - * to be set - */ if (dimm_params[dimm_number].n_ranks > (i % cs_per_dimm)) { sa = dimm_params[dimm_number].base_address; - ea = sa + (rank_density >> dbw_cap_adj) - 1; - sa += (i % cs_per_dimm) * (rank_density >> dbw_cap_adj); - ea += (i % cs_per_dimm) * (rank_density >> dbw_cap_adj); + ea = sa + rank_density - 1; + if (i != 1) + sa += (i % cs_per_dimm) * rank_density; + ea += (i % cs_per_dimm) * rank_density; } else { sa = 0; ea = 0; } if (i == 0) - ea += (rank_density >> dbw_cap_adj); + ea += rank_density; break; case FSL_DDR_CS2_CS3: - /* CS2+CS3 interleaving*/ if (dimm_params[dimm_number].n_ranks > (i % cs_per_dimm)) { sa = dimm_params[dimm_number].base_address; - ea = sa + (rank_density >> dbw_cap_adj) - 1; - sa += (i % cs_per_dimm) * (rank_density >> dbw_cap_adj); - ea += (i % cs_per_dimm) * (rank_density >> dbw_cap_adj); + ea = sa + rank_density - 1; + if (i != 3) + sa += (i % cs_per_dimm) * rank_density; + ea += (i % cs_per_dimm) * rank_density; } else { sa = 0; ea = 0; @@ -1528,38 +1521,18 @@ compute_fsl_memctl_config_regs(const memctl_options_t *popts, ea += (rank_density >> dbw_cap_adj); break; default: /* No bank(chip-select) interleaving */ + sa = dimm_params[dimm_number].base_address; + ea = sa + rank_density - 1; + if (dimm_params[dimm_number].n_ranks > (i % cs_per_dimm)) { + sa += (i % cs_per_dimm) * rank_density; + ea += (i % cs_per_dimm) * rank_density; + } else { + sa = 0; + ea = 0; + } break; } } - else if (popts->memctl_interleaving && !popts->ba_intlv_ctl) { - /* - * Only the rank on CS0 of each memory controller may - * be used if memory controller interleaving is used - * without rank interleaving within each memory - * controller. However, the ending address programmed - * into each CS0 must be the sum of the amount of - * memory in the two CS0 ranks. - */ - if (i == 0) { - ea = (2 * (rank_density >> dbw_cap_adj)) - 1; - } - - } - else if (!popts->memctl_interleaving && !popts->ba_intlv_ctl) { - /* - * No rank interleaving and no memory controller - * interleaving. - */ - sa = dimm_params[dimm_number].base_address; - ea = sa + (rank_density >> dbw_cap_adj) - 1; - if (dimm_params[dimm_number].n_ranks > (i % cs_per_dimm)) { - sa += (i % cs_per_dimm) * (rank_density >> dbw_cap_adj); - ea += (i % cs_per_dimm) * (rank_density >> dbw_cap_adj); - } else { - sa = 0; - ea = 0; - } - } sa >>= 24; ea >>= 24; @@ -1574,7 +1547,7 @@ compute_fsl_memctl_config_regs(const memctl_options_t *popts, set_csn_config(dimm_number, i, ddr, popts, dimm_params); set_csn_config_2(i, ddr); } else - printf("CS%d is disabled.\n", i); + debug("CS%d is disabled.\n", i); } /* @@ -1590,7 +1563,7 @@ compute_fsl_memctl_config_regs(const memctl_options_t *popts, set_timing_cfg_0(ddr, popts); #endif - set_timing_cfg_3(ddr, common_dimm, cas_latency); + set_timing_cfg_3(ddr, popts, common_dimm, cas_latency); set_timing_cfg_1(ddr, popts, common_dimm, cas_latency); set_timing_cfg_2(ddr, popts, common_dimm, cas_latency, additive_latency); diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/ddr3_dimm_params.c b/arch/powerpc/cpu/mpc8xxx/ddr/ddr3_dimm_params.c index d0a546610ee..3e7c269e402 100644 --- a/arch/powerpc/cpu/mpc8xxx/ddr/ddr3_dimm_params.c +++ b/arch/powerpc/cpu/mpc8xxx/ddr/ddr3_dimm_params.c @@ -1,5 +1,5 @@ /* - * Copyright 2008-2009 Freescale Semiconductor, Inc. + * Copyright 2008-2012 Freescale Semiconductor, Inc. * Dave Liu <daveliu@freescale.com> * * calculate the organization and timing parameter @@ -90,6 +90,7 @@ ddr_compute_dimm_parameters(const ddr3_spd_eeprom_t *spd, { unsigned int retval; unsigned int mtb_ps; + int ftb_10th_ps; int i; if (spd->mem_type) { @@ -197,6 +198,14 @@ ddr_compute_dimm_parameters(const ddr3_spd_eeprom_t *spd, pdimm->mtb_ps = mtb_ps; /* + * FTB - fine timebase + * use 1/10th of ps as our unit to avoid floating point + * eg, 10 for 1ps, 25 for 2.5ps, 50 for 5ps + */ + ftb_10th_ps = + ((spd->ftb_div & 0xf0) >> 4) * 10 / (spd->ftb_div & 0x0f); + pdimm->ftb_10th_ps = ftb_10th_ps; + /* * sdram minimum cycle time * we assume the MTB is 0.125ns * eg: @@ -204,7 +213,8 @@ ddr_compute_dimm_parameters(const ddr3_spd_eeprom_t *spd, * =12 MTB (1.5ns) ->DDR3-1333 * =10 MTB (1.25ns) ->DDR3-1600 */ - pdimm->tCKmin_X_ps = spd->tCK_min * mtb_ps; + pdimm->tCKmin_X_ps = spd->tCK_min * mtb_ps + + (spd->fine_tCK_min * ftb_10th_ps) / 10; /* * CAS latency supported @@ -222,7 +232,8 @@ ddr_compute_dimm_parameters(const ddr3_spd_eeprom_t *spd, * DDR3-1333H 108 MTB (13.5ns) * DDR3-1600H 90 MTB (11.25ns) */ - pdimm->tAA_ps = spd->tAA_min * mtb_ps; + pdimm->tAA_ps = spd->tAA_min * mtb_ps + + (spd->fine_tAA_min * ftb_10th_ps) / 10; /* * min write recovery time @@ -239,7 +250,8 @@ ddr_compute_dimm_parameters(const ddr3_spd_eeprom_t *spd, * DDR3-1333H 108 MTB (13.5ns) * DDR3-1600H 90 MTB (11.25) */ - pdimm->tRCD_ps = spd->tRCD_min * mtb_ps; + pdimm->tRCD_ps = spd->tRCD_min * mtb_ps + + (spd->fine_tRCD_min * ftb_10th_ps) / 10; /* * min row active to row active delay time @@ -257,7 +269,8 @@ ddr_compute_dimm_parameters(const ddr3_spd_eeprom_t *spd, * DDR3-1333H 108 MTB (13.5ns) * DDR3-1600H 90 MTB (11.25ns) */ - pdimm->tRP_ps = spd->tRP_min * mtb_ps; + pdimm->tRP_ps = spd->tRP_min * mtb_ps + + (spd->fine_tRP_min * ftb_10th_ps) / 10; /* min active to precharge delay time * eg: tRAS_min = @@ -277,7 +290,7 @@ ddr_compute_dimm_parameters(const ddr3_spd_eeprom_t *spd, * DDR3-1600H 370 MTB (46.25ns) */ pdimm->tRC_ps = (((spd->tRAS_tRC_ext & 0xf0) << 4) | spd->tRC_min_lsb) - * mtb_ps; + * mtb_ps + (spd->fine_tRC_min * ftb_10th_ps) / 10; /* * min refresh recovery delay time * eg: tRFC_min = diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/interactive.c b/arch/powerpc/cpu/mpc8xxx/ddr/interactive.c index 5b724371f60..f59d1051bfe 100644 --- a/arch/powerpc/cpu/mpc8xxx/ddr/interactive.c +++ b/arch/powerpc/cpu/mpc8xxx/ddr/interactive.c @@ -1,5 +1,5 @@ /* - * Copyright 2010-2011 Freescale Semiconductor, Inc. + * Copyright 2010-2012 Freescale Semiconductor, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -1047,7 +1047,7 @@ void ddr3_spd_dump(const ddr3_spd_eeprom_t *spd) /* General Section: Bytes 0-59 */ -#define PRINT_NXS(x, y, z...) printf("%-3d : %02x " z "\n", x, y); +#define PRINT_NXS(x, y, z...) printf("%-3d : %02x " z "\n", x, (u8)y); #define PRINT_NNXXS(n0, n1, x0, x1, s) \ printf("%-3d-%3d: %02x %02x " s "\n", n0, n1, x0, x1); @@ -1121,11 +1121,21 @@ void ddr3_spd_dump(const ddr3_spd_eeprom_t *spd) "therm_sensor SDRAM Thermal Sensor"); PRINT_NXS(33, spd->device_type, "device_type SDRAM Device Type"); - - printf("%-3d-%3d: ", 34, 59); /* Reserved, General Section */ - - for (i = 34; i <= 59; i++) - printf("%02x ", spd->res_34_59[i - 34]); + PRINT_NXS(34, spd->fine_tCK_min, + "fine_tCK_min Fine offset for tCKmin"); + PRINT_NXS(35, spd->fine_tAA_min, + "fine_tAA_min Fine offset for tAAmin"); + PRINT_NXS(36, spd->fine_tRCD_min, + "fine_tRCD_min Fine offset for tRCDmin"); + PRINT_NXS(37, spd->fine_tRP_min, + "fine_tRP_min Fine offset for tRPmin"); + PRINT_NXS(38, spd->fine_tRC_min, + "fine_tRC_min Fine offset for tRCmin"); + + printf("%-3d-%3d: ", 39, 59); /* Reserved, General Section */ + + for (i = 39; i <= 59; i++) + printf("%02x ", spd->res_39_59[i - 39]); puts("\n"); @@ -1388,7 +1398,7 @@ unsigned long long fsl_ddr_interactive(fsl_ddr_info_t *pinfo) * No need to worry for buffer overflow here in * this function; readline() maxes out at CFG_CBSIZE */ - readline_into_buffer(prompt, buffer); + readline_into_buffer(prompt, buffer, 0); argc = parse_line(buffer, argv); if (argc == 0) continue; diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/lc_common_dimm_params.c b/arch/powerpc/cpu/mpc8xxx/ddr/lc_common_dimm_params.c index 20c7db03ede..03a784cd479 100644 --- a/arch/powerpc/cpu/mpc8xxx/ddr/lc_common_dimm_params.c +++ b/arch/powerpc/cpu/mpc8xxx/ddr/lc_common_dimm_params.c @@ -1,5 +1,5 @@ /* - * Copyright 2008-2011 Freescale Semiconductor, Inc. + * Copyright 2008-2012 Freescale Semiconductor, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -27,8 +27,10 @@ compute_cas_latency_ddr3(const dimm_params_t *dimm_params, /* compute the common CAS latency supported between slots */ tmp = dimm_params[0].caslat_X; - for (i = 1; i < number_of_dimms; i++) - tmp &= dimm_params[i].caslat_X; + for (i = 1; i < number_of_dimms; i++) { + if (dimm_params[i].n_ranks) + tmp &= dimm_params[i].caslat_X; + } common_caslat = tmp; /* compute the max tAAmin tCKmin between slots */ @@ -491,5 +493,15 @@ compute_lowest_common_dimm_parameters(const dimm_params_t *dimm_params, */ outpdimm->additive_latency = additive_latency; + debug("tCKmin_ps = %u\n", outpdimm->tCKmin_X_ps); + debug("tRCD_ps = %u\n", outpdimm->tRCD_ps); + debug("tRP_ps = %u\n", outpdimm->tRP_ps); + debug("tRAS_ps = %u\n", outpdimm->tRAS_ps); + debug("tWR_ps = %u\n", outpdimm->tWR_ps); + debug("tWTR_ps = %u\n", outpdimm->tWTR_ps); + debug("tRFC_ps = %u\n", outpdimm->tRFC_ps); + debug("tRRD_ps = %u\n", outpdimm->tRRD_ps); + debug("tRC_ps = %u\n", outpdimm->tRC_ps); + return 0; } diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/main.c b/arch/powerpc/cpu/mpc8xxx/ddr/main.c index c2a03e334cf..b47268c20ea 100644 --- a/arch/powerpc/cpu/mpc8xxx/ddr/main.c +++ b/arch/powerpc/cpu/mpc8xxx/ddr/main.c @@ -1,5 +1,5 @@ /* - * Copyright 2008-2011 Freescale Semiconductor, Inc. + * Copyright 2008-2012 Freescale Semiconductor, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -15,13 +15,15 @@ #include <common.h> #include <i2c.h> #include <asm/fsl_ddr_sdram.h> +#include <asm/fsl_law.h> #include "ddr.h" -extern void fsl_ddr_set_lawbar( +void fsl_ddr_set_lawbar( const common_timing_params_t *memctl_common_params, unsigned int memctl_interleaved, unsigned int ctrl_num); +void fsl_ddr_set_intl3r(const unsigned int granule_size); /* processor specific function */ extern void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs, @@ -51,6 +53,22 @@ u8 spd_i2c_addr[CONFIG_NUM_DDR_CONTROLLERS][CONFIG_DIMM_SLOTS_PER_CTLR] = { [1][0] = SPD_EEPROM_ADDRESS3, /* controller 2 */ [1][1] = SPD_EEPROM_ADDRESS4, /* controller 2 */ }; +#elif (CONFIG_NUM_DDR_CONTROLLERS == 3) && (CONFIG_DIMM_SLOTS_PER_CTLR == 1) +u8 spd_i2c_addr[CONFIG_NUM_DDR_CONTROLLERS][CONFIG_DIMM_SLOTS_PER_CTLR] = { + [0][0] = SPD_EEPROM_ADDRESS1, /* controller 1 */ + [1][0] = SPD_EEPROM_ADDRESS2, /* controller 2 */ + [2][0] = SPD_EEPROM_ADDRESS3, /* controller 3 */ +}; +#elif (CONFIG_NUM_DDR_CONTROLLERS == 3) && (CONFIG_DIMM_SLOTS_PER_CTLR == 2) +u8 spd_i2c_addr[CONFIG_NUM_DDR_CONTROLLERS][CONFIG_DIMM_SLOTS_PER_CTLR] = { + [0][0] = SPD_EEPROM_ADDRESS1, /* controller 1 */ + [0][1] = SPD_EEPROM_ADDRESS2, /* controller 1 */ + [1][0] = SPD_EEPROM_ADDRESS3, /* controller 2 */ + [1][1] = SPD_EEPROM_ADDRESS4, /* controller 2 */ + [2][0] = SPD_EEPROM_ADDRESS5, /* controller 3 */ + [2][1] = SPD_EEPROM_ADDRESS6, /* controller 3 */ +}; + #endif static void __get_spd(generic_spd_eeprom_t *spd, u8 i2c_address) @@ -156,12 +174,12 @@ const char * step_to_string(unsigned int step) { return step_string_tbl[s]; } -int step_assign_addresses(fsl_ddr_info_t *pinfo, - unsigned int dbw_cap_adj[], - unsigned int *all_memctl_interleaving, - unsigned int *all_ctlr_rank_interleaving) +unsigned long long step_assign_addresses(fsl_ddr_info_t *pinfo, + unsigned int dbw_cap_adj[]) { int i, j; + unsigned long long total_mem, current_mem_base, total_ctlr_mem; + unsigned long long rank_density, ctlr_density = 0; /* * If a reduced data width is requested, but the SPD @@ -220,86 +238,108 @@ int step_assign_addresses(fsl_ddr_info_t *pinfo, "specified controller %u\n", i); return 1; } + debug("dbw_cap_adj[%d]=%d\n", i, dbw_cap_adj[i]); } - j = 0; - for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) - if (pinfo->memctl_opts[i].memctl_interleaving) - j++; - /* - * Not support less than all memory controllers interleaving - * if more than two controllers - */ - if (j == CONFIG_NUM_DDR_CONTROLLERS) - *all_memctl_interleaving = 1; - - /* Check that all controllers are rank interleaving. */ - j = 0; - for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) - if (pinfo->memctl_opts[i].ba_intlv_ctl) - j++; - /* - * All memory controllers must be populated to qualify for - * all controller rank interleaving - */ - if (j == CONFIG_NUM_DDR_CONTROLLERS) - *all_ctlr_rank_interleaving = 1; - - if (*all_memctl_interleaving) { - unsigned long long addr, total_mem_per_ctlr = 0; - /* - * If interleaving between memory controllers, - * make each controller start at a base address - * of 0. - * - * Also, if bank interleaving (chip select - * interleaving) is enabled on each memory - * controller, CS0 needs to be programmed to - * cover the entire memory range on that memory - * controller - * - * Bank interleaving also implies that each - * addressed chip select is identical in size. - */ - + current_mem_base = 0ull; + total_mem = 0; + if (pinfo->memctl_opts[0].memctl_interleaving) { + rank_density = pinfo->dimm_params[0][0].rank_density >> + dbw_cap_adj[0]; + switch (pinfo->memctl_opts[0].ba_intlv_ctl & + FSL_DDR_CS0_CS1_CS2_CS3) { + case FSL_DDR_CS0_CS1_CS2_CS3: + ctlr_density = 4 * rank_density; + break; + case FSL_DDR_CS0_CS1: + case FSL_DDR_CS0_CS1_AND_CS2_CS3: + ctlr_density = 2 * rank_density; + break; + case FSL_DDR_CS2_CS3: + default: + ctlr_density = rank_density; + break; + } + debug("rank density is 0x%llx, ctlr density is 0x%llx\n", + rank_density, ctlr_density); for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { - addr = 0; - pinfo->common_timing_params[i].base_address = 0ull; - for (j = 0; j < CONFIG_DIMM_SLOTS_PER_CTLR; j++) { - unsigned long long cap - = pinfo->dimm_params[i][j].capacity; - - pinfo->dimm_params[i][j].base_address = addr; - addr += cap >> dbw_cap_adj[i]; - total_mem_per_ctlr += cap >> dbw_cap_adj[i]; + if (pinfo->memctl_opts[i].memctl_interleaving) { + switch (pinfo->memctl_opts[i].memctl_interleaving_mode) { + case FSL_DDR_CACHE_LINE_INTERLEAVING: + case FSL_DDR_PAGE_INTERLEAVING: + case FSL_DDR_BANK_INTERLEAVING: + case FSL_DDR_SUPERBANK_INTERLEAVING: + total_ctlr_mem = 2 * ctlr_density; + break; + case FSL_DDR_3WAY_1KB_INTERLEAVING: + case FSL_DDR_3WAY_4KB_INTERLEAVING: + case FSL_DDR_3WAY_8KB_INTERLEAVING: + total_ctlr_mem = 3 * ctlr_density; + break; + case FSL_DDR_4WAY_1KB_INTERLEAVING: + case FSL_DDR_4WAY_4KB_INTERLEAVING: + case FSL_DDR_4WAY_8KB_INTERLEAVING: + total_ctlr_mem = 4 * ctlr_density; + break; + default: + panic("Unknown interleaving mode"); + } + pinfo->common_timing_params[i].base_address = + current_mem_base; + pinfo->common_timing_params[i].total_mem = + total_ctlr_mem; + total_mem = current_mem_base + total_ctlr_mem; + debug("ctrl %d base 0x%llx\n", i, current_mem_base); + debug("ctrl %d total 0x%llx\n", i, total_ctlr_mem); + } else { + /* when 3rd controller not interleaved */ + current_mem_base = total_mem; + total_ctlr_mem = 0; + pinfo->common_timing_params[i].base_address = + current_mem_base; + for (j = 0; j < CONFIG_DIMM_SLOTS_PER_CTLR; j++) { + unsigned long long cap = + pinfo->dimm_params[i][j].capacity >> dbw_cap_adj[i]; + pinfo->dimm_params[i][j].base_address = + current_mem_base; + debug("ctrl %d dimm %d base 0x%llx\n", i, j, current_mem_base); + current_mem_base += cap; + total_ctlr_mem += cap; + } + debug("ctrl %d total 0x%llx\n", i, total_ctlr_mem); + pinfo->common_timing_params[i].total_mem = + total_ctlr_mem; + total_mem += total_ctlr_mem; } } - pinfo->common_timing_params[0].total_mem = total_mem_per_ctlr; } else { /* * Simple linear assignment if memory * controllers are not interleaved. */ - unsigned long long cur_memsize = 0; for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { - u64 total_mem_per_ctlr = 0; + total_ctlr_mem = 0; pinfo->common_timing_params[i].base_address = - cur_memsize; + current_mem_base; for (j = 0; j < CONFIG_DIMM_SLOTS_PER_CTLR; j++) { /* Compute DIMM base addresses. */ unsigned long long cap = - pinfo->dimm_params[i][j].capacity; + pinfo->dimm_params[i][j].capacity >> dbw_cap_adj[i]; pinfo->dimm_params[i][j].base_address = - cur_memsize; - cur_memsize += cap >> dbw_cap_adj[i]; - total_mem_per_ctlr += cap >> dbw_cap_adj[i]; + current_mem_base; + debug("ctrl %d dimm %d base 0x%llx\n", i, j, current_mem_base); + current_mem_base += cap; + total_ctlr_mem += cap; } + debug("ctrl %d total 0x%llx\n", i, total_ctlr_mem); pinfo->common_timing_params[i].total_mem = - total_mem_per_ctlr; + total_ctlr_mem; + total_mem += total_ctlr_mem; } } + debug("Total mem by %s is 0x%llx\n", __func__, total_mem); - return 0; + return total_mem; } unsigned long long @@ -307,8 +347,6 @@ fsl_ddr_compute(fsl_ddr_info_t *pinfo, unsigned int start_step, unsigned int size_only) { unsigned int i, j; - unsigned int all_controllers_memctl_interleaving = 0; - unsigned int all_controllers_rank_interleaving = 0; unsigned long long total_mem = 0; fsl_ddr_cfg_regs_t *ddr_reg = pinfo->fsl_ddr_config_reg; @@ -345,9 +383,10 @@ fsl_ddr_compute(fsl_ddr_info_t *pinfo, unsigned int start_step, retval = compute_dimm_parameters(spd, pdimm, i); #ifdef CONFIG_SYS_DDR_RAW_TIMING - if (retval != 0) { - printf("SPD error! Trying fallback to " - "raw timing calculation\n"); + if (!i && !j && retval) { + printf("SPD error on controller %d! " + "Trying fallback to raw timing " + "calculation\n", i); fsl_ddr_get_dimm_params(pdimm, i, j); } #else @@ -407,17 +446,14 @@ fsl_ddr_compute(fsl_ddr_info_t *pinfo, unsigned int start_step, &pinfo->memctl_opts[i], pinfo->dimm_params[i], i); } - check_interleaving_options(pinfo); case STEP_ASSIGN_ADDRESSES: /* STEP 5: Assign addresses to chip selects */ - step_assign_addresses(pinfo, - dbw_capacity_adjust, - &all_controllers_memctl_interleaving, - &all_controllers_rank_interleaving); + check_interleaving_options(pinfo); + total_mem = step_assign_addresses(pinfo, dbw_capacity_adjust); case STEP_COMPUTE_REGS: /* STEP 6: compute controller register values */ - debug("FSL Memory ctrl cg register computation\n"); + debug("FSL Memory ctrl register computation\n"); for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { if (timing_params[i].ndimms_present == 0) { memset(&ddr_reg[i], 0, @@ -437,21 +473,7 @@ fsl_ddr_compute(fsl_ddr_info_t *pinfo, unsigned int start_step, break; } - /* Compute the total amount of memory. */ - - /* - * If bank interleaving but NOT memory controller interleaving - * CS_BNDS describe the quantity of memory on each memory - * controller, so the total is the sum across. - */ - if (!all_controllers_memctl_interleaving - && all_controllers_rank_interleaving) { - total_mem = 0; - for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { - total_mem += timing_params[i].total_mem; - } - - } else { + { /* * Compute the amount of memory available just by * looking for the highest valid CSn_BNDS value. @@ -489,7 +511,7 @@ fsl_ddr_compute(fsl_ddr_info_t *pinfo, unsigned int start_step, phys_size_t fsl_ddr_sdram(void) { unsigned int i; - unsigned int memctl_interleaved; + unsigned int law_memctl = LAW_TRGT_IF_DDR_1; unsigned long long total_memory; fsl_ddr_info_t info; @@ -504,34 +526,6 @@ phys_size_t fsl_ddr_sdram(void) #endif total_memory = fsl_ddr_compute(&info, STEP_GET_SPD, 0); - /* Check for memory controller interleaving. */ - memctl_interleaved = 0; - for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { - memctl_interleaved += - info.memctl_opts[i].memctl_interleaving; - } - - if (memctl_interleaved) { - if (memctl_interleaved == CONFIG_NUM_DDR_CONTROLLERS) { - debug("memctl interleaving\n"); - /* - * Change the meaning of memctl_interleaved - * to be "boolean". - */ - memctl_interleaved = 1; - } else { - printf("Warning: memctl interleaving not " - "properly configured on all controllers\n"); - memctl_interleaved = 0; - for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) - info.memctl_opts[i].memctl_interleaving = 0; - debug("Recomputing with memctl_interleaving off.\n"); - total_memory = fsl_ddr_compute(&info, - STEP_ASSIGN_ADDRESSES, - 0); - } - } - /* Program configuration registers. */ for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { debug("Programming controller %u\n", i); @@ -544,24 +538,69 @@ phys_size_t fsl_ddr_sdram(void) fsl_ddr_set_memctl_regs(&(info.fsl_ddr_config_reg[i]), i); } - if (memctl_interleaved) { - const unsigned int ctrl_num = 0; - - /* Only set LAWBAR1 if memory controller interleaving is on. */ - fsl_ddr_set_lawbar(&info.common_timing_params[0], - memctl_interleaved, ctrl_num); - } else { - /* - * Memory controller interleaving is NOT on; - * set each lawbar individually. - */ - for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { + /* program LAWs */ + for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { + if (info.memctl_opts[i].memctl_interleaving) { + switch (info.memctl_opts[i].memctl_interleaving_mode) { + case FSL_DDR_CACHE_LINE_INTERLEAVING: + case FSL_DDR_PAGE_INTERLEAVING: + case FSL_DDR_BANK_INTERLEAVING: + case FSL_DDR_SUPERBANK_INTERLEAVING: + if (i == 0) { + law_memctl = LAW_TRGT_IF_DDR_INTRLV; + fsl_ddr_set_lawbar(&info.common_timing_params[i], + law_memctl, i); + } else if (i == 2) { + law_memctl = LAW_TRGT_IF_DDR_INTLV_34; + fsl_ddr_set_lawbar(&info.common_timing_params[i], + law_memctl, i); + } + break; + case FSL_DDR_3WAY_1KB_INTERLEAVING: + case FSL_DDR_3WAY_4KB_INTERLEAVING: + case FSL_DDR_3WAY_8KB_INTERLEAVING: + law_memctl = LAW_TRGT_IF_DDR_INTLV_123; + if (i == 0) { + fsl_ddr_set_intl3r(info.memctl_opts[i].memctl_interleaving_mode); + fsl_ddr_set_lawbar(&info.common_timing_params[i], + law_memctl, i); + } + break; + case FSL_DDR_4WAY_1KB_INTERLEAVING: + case FSL_DDR_4WAY_4KB_INTERLEAVING: + case FSL_DDR_4WAY_8KB_INTERLEAVING: + law_memctl = LAW_TRGT_IF_DDR_INTLV_1234; + if (i == 0) + fsl_ddr_set_lawbar(&info.common_timing_params[i], + law_memctl, i); + /* place holder for future 4-way interleaving */ + break; + default: + break; + } + } else { + switch (i) { + case 0: + law_memctl = LAW_TRGT_IF_DDR_1; + break; + case 1: + law_memctl = LAW_TRGT_IF_DDR_2; + break; + case 2: + law_memctl = LAW_TRGT_IF_DDR_3; + break; + case 3: + law_memctl = LAW_TRGT_IF_DDR_4; + break; + default: + break; + } fsl_ddr_set_lawbar(&info.common_timing_params[i], - 0, i); + law_memctl, i); } } - debug("total_memory = %llu\n", total_memory); + debug("total_memory by %s = %llu\n", __func__, total_memory); #if !defined(CONFIG_PHYS_64BIT) /* Check for 4G or more. Bad. */ diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/options.c b/arch/powerpc/cpu/mpc8xxx/ddr/options.c index 00ec57be1ff..13e48252742 100644 --- a/arch/powerpc/cpu/mpc8xxx/ddr/options.c +++ b/arch/powerpc/cpu/mpc8xxx/ddr/options.c @@ -1,5 +1,5 @@ /* - * Copyright 2008, 2010-2011 Freescale Semiconductor, Inc. + * Copyright 2008, 2010-2012 Freescale Semiconductor, Inc. * * 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 @@ -19,7 +19,6 @@ * This is pretty fragile on both the use of stack and if the buffer is big * enough. However we will get a warning from getenv_f for the later. */ -#define HWCONFIG_BUFFER_SIZE 128 /* Board-specific functions defined in each board's ddr.c */ extern void fsl_ddr_board_options(memctl_options_t *popts, @@ -790,46 +789,97 @@ unsigned int populate_memctl_options(int all_DIMMs_registered, * should be a subset of the requested configuration. */ #if (CONFIG_NUM_DDR_CONTROLLERS > 1) - if (hwconfig_sub_f("fsl_ddr", "ctlr_intlv", buf)) { - if (pdimm[0].n_ranks == 0) { - printf("There is no rank on CS0 for controller %d. Because only" - " rank on CS0 and ranks chip-select interleaved with CS0" - " are controller interleaved, force non memory " - "controller interleaving\n", ctrl_num); - popts->memctl_interleaving = 0; - } else { - popts->memctl_interleaving = 1; - /* - * test null first. if CONFIG_HWCONFIG is not defined - * hwconfig_arg_cmp returns non-zero - */ - if (hwconfig_subarg_cmp_f("fsl_ddr", "ctlr_intlv", - "null", buf)) { - popts->memctl_interleaving = 0; - debug("memory controller interleaving disabled.\n"); - } else if (hwconfig_subarg_cmp_f("fsl_ddr", - "ctlr_intlv", - "cacheline", buf)) - popts->memctl_interleaving_mode = - FSL_DDR_CACHE_LINE_INTERLEAVING; - else if (hwconfig_subarg_cmp_f("fsl_ddr", "ctlr_intlv", - "page", buf)) - popts->memctl_interleaving_mode = - FSL_DDR_PAGE_INTERLEAVING; - else if (hwconfig_subarg_cmp_f("fsl_ddr", "ctlr_intlv", - "bank", buf)) - popts->memctl_interleaving_mode = - FSL_DDR_BANK_INTERLEAVING; - else if (hwconfig_subarg_cmp_f("fsl_ddr", "ctlr_intlv", - "superbank", buf)) - popts->memctl_interleaving_mode = - FSL_DDR_SUPERBANK_INTERLEAVING; - else { - popts->memctl_interleaving = 0; - printf("hwconfig has unrecognized parameter for ctlr_intlv.\n"); - } - } + if (!hwconfig_sub_f("fsl_ddr", "ctlr_intlv", buf)) + goto done; + + if (pdimm[0].n_ranks == 0) { + printf("There is no rank on CS0 for controller %d.\n", ctrl_num); + popts->memctl_interleaving = 0; + goto done; + } + popts->memctl_interleaving = 1; + /* + * test null first. if CONFIG_HWCONFIG is not defined + * hwconfig_arg_cmp returns non-zero + */ + if (hwconfig_subarg_cmp_f("fsl_ddr", "ctlr_intlv", + "null", buf)) { + popts->memctl_interleaving = 0; + debug("memory controller interleaving disabled.\n"); + } else if (hwconfig_subarg_cmp_f("fsl_ddr", + "ctlr_intlv", + "cacheline", buf)) { + popts->memctl_interleaving_mode = + ((CONFIG_NUM_DDR_CONTROLLERS == 3) && ctrl_num == 2) ? + 0 : FSL_DDR_CACHE_LINE_INTERLEAVING; + popts->memctl_interleaving = + ((CONFIG_NUM_DDR_CONTROLLERS == 3) && ctrl_num == 2) ? + 0 : 1; + } else if (hwconfig_subarg_cmp_f("fsl_ddr", + "ctlr_intlv", + "page", buf)) { + popts->memctl_interleaving_mode = + ((CONFIG_NUM_DDR_CONTROLLERS == 3) && ctrl_num == 2) ? + 0 : FSL_DDR_PAGE_INTERLEAVING; + popts->memctl_interleaving = + ((CONFIG_NUM_DDR_CONTROLLERS == 3) && ctrl_num == 2) ? + 0 : 1; + } else if (hwconfig_subarg_cmp_f("fsl_ddr", + "ctlr_intlv", + "bank", buf)) { + popts->memctl_interleaving_mode = + ((CONFIG_NUM_DDR_CONTROLLERS == 3) && ctrl_num == 2) ? + 0 : FSL_DDR_BANK_INTERLEAVING; + popts->memctl_interleaving = + ((CONFIG_NUM_DDR_CONTROLLERS == 3) && ctrl_num == 2) ? + 0 : 1; + } else if (hwconfig_subarg_cmp_f("fsl_ddr", + "ctlr_intlv", + "superbank", buf)) { + popts->memctl_interleaving_mode = + ((CONFIG_NUM_DDR_CONTROLLERS == 3) && ctrl_num == 2) ? + 0 : FSL_DDR_SUPERBANK_INTERLEAVING; + popts->memctl_interleaving = + ((CONFIG_NUM_DDR_CONTROLLERS == 3) && ctrl_num == 2) ? + 0 : 1; +#if (CONFIG_NUM_DDR_CONTROLLERS == 3) + } else if (hwconfig_subarg_cmp_f("fsl_ddr", + "ctlr_intlv", + "3way_1KB", buf)) { + popts->memctl_interleaving_mode = + FSL_DDR_3WAY_1KB_INTERLEAVING; + } else if (hwconfig_subarg_cmp_f("fsl_ddr", + "ctlr_intlv", + "3way_4KB", buf)) { + popts->memctl_interleaving_mode = + FSL_DDR_3WAY_4KB_INTERLEAVING; + } else if (hwconfig_subarg_cmp_f("fsl_ddr", + "ctlr_intlv", + "3way_8KB", buf)) { + popts->memctl_interleaving_mode = + FSL_DDR_3WAY_8KB_INTERLEAVING; +#elif (CONFIG_NUM_DDR_CONTROLLERS == 4) + } else if (hwconfig_subarg_cmp_f("fsl_ddr", + "ctlr_intlv", + "4way_1KB", buf)) { + popts->memctl_interleaving_mode = + FSL_DDR_4WAY_1KB_INTERLEAVING; + } else if (hwconfig_subarg_cmp_f("fsl_ddr", + "ctlr_intlv", + "4way_4KB", buf)) { + popts->memctl_interleaving_mode = + FSL_DDR_4WAY_4KB_INTERLEAVING; + } else if (hwconfig_subarg_cmp_f("fsl_ddr", + "ctlr_intlv", + "4way_8KB", buf)) { + popts->memctl_interleaving_mode = + FSL_DDR_4WAY_8KB_INTERLEAVING; +#endif + } else { + popts->memctl_interleaving = 0; + printf("hwconfig has unrecognized parameter for ctlr_intlv.\n"); } +done: #endif if ((hwconfig_sub_f("fsl_ddr", "bank_intlv", buf)) && (CONFIG_CHIP_SELECTS_PER_CTRL > 1)) { @@ -859,20 +909,20 @@ unsigned int populate_memctl_options(int all_DIMMs_registered, popts->ba_intlv_ctl = 0; printf("Not enough bank(chip-select) for " "CS0+CS1+CS2+CS3 on controller %d, " - "force non-interleaving!\n", ctrl_num); + "interleaving disabled!\n", ctrl_num); } #elif (CONFIG_DIMM_SLOTS_PER_CTLR == 2) if ((pdimm[0].n_ranks < 2) && (pdimm[1].n_ranks < 2)) { popts->ba_intlv_ctl = 0; printf("Not enough bank(chip-select) for " "CS0+CS1+CS2+CS3 on controller %d, " - "force non-interleaving!\n", ctrl_num); + "interleaving disabled!\n", ctrl_num); } if (pdimm[0].capacity != pdimm[1].capacity) { popts->ba_intlv_ctl = 0; printf("Not identical DIMM size for " "CS0+CS1+CS2+CS3 on controller %d, " - "force non-interleaving!\n", ctrl_num); + "interleaving disabled!\n", ctrl_num); } #endif break; @@ -881,7 +931,7 @@ unsigned int populate_memctl_options(int all_DIMMs_registered, popts->ba_intlv_ctl = 0; printf("Not enough bank(chip-select) for " "CS0+CS1 on controller %d, " - "force non-interleaving!\n", ctrl_num); + "interleaving disabled!\n", ctrl_num); } break; case FSL_DDR_CS2_CS3: @@ -889,13 +939,13 @@ unsigned int populate_memctl_options(int all_DIMMs_registered, if (pdimm[0].n_ranks < 4) { popts->ba_intlv_ctl = 0; printf("Not enough bank(chip-select) for CS2+CS3 " - "on controller %d, force non-interleaving!\n", ctrl_num); + "on controller %d, interleaving disabled!\n", ctrl_num); } #elif (CONFIG_DIMM_SLOTS_PER_CTLR == 2) if (pdimm[1].n_ranks < 2) { popts->ba_intlv_ctl = 0; printf("Not enough bank(chip-select) for CS2+CS3 " - "on controller %d, force non-interleaving!\n", ctrl_num); + "on controller %d, interleaving disabled!\n", ctrl_num); } #endif break; @@ -905,14 +955,14 @@ unsigned int populate_memctl_options(int all_DIMMs_registered, popts->ba_intlv_ctl = 0; printf("Not enough bank(CS) for CS0+CS1 and " "CS2+CS3 on controller %d, " - "force non-interleaving!\n", ctrl_num); + "interleaving disabled!\n", ctrl_num); } #elif (CONFIG_DIMM_SLOTS_PER_CTLR == 2) if ((pdimm[0].n_ranks < 2) || (pdimm[1].n_ranks < 2)) { popts->ba_intlv_ctl = 0; printf("Not enough bank(CS) for CS0+CS1 and " "CS2+CS3 on controller %d, " - "force non-interleaving!\n", ctrl_num); + "interleaving disabled!\n", ctrl_num); } #endif break; @@ -954,33 +1004,73 @@ unsigned int populate_memctl_options(int all_DIMMs_registered, void check_interleaving_options(fsl_ddr_info_t *pinfo) { - int i, j, check_n_ranks, intlv_fixed = 0; + int i, j, k, check_n_ranks, intlv_invalid = 0; + unsigned int check_intlv, check_n_row_addr, check_n_col_addr; unsigned long long check_rank_density; + struct dimm_params_s *dimm; /* * Check if all controllers are configured for memory * controller interleaving. Identical dimms are recommended. At least - * the size should be checked. + * the size, row and col address should be checked. */ j = 0; check_n_ranks = pinfo->dimm_params[0][0].n_ranks; check_rank_density = pinfo->dimm_params[0][0].rank_density; + check_n_row_addr = pinfo->dimm_params[0][0].n_row_addr; + check_n_col_addr = pinfo->dimm_params[0][0].n_col_addr; + check_intlv = pinfo->memctl_opts[0].memctl_interleaving_mode; for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { - if ((pinfo->memctl_opts[i].memctl_interleaving) && \ - (check_rank_density == pinfo->dimm_params[i][0].rank_density) && \ - (check_n_ranks == pinfo->dimm_params[i][0].n_ranks)) { + dimm = &pinfo->dimm_params[i][0]; + if (!pinfo->memctl_opts[i].memctl_interleaving) { + continue; + } else if (((check_rank_density != dimm->rank_density) || + (check_n_ranks != dimm->n_ranks) || + (check_n_row_addr != dimm->n_row_addr) || + (check_n_col_addr != dimm->n_col_addr) || + (check_intlv != + pinfo->memctl_opts[i].memctl_interleaving_mode))){ + intlv_invalid = 1; + break; + } else { j++; } + } - if (j != CONFIG_NUM_DDR_CONTROLLERS) { + if (intlv_invalid) { for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) - if (pinfo->memctl_opts[i].memctl_interleaving) { + pinfo->memctl_opts[i].memctl_interleaving = 0; + printf("Not all DIMMs are identical. " + "Memory controller interleaving disabled.\n"); + } else { + switch (check_intlv) { + case FSL_DDR_CACHE_LINE_INTERLEAVING: + case FSL_DDR_PAGE_INTERLEAVING: + case FSL_DDR_BANK_INTERLEAVING: + case FSL_DDR_SUPERBANK_INTERLEAVING: + if (3 == CONFIG_NUM_DDR_CONTROLLERS) + k = 2; + else + k = CONFIG_NUM_DDR_CONTROLLERS; + break; + case FSL_DDR_3WAY_1KB_INTERLEAVING: + case FSL_DDR_3WAY_4KB_INTERLEAVING: + case FSL_DDR_3WAY_8KB_INTERLEAVING: + case FSL_DDR_4WAY_1KB_INTERLEAVING: + case FSL_DDR_4WAY_4KB_INTERLEAVING: + case FSL_DDR_4WAY_8KB_INTERLEAVING: + default: + k = CONFIG_NUM_DDR_CONTROLLERS; + break; + } + debug("%d of %d controllers are interleaving.\n", j, k); + if (j != k) { + for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) pinfo->memctl_opts[i].memctl_interleaving = 0; - intlv_fixed = 1; - } - if (intlv_fixed) - printf("Not all DIMMs are identical in size. " - "Memory controller interleaving disabled.\n"); + printf("Not all controllers have compatible " + "interleaving mode. All disabled.\n"); + } } + debug("Checking interleaving options completed\n"); } int fsl_use_spd(void) diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/util.c b/arch/powerpc/cpu/mpc8xxx/ddr/util.c index eb6a17a8503..664ad09298f 100644 --- a/arch/powerpc/cpu/mpc8xxx/ddr/util.c +++ b/arch/powerpc/cpu/mpc8xxx/ddr/util.c @@ -1,5 +1,5 @@ /* - * Copyright 2008-2011 Freescale Semiconductor, Inc. + * Copyright 2008-2012 Freescale Semiconductor, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -79,7 +79,7 @@ unsigned int mclk_to_picos(unsigned int mclk) void __fsl_ddr_set_lawbar(const common_timing_params_t *memctl_common_params, - unsigned int memctl_interleaved, + unsigned int law_memctl, unsigned int ctrl_num) { unsigned long long base = memctl_common_params->base_address; @@ -98,28 +98,13 @@ __fsl_ddr_set_lawbar(const common_timing_params_t *memctl_common_params, if ((base + size) >= CONFIG_MAX_MEM_MAPPED) size = CONFIG_MAX_MEM_MAPPED - base; #endif - - if (ctrl_num == 0) { - /* - * Set up LAW for DDR controller 1 space. - */ - unsigned int lawbar1_target_id = memctl_interleaved - ? LAW_TRGT_IF_DDR_INTRLV : LAW_TRGT_IF_DDR_1; - - if (set_ddr_laws(base, size, lawbar1_target_id) < 0) { - printf("%s: ERROR (ctrl #0, intrlv=%d)\n", __func__, - memctl_interleaved); - return ; - } - } else if (ctrl_num == 1) { - if (set_ddr_laws(base, size, LAW_TRGT_IF_DDR_2) < 0) { - printf("%s: ERROR (ctrl #1)\n", __func__); - return ; - } - } else { - printf("%s: unexpected DDR controller number (%u)\n", __func__, - ctrl_num); + if (set_ddr_laws(base, size, law_memctl) < 0) { + printf("%s: ERROR (ctrl #%d, TRGT ID=%x)\n", __func__, ctrl_num, + law_memctl); + return ; } + debug("setup ddr law base = 0x%llx, size 0x%llx, TRGT_ID 0x%x\n", + base, size, law_memctl); } __attribute__((weak, alias("__fsl_ddr_set_lawbar"))) void @@ -127,6 +112,15 @@ fsl_ddr_set_lawbar(const common_timing_params_t *memctl_common_params, unsigned int memctl_interleaved, unsigned int ctrl_num); +void fsl_ddr_set_intl3r(const unsigned int granule_size) +{ +#ifdef CONFIG_E6500 + u32 *mcintl3r = (void *) (CONFIG_SYS_IMMR + 0x18004); + *mcintl3r = 0x80000000 | (granule_size & 0x1f); + debug("Enable MCINTL3R with granule size 0x%x\n", granule_size); +#endif +} + void board_add_ram_info(int use_default) { #if defined(CONFIG_MPC83xx) @@ -137,6 +131,9 @@ void board_add_ram_info(int use_default) #elif defined(CONFIG_MPC86xx) ccsr_ddr_t *ddr = (void *)(CONFIG_SYS_MPC86xx_DDR_ADDR); #endif +#if defined(CONFIG_E6500) && (CONFIG_NUM_DDR_CONTROLLERS == 3) + u32 *mcintl3r = (void *) (CONFIG_SYS_IMMR + 0x18004); +#endif #if (CONFIG_NUM_DDR_CONTROLLERS > 1) uint32_t cs0_config = in_be32(&ddr->cs0_config); #endif @@ -180,7 +177,29 @@ void board_add_ram_info(int use_default) else puts(", ECC off)"); -#if (CONFIG_NUM_DDR_CONTROLLERS > 1) +#if (CONFIG_NUM_DDR_CONTROLLERS == 3) +#ifdef CONFIG_E6500 + if (*mcintl3r & 0x80000000) { + puts("\n"); + puts(" DDR Controller Interleaving Mode: "); + switch (*mcintl3r & 0x1f) { + case FSL_DDR_3WAY_1KB_INTERLEAVING: + puts("3-way 1KB"); + break; + case FSL_DDR_3WAY_4KB_INTERLEAVING: + puts("3-way 4KB"); + break; + case FSL_DDR_3WAY_8KB_INTERLEAVING: + puts("3-way 8KB"); + break; + default: + puts("3-way UNKNOWN"); + break; + } + } +#endif +#endif +#if (CONFIG_NUM_DDR_CONTROLLERS >= 2) if (cs0_config & 0x20000000) { puts("\n"); puts(" DDR Controller Interleaving Mode: "); diff --git a/arch/powerpc/cpu/mpc8xxx/fdt.c b/arch/powerpc/cpu/mpc8xxx/fdt.c index 09810be7d30..32ab0509622 100644 --- a/arch/powerpc/cpu/mpc8xxx/fdt.c +++ b/arch/powerpc/cpu/mpc8xxx/fdt.c @@ -62,8 +62,9 @@ void ft_fixup_num_cores(void *blob) { off = fdt_node_offset_by_prop_value(blob, -1, "device_type", "cpu", 4); while (off != -FDT_ERR_NOTFOUND) { u32 *reg = (u32 *)fdt_getprop(blob, off, "reg", 0); + u32 phys_cpu_id = thread_to_core(*reg); - if (!is_core_valid(*reg) || is_core_disabled(*reg)) { + if (!is_core_valid(phys_cpu_id) || is_core_disabled(phys_cpu_id)) { int ph = fdt_get_phandle(blob, off); /* Delete the cpu node once there are no cpu handles */ diff --git a/arch/powerpc/cpu/mpc8xxx/fsl_ifc.c b/arch/powerpc/cpu/mpc8xxx/fsl_ifc.c index 66824960d3f..56b319f5d4b 100644 --- a/arch/powerpc/cpu/mpc8xxx/fsl_ifc.c +++ b/arch/powerpc/cpu/mpc8xxx/fsl_ifc.c @@ -44,12 +44,18 @@ void init_early_memctl_regs(void) set_ifc_ftim(IFC_CS0, IFC_FTIM3, CONFIG_SYS_CS0_FTIM3); #if !defined(CONFIG_SYS_FSL_ERRATUM_IFC_A003399) || defined(CONFIG_SYS_RAMBOOT) +#ifdef CONFIG_SYS_CSPR0_EXT + set_ifc_cspr_ext(IFC_CS0, CONFIG_SYS_CSPR0_EXT); +#endif set_ifc_cspr(IFC_CS0, CONFIG_SYS_CSPR0); set_ifc_amask(IFC_CS0, CONFIG_SYS_AMASK0); set_ifc_csor(IFC_CS0, CONFIG_SYS_CSOR0); #endif #endif +#ifdef CONFIG_SYS_CSPR1_EXT + set_ifc_cspr_ext(IFC_CS1, CONFIG_SYS_CSPR1_EXT); +#endif #if defined(CONFIG_SYS_CSPR1) && defined(CONFIG_SYS_CSOR1) set_ifc_ftim(IFC_CS1, IFC_FTIM0, CONFIG_SYS_CS1_FTIM0); set_ifc_ftim(IFC_CS1, IFC_FTIM1, CONFIG_SYS_CS1_FTIM1); @@ -61,6 +67,9 @@ void init_early_memctl_regs(void) set_ifc_cspr(IFC_CS1, CONFIG_SYS_CSPR1); #endif +#ifdef CONFIG_SYS_CSPR2_EXT + set_ifc_cspr_ext(IFC_CS2, CONFIG_SYS_CSPR2_EXT); +#endif #if defined(CONFIG_SYS_CSPR2) && defined(CONFIG_SYS_CSOR2) set_ifc_ftim(IFC_CS2, IFC_FTIM0, CONFIG_SYS_CS2_FTIM0); set_ifc_ftim(IFC_CS2, IFC_FTIM1, CONFIG_SYS_CS2_FTIM1); @@ -72,6 +81,9 @@ void init_early_memctl_regs(void) set_ifc_cspr(IFC_CS2, CONFIG_SYS_CSPR2); #endif +#ifdef CONFIG_SYS_CSPR3_EXT + set_ifc_cspr_ext(IFC_CS3, CONFIG_SYS_CSPR3_EXT); +#endif #if defined(CONFIG_SYS_CSPR3) && defined(CONFIG_SYS_CSOR3) set_ifc_ftim(IFC_CS3, IFC_FTIM0, CONFIG_SYS_CS3_FTIM0); set_ifc_ftim(IFC_CS3, IFC_FTIM1, CONFIG_SYS_CS3_FTIM1); diff --git a/arch/powerpc/cpu/mpc8xxx/srio.c b/arch/powerpc/cpu/mpc8xxx/srio.c index c7f394972bf..0cb65b32e48 100644 --- a/arch/powerpc/cpu/mpc8xxx/srio.c +++ b/arch/powerpc/cpu/mpc8xxx/srio.c @@ -95,126 +95,92 @@ void srio_init(void) } } -#ifdef CONFIG_SRIOBOOT_MASTER -void srio_boot_master(void) +#ifdef CONFIG_FSL_CORENET +void srio_boot_master(int port) { struct ccsr_rio *srio = (void *)CONFIG_SYS_FSL_SRIO_ADDR; /* set port accept-all */ - out_be32((void *)&srio->impl.port[CONFIG_SRIOBOOT_MASTER_PORT].ptaacr, + out_be32((void *)&srio->impl.port[port - 1].ptaacr, SRIO_PORT_ACCEPT_ALL); - debug("SRIOBOOT - MASTER: Master port [ %d ] for srio boot.\n", - CONFIG_SRIOBOOT_MASTER_PORT); + debug("SRIOBOOT - MASTER: Master port [ %d ] for srio boot.\n", port); /* configure inbound window for slave's u-boot image */ debug("SRIOBOOT - MASTER: Inbound window for slave's image; " "Local = 0x%llx, Srio = 0x%llx, Size = 0x%x\n", - (u64)CONFIG_SRIOBOOT_SLAVE_IMAGE_LAW_PHYS1, - (u64)CONFIG_SRIOBOOT_SLAVE_IMAGE_SRIO_PHYS1, - CONFIG_SRIOBOOT_SLAVE_IMAGE_SIZE); - out_be32((void *)&srio->atmu - .port[CONFIG_SRIOBOOT_MASTER_PORT].inbw[0].riwtar, - CONFIG_SRIOBOOT_SLAVE_IMAGE_LAW_PHYS1 >> 12); - out_be32((void *)&srio->atmu - .port[CONFIG_SRIOBOOT_MASTER_PORT].inbw[0].riwbar, - CONFIG_SRIOBOOT_SLAVE_IMAGE_SRIO_PHYS1 >> 12); - out_be32((void *)&srio->atmu - .port[CONFIG_SRIOBOOT_MASTER_PORT].inbw[0].riwar, + (u64)CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_PHYS, + (u64)CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_BUS1, + CONFIG_SRIO_PCIE_BOOT_IMAGE_SIZE); + out_be32((void *)&srio->atmu.port[port - 1].inbw[0].riwtar, + CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_PHYS >> 12); + out_be32((void *)&srio->atmu.port[port - 1].inbw[0].riwbar, + CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_BUS1 >> 12); + out_be32((void *)&srio->atmu.port[port - 1].inbw[0].riwar, SRIO_IB_ATMU_AR - | atmu_size_mask(CONFIG_SRIOBOOT_SLAVE_IMAGE_SIZE)); + | atmu_size_mask(CONFIG_SRIO_PCIE_BOOT_IMAGE_SIZE)); /* configure inbound window for slave's u-boot image */ debug("SRIOBOOT - MASTER: Inbound window for slave's image; " "Local = 0x%llx, Srio = 0x%llx, Size = 0x%x\n", - (u64)CONFIG_SRIOBOOT_SLAVE_IMAGE_LAW_PHYS2, - (u64)CONFIG_SRIOBOOT_SLAVE_IMAGE_SRIO_PHYS2, - CONFIG_SRIOBOOT_SLAVE_IMAGE_SIZE); - out_be32((void *)&srio->atmu - .port[CONFIG_SRIOBOOT_MASTER_PORT].inbw[1].riwtar, - CONFIG_SRIOBOOT_SLAVE_IMAGE_LAW_PHYS2 >> 12); - out_be32((void *)&srio->atmu - .port[CONFIG_SRIOBOOT_MASTER_PORT].inbw[1].riwbar, - CONFIG_SRIOBOOT_SLAVE_IMAGE_SRIO_PHYS2 >> 12); - out_be32((void *)&srio->atmu - .port[CONFIG_SRIOBOOT_MASTER_PORT].inbw[1].riwar, + (u64)CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_PHYS, + (u64)CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_BUS2, + CONFIG_SRIO_PCIE_BOOT_IMAGE_SIZE); + out_be32((void *)&srio->atmu.port[port - 1].inbw[1].riwtar, + CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_PHYS >> 12); + out_be32((void *)&srio->atmu.port[port - 1].inbw[1].riwbar, + CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_BUS2 >> 12); + out_be32((void *)&srio->atmu.port[port - 1].inbw[1].riwar, SRIO_IB_ATMU_AR - | atmu_size_mask(CONFIG_SRIOBOOT_SLAVE_IMAGE_SIZE)); + | atmu_size_mask(CONFIG_SRIO_PCIE_BOOT_IMAGE_SIZE)); - /* configure inbound window for slave's ucode */ - debug("SRIOBOOT - MASTER: Inbound window for slave's ucode; " + /* configure inbound window for slave's ucode and ENV */ + debug("SRIOBOOT - MASTER: Inbound window for slave's ucode and ENV; " "Local = 0x%llx, Srio = 0x%llx, Size = 0x%x\n", - (u64)CONFIG_SRIOBOOT_SLAVE_UCODE_LAW_PHYS, - (u64)CONFIG_SRIOBOOT_SLAVE_UCODE_SRIO_PHYS, - CONFIG_SRIOBOOT_SLAVE_UCODE_SIZE); - out_be32((void *)&srio->atmu - .port[CONFIG_SRIOBOOT_MASTER_PORT].inbw[2].riwtar, - CONFIG_SRIOBOOT_SLAVE_UCODE_LAW_PHYS >> 12); - out_be32((void *)&srio->atmu - .port[CONFIG_SRIOBOOT_MASTER_PORT].inbw[2].riwbar, - CONFIG_SRIOBOOT_SLAVE_UCODE_SRIO_PHYS >> 12); - out_be32((void *)&srio->atmu - .port[CONFIG_SRIOBOOT_MASTER_PORT].inbw[2].riwar, - SRIO_IB_ATMU_AR - | atmu_size_mask(CONFIG_SRIOBOOT_SLAVE_UCODE_SIZE)); - - /* configure inbound window for slave's ENV */ - debug("SRIOBOOT - MASTER: Inbound window for slave's ENV; " - "Local = 0x%llx, Siro = 0x%llx, Size = 0x%x\n", - CONFIG_SRIOBOOT_SLAVE_ENV_LAW_PHYS, - CONFIG_SRIOBOOT_SLAVE_ENV_SRIO_PHYS, - CONFIG_SRIOBOOT_SLAVE_ENV_SIZE); - out_be32((void *)&srio->atmu - .port[CONFIG_SRIOBOOT_MASTER_PORT].inbw[3].riwtar, - CONFIG_SRIOBOOT_SLAVE_ENV_LAW_PHYS >> 12); - out_be32((void *)&srio->atmu - .port[CONFIG_SRIOBOOT_MASTER_PORT].inbw[3].riwbar, - CONFIG_SRIOBOOT_SLAVE_ENV_SRIO_PHYS >> 12); - out_be32((void *)&srio->atmu - .port[CONFIG_SRIOBOOT_MASTER_PORT].inbw[3].riwar, + (u64)CONFIG_SRIO_PCIE_BOOT_UCODE_ENV_MEM_PHYS, + (u64)CONFIG_SRIO_PCIE_BOOT_UCODE_ENV_MEM_BUS, + CONFIG_SRIO_PCIE_BOOT_UCODE_ENV_SIZE); + out_be32((void *)&srio->atmu.port[port - 1].inbw[2].riwtar, + CONFIG_SRIO_PCIE_BOOT_UCODE_ENV_MEM_PHYS >> 12); + out_be32((void *)&srio->atmu.port[port - 1].inbw[2].riwbar, + CONFIG_SRIO_PCIE_BOOT_UCODE_ENV_MEM_BUS >> 12); + out_be32((void *)&srio->atmu.port[port - 1].inbw[2].riwar, SRIO_IB_ATMU_AR - | atmu_size_mask(CONFIG_SRIOBOOT_SLAVE_ENV_SIZE)); + | atmu_size_mask(CONFIG_SRIO_PCIE_BOOT_UCODE_ENV_SIZE)); } -#ifdef CONFIG_SRIOBOOT_SLAVE_HOLDOFF -void srio_boot_master_release_slave(void) +void srio_boot_master_release_slave(int port) { struct ccsr_rio *srio = (void *)CONFIG_SYS_FSL_SRIO_ADDR; u32 escsr; debug("SRIOBOOT - MASTER: " "Check the port status and release slave core ...\n"); - escsr = in_be32((void *)&srio->lp_serial - .port[CONFIG_SRIOBOOT_MASTER_PORT].pescsr); + escsr = in_be32((void *)&srio->lp_serial.port[port - 1].pescsr); if (escsr & 0x2) { if (escsr & 0x10100) { debug("SRIOBOOT - MASTER: Port [ %d ] is error.\n", - CONFIG_SRIOBOOT_MASTER_PORT); + port); } else { debug("SRIOBOOT - MASTER: " - "Port [ %d ] is ready, now release slave's core ...\n", - CONFIG_SRIOBOOT_MASTER_PORT); + "Port [ %d ] is ready, now release slave's core ...\n", + port); /* * configure outbound window * with maintenance attribute to set slave's LCSBA1CSR */ - out_be32((void *)&srio->atmu - .port[CONFIG_SRIOBOOT_MASTER_PORT] + out_be32((void *)&srio->atmu.port[port - 1] .outbw[1].rowtar, 0); - out_be32((void *)&srio->atmu - .port[CONFIG_SRIOBOOT_MASTER_PORT] + out_be32((void *)&srio->atmu.port[port - 1] .outbw[1].rowtear, 0); - if (CONFIG_SRIOBOOT_MASTER_PORT) - out_be32((void *)&srio->atmu - .port[CONFIG_SRIOBOOT_MASTER_PORT] + if (port - 1) + out_be32((void *)&srio->atmu.port[port - 1] .outbw[1].rowbar, CONFIG_SYS_SRIO2_MEM_PHYS >> 12); else - out_be32((void *)&srio->atmu - .port[CONFIG_SRIOBOOT_MASTER_PORT] + out_be32((void *)&srio->atmu.port[port - 1] .outbw[1].rowbar, CONFIG_SYS_SRIO1_MEM_PHYS >> 12); - out_be32((void *)&srio->atmu - .port[CONFIG_SRIOBOOT_MASTER_PORT] + out_be32((void *)&srio->atmu.port[port - 1] .outbw[1].rowar, SRIO_OB_ATMU_AR_MAINT | atmu_size_mask(SRIO_MAINT_WIN_SIZE)); @@ -223,27 +189,22 @@ void srio_boot_master_release_slave(void) * configure outbound window * with R/W attribute to set slave's BRR */ - out_be32((void *)&srio->atmu - .port[CONFIG_SRIOBOOT_MASTER_PORT] + out_be32((void *)&srio->atmu.port[port - 1] .outbw[2].rowtar, SRIO_LCSBA1CSR >> 9); - out_be32((void *)&srio->atmu - .port[CONFIG_SRIOBOOT_MASTER_PORT] + out_be32((void *)&srio->atmu.port[port - 1] .outbw[2].rowtear, 0); - if (CONFIG_SRIOBOOT_MASTER_PORT) - out_be32((void *)&srio->atmu - .port[CONFIG_SRIOBOOT_MASTER_PORT] + if (port - 1) + out_be32((void *)&srio->atmu.port[port - 1] .outbw[2].rowbar, (CONFIG_SYS_SRIO2_MEM_PHYS + SRIO_MAINT_WIN_SIZE) >> 12); else - out_be32((void *)&srio->atmu - .port[CONFIG_SRIOBOOT_MASTER_PORT] + out_be32((void *)&srio->atmu.port[port - 1] .outbw[2].rowbar, (CONFIG_SYS_SRIO1_MEM_PHYS + SRIO_MAINT_WIN_SIZE) >> 12); - out_be32((void *)&srio->atmu - .port[CONFIG_SRIOBOOT_MASTER_PORT] + out_be32((void *)&srio->atmu.port[port - 1] .outbw[2].rowar, SRIO_OB_ATMU_AR_RW | atmu_size_mask(SRIO_RW_WIN_SIZE)); @@ -252,7 +213,7 @@ void srio_boot_master_release_slave(void) * Set the LCSBA1CSR register in slave * by the maint-outbound window */ - if (CONFIG_SRIOBOOT_MASTER_PORT) { + if (port - 1) { out_be32((void *)CONFIG_SYS_SRIO2_MEM_VIRT + SRIO_LCSBA1CSR_OFFSET, SRIO_LCSBA1CSR); @@ -266,8 +227,8 @@ void srio_boot_master_release_slave(void) */ out_be32((void *)CONFIG_SYS_SRIO2_MEM_VIRT + SRIO_MAINT_WIN_SIZE - + CONFIG_SRIOBOOT_SLAVE_BRR_OFFSET, - CONFIG_SRIOBOOT_SLAVE_RELEASE_MASK); + + CONFIG_SRIO_PCIE_BOOT_BRR_OFFSET, + CONFIG_SRIO_PCIE_BOOT_RELEASE_MASK); } else { out_be32((void *)CONFIG_SYS_SRIO1_MEM_VIRT + SRIO_LCSBA1CSR_OFFSET, @@ -282,15 +243,13 @@ void srio_boot_master_release_slave(void) */ out_be32((void *)CONFIG_SYS_SRIO1_MEM_VIRT + SRIO_MAINT_WIN_SIZE - + CONFIG_SRIOBOOT_SLAVE_BRR_OFFSET, - CONFIG_SRIOBOOT_SLAVE_RELEASE_MASK); + + CONFIG_SRIO_PCIE_BOOT_BRR_OFFSET, + CONFIG_SRIO_PCIE_BOOT_RELEASE_MASK); } debug("SRIOBOOT - MASTER: " "Release slave successfully! Now the slave should start up!\n"); } } else - debug("SRIOBOOT - MASTER: Port [ %d ] is not ready.\n", - CONFIG_SRIOBOOT_MASTER_PORT); + debug("SRIOBOOT - MASTER: Port [ %d ] is not ready.\n", port); } #endif -#endif diff --git a/arch/powerpc/include/asm/config.h b/arch/powerpc/include/asm/config.h index d1386369395..67cea01aae8 100644 --- a/arch/powerpc/include/asm/config.h +++ b/arch/powerpc/include/asm/config.h @@ -29,6 +29,10 @@ #include <asm/config_mpc86xx.h> #endif +#ifndef HWCONFIG_BUFFER_SIZE + #define HWCONFIG_BUFFER_SIZE 256 +#endif + /* CONFIG_HARD_SPI triggers SPI bus initialization in PowerPC */ #if defined(CONFIG_MPC8XXX_SPI) || defined(CONFIG_FSL_ESPI) # ifndef CONFIG_HARD_SPI diff --git a/arch/powerpc/include/asm/config_mpc85xx.h b/arch/powerpc/include/asm/config_mpc85xx.h index b6c44bb11d1..aa27741a921 100644 --- a/arch/powerpc/include/asm/config_mpc85xx.h +++ b/arch/powerpc/include/asm/config_mpc85xx.h @@ -37,6 +37,7 @@ #if defined(CONFIG_MPC8536) #define CONFIG_MAX_CPUS 1 #define CONFIG_SYS_FSL_NUM_LAWS 12 +#define CONFIG_SYS_PPC_E500_DEBUG_TLB 1 #define CONFIG_SYS_FSL_SEC_COMPAT 2 #define CONFIG_SYS_CCSRBAR_DEFAULT 0xff700000 @@ -54,12 +55,14 @@ #elif defined(CONFIG_MPC8544) #define CONFIG_MAX_CPUS 1 #define CONFIG_SYS_FSL_NUM_LAWS 10 +#define CONFIG_SYS_PPC_E500_DEBUG_TLB 0 #define CONFIG_SYS_FSL_SEC_COMPAT 2 #define CONFIG_SYS_CCSRBAR_DEFAULT 0xff700000 #elif defined(CONFIG_MPC8548) #define CONFIG_MAX_CPUS 1 #define CONFIG_SYS_FSL_NUM_LAWS 10 +#define CONFIG_SYS_PPC_E500_DEBUG_TLB 0 #define CONFIG_SYS_FSL_SEC_COMPAT 2 #define CONFIG_SYS_CCSRBAR_DEFAULT 0xff700000 #define CONFIG_SYS_FSL_ERRATUM_NMG_DDR120 @@ -113,6 +116,7 @@ #elif defined(CONFIG_MPC8572) #define CONFIG_MAX_CPUS 2 #define CONFIG_SYS_FSL_NUM_LAWS 12 +#define CONFIG_SYS_PPC_E500_DEBUG_TLB 2 #define CONFIG_SYS_FSL_SEC_COMPAT 2 #define CONFIG_SYS_CCSRBAR_DEFAULT 0xff700000 #define CONFIG_SYS_FSL_ERRATUM_DDR_115 @@ -191,33 +195,6 @@ #define CONFIG_SYS_FSL_ERRATUM_P1010_A003549 #define CONFIG_SYS_FSL_ERRATUM_IFC_A003399 -/* P1015 is single core version of P1024 */ -#elif defined(CONFIG_P1015) -#define CONFIG_MAX_CPUS 1 -#define CONFIG_SYS_FSL_NUM_LAWS 12 -#define CONFIG_SYS_PPC_E500_DEBUG_TLB 2 -#define CONFIG_TSECV2 -#define CONFIG_FSL_PCIE_DISABLE_ASPM -#define CONFIG_SYS_FSL_SEC_COMPAT 2 -#define CONFIG_SYS_CCSRBAR_DEFAULT 0xff700000 -#define CONFIG_SYS_FSL_ERRATUM_ELBC_A001 -#define CONFIG_SYS_FSL_ERRATUM_ESDHC111 - -/* P1016 is single core version of P1025 */ -#elif defined(CONFIG_P1016) -#define CONFIG_MAX_CPUS 1 -#define CONFIG_SYS_FSL_NUM_LAWS 12 -#define CONFIG_SYS_PPC_E500_DEBUG_TLB 2 -#define CONFIG_TSECV2 -#define CONFIG_FSL_PCIE_DISABLE_ASPM -#define CONFIG_SYS_FSL_SEC_COMPAT 2 -#define CONFIG_SYS_FSL_ERRATUM_ELBC_A001 -#define CONFIG_SYS_FSL_ERRATUM_ESDHC111 -#define QE_MURAM_SIZE 0x6000UL -#define MAX_QE_RISC 1 -#define QE_NUM_OF_SNUM 28 -#define CONFIG_SYS_CCSRBAR_DEFAULT 0xff700000 - /* P1017 is single core version of P1023 */ #elif defined(CONFIG_P1017) #define CONFIG_MAX_CPUS 1 @@ -333,30 +310,7 @@ #define CONFIG_SYS_FSL_RMU #define CONFIG_SYS_FSL_SRIO_MSG_UNIT_NUM 2 -#elif defined(CONFIG_PPC_P2040) -#define CONFIG_MAX_CPUS 4 -#define CONFIG_SYS_FSL_NUM_CC_PLLS 2 -#define CONFIG_SYS_FSL_NUM_LAWS 32 -#define CONFIG_SYS_FSL_SEC_COMPAT 4 -#define CONFIG_SYS_NUM_FMAN 1 -#define CONFIG_SYS_NUM_FM1_DTSEC 5 -#define CONFIG_NUM_DDR_CONTROLLERS 1 -#define CONFIG_SYS_FM_MURAM_SIZE 0x28000 -#define CONFIG_SYS_FSL_TBCLK_DIV 32 -#define CONFIG_SYS_FSL_PCIE_COMPAT "fsl,qoriq-pcie-v2.2" -#define CONFIG_SYS_CCSRBAR_DEFAULT 0xfe000000 -#define CONFIG_SYS_FSL_USB1_PHY_ENABLE -#define CONFIG_SYS_FSL_USB2_PHY_ENABLE -#define CONFIG_SYS_FSL_USB_INTERNAL_UTMI_PHY -#define CONFIG_SYS_FSL_ERRATUM_ESDHC111 -#define CONFIG_SYS_FSL_ERRATUM_NMG_CPU_A011 -#define CONFIG_SYS_FSL_ERRATUM_CPU_A003999 -#define CONFIG_SYS_FSL_ERRATUM_DDR_A003474 -#define CONFIG_SYS_FSL_SRIO_MAX_PORTS 2 -#define CONFIG_SYS_FSL_SRIO_OB_WIN_NUM 9 -#define CONFIG_SYS_FSL_SRIO_IB_WIN_NUM 5 - -#elif defined(CONFIG_PPC_P2041) +#elif defined(CONFIG_PPC_P2041) /* also supports P2040 */ #define CONFIG_MAX_CPUS 4 #define CONFIG_SYS_FSL_NUM_CC_PLLS 2 #define CONFIG_SYS_FSL_NUM_LAWS 32 @@ -380,6 +334,10 @@ #define CONFIG_SYS_FSL_SRIO_MAX_PORTS 2 #define CONFIG_SYS_FSL_SRIO_OB_WIN_NUM 9 #define CONFIG_SYS_FSL_SRIO_IB_WIN_NUM 5 +#define CONFIG_SYS_FSL_ERRATUM_A004510 +#define CONFIG_SYS_FSL_ERRATUM_A004510_SVR_REV 0x10 +#define CONFIG_SYS_FSL_ERRATUM_A004510_SVR_REV2 0x11 +#define CONFIG_SYS_FSL_CORENET_SNOOPVEC_COREONLY 0xf0000000 #elif defined(CONFIG_PPC_P3041) #define CONFIG_MAX_CPUS 4 @@ -399,47 +357,18 @@ #define CONFIG_SYS_FSL_USB2_PHY_ENABLE #define CONFIG_SYS_FSL_USB_INTERNAL_UTMI_PHY #define CONFIG_SYS_FSL_ERRATUM_ESDHC111 +#define CONFIG_SYS_FSL_ERRATUM_NMG_CPU_A011 #define CONFIG_SYS_FSL_ERRATUM_CPU_A003999 #define CONFIG_SYS_FSL_ERRATUM_DDR_A003474 #define CONFIG_SYS_FSL_SRIO_MAX_PORTS 2 #define CONFIG_SYS_FSL_SRIO_OB_WIN_NUM 9 #define CONFIG_SYS_FSL_SRIO_IB_WIN_NUM 5 +#define CONFIG_SYS_FSL_ERRATUM_A004510 +#define CONFIG_SYS_FSL_ERRATUM_A004510_SVR_REV 0x10 +#define CONFIG_SYS_FSL_ERRATUM_A004510_SVR_REV2 0x11 +#define CONFIG_SYS_FSL_CORENET_SNOOPVEC_COREONLY 0xf0000000 -#elif defined(CONFIG_PPC_P3060) -#define CONFIG_MAX_CPUS 8 -#define CONFIG_SYS_FSL_NUM_CC_PLLS 4 -#define CONFIG_SYS_FSL_NUM_LAWS 32 -#define CONFIG_SYS_FSL_SEC_COMPAT 4 -#define CONFIG_SYS_NUM_FMAN 2 -#define CONFIG_SYS_NUM_FM1_DTSEC 4 -#define CONFIG_SYS_NUM_FM2_DTSEC 4 -#define CONFIG_NUM_DDR_CONTROLLERS 1 -#define CONFIG_SYS_FM_MURAM_SIZE 0x28000 -#define CONFIG_SYS_FSL_TBCLK_DIV 16 -#define CONFIG_SYS_FSL_PCIE_COMPAT "fsl,qoriq-pcie-v2.2" -#define CONFIG_SYS_CCSRBAR_DEFAULT 0xfe000000 -#define CONFIG_SYS_FSL_ERRATUM_DDR_A003 -#define CONFIG_SYS_FSL_ERRATUM_CPU_A003999 -#define CONFIG_SYS_FSL_SRIO_MAX_PORTS 2 -#define CONFIG_SYS_FSL_SRIO_OB_WIN_NUM 9 -#define CONFIG_SYS_FSL_SRIO_IB_WIN_NUM 5 - -#elif defined(CONFIG_PPC_P4040) -#define CONFIG_MAX_CPUS 4 -#define CONFIG_SYS_FSL_NUM_CC_PLLS 4 -#define CONFIG_SYS_FSL_NUM_LAWS 32 -#define CONFIG_SYS_FSL_SEC_COMPAT 4 -#define CONFIG_SYS_FM_MURAM_SIZE 0x28000 -#define CONFIG_SYS_FSL_TBCLK_DIV 16 -#define CONFIG_SYS_FSL_PCIE_COMPAT "fsl,p4080-pcie" -#define CONFIG_SYS_CCSRBAR_DEFAULT 0xfe000000 -#define CONFIG_SYS_FSL_ERRATUM_CPU_A003999 -#define CONFIG_SYS_FSL_ERRATUM_DDR_A003474 -#define CONFIG_SYS_FSL_SRIO_MAX_PORTS 2 -#define CONFIG_SYS_FSL_SRIO_OB_WIN_NUM 9 -#define CONFIG_SYS_FSL_SRIO_IB_WIN_NUM 5 - -#elif defined(CONFIG_PPC_P4080) +#elif defined(CONFIG_PPC_P4080) /* also supports P4040 */ #define CONFIG_MAX_CPUS 8 #define CONFIG_SYS_FSL_NUM_CC_PLLS 4 #define CONFIG_SYS_FSL_NUM_LAWS 32 @@ -474,32 +403,11 @@ #define CONFIG_SYS_FSL_SRIO_IB_WIN_NUM 5 #define CONFIG_SYS_FSL_RMU #define CONFIG_SYS_FSL_SRIO_MSG_UNIT_NUM 2 +#define CONFIG_SYS_FSL_ERRATUM_A004510 +#define CONFIG_SYS_FSL_ERRATUM_A004510_SVR_REV 0x20 +#define CONFIG_SYS_FSL_CORENET_SNOOPVEC_COREONLY 0xff000000 -/* P5010 is single core version of P5020 */ -#elif defined(CONFIG_PPC_P5010) -#define CONFIG_MAX_CPUS 1 -#define CONFIG_SYS_FSL_NUM_CC_PLLS 2 -#define CONFIG_SYS_FSL_NUM_LAWS 32 -#define CONFIG_SYS_FSL_SEC_COMPAT 4 -#define CONFIG_FSL_SATA_V2 -#define CONFIG_SYS_NUM_FMAN 1 -#define CONFIG_SYS_NUM_FM1_DTSEC 5 -#define CONFIG_SYS_NUM_FM1_10GEC 1 -#define CONFIG_NUM_DDR_CONTROLLERS 1 -#define CONFIG_SYS_FM_MURAM_SIZE 0x28000 -#define CONFIG_SYS_FSL_TBCLK_DIV 32 -#define CONFIG_SYS_FSL_PCIE_COMPAT "fsl,qoriq-pcie-v2.2" -#define CONFIG_SYS_CCSRBAR_DEFAULT 0xfe000000 -#define CONFIG_SYS_FSL_USB1_PHY_ENABLE -#define CONFIG_SYS_FSL_USB2_PHY_ENABLE -#define CONFIG_SYS_FSL_USB_INTERNAL_UTMI_PHY -#define CONFIG_SYS_FSL_ERRATUM_ESDHC111 -#define CONFIG_SYS_FSL_ERRATUM_DDR_A003474 -#define CONFIG_SYS_FSL_SRIO_MAX_PORTS 2 -#define CONFIG_SYS_FSL_SRIO_OB_WIN_NUM 9 -#define CONFIG_SYS_FSL_SRIO_IB_WIN_NUM 5 - -#elif defined(CONFIG_PPC_P5020) +#elif defined(CONFIG_PPC_P5020) /* also supports P5010 */ #define CONFIG_MAX_CPUS 2 #define CONFIG_SYS_FSL_NUM_CC_PLLS 2 #define CONFIG_SYS_FSL_NUM_LAWS 32 @@ -521,6 +429,9 @@ #define CONFIG_SYS_FSL_SRIO_MAX_PORTS 2 #define CONFIG_SYS_FSL_SRIO_OB_WIN_NUM 9 #define CONFIG_SYS_FSL_SRIO_IB_WIN_NUM 5 +#define CONFIG_SYS_FSL_ERRATUM_A004510 +#define CONFIG_SYS_FSL_ERRATUM_A004510_SVR_REV 0x10 +#define CONFIG_SYS_FSL_CORENET_SNOOPVEC_COREONLY 0xc0000000 #elif defined(CONFIG_BSC9131) #define CONFIG_MAX_CPUS 1 diff --git a/arch/powerpc/include/asm/fsl_ddr_dimm_params.h b/arch/powerpc/include/asm/fsl_ddr_dimm_params.h index 982b8094625..ffe4db8b8aa 100644 --- a/arch/powerpc/include/asm/fsl_ddr_dimm_params.h +++ b/arch/powerpc/include/asm/fsl_ddr_dimm_params.h @@ -43,6 +43,7 @@ typedef struct dimm_params_s { /* DIMM timing parameters */ unsigned int mtb_ps; /* medium timebase ps, only for ddr3 */ + unsigned int ftb_10th_ps; /* fine timebase, in 1/10 ps, only for ddr3 */ unsigned int tAA_ps; /* minimum CAS latency time, only for ddr3 */ unsigned int tFAW_ps; /* four active window delay, only for ddr3 */ diff --git a/arch/powerpc/include/asm/fsl_ddr_sdram.h b/arch/powerpc/include/asm/fsl_ddr_sdram.h index 93639ba8516..e271342f089 100644 --- a/arch/powerpc/include/asm/fsl_ddr_sdram.h +++ b/arch/powerpc/include/asm/fsl_ddr_sdram.h @@ -76,6 +76,13 @@ typedef ddr3_spd_eeprom_t generic_spd_eeprom_t; #define FSL_DDR_PAGE_INTERLEAVING 0x1 #define FSL_DDR_BANK_INTERLEAVING 0x2 #define FSL_DDR_SUPERBANK_INTERLEAVING 0x3 +#define FSL_DDR_3WAY_1KB_INTERLEAVING 0xA +#define FSL_DDR_3WAY_4KB_INTERLEAVING 0xC +#define FSL_DDR_3WAY_8KB_INTERLEAVING 0xD +/* placeholder for 4-way interleaving */ +#define FSL_DDR_4WAY_1KB_INTERLEAVING 0x1A +#define FSL_DDR_4WAY_4KB_INTERLEAVING 0x1C +#define FSL_DDR_4WAY_8KB_INTERLEAVING 0x1D /* DDR_SDRAM_CFG - DDR SDRAM Control Configuration */ @@ -88,6 +95,7 @@ typedef ddr3_spd_eeprom_t generic_spd_eeprom_t; #define SDRAM_CFG_SDRAM_TYPE_MASK 0x07000000 #define SDRAM_CFG_SDRAM_TYPE_SHIFT 24 #define SDRAM_CFG_DYN_PWR 0x00200000 +#define SDRAM_CFG_DBW_MASK 0x00180000 #define SDRAM_CFG_32_BE 0x00080000 #define SDRAM_CFG_16_BE 0x00100000 #define SDRAM_CFG_8_BE 0x00040000 diff --git a/arch/powerpc/include/asm/fsl_ifc.h b/arch/powerpc/include/asm/fsl_ifc.h index 7d95eb4416a..ba41b73cc03 100644 --- a/arch/powerpc/include/asm/fsl_ifc.h +++ b/arch/powerpc/include/asm/fsl_ifc.h @@ -783,12 +783,16 @@ extern void init_early_memctl_regs(void); #define IFC_BASE_ADDR ((struct fsl_ifc *)CONFIG_SYS_IFC_ADDR) +#define get_ifc_cspr_ext(i) (in_be32(&(IFC_BASE_ADDR)->cspr_cs[i].cspr_ext)) #define get_ifc_cspr(i) (in_be32(&(IFC_BASE_ADDR)->cspr_cs[i].cspr)) +#define get_ifc_csor_ext(i) (in_be32(&(IFC_BASE_ADDR)->csor_cs[i].csor_ext)) #define get_ifc_csor(i) (in_be32(&(IFC_BASE_ADDR)->csor_cs[i].csor)) #define get_ifc_amask(i) (in_be32(&(IFC_BASE_ADDR)->amask_cs[i].amask)) #define get_ifc_ftim(i, j) (in_be32(&(IFC_BASE_ADDR)->ftim_cs[i].ftim[j])) +#define set_ifc_cspr_ext(i, v) (out_be32(&(IFC_BASE_ADDR)->cspr_cs[i].cspr_ext, v)) #define set_ifc_cspr(i, v) (out_be32(&(IFC_BASE_ADDR)->cspr_cs[i].cspr, v)) +#define set_ifc_csor_ext(i, v) (out_be32(&(IFC_BASE_ADDR)->csor_cs[i].csor_ext, v)) #define set_ifc_csor(i, v) (out_be32(&(IFC_BASE_ADDR)->csor_cs[i].csor, v)) #define set_ifc_amask(i, v) (out_be32(&(IFC_BASE_ADDR)->amask_cs[i].amask, v)) #define set_ifc_ftim(i, j, v) \ @@ -909,22 +913,24 @@ struct fsl_ifc_gpcm { */ struct fsl_ifc { u32 ifc_rev; - u32 res1[0x3]; + u32 res1[0x2]; struct { + u32 cspr_ext; u32 cspr; - u32 res2[0x2]; + u32 res2; } cspr_cs[FSL_IFC_BANK_COUNT]; - u32 res3[0x18]; + u32 res3[0x19]; struct { u32 amask; u32 res4[0x2]; } amask_cs[FSL_IFC_BANK_COUNT]; - u32 res5[0x18]; + u32 res5[0x17]; struct { + u32 csor_ext; u32 csor; - u32 res6[0x2]; + u32 res6; } csor_cs[FSL_IFC_BANK_COUNT]; - u32 res7[0x18]; + u32 res7[0x19]; struct { u32 ftim[4]; u32 res8[0x8]; diff --git a/arch/powerpc/include/asm/fsl_law.h b/arch/powerpc/include/asm/fsl_law.h index 13caffd96e2..f9cec8ea441 100644 --- a/arch/powerpc/include/asm/fsl_law.h +++ b/arch/powerpc/include/asm/fsl_law.h @@ -60,14 +60,19 @@ enum law_trgt_if { LAW_TRGT_IF_DDR_1 = 0x10, LAW_TRGT_IF_DDR_2 = 0x11, /* 2nd controller */ + LAW_TRGT_IF_DDR_3 = 0x12, + LAW_TRGT_IF_DDR_4 = 0x13, LAW_TRGT_IF_DDR_INTRLV = 0x14, - + LAW_TRGT_IF_DDR_INTLV_34 = 0x15, + LAW_TRGT_IF_DDR_INTLV_123 = 0x17, + LAW_TRGT_IF_DDR_INTLV_1234 = 0x16, LAW_TRGT_IF_BMAN = 0x18, LAW_TRGT_IF_DCSR = 0x1d, LAW_TRGT_IF_LBC = 0x1f, LAW_TRGT_IF_QMAN = 0x3c, }; #define LAW_TRGT_IF_DDR LAW_TRGT_IF_DDR_1 +#define LAW_TRGT_IF_IFC LAW_TRGT_IF_LBC #else enum law_trgt_if { LAW_TRGT_IF_PCI = 0x00, @@ -86,6 +91,12 @@ enum law_trgt_if { LAW_TRGT_IF_DPAA_SWP_SRAM = 0x0e, LAW_TRGT_IF_DDR = 0x0f, LAW_TRGT_IF_DDR_2 = 0x16, /* 2nd controller */ + /* place holder for 3-way and 4-way interleaving */ + LAW_TRGT_IF_DDR_3, + LAW_TRGT_IF_DDR_4, + LAW_TRGT_IF_DDR_INTLV_34, + LAW_TRGT_IF_DDR_INTLV_123, + LAW_TRGT_IF_DDR_INTLV_1234, }; #define LAW_TRGT_IF_DDR_1 LAW_TRGT_IF_DDR #define LAW_TRGT_IF_PCI_1 LAW_TRGT_IF_PCI diff --git a/arch/powerpc/include/asm/fsl_serdes.h b/arch/powerpc/include/asm/fsl_serdes.h index 0f31af1db32..22525f11561 100644 --- a/arch/powerpc/include/asm/fsl_serdes.h +++ b/arch/powerpc/include/asm/fsl_serdes.h @@ -41,6 +41,7 @@ enum srds_prtcl { SGMII_FM2_DTSEC2, SGMII_FM2_DTSEC3, SGMII_FM2_DTSEC4, + SGMII_FM2_DTSEC5, SGMII_TSEC1, SGMII_TSEC2, SGMII_TSEC3, diff --git a/arch/powerpc/include/asm/fsl_srio.h b/arch/powerpc/include/asm/fsl_srio.h index a905a266c4d..dfd8e08f3ed 100644 --- a/arch/powerpc/include/asm/fsl_srio.h +++ b/arch/powerpc/include/asm/fsl_srio.h @@ -55,10 +55,8 @@ enum atmu_size { #define atmu_size_bytes(x) (1ULL << ((x & 0x3f) + 1)) extern void srio_init(void); -#ifdef CONFIG_SRIOBOOT_MASTER -extern void srio_boot_master(void); -#ifdef CONFIG_SRIOBOOT_SLAVE_HOLDOFF -extern void srio_boot_master_release_slave(void); -#endif +#ifdef CONFIG_FSL_CORENET +extern void srio_boot_master(int port); +extern void srio_boot_master_release_slave(int port); #endif #endif diff --git a/arch/powerpc/include/asm/immap_85xx.h b/arch/powerpc/include/asm/immap_85xx.h index 53d563ed0a0..7de33a7dded 100644 --- a/arch/powerpc/include/asm/immap_85xx.h +++ b/arch/powerpc/include/asm/immap_85xx.h @@ -1729,6 +1729,7 @@ typedef struct ccsr_gur { #define FSL_CORENET_DEVDISR2_DTSEC2_2 0x00004000 #define FSL_CORENET_DEVDISR2_DTSEC2_3 0x00002000 #define FSL_CORENET_DEVDISR2_DTSEC2_4 0x00001000 +#define FSL_CORENET_DEVDISR2_DTSEC2_5 0x00000800 #define FSL_CORENET_NUM_DEVDISR 2 u8 res7[8]; u32 powmgtcsr; /* Power management status & control */ @@ -1758,13 +1759,14 @@ typedef struct ccsr_gur { #define FSL_CORENET_RCWSR5_DDR_SYNC 0x00000080 #define FSL_CORENET_RCWSR5_DDR_SYNC_SHIFT 7 #define FSL_CORENET_RCWSR5_SRDS_EN 0x00002000 +#define FSL_CORENET_RCWSR6_BOOT_LOC 0x0f800000 #define FSL_CORENET_RCWSRn_SRDS_LPD_B2 0x3c000000 /* bits 162..165 */ #define FSL_CORENET_RCWSRn_SRDS_LPD_B3 0x003c0000 /* bits 170..173 */ #define FSL_CORENET_RCWSR7_MCK_TO_PLAT_RAT 0x00400000 #define FSL_CORENET_RCWSR8_HOST_AGT_B1 0x00e00000 #define FSL_CORENET_RCWSR8_HOST_AGT_B2 0x00100000 #define FSL_CORENET_RCWSR11_EC1 0x00c00000 /* bits 360..361 */ -#if defined(CONFIG_PPC_P4080) || defined(CONFIG_PPC_P3060) +#ifdef CONFIG_PPC_P4080 #define FSL_CORENET_RCWSR11_EC1_FM1_DTSEC1 0x00000000 #define FSL_CORENET_RCWSR11_EC1_FM1_USB1 0x00800000 #define FSL_CORENET_RCWSR11_EC2 0x001c0000 /* bits 363..365 */ @@ -1772,7 +1774,7 @@ typedef struct ccsr_gur { #define FSL_CORENET_RCWSR11_EC2_FM1_DTSEC2 0x00080000 #define FSL_CORENET_RCWSR11_EC2_USB2 0x00100000 #endif -#if defined(CONFIG_PPC_P2040) || defined(CONFIG_PPC_P2041) \ +#if defined(CONFIG_PPC_P2041) \ || defined(CONFIG_PPC_P3041) || defined(CONFIG_PPC_P5020) #define FSL_CORENET_RCWSR11_EC1_FM1_DTSEC4_RGMII 0x00000000 #define FSL_CORENET_RCWSR11_EC1_FM1_DTSEC4_MII 0x00800000 @@ -1836,7 +1838,13 @@ typedef struct ccsr_gur { u8 res31[184]; u32 sriopstecr; /* SRIO prescaler timer enable control */ u32 dcsrcr; /* DCSR Control register */ - u8 res32[1784]; + u8 res31a[56]; + u32 tp_ityp[64]; /* Topology Initiator Type Register */ + struct { + u32 upper; + u32 lower; + } tp_cluster[16]; /* Core Cluster n Topology Register */ + u8 res32[1344]; u32 pmuxcr; /* Pin multiplexing control */ u8 res33[60]; u32 iovselsr; /* I/O voltage selection status */ @@ -1849,6 +1857,18 @@ typedef struct ccsr_gur { u8 res37[380]; } ccsr_gur_t; +#define TP_ITYP_AV 0x00000001 /* Initiator available */ +#define TP_ITYP_TYPE(x) (((x) & 0x6) >> 1) /* Initiator Type */ +#define TP_ITYP_TYPE_OTHER 0x0 +#define TP_ITYP_TYPE_PPC 0x1 /* PowerPC */ +#define TP_ITYP_TYPE_SC 0x2 /* StarCore DSP */ +#define TP_ITYP_TYPE_HA 0x3 /* HW Accelerator */ +#define TP_ITYP_THDS(x) (((x) & 0x18) >> 3) /* # threads */ +#define TP_ITYP_VER(x) (((x) & 0xe0) >> 5) /* Initiator Version */ + +#define TP_CLUSTER_EOC 0x80000000 /* end of clusters */ +#define TP_CLUSTER_INIT_MASK 0x0000003f /* initiator mask */ + #define FSL_CORENET_DCSR_SZ_MASK 0x00000003 #define FSL_CORENET_DCSR_SZ_4M 0x0 #define FSL_CORENET_DCSR_SZ_1G 0x3 @@ -1890,6 +1910,73 @@ typedef struct ccsr_clk { u8 res15[0x3dc]; } ccsr_clk_t; +#ifdef CONFIG_SYS_FSL_QORIQ_CHASSIS2 +typedef struct ccsr_rcpm { + u8 res_00[12]; + u32 tph10sr0; /* Thread PH10 Status Register */ + u8 res_10[12]; + u32 tph10setr0; /* Thread PH10 Set Control Register */ + u8 res_20[12]; + u32 tph10clrr0; /* Thread PH10 Clear Control Register */ + u8 res_30[12]; + u32 tph10psr0; /* Thread PH10 Previous Status Register */ + u8 res_40[12]; + u32 twaitsr0; /* Thread Wait Status Register */ + u8 res_50[96]; + u32 pcph15sr; /* Physical Core PH15 Status Register */ + u32 pcph15setr; /* Physical Core PH15 Set Control Register */ + u32 pcph15clrr; /* Physical Core PH15 Clear Control Register */ + u32 pcph15psr; /* Physical Core PH15 Prev Status Register */ + u8 res_c0[16]; + u32 pcph20sr; /* Physical Core PH20 Status Register */ + u32 pcph20setr; /* Physical Core PH20 Set Control Register */ + u32 pcph20clrr; /* Physical Core PH20 Clear Control Register */ + u32 pcph20psr; /* Physical Core PH20 Prev Status Register */ + u32 pcpw20sr; /* Physical Core PW20 Status Register */ + u8 res_e0[12]; + u32 pcph30sr; /* Physical Core PH30 Status Register */ + u32 pcph30setr; /* Physical Core PH30 Set Control Register */ + u32 pcph30clrr; /* Physical Core PH30 Clear Control Register */ + u32 pcph30psr; /* Physical Core PH30 Prev Status Register */ + u8 res_100[32]; + u32 ippwrgatecr; /* IP Power Gating Control Register */ + u8 res_124[12]; + u32 powmgtcsr; /* Power Management Control & Status Reg */ + u8 res_134[12]; + u32 ippdexpcr[4]; /* IP Powerdown Exception Control Reg */ + u8 res_150[12]; + u32 tpmimr0; /* Thread PM Interrupt Mask Reg */ + u8 res_160[12]; + u32 tpmcimr0; /* Thread PM Crit Interrupt Mask Reg */ + u8 res_170[12]; + u32 tpmmcmr0; /* Thread PM Machine Check Interrupt Mask Reg */ + u8 res_180[12]; + u32 tpmnmimr0; /* Thread PM NMI Mask Reg */ + u8 res_190[12]; + u32 tmcpmaskcr0; /* Thread Machine Check Mask Control Reg */ + u32 pctbenr; /* Physical Core Time Base Enable Reg */ + u32 pctbclkselr; /* Physical Core Time Base Clock Select */ + u32 tbclkdivr; /* Time Base Clock Divider Register */ + u8 res_1ac[4]; + u32 ttbhltcr[4]; /* Thread Time Base Halt Control Register */ + u32 clpcl10sr; /* Cluster PCL10 Status Register */ + u32 clpcl10setr; /* Cluster PCL30 Set Control Register */ + u32 clpcl10clrr; /* Cluster PCL30 Clear Control Register */ + u32 clpcl10psr; /* Cluster PCL30 Prev Status Register */ + u32 cddslpsetr; /* Core Domain Deep Sleep Set Register */ + u32 cddslpclrr; /* Core Domain Deep Sleep Clear Register */ + u32 cdpwroksetr; /* Core Domain Power OK Set Register */ + u32 cdpwrokclrr; /* Core Domain Power OK Clear Register */ + u32 cdpwrensr; /* Core Domain Power Enable Status Register */ + u32 cddslsr; /* Core Domain Deep Sleep Status Register */ + u8 res_1e8[8]; + u32 dslpcntcr[8]; /* Deep Sleep Counter Cfg Register */ + u8 res_300[3568]; +} ccsr_rcpm_t; + +#define ctbenrl pctbenr + +#else typedef struct ccsr_rcpm { u8 res1[4]; u32 cdozsrl; /* Core Doze Status */ @@ -1926,6 +2013,7 @@ typedef struct ccsr_rcpm { u32 ctbhltcrl; /* Core Time Base Halt Control */ u8 res18[0xf68]; } ccsr_rcpm_t; +#endif /* CONFIG_SYS_FSL_QORIQ_CHASSIS2 */ #else typedef struct ccsr_gur { @@ -2259,8 +2347,7 @@ typedef struct ccsr_gur { u8 res11a[76]; par_io_t qe_par_io[7]; u8 res11b[1600]; -#elif defined(CONFIG_P1012) || defined(CONFIG_P1016) || \ - defined(CONFIG_P1021) || defined(CONFIG_P1025) +#elif defined(CONFIG_P1012) || defined(CONFIG_P1021) || defined(CONFIG_P1025) u8 res11a[12]; u32 iovselsr; u8 res11b[60]; @@ -2534,6 +2621,7 @@ struct ccsr_rman { #define CONFIG_SYS_FSL_CORENET_CCM_OFFSET 0x0000 #define CONFIG_SYS_MPC85xx_DDR_OFFSET 0x8000 #define CONFIG_SYS_MPC85xx_DDR2_OFFSET 0x9000 +#define CONFIG_SYS_MPC85xx_DDR3_OFFSET 0xA000 #define CONFIG_SYS_FSL_CORENET_CLK_OFFSET 0xE1000 #define CONFIG_SYS_FSL_CORENET_RCPM_OFFSET 0xE2000 #define CONFIG_SYS_FSL_CORENET_SERDES_OFFSET 0xEA000 @@ -2544,6 +2632,7 @@ struct ccsr_rman { #define CONFIG_SYS_MPC85xx_ESPI_OFFSET 0x110000 #define CONFIG_SYS_MPC85xx_ESDHC_OFFSET 0x114000 #define CONFIG_SYS_MPC85xx_LBC_OFFSET 0x124000 +#define CONFIG_SYS_MPC85xx_IFC_OFFSET 0x124000 #define CONFIG_SYS_MPC85xx_GPIO_OFFSET 0x130000 #define CONFIG_SYS_FSL_CORENET_RMAN_OFFSET 0x1e0000 #define CONFIG_SYS_MPC85xx_PCIE1_OFFSET 0x200000 @@ -2652,6 +2741,8 @@ struct ccsr_rman { (CONFIG_SYS_IMMR + CONFIG_SYS_MPC85xx_DDR_OFFSET) #define CONFIG_SYS_MPC85xx_DDR2_ADDR \ (CONFIG_SYS_IMMR + CONFIG_SYS_MPC85xx_DDR2_OFFSET) +#define CONFIG_SYS_MPC85xx_DDR3_ADDR \ + (CONFIG_SYS_IMMR + CONFIG_SYS_MPC85xx_DDR3_OFFSET) #define CONFIG_SYS_LBC_ADDR \ (CONFIG_SYS_IMMR + CONFIG_SYS_MPC85xx_LBC_OFFSET) #define CONFIG_SYS_IFC_ADDR \ diff --git a/arch/powerpc/include/asm/io.h b/arch/powerpc/include/asm/io.h index ec0bfaee991..9e208618d94 100644 --- a/arch/powerpc/include/asm/io.h +++ b/arch/powerpc/include/asm/io.h @@ -162,7 +162,7 @@ static inline void __raw_writel(unsigned int v, volatile void __iomem *addr) * is actually performed (i.e. the data has come back) before we start * executing any following instructions. */ -static inline u8 in_8(const volatile unsigned char __iomem *addr) +extern inline u8 in_8(const volatile unsigned char __iomem *addr) { u8 ret; @@ -173,7 +173,7 @@ static inline u8 in_8(const volatile unsigned char __iomem *addr) return ret; } -static inline void out_8(volatile unsigned char __iomem *addr, u8 val) +extern inline void out_8(volatile unsigned char __iomem *addr, u8 val) { __asm__ __volatile__("sync;\n" "stb%U0%X0 %1,%0;\n" @@ -181,7 +181,7 @@ static inline void out_8(volatile unsigned char __iomem *addr, u8 val) : "r" (val)); } -static inline u16 in_le16(const volatile unsigned short __iomem *addr) +extern inline u16 in_le16(const volatile unsigned short __iomem *addr) { u16 ret; @@ -192,7 +192,7 @@ static inline u16 in_le16(const volatile unsigned short __iomem *addr) return ret; } -static inline u16 in_be16(const volatile unsigned short __iomem *addr) +extern inline u16 in_be16(const volatile unsigned short __iomem *addr) { u16 ret; @@ -202,18 +202,18 @@ static inline u16 in_be16(const volatile unsigned short __iomem *addr) return ret; } -static inline void out_le16(volatile unsigned short __iomem *addr, u16 val) +extern inline void out_le16(volatile unsigned short __iomem *addr, u16 val) { __asm__ __volatile__("sync; sthbrx %1,0,%2" : "=m" (*addr) : "r" (val), "r" (addr)); } -static inline void out_be16(volatile unsigned short __iomem *addr, u16 val) +extern inline void out_be16(volatile unsigned short __iomem *addr, u16 val) { __asm__ __volatile__("sync; sth%U0%X0 %1,%0" : "=m" (*addr) : "r" (val)); } -static inline u32 in_le32(const volatile unsigned __iomem *addr) +extern inline u32 in_le32(const volatile unsigned __iomem *addr) { u32 ret; @@ -224,7 +224,7 @@ static inline u32 in_le32(const volatile unsigned __iomem *addr) return ret; } -static inline u32 in_be32(const volatile unsigned __iomem *addr) +extern inline u32 in_be32(const volatile unsigned __iomem *addr) { u32 ret; @@ -234,13 +234,13 @@ static inline u32 in_be32(const volatile unsigned __iomem *addr) return ret; } -static inline void out_le32(volatile unsigned __iomem *addr, u32 val) +extern inline void out_le32(volatile unsigned __iomem *addr, u32 val) { __asm__ __volatile__("sync; stwbrx %1,0,%2" : "=m" (*addr) : "r" (val), "r" (addr)); } -static inline void out_be32(volatile unsigned __iomem *addr, u32 val) +extern inline void out_be32(volatile unsigned __iomem *addr, u32 val) { __asm__ __volatile__("sync; stw%U0%X0 %1,%0" : "=m" (*addr) : "r" (val)); } diff --git a/arch/powerpc/include/asm/mmu.h b/arch/powerpc/include/asm/mmu.h index 209103e3ce1..2e0e292da05 100644 --- a/arch/powerpc/include/asm/mmu.h +++ b/arch/powerpc/include/asm/mmu.h @@ -475,6 +475,10 @@ extern void print_bats(void); #define BOOKE_PAGESZ_256GB 14 #define BOOKE_PAGESZ_1TB 15 +#define TLBIVAX_ALL 4 +#define TLBIVAX_TLB0 0 +#define TLBIVAX_TLB1 8 + #ifdef CONFIG_E500 #ifndef __ASSEMBLY__ extern void set_tlb(u8 tlb, u32 epn, u64 rpn, diff --git a/arch/powerpc/include/asm/mp.h b/arch/powerpc/include/asm/mp.h index 3ffa30b9789..fe490bac05a 100644 --- a/arch/powerpc/include/asm/mp.h +++ b/arch/powerpc/include/asm/mp.h @@ -28,4 +28,10 @@ void cpu_mp_lmb_reserve(struct lmb *lmb); u32 determine_mp_bootpg(void); int is_core_disabled(int nr); +#ifdef CONFIG_E6500 +#define thread_to_core(x) (x >> 1) +#else +#define thread_to_core(x) (x) +#endif + #endif diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h index dc009d66046..36695e2fb6d 100644 --- a/arch/powerpc/include/asm/processor.h +++ b/arch/powerpc/include/asm/processor.h @@ -486,11 +486,13 @@ #define SPRN_L2CFG0 0x207 /* L2 Cache Configuration Register 0 */ #define SPRN_L1CSR0 0x3f2 /* L1 Data Cache Control and Status Register 0 */ #define L1CSR0_CPE 0x00010000 /* Data Cache Parity Enable */ +#define L1CSR0_CUL 0x00000400 /* (D-)Cache Unable to Lock */ #define L1CSR0_DCLFR 0x00000100 /* D-Cache Lock Flash Reset */ #define L1CSR0_DCFI 0x00000002 /* Data Cache Flash Invalidate */ #define L1CSR0_DCE 0x00000001 /* Data Cache Enable */ #define SPRN_L1CSR1 0x3f3 /* L1 Instruction Cache Control and Status Register 1 */ #define L1CSR1_CPE 0x00010000 /* Instruction Cache Parity Enable */ +#define L1CSR1_ICUL 0x00000400 /* I-Cache Unable to Lock */ #define L1CSR1_ICLFR 0x00000100 /* I-Cache Lock Flash Reset */ #define L1CSR1_ICFI 0x00000002 /* Instruction Cache Flash Invalidate */ #define L1CSR1_ICE 0x00000001 /* Instruction Cache Enable */ @@ -513,6 +515,7 @@ #define SPRN_TLB0CFG 0x2B0 /* TLB 0 Config Register */ #define SPRN_TLB1CFG 0x2B1 /* TLB 1 Config Register */ +#define TLBnCFG_NENTRY_MASK 0x00000fff #define SPRN_TLB0PS 0x158 /* TLB 0 Page Size Register */ #define SPRN_TLB1PS 0x159 /* TLB 1 Page Size Register */ #define SPRN_MMUCSR0 0x3f4 /* MMU control and status register 0 */ @@ -948,6 +951,7 @@ #define PVR_VER_E500_V2 0x8021 #define PVR_VER_E500MC 0x8023 #define PVR_VER_E5500 0x8024 +#define PVR_VER_E6500 0x8040 #define PVR_86xx 0x80040000 @@ -1075,8 +1079,6 @@ #define SVR_P1012 0x80E501 #define SVR_P1013 0x80E700 #define SVR_P1014 0x80F101 -#define SVR_P1015 0x80E502 -#define SVR_P1016 0x80E503 #define SVR_P1017 0x80F700 #define SVR_P1020 0x80E400 #define SVR_P1021 0x80E401 @@ -1089,7 +1091,6 @@ #define SVR_P2040 0x821000 #define SVR_P2041 0x821001 #define SVR_P3041 0x821103 -#define SVR_P3060 0x820002 #define SVR_P4040 0x820100 #define SVR_P4080 0x820000 #define SVR_P5010 0x822100 @@ -1158,6 +1159,7 @@ struct cpu_type { }; struct cpu_type *identify_cpu(u32 ver); +int fixup_cpu(void); #if defined(CONFIG_MPC85xx) || defined(CONFIG_MPC86xx) #define CPU_TYPE_ENTRY(n, v, nc) \ diff --git a/arch/powerpc/lib/board.c b/arch/powerpc/lib/board.c index fea310eedd1..07feaf55fc2 100644 --- a/arch/powerpc/lib/board.c +++ b/arch/powerpc/lib/board.c @@ -345,6 +345,13 @@ ulong get_effective_memsize(void) #endif } +int __fixup_cpu(void) +{ + return 0; +} + +int fixup_cpu(void) __attribute__((weak, alias("__fixup_cpu"))); + /* * This is the first part of the initialization sequence that is * implemented in C, but still running from ROM. @@ -521,9 +528,8 @@ void board_init_f(ulong bootflag) addr_sp -= 16; addr_sp &= ~0xF; s = (ulong *) addr_sp; - *s-- = 0; - *s-- = 0; - addr_sp = (ulong) s; + *s = 0; /* Terminate back chain */ + *++s = 0; /* NULL return address */ debug("Stack Pointer at: %08lx\n", addr_sp); /* @@ -647,6 +653,12 @@ void board_init_r(gd_t *id, ulong dest_addr) * We need to update it to point to the same CPU entry in RAM. */ gd->cpu += dest_addr - CONFIG_SYS_MONITOR_BASE; + + /* + * If we didn't know the cpu mask & # cores, we can save them of + * now rather than 'computing' them constantly + */ + fixup_cpu(); #endif #ifdef CONFIG_SYS_EXTRA_ENV_RELOC diff --git a/arch/sparc/lib/board.c b/arch/sparc/lib/board.c index 6f33666265e..ff0e0f2fd04 100644 --- a/arch/sparc/lib/board.c +++ b/arch/sparc/lib/board.c @@ -62,7 +62,6 @@ DECLARE_GLOBAL_DATA_PTR; */ extern void timer_interrupt_init(void); -extern void malloc_bin_reloc(void); extern int do_ambapp_print(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]); extern int prom_init(void); |