From 74c5dfd81f94a2a1f0d6990d17c491d718e8b9ea Mon Sep 17 00:00:00 2001 From: Timur Tabi Date: Fri, 4 Sep 2009 17:05:24 -0500 Subject: fsl: add register read-back to set_law() After programming a new LAW, we should read-back the LAWAR register so that we sync the writes. Otherwise, code that attempts to use the new LAW-mapped memory might fail right away. Signed-off-by: Timur Tabi Signed-off-by: Kumar Gala --- drivers/misc/fsl_law.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/misc/fsl_law.c') diff --git a/drivers/misc/fsl_law.c b/drivers/misc/fsl_law.c index 147fe0a21c..7bdd355c74 100644 --- a/drivers/misc/fsl_law.c +++ b/drivers/misc/fsl_law.c @@ -58,7 +58,8 @@ void set_law(u8 idx, phys_addr_t addr, enum law_size sz, enum law_trgt_if id) out_be32(lawbar, addr >> 12); out_be32(lawar, LAWAR_EN | ((u32)id << 20) | (u32)sz); - return ; + /* Read back so that we sync the writes */ + in_be32(lawar); } int set_next_law(phys_addr_t addr, enum law_size sz, enum law_trgt_if id) -- cgit From 7da53351d817c6d77364cfde922891f37d0e5ed8 Mon Sep 17 00:00:00 2001 From: Mingkai Hu Date: Fri, 11 Sep 2009 14:19:10 +0800 Subject: ppc/85xx: add boot from NAND/eSDHC/eSPI support The MPC8536E is capable of booting form NAND/eSDHC/eSPI, this patch implements these three bootup methods in a unified way - all of these use the general cpu/mpc85xx/start.S, and load the main image to L2SRAM which lets us use the SPD to initialize the SDRAM. For all three bootup methods, the bootup process can be divided into two stages: the first stage will initialize the corresponding controller, configure the L2SRAM, then copy the second stage image to L2SRAM and jump to it. The second stage image is just like the general U-Boot image to configure all the hardware and boot up to U-Boot command line. When boot from NAND, the eLBC controller will first load the first stage image to internal 4K RAM buffer because it's also stored on the NAND flash. The first stage image, also call 4K NAND loader, will initialize the L2SRAM, load the second stage image to L2SRAM and jump to it. The 4K NAND loader's code comes from the corresponding nand_spl directory, along with the code twisted by CONFIG_NAND_SPL. When boot from eSDHC/eSPI, there's no such a first stage image because the CPU ROM code does the same work. It will initialize the L2SRAM according to the config addr/word pairs on the fixed address and initialize the eSDHC/eSPI controller, then load the second stage image to L2SRAM and jump to it. The macro CONFIG_SYS_RAMBOOT is used to control the code to produce the second stage image for all different bootup methods. It's set in the board config file when one of the bootup methods above is selected. Signed-off-by: Mingkai Hu Signed-off-by: Kumar Gala --- drivers/misc/fsl_law.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/misc/fsl_law.c') diff --git a/drivers/misc/fsl_law.c b/drivers/misc/fsl_law.c index 7bdd355c74..aa877c65fd 100644 --- a/drivers/misc/fsl_law.c +++ b/drivers/misc/fsl_law.c @@ -74,6 +74,7 @@ int set_next_law(phys_addr_t addr, enum law_size sz, enum law_trgt_if id) return idx; } +#ifndef CONFIG_NAND_SPL int set_last_law(phys_addr_t addr, enum law_size sz, enum law_trgt_if id) { u32 idx; @@ -166,6 +167,7 @@ int set_ddr_laws(u64 start, u64 sz, enum law_trgt_if id) return 0; } +#endif void init_laws(void) { -- cgit From 418ec8584343f04048e2cc7ee96b6b29be54ad97 Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Thu, 19 Mar 2009 02:32:23 -0500 Subject: ppc/p4080: Add support for CoreNet style platform LAWs On CoreNet based platforms the LAW address is split between an high & low register and we no longer shift the address. Also, the target IDs on CoreNet platforms have been completely re-assigned. Additionally, added a new find_law() API to which LAW an address hits in. This is need for the CoreNet style boot release code since it will need to determine what the target ID should be set to for boot window translation. Finally, enamed LAWAR_EN to LAW_EN and moved to header so we can use it elsewhere. Signed-off-by: Kumar Gala --- drivers/misc/fsl_law.c | 126 ++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 115 insertions(+), 11 deletions(-) (limited to 'drivers/misc/fsl_law.c') diff --git a/drivers/misc/fsl_law.c b/drivers/misc/fsl_law.c index aa877c65fd..7c59c887f1 100644 --- a/drivers/misc/fsl_law.c +++ b/drivers/misc/fsl_law.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Freescale Semiconductor, Inc. + * Copyright 2008-2009 Freescale Semiconductor, Inc. * * (C) Copyright 2000 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. @@ -29,7 +29,6 @@ DECLARE_GLOBAL_DATA_PTR; -#define LAWAR_EN 0x80000000 /* number of LAWs in the hw implementation */ #if defined(CONFIG_MPC8540) || defined(CONFIG_MPC8541) || \ defined(CONFIG_MPC8560) || defined(CONFIG_MPC8555) @@ -46,6 +45,56 @@ DECLARE_GLOBAL_DATA_PTR; #error FSL_HW_NUM_LAWS not defined for this platform #endif +#ifdef CONFIG_FSL_CORENET +void set_law(u8 idx, phys_addr_t addr, enum law_size sz, enum law_trgt_if id) +{ + volatile ccsr_local_t *ccm = (void *)(CONFIG_SYS_FSL_CORENET_CCM_ADDR); + + gd->used_laws |= (1 << idx); + + out_be32(&ccm->law[idx].lawar, 0); + out_be32(&ccm->law[idx].lawbarh, ((u64)addr >> 32)); + out_be32(&ccm->law[idx].lawbarl, addr & 0xffffffff); + out_be32(&ccm->law[idx].lawar, LAW_EN | ((u32)id << 20) | (u32)sz); + + /* Read back so that we sync the writes */ + in_be32(&ccm->law[idx].lawar); +} + +void disable_law(u8 idx) +{ + volatile ccsr_local_t *ccm = (void *)(CONFIG_SYS_FSL_CORENET_CCM_ADDR); + + gd->used_laws &= ~(1 << idx); + + out_be32(&ccm->law[idx].lawar, 0); + out_be32(&ccm->law[idx].lawbarh, 0); + out_be32(&ccm->law[idx].lawbarl, 0); + + /* Read back so that we sync the writes */ + in_be32(&ccm->law[idx].lawar); + + return; +} + +static int get_law_entry(u8 i, struct law_entry *e) +{ + volatile ccsr_local_t *ccm = (void *)(CONFIG_SYS_FSL_CORENET_CCM_ADDR); + u32 lawar; + + lawar = in_be32(&ccm->law[i].lawar); + + if (!(lawar & LAW_EN)) + return 0; + + e->addr = ((u64)in_be32(&ccm->law[i].lawbarh) << 32) | + in_be32(&ccm->law[i].lawbarl); + e->size = lawar & 0x3f; + e->trgt_id = (lawar >> 20) & 0xff; + + return 1; +} +#else void set_law(u8 idx, phys_addr_t addr, enum law_size sz, enum law_trgt_if id) { volatile u32 *base = (volatile u32 *)(CONFIG_SYS_IMMR + 0xc08); @@ -56,12 +105,49 @@ void set_law(u8 idx, phys_addr_t addr, enum law_size sz, enum law_trgt_if id) out_be32(lawar, 0); out_be32(lawbar, addr >> 12); - out_be32(lawar, LAWAR_EN | ((u32)id << 20) | (u32)sz); + out_be32(lawar, LAW_EN | ((u32)id << 20) | (u32)sz); /* Read back so that we sync the writes */ in_be32(lawar); } +void disable_law(u8 idx) +{ + volatile u32 *base = (volatile u32 *)(CONFIG_SYS_IMMR + 0xc08); + volatile u32 *lawbar = base + 8 * idx; + volatile u32 *lawar = base + 8 * idx + 2; + + gd->used_laws &= ~(1 << idx); + + out_be32(lawar, 0); + out_be32(lawbar, 0); + + /* Read back so that we sync the writes */ + in_be32(lawar); + + return; +} + +static int get_law_entry(u8 i, struct law_entry *e) +{ + volatile u32 *base = (volatile u32 *)(CONFIG_SYS_IMMR + 0xc08); + volatile u32 *lawbar = base + 8 * i; + volatile u32 *lawar = base + 8 * i + 2; + u32 temp; + + temp = in_be32(lawar); + + if (!(temp & LAW_EN)) + return 0; + + e->addr = (u64)in_be32(lawbar) << 12; + e->size = temp & 0x3f; + e->trgt_id = (temp >> 20) & 0xff; + + return 1; +} +#endif + int set_next_law(phys_addr_t addr, enum law_size sz, enum law_trgt_if id) { u32 idx = ffz(gd->used_laws); @@ -94,18 +180,30 @@ int set_last_law(phys_addr_t addr, enum law_size sz, enum law_trgt_if id) return idx; } -void disable_law(u8 idx) +struct law_entry find_law(phys_addr_t addr) { - volatile u32 *base = (volatile u32 *)(CONFIG_SYS_IMMR + 0xc08); - volatile u32 *lawbar = base + 8 * idx; - volatile u32 *lawar = base + 8 * idx + 2; + struct law_entry entry; + int i; - gd->used_laws &= ~(1 << idx); + entry.index = -1; + entry.addr = 0; + entry.size = 0; + entry.trgt_id = 0; - out_be32(lawar, 0); - out_be32(lawbar, 0); + for (i = 0; i < FSL_HW_NUM_LAWS; i++) { + u64 upper; - return; + if (!get_law_entry(i, &entry)) + continue; + + upper = entry.addr + (2ull << entry.size); + if ((addr >= entry.addr) && (addr < upper)) { + entry.index = i; + break; + } + } + + return entry; } void print_laws(void) @@ -173,7 +271,13 @@ void init_laws(void) { int i; +#if FSL_HW_NUM_LAWS < 32 gd->used_laws = ~((1 << FSL_HW_NUM_LAWS) - 1); +#elif FSL_HW_NUM_LAWS == 32 + gd->used_laws = 0; +#else +#error FSL_HW_NUM_LAWS can not be greater than 32 w/o code changes +#endif for (i = 0; i < num_law_entries; i++) { if (law_table[i].index == -1) -- cgit From 7e4259bba4c56536760e42d32dacfb3233f216fd Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Thu, 19 Mar 2009 02:39:17 -0500 Subject: ppc/p4080: Add various p4080 related defines (and p4040) There are various locations that we have chip specific info: * Makefile for which ddr code to build * Added p4080 & p4040 to cpu_type_list and SVR list * Added number of LAWs for p4080 * Set CONFIG_MAX_CPUS to 8 for p4080 Signed-off-by: Kumar Gala --- drivers/misc/fsl_law.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/misc/fsl_law.c') diff --git a/drivers/misc/fsl_law.c b/drivers/misc/fsl_law.c index 7c59c887f1..425eb181bf 100644 --- a/drivers/misc/fsl_law.c +++ b/drivers/misc/fsl_law.c @@ -41,6 +41,8 @@ DECLARE_GLOBAL_DATA_PTR; defined(CONFIG_P1011) || defined(CONFIG_P1020) || \ defined(CONFIG_P2010) || defined(CONFIG_P2020) #define FSL_HW_NUM_LAWS 12 +#elif defined(CONFIG_PPC_P4080) +#define FSL_HW_NUM_LAWS 32 #else #error FSL_HW_NUM_LAWS not defined for this platform #endif -- cgit From 24b17d8a3c3a4b9ceaf6363ebe0021011b0b8bd8 Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Wed, 30 Sep 2009 08:39:44 -0500 Subject: ppc/85xx: get_law_entry isn't used in CONFIG_NAND_SPL Don't include get_law_entry as part of the NAND_SPL build since the code isnt used. Signed-off-by: Kumar Gala --- drivers/misc/fsl_law.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/misc/fsl_law.c') diff --git a/drivers/misc/fsl_law.c b/drivers/misc/fsl_law.c index 425eb181bf..287e555900 100644 --- a/drivers/misc/fsl_law.c +++ b/drivers/misc/fsl_law.c @@ -79,6 +79,7 @@ void disable_law(u8 idx) return; } +#ifndef CONFIG_NAND_SPL static int get_law_entry(u8 i, struct law_entry *e) { volatile ccsr_local_t *ccm = (void *)(CONFIG_SYS_FSL_CORENET_CCM_ADDR); @@ -96,6 +97,7 @@ static int get_law_entry(u8 i, struct law_entry *e) return 1; } +#endif #else void set_law(u8 idx, phys_addr_t addr, enum law_size sz, enum law_trgt_if id) { @@ -130,6 +132,7 @@ void disable_law(u8 idx) return; } +#ifndef CONFIG_NAND_SPL static int get_law_entry(u8 i, struct law_entry *e) { volatile u32 *base = (volatile u32 *)(CONFIG_SYS_IMMR + 0xc08); @@ -149,6 +152,7 @@ static int get_law_entry(u8 i, struct law_entry *e) return 1; } #endif +#endif int set_next_law(phys_addr_t addr, enum law_size sz, enum law_trgt_if id) { -- cgit