summaryrefslogtreecommitdiff
path: root/cpu/mpc83xx
diff options
context:
space:
mode:
authorWolfgang Denk <wd@denx.de>2008-09-03 23:44:18 +0200
committerWolfgang Denk <wd@denx.de>2008-09-03 23:44:18 +0200
commitd459516188af37da22a3b86914dbd81d83fac79f (patch)
treedefe29ba4e93edddd4bb352ac3737a8a8fcdb99e /cpu/mpc83xx
parentce42d166ac3c55ebf1e7c2f9707a79acefa006be (diff)
parent64ac1eb5afafced49b327425ad1814b2dc422d6e (diff)
Merge branch 'master' of git://git.denx.de/u-boot-mpc83xx
Diffstat (limited to 'cpu/mpc83xx')
-rw-r--r--cpu/mpc83xx/cpu_init.c140
-rw-r--r--cpu/mpc83xx/start.S71
2 files changed, 183 insertions, 28 deletions
diff --git a/cpu/mpc83xx/cpu_init.c b/cpu/mpc83xx/cpu_init.c
index 67c9e570c3..ff01cf10f5 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)
@@ -283,12 +287,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
}
@@ -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 16ed494f81..14bfbdade8 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
@@ -483,17 +483,29 @@ 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 */
+ /* - 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
@@ -703,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
@@ -717,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
@@ -737,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
@@ -764,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
@@ -1060,9 +1079,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
@@ -1070,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
@@ -1082,8 +1101,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
@@ -1096,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 */