From d9fe88173cb4f7d293796ffe10c7a0d3d426d8f9 Mon Sep 17 00:00:00 2001 From: Nick Spence Date: Fri, 22 Aug 2008 23:52:50 -0700 Subject: MPC83XX: Fix GPIO configuration - set gpio level before direction Set DAT value before DIR values to avoid creating glitches on the GPIO signals. Set gpio level register before direction register to inhibit glitches on high level output pins. Dir and data gets cleared at powerup, so high level output lines see a short low pulse between setting the direction and level registers. Issue was seen on a new board with the nReset line of the NOR flash connected to a GPIO. Setting the direction register puts the NOR flash in reset so the next instruction to set the level cannot get executed. Signed-off-by: Nick Spence Signed-off-by: Peter Korsgaard Signed-off-by: Kim Phillips diff --git a/cpu/mpc83xx/cpu_init.c b/cpu/mpc83xx/cpu_init.c index 67c9e57..4514dbb 100644 --- a/cpu/mpc83xx/cpu_init.c +++ b/cpu/mpc83xx/cpu_init.c @@ -283,12 +283,12 @@ void cpu_init_f (volatile immap_t * im) im->sysconf.lblaw[7].ar = CFG_LBLAWAR7_PRELIM; #endif #ifdef CFG_GPIO1_PRELIM - im->gpio[0].dir = CFG_GPIO1_DIR; im->gpio[0].dat = CFG_GPIO1_DAT; + im->gpio[0].dir = CFG_GPIO1_DIR; #endif #ifdef CFG_GPIO2_PRELIM - im->gpio[1].dir = CFG_GPIO2_DIR; im->gpio[1].dat = CFG_GPIO2_DAT; + im->gpio[1].dir = CFG_GPIO2_DIR; #endif } -- cgit v0.10.2 From ade50c7fa1b16ef98be17e9c3ae286aecf4f5605 Mon Sep 17 00:00:00 2001 From: Nick Spence Date: Thu, 28 Aug 2008 14:09:11 -0700 Subject: mpc83xx: use r4 instead of r2 in lock_ram_in_cache and unlock_ram_in_cache This is needed in unlock_ram_in_cache() because it is called from C and will corrupt the small data area anchor that is kept in R2. lock_ram_in_cache() is modified similarly as good coding practice, but is not called from C. Signed-off-by: Nick Spence Signed-off-by: Kim Phillips diff --git a/cpu/mpc83xx/start.S b/cpu/mpc83xx/start.S index 16ed494..75ad36c 100644 --- a/cpu/mpc83xx/start.S +++ b/cpu/mpc83xx/start.S @@ -1060,9 +1060,9 @@ lock_ram_in_cache: */ lis r3, (CFG_INIT_RAM_ADDR & ~31)@h ori r3, r3, (CFG_INIT_RAM_ADDR & ~31)@l - li r2, ((CFG_INIT_RAM_END & ~31) + \ + li r4, ((CFG_INIT_RAM_END & ~31) + \ (CFG_INIT_RAM_ADDR & 31) + 31) / 32 - mtctr r2 + mtctr r4 1: dcbz r0, r3 addi r3, r3, 32 @@ -1082,8 +1082,9 @@ unlock_ram_in_cache: /* invalidate the INIT_RAM section */ lis r3, (CFG_INIT_RAM_ADDR & ~31)@h ori r3, r3, (CFG_INIT_RAM_ADDR & ~31)@l - li r2,512 - mtctr r2 + li r4, ((CFG_INIT_RAM_END & ~31) + \ + (CFG_INIT_RAM_ADDR & 31) + 31) / 32 + mtctr r4 1: icbi r0, r3 dcbi r0, r3 addi r3, r3, 32 -- cgit v0.10.2 From 46497056ae3b1e81e736e9cf3a170472c5d9719f Mon Sep 17 00:00:00 2001 From: Nick Spence Date: Thu, 28 Aug 2008 14:09:19 -0700 Subject: mpc83xx: Store and display Arbiter Event Register values Record the Arbiter Event Register values and optionally display them. The Arbiter Event Register can record the type and effective address of an arbiter error, even through an HRESET. This patch stores the values in the global data structure. Display of the Arbiter Event registers immediately after the RSR value can be enabled with defines. The Arbiter values will only be displayed if an arbiter event has occured since the last Power On Reset, and either of the following defines exist: #define CONFIG_DISPLAY_AER_BRIEF - display only the arbiter address and and type register values #define CONFIG_DISPLAY_AER_FULL - display and interpret the arbiter event register values Address Only transactions are one of the trapped events that can register as an arbiter event. They occur with some cache manipulation instructions if the HID0_ABE (Address Broadcast Enable) is set and the memory region has the MEMORY_COHERENCE WIMG bit set. Setting: #define CONFIG_MASK_AER_AO - prevents the arbiter from recording address only events, so that it can still capture other real problems. Signed-off-by: Nick Spence Signed-off-by: Kim Phillips diff --git a/cpu/mpc83xx/cpu_init.c b/cpu/mpc83xx/cpu_init.c index 4514dbb..ff01cf1 100644 --- a/cpu/mpc83xx/cpu_init.c +++ b/cpu/mpc83xx/cpu_init.c @@ -167,6 +167,10 @@ void cpu_init_f (volatile immap_t * im) gd->reset_status = im->reset.rsr; im->reset.rsr = ~(RSR_RES); + /* AER - Arbiter Event Register - store status */ + gd->arbiter_event_attributes = im->arbiter.aeatr; + gd->arbiter_event_address = im->arbiter.aeadr; + /* * RMR - Reset Mode Register * contains checkstop reset enable (4.6.1.4) @@ -303,6 +307,130 @@ int cpu_init_r (void) } /* + * Print out the bus arbiter event + */ +#if defined(CONFIG_DISPLAY_AER_FULL) +static int print_83xx_arb_event(int force) +{ + static char* event[] = { + "Address Time Out", + "Data Time Out", + "Address Only Transfer Type", + "External Control Word Transfer Type", + "Reserved Transfer Type", + "Transfer Error", + "reserved", + "reserved" + }; + static char* master[] = { + "e300 Core Data Transaction", + "reserved", + "e300 Core Instruction Fetch", + "reserved", + "TSEC1", + "TSEC2", + "USB MPH", + "USB DR", + "Encryption Core", + "I2C Boot Sequencer", + "JTAG", + "reserved", + "eSDHC", + "PCI1", + "PCI2", + "DMA", + "QUICC Engine 00", + "QUICC Engine 01", + "QUICC Engine 10", + "QUICC Engine 11", + "reserved", + "reserved", + "reserved", + "reserved", + "SATA1", + "SATA2", + "SATA3", + "SATA4", + "reserved", + "PCI Express 1", + "PCI Express 2", + "TDM-DMAC" + }; + static char *transfer[] = { + "Address-only, Clean Block", + "Address-only, lwarx reservation set", + "Single-beat or Burst write", + "reserved", + "Address-only, Flush Block", + "reserved", + "Burst write", + "reserved", + "Address-only, sync", + "Address-only, tlbsync", + "Single-beat or Burst read", + "Single-beat or Burst read", + "Address-only, Kill Block", + "Address-only, icbi", + "Burst read", + "reserved", + "Address-only, eieio", + "reserved", + "Single-beat write", + "reserved", + "ecowx - Illegal single-beat write", + "reserved", + "reserved", + "reserved", + "Address-only, TLB Invalidate", + "reserved", + "Single-beat or Burst read", + "reserved", + "eciwx - Illegal single-beat read", + "reserved", + "Burst read", + "reserved" + }; + + int etype = (gd->arbiter_event_attributes & AEATR_EVENT) + >> AEATR_EVENT_SHIFT; + int mstr_id = (gd->arbiter_event_attributes & AEATR_MSTR_ID) + >> AEATR_MSTR_ID_SHIFT; + int tbst = (gd->arbiter_event_attributes & AEATR_TBST) + >> AEATR_TBST_SHIFT; + int tsize = (gd->arbiter_event_attributes & AEATR_TSIZE) + >> AEATR_TSIZE_SHIFT; + int ttype = (gd->arbiter_event_attributes & AEATR_TTYPE) + >> AEATR_TTYPE_SHIFT; + + if (!force && !gd->arbiter_event_address) + return 0; + + puts("Arbiter Event Status:\n"); + printf(" Event Address: 0x%08lX\n", gd->arbiter_event_address); + printf(" Event Type: 0x%1x = %s\n", etype, event[etype]); + printf(" Master ID: 0x%02x = %s\n", mstr_id, master[mstr_id]); + printf(" Transfer Size: 0x%1x = %d bytes\n", (tbst<<3) | tsize, + tbst ? (tsize ? tsize : 8) : 16 + 8 * tsize); + printf(" Transfer Type: 0x%02x = %s\n", ttype, transfer[ttype]); + + return gd->arbiter_event_address; +} + +#elif defined(CONFIG_DISPLAY_AER_BRIEF) + +static int print_83xx_arb_event(int force) +{ + if (!force && !gd->arbiter_event_address) + return 0; + + printf("Arbiter Event Status: AEATR=0x%08lX, AEADR=0x%08lX\n", + gd->arbiter_event_attributes, gd->arbiter_event_address); + + return gd->arbiter_event_address; +} +#endif /* CONFIG_DISPLAY_AER_xxxx */ + +/* * Figure out the cause of the reset */ int prt_83xx_rsr(void) @@ -334,6 +462,12 @@ int prt_83xx_rsr(void) printf("%s%s", sep, bits[i].desc); sep = ", "; } - puts("\n\n"); + puts("\n"); + +#if defined(CONFIG_DISPLAY_AER_FULL) || defined(CONFIG_DISPLAY_AER_BRIEF) + print_83xx_arb_event(rsr & RSR_BMRS); +#endif + puts("\n"); + return 0; } diff --git a/cpu/mpc83xx/start.S b/cpu/mpc83xx/start.S index 75ad36c..e452bfb 100644 --- a/cpu/mpc83xx/start.S +++ b/cpu/mpc83xx/start.S @@ -483,6 +483,17 @@ init_e300_core: /* time t 10 */ 1: #endif /* CONFIG_WATCHDOG */ +#if defined(CONFIG_MASK_AER_AO) + /* Write the Arbiter Event Enable to mask Address Only traps. */ + /* This prevents the dcbz instruction from being trapped when */ + /* HID0_ABE Address Broadcast Enable is set and the MEMORY */ + /* COHERENCY bit is set in the WIMG bits, which is often */ + /* needed for PCI operation. */ + lwz r4, 0x0808(r3) + rlwinm r0, r4, 0, ~AER_AO + stw r0, 0x0808(r3) +#endif /* CONFIG_MASK_AER_AO */ + /* Initialize the Hardware Implementation-dependent Registers */ /* HID0 also contains cache control */ /*------------------------------------------------------*/ diff --git a/include/asm-ppc/global_data.h b/include/asm-ppc/global_data.h index c09b07d..a9366c3 100644 --- a/include/asm-ppc/global_data.h +++ b/include/asm-ppc/global_data.h @@ -122,6 +122,10 @@ typedef struct global_data { phys_size_t ram_size; /* RAM size */ unsigned long reloc_off; /* Relocation Offset */ unsigned long reset_status; /* reset status register at boot */ +#if defined(CONFIG_MPC83XX) + unsigned long arbiter_event_attributes; + unsigned long arbiter_event_address; +#endif unsigned long env_addr; /* Address of Environment struct */ unsigned long env_valid; /* Checksum of Environment valid? */ unsigned long have_console; /* serial_init() was called */ -- cgit v0.10.2 From 6eb2a44e27919fdc601e0c05404b298a7602c0e3 Mon Sep 17 00:00:00 2001 From: Nick Spence Date: Thu, 28 Aug 2008 14:09:25 -0700 Subject: mpc83xx: clean up cache operations and unlock_ram_in_cache() functions Cleans up some latent issues with the data cache control so that dcache_enable() and dcache_disable() will work reliably (after unlock_ram_in_cache() has been called) Signed-off-by: Nick Spence Signed-off-by: Kim Phillips diff --git a/cpu/mpc83xx/start.S b/cpu/mpc83xx/start.S index e452bfb..14bfbda 100644 --- a/cpu/mpc83xx/start.S +++ b/cpu/mpc83xx/start.S @@ -208,7 +208,7 @@ in_flash: bl enable_addr_trans sync - /* enable and invalidate the data cache */ + /* enable the data cache */ bl dcache_enable sync #ifdef CFG_INIT_RAM_LOCK @@ -496,15 +496,16 @@ init_e300_core: /* time t 10 */ /* Initialize the Hardware Implementation-dependent Registers */ /* HID0 also contains cache control */ + /* - force invalidation of data and instruction caches */ /*------------------------------------------------------*/ lis r3, CFG_HID0_INIT@h - ori r3, r3, CFG_HID0_INIT@l + ori r3, r3, (CFG_HID0_INIT | HID0_ICFI | HID0_DCFI)@l SYNC mtspr HID0, r3 lis r3, CFG_HID0_FINAL@h - ori r3, r3, CFG_HID0_FINAL@l + ori r3, r3, (CFG_HID0_FINAL & ~(HID0_ICFI | HID0_DCFI))@l SYNC mtspr HID0, r3 @@ -714,8 +715,7 @@ disable_addr_trans: icache_enable: mfspr r3, HID0 ori r3, r3, HID0_ICE - lis r4, 0 - ori r4, r4, HID0_ILOCK + li r4, HID0_ICFI|HID0_ILOCK andc r3, r3, r4 ori r4, r3, HID0_ICFI isync @@ -728,13 +728,10 @@ icache_enable: icache_disable: mfspr r3, HID0 lis r4, 0 - ori r4, r4, HID0_ICE|HID0_ILOCK + ori r4, r4, HID0_ICE|HID0_ICFI|HID0_ILOCK andc r3, r3, r4 - ori r4, r3, HID0_ICFI isync - mtspr HID0, r4 /* sets invalidate, clears enable and lock*/ - isync - mtspr HID0, r3 /* clears invalidate */ + mtspr HID0, r3 /* clears invalidate, enable and lock */ blr .globl icache_status @@ -748,25 +745,24 @@ dcache_enable: mfspr r3, HID0 li r5, HID0_DCFI|HID0_DLOCK andc r3, r3, r5 - mtspr HID0, r3 /* no invalidate, unlock */ ori r3, r3, HID0_DCE - ori r5, r3, HID0_DCFI - mtspr HID0, r5 /* enable + invalidate */ - mtspr HID0, r3 /* enable */ sync + mtspr HID0, r3 /* enable, no invalidate */ blr .globl dcache_disable dcache_disable: + mflr r4 + bl flush_dcache /* uses r3 and r5 */ mfspr r3, HID0 - lis r4, 0 - ori r4, r4, HID0_DCE|HID0_DLOCK - andc r3, r3, r4 - ori r4, r3, HID0_DCI + li r5, HID0_DCE|HID0_DLOCK + andc r3, r3, r5 + ori r5, r3, HID0_DCFI sync - mtspr HID0, r4 /* sets invalidate, clears enable and lock */ + mtspr HID0, r5 /* sets invalidate, clears enable and lock */ sync mtspr HID0, r3 /* clears invalidate */ + mtlr r4 blr .globl dcache_status @@ -775,6 +771,18 @@ dcache_status: rlwinm r3, r3, (31 - HID0_DCE_SHIFT + 1), 31, 31 blr + .globl flush_dcache +flush_dcache: + lis r3, 0 + lis r5, CFG_CACHELINE_SIZE +1: cmp 0, 1, r3, r5 + bge 2f + lwz r5, 0(r3) + lis r5, CFG_CACHELINE_SIZE + addi r3, r3, 0x4 + b 1b +2: blr + .globl get_pvr get_pvr: mfspr r3, PVR @@ -1081,7 +1089,7 @@ lock_ram_in_cache: /* Lock the data cache */ mfspr r0, HID0 - ori r0, r0, 0x1000 + ori r0, r0, HID0_DLOCK sync mtspr HID0, r0 sync @@ -1108,9 +1116,10 @@ unlock_ram_in_cache: li r5, HID0_DLOCK|HID0_DCFI andc r3, r3, r5 /* no invalidate, unlock */ ori r5, r3, HID0_DCFI /* invalidate, unlock */ + sync mtspr HID0, r5 /* invalidate, unlock */ - mtspr HID0, r3 /* no invalidate, unlock */ sync + mtspr HID0, r3 /* no invalidate, unlock */ blr #endif /* !CONFIG_NAND_SPL */ #endif /* CFG_INIT_RAM_LOCK */ -- cgit v0.10.2 From 64ac1eb5afafced49b327425ad1814b2dc422d6e Mon Sep 17 00:00:00 2001 From: Nick Spence Date: Tue, 2 Sep 2008 15:21:16 -0500 Subject: mpc83xx: fix mpc8313 in-tree building with NAND and add mpc8313 NAND build to MAKEALL Signed-off-by: Nick Spence Signed-off-by: Kim Phillips diff --git a/MAKEALL b/MAKEALL index fe284b5..fbdcb42 100755 --- a/MAKEALL +++ b/MAKEALL @@ -320,7 +320,7 @@ LIST_8260=" \ LIST_83xx=" \ MPC8313ERDB_33 \ - MPC8313ERDB_66 \ + MPC8313ERDB_NAND_66 \ MPC8315ERDB \ MPC8323ERDB \ MPC832XEMDS \ diff --git a/Makefile b/Makefile index 2d4b513..8d82ef5 100644 --- a/Makefile +++ b/Makefile @@ -2083,6 +2083,9 @@ MPC8313ERDB_NAND_66_config: unconfig echo "#define CONFIG_NAND_U_BOOT" >>$(obj)include/config.h ; \ fi ; @$(MKCONFIG) -a MPC8313ERDB ppc mpc83xx mpc8313erdb freescale + @if [ "$(findstring _NAND_,$@)" ] ; then \ + echo "CONFIG_NAND_U_BOOT = y" >> $(obj)include/config.mk ; \ + fi ; MPC8315ERDB_config: unconfig @$(MKCONFIG) -a MPC8315ERDB ppc mpc83xx mpc8315erdb freescale -- cgit v0.10.2