summaryrefslogtreecommitdiffstats
path: root/post/cpu/mpc8xx
diff options
context:
space:
mode:
authorWolfgang Denk <wd@pollux.denx.de>2007-03-06 18:08:43 +0100
committerWolfgang Denk <wd@denx.de>2007-03-06 18:08:43 +0100
commitad5bb451ade552c44bef9119d907929ebc2c126f (patch)
treedf979d3c6385a161cd6df6b6f903ed7eaad31948 /post/cpu/mpc8xx
parenta5284efd125967675b2e9c6ef7b95832268ad360 (diff)
downloadtalos-obmc-uboot-ad5bb451ade552c44bef9119d907929ebc2c126f.tar.gz
talos-obmc-uboot-ad5bb451ade552c44bef9119d907929ebc2c126f.zip
Restructure POST directory to support of other CPUs, boards, etc.
Diffstat (limited to 'post/cpu/mpc8xx')
-rw-r--r--post/cpu/mpc8xx/Makefile29
-rw-r--r--post/cpu/mpc8xx/cache_8xx.S495
-rw-r--r--post/cpu/mpc8xx/ether.c631
-rw-r--r--post/cpu/mpc8xx/spr.c152
-rw-r--r--post/cpu/mpc8xx/uart.c560
-rw-r--r--post/cpu/mpc8xx/usb.c269
-rw-r--r--post/cpu/mpc8xx/watchdog.c78
7 files changed, 2214 insertions, 0 deletions
diff --git a/post/cpu/mpc8xx/Makefile b/post/cpu/mpc8xx/Makefile
new file mode 100644
index 0000000000..9dd3f0fce9
--- /dev/null
+++ b/post/cpu/mpc8xx/Makefile
@@ -0,0 +1,29 @@
+#
+# (C) Copyright 2002-2007
+# Wolfgang Denk, DENX Software Engineering, wd@denx.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
+#
+
+LIB = libpostmpc8xx.a
+
+AOBJS = cache_8xx.o
+COBJS = ether.o spr.o uart.o usb.o watchdog.o
+
+include $(TOPDIR)/post/rules.mk
diff --git a/post/cpu/mpc8xx/cache_8xx.S b/post/cpu/mpc8xx/cache_8xx.S
new file mode 100644
index 0000000000..2d41b5566a
--- /dev/null
+++ b/post/cpu/mpc8xx/cache_8xx.S
@@ -0,0 +1,495 @@
+/*
+ * Copyright (C) 2002 Wolfgang Denk <wd@denx.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 <config.h>
+
+#ifdef CONFIG_POST
+#if defined(CONFIG_MPC823) || \
+ defined(CONFIG_MPC850) || \
+ defined(CONFIG_MPC855) || \
+ defined(CONFIG_MPC860) || \
+ defined(CONFIG_MPC862)
+
+#include <post.h>
+#include <ppc_asm.tmpl>
+#include <ppc_defs.h>
+#include <asm/cache.h>
+
+#if CONFIG_POST & CFG_POST_CACHE
+
+ .text
+
+cache_post_dinvalidate:
+ lis r10, IDC_INVALL@h
+ mtspr DC_CST, r10
+ blr
+
+cache_post_iinvalidate:
+ lis r10, IDC_INVALL@h
+ mtspr IC_CST, r10
+ isync
+ blr
+
+cache_post_ddisable:
+ lis r10, IDC_DISABLE@h
+ mtspr DC_CST, r10
+ blr
+
+cache_post_dwb:
+ lis r10, IDC_ENABLE@h
+ mtspr DC_CST, r10
+ lis r10, DC_CFWT@h
+ mtspr DC_CST, r10
+ blr
+
+cache_post_dwt:
+ lis r10, IDC_ENABLE@h
+ mtspr DC_CST, r10
+ lis r10, DC_SFWT@h
+ mtspr DC_CST, r10
+ blr
+
+cache_post_idisable:
+ lis r10, IDC_DISABLE@h
+ mtspr IC_CST, r10
+ isync
+ blr
+
+cache_post_ienable:
+ lis r10, IDC_ENABLE@h
+ mtspr IC_CST, r10
+ isync
+ blr
+
+cache_post_iunlock:
+ lis r10, IDC_UNALL@h
+ mtspr IC_CST, r10
+ isync
+ blr
+
+cache_post_ilock:
+ mtspr IC_ADR, r3
+ lis r10, IDC_LDLCK@h
+ mtspr IC_CST, r10
+ isync
+ blr
+
+/*
+ * turn on the data cache
+ * switch the data cache to write-back or write-through mode
+ * invalidate the data cache
+ * write the negative pattern to a cached area
+ * read the area
+ *
+ * The negative pattern must be read at the last step
+ */
+ .global cache_post_test1
+cache_post_test1:
+ mflr r0
+ stw r0, 4(r1)
+
+ stwu r3, -4(r1)
+ stwu r4, -4(r1)
+
+ bl cache_post_dwb
+ bl cache_post_dinvalidate
+
+ /* Write the negative pattern to the test area */
+ lwz r0, 0(r1)
+ mtctr r0
+ li r0, 0xff
+ lwz r3, 4(r1)
+ subi r3, r3, 1
+1:
+ stbu r0, 1(r3)
+ bdnz 1b
+
+ /* Read the test area */
+ lwz r0, 0(r1)
+ mtctr r0
+ lwz r4, 4(r1)
+ subi r4, r4, 1
+ li r3, 0
+1:
+ lbzu r0, 1(r4)
+ cmpli cr0, r0, 0xff
+ beq 2f
+ li r3, -1
+ b 3f
+2:
+ bdnz 1b
+3:
+
+ bl cache_post_ddisable
+ bl cache_post_dinvalidate
+
+ addi r1, r1, 8
+
+ lwz r0, 4(r1)
+ mtlr r0
+ blr
+
+/*
+ * turn on the data cache
+ * switch the data cache to write-back or write-through mode
+ * invalidate the data cache
+ * write the zero pattern to a cached area
+ * turn off the data cache
+ * write the negative pattern to the area
+ * turn on the data cache
+ * read the area
+ *
+ * The negative pattern must be read at the last step
+ */
+ .global cache_post_test2
+cache_post_test2:
+ mflr r0
+ stw r0, 4(r1)
+
+ stwu r3, -4(r1)
+ stwu r4, -4(r1)
+
+ bl cache_post_dwb
+ bl cache_post_dinvalidate
+
+ /* Write the zero pattern to the test area */
+ lwz r0, 0(r1)
+ mtctr r0
+ li r0, 0
+ lwz r3, 4(r1)
+ subi r3, r3, 1
+1:
+ stbu r0, 1(r3)
+ bdnz 1b
+
+ bl cache_post_ddisable
+
+ /* Write the negative pattern to the test area */
+ lwz r0, 0(r1)
+ mtctr r0
+ li r0, 0xff
+ lwz r3, 4(r1)
+ subi r3, r3, 1
+1:
+ stbu r0, 1(r3)
+ bdnz 1b
+
+ bl cache_post_dwb
+
+ /* Read the test area */
+ lwz r0, 0(r1)
+ mtctr r0
+ lwz r4, 4(r1)
+ subi r4, r4, 1
+ li r3, 0
+1:
+ lbzu r0, 1(r4)
+ cmpli cr0, r0, 0xff
+ beq 2f
+ li r3, -1
+ b 3f
+2:
+ bdnz 1b
+3:
+
+ bl cache_post_ddisable
+ bl cache_post_dinvalidate
+
+ addi r1, r1, 8
+
+ lwz r0, 4(r1)
+ mtlr r0
+ blr
+
+/*
+ * turn on the data cache
+ * switch the data cache to write-through mode
+ * invalidate the data cache
+ * write the zero pattern to a cached area
+ * flush the data cache
+ * write the negative pattern to the area
+ * turn off the data cache
+ * read the area
+ *
+ * The negative pattern must be read at the last step
+ */
+ .global cache_post_test3
+cache_post_test3:
+ mflr r0
+ stw r0, 4(r1)
+
+ stwu r3, -4(r1)
+ stwu r4, -4(r1)
+
+ bl cache_post_ddisable
+ bl cache_post_dinvalidate
+
+ /* Write the zero pattern to the test area */
+ lwz r0, 0(r1)
+ mtctr r0
+ li r0, 0
+ lwz r3, 4(r1)
+ subi r3, r3, 1
+1:
+ stbu r0, 1(r3)
+ bdnz 1b
+
+ bl cache_post_dwt
+ bl cache_post_dinvalidate
+
+ /* Write the negative pattern to the test area */
+ lwz r0, 0(r1)
+ mtctr r0
+ li r0, 0xff
+ lwz r3, 4(r1)
+ subi r3, r3, 1
+1:
+ stbu r0, 1(r3)
+ bdnz 1b
+
+ bl cache_post_ddisable
+ bl cache_post_dinvalidate
+
+ /* Read the test area */
+ lwz r0, 0(r1)
+ mtctr r0
+ lwz r4, 4(r1)
+ subi r4, r4, 1
+ li r3, 0
+1:
+ lbzu r0, 1(r4)
+ cmpli cr0, r0, 0xff
+ beq 2f
+ li r3, -1
+ b 3f
+2:
+ bdnz 1b
+3:
+
+ addi r1, r1, 8
+
+ lwz r0, 4(r1)
+ mtlr r0
+ blr
+
+/*
+ * turn on the data cache
+ * switch the data cache to write-back mode
+ * invalidate the data cache
+ * write the negative pattern to a cached area
+ * flush the data cache
+ * write the zero pattern to the area
+ * invalidate the data cache
+ * read the area
+ *
+ * The negative pattern must be read at the last step
+ */
+ .global cache_post_test4
+cache_post_test4:
+ mflr r0
+ stw r0, 4(r1)
+
+ stwu r3, -4(r1)
+ stwu r4, -4(r1)
+
+ bl cache_post_ddisable
+ bl cache_post_dinvalidate
+
+ /* Write the negative pattern to the test area */
+ lwz r0, 0(r1)
+ mtctr r0
+ li r0, 0xff
+ lwz r3, 4(r1)
+ subi r3, r3, 1
+1:
+ stbu r0, 1(r3)
+ bdnz 1b
+
+ bl cache_post_dwb
+ bl cache_post_dinvalidate
+
+ /* Write the zero pattern to the test area */
+ lwz r0, 0(r1)
+ mtctr r0
+ li r0, 0
+ lwz r3, 4(r1)
+ subi r3, r3, 1
+1:
+ stbu r0, 1(r3)
+ bdnz 1b
+
+ bl cache_post_ddisable
+ bl cache_post_dinvalidate
+
+ /* Read the test area */
+ lwz r0, 0(r1)
+ mtctr r0
+ lwz r4, 4(r1)
+ subi r4, r4, 1
+ li r3, 0
+1:
+ lbzu r0, 1(r4)
+ cmpli cr0, r0, 0xff
+ beq 2f
+ li r3, -1
+ b 3f
+2:
+ bdnz 1b
+3:
+
+ addi r1, r1, 8
+
+ lwz r0, 4(r1)
+ mtlr r0
+ blr
+
+cache_post_test5_1:
+ li r3, 0
+cache_post_test5_2:
+ li r3, -1
+
+/*
+ * turn on the instruction cache
+ * unlock the entire instruction cache
+ * invalidate the instruction cache
+ * lock a branch instruction in the instruction cache
+ * replace the branch instruction with "nop"
+ * jump to the branch instruction
+ * check that the branch instruction was executed
+*/
+ .global cache_post_test5
+cache_post_test5:
+ mflr r0
+ stw r0, 4(r1)
+
+ bl cache_post_ienable
+ bl cache_post_iunlock
+ bl cache_post_iinvalidate
+
+ /* Compute r9 = cache_post_test5_reloc */
+ bl cache_post_test5_reloc
+cache_post_test5_reloc:
+ mflr r9
+
+ /* Copy the test instruction to cache_post_test5_data */
+ lis r3, (cache_post_test5_1 - cache_post_test5_reloc)@h
+ ori r3, r3, (cache_post_test5_1 - cache_post_test5_reloc)@l
+ add r3, r3, r9
+ lis r4, (cache_post_test5_data - cache_post_test5_reloc)@h
+ ori r4, r4, (cache_post_test5_data - cache_post_test5_reloc)@l
+ add r4, r4, r9
+ lwz r0, 0(r3)
+ stw r0, 0(r4)
+
+ bl cache_post_iinvalidate
+
+ /* Lock the branch instruction */
+ lis r3, (cache_post_test5_data - cache_post_test5_reloc)@h
+ ori r3, r3, (cache_post_test5_data - cache_post_test5_reloc)@l
+ add r3, r3, r9
+ bl cache_post_ilock
+
+ /* Replace the test instruction */
+ lis r3, (cache_post_test5_2 - cache_post_test5_reloc)@h
+ ori r3, r3, (cache_post_test5_2 - cache_post_test5_reloc)@l
+ add r3, r3, r9
+ lis r4, (cache_post_test5_data - cache_post_test5_reloc)@h
+ ori r4, r4, (cache_post_test5_data - cache_post_test5_reloc)@l
+ add r4, r4, r9
+ lwz r0, 0(r3)
+ stw r0, 0(r4)
+
+ bl cache_post_iinvalidate
+
+ /* Execute to the test instruction */
+cache_post_test5_data:
+ nop
+
+ bl cache_post_iunlock
+
+ lwz r0, 4(r1)
+ mtlr r0
+ blr
+
+cache_post_test6_1:
+ li r3, -1
+cache_post_test6_2:
+ li r3, 0
+
+/*
+ * turn on the instruction cache
+ * unlock the entire instruction cache
+ * invalidate the instruction cache
+ * lock a branch instruction in the instruction cache
+ * replace the branch instruction with "nop"
+ * jump to the branch instruction
+ * check that the branch instruction was executed
+ */
+ .global cache_post_test6
+cache_post_test6:
+ mflr r0
+ stw r0, 4(r1)
+
+ bl cache_post_ienable
+ bl cache_post_iunlock
+ bl cache_post_iinvalidate
+
+ /* Compute r9 = cache_post_test6_reloc */
+ bl cache_post_test6_reloc
+cache_post_test6_reloc:
+ mflr r9
+
+ /* Copy the test instruction to cache_post_test6_data */
+ lis r3, (cache_post_test6_1 - cache_post_test6_reloc)@h
+ ori r3, r3, (cache_post_test6_1 - cache_post_test6_reloc)@l
+ add r3, r3, r9
+ lis r4, (cache_post_test6_data - cache_post_test6_reloc)@h
+ ori r4, r4, (cache_post_test6_data - cache_post_test6_reloc)@l
+ add r4, r4, r9
+ lwz r0, 0(r3)
+ stw r0, 0(r4)
+
+ bl cache_post_iinvalidate
+
+ /* Replace the test instruction */
+ lis r3, (cache_post_test6_2 - cache_post_test6_reloc)@h
+ ori r3, r3, (cache_post_test6_2 - cache_post_test6_reloc)@l
+ add r3, r3, r9
+ lis r4, (cache_post_test6_data - cache_post_test6_reloc)@h
+ ori r4, r4, (cache_post_test6_data - cache_post_test6_reloc)@l
+ add r4, r4, r9
+ lwz r0, 0(r3)
+ stw r0, 0(r4)
+
+ bl cache_post_iinvalidate
+
+ /* Execute to the test instruction */
+cache_post_test6_data:
+ nop
+
+ lwz r0, 4(r1)
+ mtlr r0
+ blr
+
+#endif /* CONFIG_MPC823 || MPC850 || MPC855 || MPC860 */
+#endif /* CONFIG_POST & CFG_POST_CACHE */
+#endif /* CONFIG_POST */
diff --git a/post/cpu/mpc8xx/ether.c b/post/cpu/mpc8xx/ether.c
new file mode 100644
index 0000000000..8c87b5927e
--- /dev/null
+++ b/post/cpu/mpc8xx/ether.c
@@ -0,0 +1,631 @@
+/*
+ * (C) Copyright 2002
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.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>
+
+/*
+ * Ethernet test
+ *
+ * The Serial Communication Controllers (SCC) listed in ctlr_list array below
+ * are tested in the loopback ethernet mode.
+ * The controllers are configured accordingly and several packets
+ * are transmitted. The configurable test parameters are:
+ * MIN_PACKET_LENGTH - minimum size of packet to transmit
+ * MAX_PACKET_LENGTH - maximum size of packet to transmit
+ * TEST_NUM - number of tests
+ */
+
+#ifdef CONFIG_POST
+
+#include <post.h>
+#if CONFIG_POST & CFG_POST_ETHER
+#if defined(CONFIG_8xx)
+#include <commproc.h>
+#elif defined(CONFIG_MPC8260)
+#include <asm/cpm_8260.h>
+#else
+#error "Apparently a bad configuration, please fix."
+#endif
+
+#include <command.h>
+#include <net.h>
+#include <serial.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define MIN_PACKET_LENGTH 64
+#define MAX_PACKET_LENGTH 256
+#define TEST_NUM 1
+
+#define CTLR_SCC 0
+
+extern void spi_init_f (void);
+extern void spi_init_r (void);
+
+/* The list of controllers to test */
+#if defined(CONFIG_MPC823)
+static int ctlr_list[][2] = { {CTLR_SCC, 1} };
+#else
+static int ctlr_list[][2] = { };
+#endif
+
+#define CTRL_LIST_SIZE (sizeof(ctlr_list) / sizeof(ctlr_list[0]))
+
+static struct {
+ void (*init) (int index);
+ void (*halt) (int index);
+ int (*send) (int index, volatile void *packet, int length);
+ int (*recv) (int index, void *packet, int length);
+} ctlr_proc[1];
+
+static char *ctlr_name[1] = { "SCC" };
+
+/* Ethernet Transmit and Receive Buffers */
+#define DBUF_LENGTH 1520
+
+#define TX_BUF_CNT 2
+
+#define TOUT_LOOP 100
+
+static char txbuf[DBUF_LENGTH];
+
+static uint rxIdx; /* index of the current RX buffer */
+static uint txIdx; /* index of the current TX buffer */
+
+/*
+ * SCC Ethernet Tx and Rx buffer descriptors allocated at the
+ * immr->udata_bd address on Dual-Port RAM
+ * Provide for Double Buffering
+ */
+
+typedef volatile struct CommonBufferDescriptor {
+ cbd_t rxbd[PKTBUFSRX]; /* Rx BD */
+ cbd_t txbd[TX_BUF_CNT]; /* Tx BD */
+} RTXBD;
+
+static RTXBD *rtx;
+
+ /*
+ * SCC callbacks
+ */
+
+static void scc_init (int scc_index)
+{
+ bd_t *bd = gd->bd;
+
+ static int proff[] =
+ { PROFF_SCC1, PROFF_SCC2, PROFF_SCC3, PROFF_SCC4 };
+ static unsigned int cpm_cr[] =
+ { CPM_CR_CH_SCC1, CPM_CR_CH_SCC2, CPM_CR_CH_SCC3,
+CPM_CR_CH_SCC4 };
+
+ int i;
+ scc_enet_t *pram_ptr;
+
+ volatile immap_t *immr = (immap_t *) CFG_IMMR;
+
+ immr->im_cpm.cp_scc[scc_index].scc_gsmrl &=
+ ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);
+
+#if defined(CONFIG_FADS)
+#if defined(CONFIG_MPC860T) || defined(CONFIG_MPC86xADS)
+ /* The FADS860T and MPC86xADS don't use the MODEM_EN or DATA_VOICE signals. */
+ *((uint *) BCSR4) &= ~BCSR4_ETHLOOP;
+ *((uint *) BCSR4) |= BCSR4_TFPLDL | BCSR4_TPSQEL;
+ *((uint *) BCSR1) &= ~BCSR1_ETHEN;
+#else
+ *((uint *) BCSR4) &= ~(BCSR4_ETHLOOP | BCSR4_MODEM_EN);
+ *((uint *) BCSR4) |= BCSR4_TFPLDL | BCSR4_TPSQEL | BCSR4_DATA_VOICE;
+ *((uint *) BCSR1) &= ~BCSR1_ETHEN;
+#endif
+#endif
+
+ pram_ptr = (scc_enet_t *) & (immr->im_cpm.cp_dparam[proff[scc_index]]);
+
+ rxIdx = 0;
+ txIdx = 0;
+
+#ifdef CFG_ALLOC_DPRAM
+ rtx = (RTXBD *) (immr->im_cpm.cp_dpmem +
+ dpram_alloc_align (sizeof (RTXBD), 8));
+#else
+ rtx = (RTXBD *) (immr->im_cpm.cp_dpmem + CPM_SCC_BASE);
+#endif
+
+#if 0
+
+#if (defined(PA_ENET_RXD) && defined(PA_ENET_TXD))
+ /* Configure port A pins for Txd and Rxd.
+ */
+ immr->im_ioport.iop_papar |= (PA_ENET_RXD | PA_ENET_TXD);
+ immr->im_ioport.iop_padir &= ~(PA_ENET_RXD | PA_ENET_TXD);
+ immr->im_ioport.iop_paodr &= ~PA_ENET_TXD;
+#elif (defined(PB_ENET_RXD) && defined(PB_ENET_TXD))
+ /* Configure port B pins for Txd and Rxd.
+ */
+ immr->im_cpm.cp_pbpar |= (PB_ENET_RXD | PB_ENET_TXD);
+ immr->im_cpm.cp_pbdir &= ~(PB_ENET_RXD | PB_ENET_TXD);
+ immr->im_cpm.cp_pbodr &= ~PB_ENET_TXD;
+#else
+#error Configuration Error: exactly ONE of PA_ENET_[RT]XD, PB_ENET_[RT]XD must be defined
+#endif
+
+#if defined(PC_ENET_LBK)
+ /* Configure port C pins to disable External Loopback
+ */
+ immr->im_ioport.iop_pcpar &= ~PC_ENET_LBK;
+ immr->im_ioport.iop_pcdir |= PC_ENET_LBK;
+ immr->im_ioport.iop_pcso &= ~PC_ENET_LBK;
+ immr->im_ioport.iop_pcdat &= ~PC_ENET_LBK; /* Disable Loopback */
+#endif /* PC_ENET_LBK */
+
+ /* Configure port C pins to enable CLSN and RENA.
+ */
+ immr->im_ioport.iop_pcpar &= ~(PC_ENET_CLSN | PC_ENET_RENA);
+ immr->im_ioport.iop_pcdir &= ~(PC_ENET_CLSN | PC_ENET_RENA);
+ immr->im_ioport.iop_pcso |= (PC_ENET_CLSN | PC_ENET_RENA);
+
+ /* Configure port A for TCLK and RCLK.
+ */
+ immr->im_ioport.iop_papar |= (PA_ENET_TCLK | PA_ENET_RCLK);
+ immr->im_ioport.iop_padir &= ~(PA_ENET_TCLK | PA_ENET_RCLK);
+
+ /*
+ * Configure Serial Interface clock routing -- see section 16.7.5.3
+ * First, clear all SCC bits to zero, then set the ones we want.
+ */
+
+ immr->im_cpm.cp_sicr &= ~SICR_ENET_MASK;
+ immr->im_cpm.cp_sicr |= SICR_ENET_CLKRT;
+#else
+ /*
+ * SCC2 receive clock is BRG2
+ * SCC2 transmit clock is BRG3
+ */
+ immr->im_cpm.cp_brgc2 = 0x0001000C;
+ immr->im_cpm.cp_brgc3 = 0x0001000C;
+
+ immr->im_cpm.cp_sicr &= ~0x00003F00;
+ immr->im_cpm.cp_sicr |= 0x00000a00;
+#endif /* 0 */
+
+
+ /*
+ * Initialize SDCR -- see section 16.9.23.7
+ * SDMA configuration register
+ */
+ immr->im_siu_conf.sc_sdcr = 0x01;
+
+
+ /*
+ * Setup SCC Ethernet Parameter RAM
+ */
+
+ pram_ptr->sen_genscc.scc_rfcr = 0x18; /* Normal Operation and Mot byte ordering */
+ pram_ptr->sen_genscc.scc_tfcr = 0x18; /* Mot byte ordering, Normal access */
+
+ pram_ptr->sen_genscc.scc_mrblr = DBUF_LENGTH; /* max. ET package len 1520 */
+
+ pram_ptr->sen_genscc.scc_rbase = (unsigned int) (&rtx->rxbd[0]); /* Set RXBD tbl start at Dual Port */
+ pram_ptr->sen_genscc.scc_tbase = (unsigned int) (&rtx->txbd[0]); /* Set TXBD tbl start at Dual Port */
+
+ /*
+ * Setup Receiver Buffer Descriptors (13.14.24.18)
+ * Settings:
+ * Empty, Wrap
+ */
+
+ for (i = 0; i < PKTBUFSRX; i++) {
+ rtx->rxbd[i].cbd_sc = BD_ENET_RX_EMPTY;
+ rtx->rxbd[i].cbd_datlen = 0; /* Reset */
+ rtx->rxbd[i].cbd_bufaddr = (uint) NetRxPackets[i];
+ }
+
+ rtx->rxbd[PKTBUFSRX - 1].cbd_sc |= BD_ENET_RX_WRAP;
+
+ /*
+ * Setup Ethernet Transmitter Buffer Descriptors (13.14.24.19)
+ * Settings:
+ * Add PADs to Short FRAMES, Wrap, Last, Tx CRC
+ */
+
+ for (i = 0; i < TX_BUF_CNT; i++) {
+ rtx->txbd[i].cbd_sc =
+ (BD_ENET_TX_PAD | BD_ENET_TX_LAST | BD_ENET_TX_TC);
+ rtx->txbd[i].cbd_datlen = 0; /* Reset */
+ rtx->txbd[i].cbd_bufaddr = (uint) (&txbuf[0]);
+ }
+
+ rtx->txbd[TX_BUF_CNT - 1].cbd_sc |= BD_ENET_TX_WRAP;
+
+ /*
+ * Enter Command: Initialize Rx Params for SCC
+ */
+
+ do { /* Spin until ready to issue command */
+ __asm__ ("eieio");
+ } while (immr->im_cpm.cp_cpcr & CPM_CR_FLG);
+ /* Issue command */
+ immr->im_cpm.cp_cpcr =
+ ((CPM_CR_INIT_RX << 8) | (cpm_cr[scc_index] << 4) |
+ CPM_CR_FLG);
+ do { /* Spin until command processed */
+ __asm__ ("eieio");
+ } while (immr->im_cpm.cp_cpcr & CPM_CR_FLG);
+
+ /*
+ * Ethernet Specific Parameter RAM
+ * see table 13-16, pg. 660,
+ * pg. 681 (example with suggested settings)
+ */
+
+ pram_ptr->sen_cpres = ~(0x0); /* Preset CRC */
+ pram_ptr->sen_cmask = 0xdebb20e3; /* Constant Mask for CRC */
+ pram_ptr->sen_crcec = 0x0; /* Error Counter CRC (unused) */
+ pram_ptr->sen_alec = 0x0; /* Alignment Error Counter (unused) */
+ pram_ptr->sen_disfc = 0x0; /* Discard Frame Counter (unused) */
+ pram_ptr->sen_pads = 0x8888; /* Short Frame PAD Characters */
+
+ pram_ptr->sen_retlim = 15; /* Retry Limit Threshold */
+ pram_ptr->sen_maxflr = 1518; /* MAX Frame Length Register */
+ pram_ptr->sen_minflr = 64; /* MIN Frame Length Register */
+
+ pram_ptr->sen_maxd1 = DBUF_LENGTH; /* MAX DMA1 Length Register */
+ pram_ptr->sen_maxd2 = DBUF_LENGTH; /* MAX DMA2 Length Register */
+
+ pram_ptr->sen_gaddr1 = 0x0; /* Group Address Filter 1 (unused) */
+ pram_ptr->sen_gaddr2 = 0x0; /* Group Address Filter 2 (unused) */
+ pram_ptr->sen_gaddr3 = 0x0; /* Group Address Filter 3 (unused) */
+ pram_ptr->sen_gaddr4 = 0x0; /* Group Address Filter 4 (unused) */
+
+#define ea bd->bi_enetaddr
+ pram_ptr->sen_paddrh = (ea[5] << 8) + ea[4];
+ pram_ptr->sen_paddrm = (ea[3] << 8) + ea[2];
+ pram_ptr->sen_paddrl = (ea[1] << 8) + ea[0];
+#undef ea
+
+ pram_ptr->sen_pper = 0x0; /* Persistence (unused) */
+ pram_ptr->sen_iaddr1 = 0x0; /* Individual Address Filter 1 (unused) */
+ pram_ptr->sen_iaddr2 = 0x0; /* Individual Address Filter 2 (unused) */
+ pram_ptr->sen_iaddr3 = 0x0; /* Individual Address Filter 3 (unused) */
+ pram_ptr->sen_iaddr4 = 0x0; /* Individual Address Filter 4 (unused) */
+ pram_ptr->sen_taddrh = 0x0; /* Tmp Address (MSB) (unused) */
+ pram_ptr->sen_taddrm = 0x0; /* Tmp Address (unused) */
+ pram_ptr->sen_taddrl = 0x0; /* Tmp Address (LSB) (unused) */
+
+ /*
+ * Enter Command: Initialize Tx Params for SCC
+ */
+
+ do { /* Spin until ready to issue command */
+ __asm__ ("eieio");
+ } while (immr->im_cpm.cp_cpcr & CPM_CR_FLG);
+ /* Issue command */
+ immr->im_cpm.cp_cpcr =
+ ((CPM_CR_INIT_TX << 8) | (cpm_cr[scc_index] << 4) |
+ CPM_CR_FLG);
+ do { /* Spin until command processed */
+ __asm__ ("eieio");
+ } while (immr->im_cpm.cp_cpcr & CPM_CR_FLG);
+
+ /*
+ * Mask all Events in SCCM - we use polling mode
+ */
+ immr->im_cpm.cp_scc[scc_index].scc_sccm = 0;
+
+ /*
+ * Clear Events in SCCE -- Clear bits by writing 1's
+ */
+
+ immr->im_cpm.cp_scc[scc_index].scc_scce = ~(0x0);
+
+
+ /*
+ * Initialize GSMR High 32-Bits
+ * Settings: Normal Mode
+ */
+
+ immr->im_cpm.cp_scc[scc_index].scc_gsmrh = 0;
+
+ /*
+ * Initialize GSMR Low 32-Bits, but do not Enable Transmit/Receive
+ * Settings:
+ * TCI = Invert
+ * TPL = 48 bits
+ * TPP = Repeating 10's
+ * LOOP = Loopback
+ * MODE = Ethernet
+ */
+
+ immr->im_cpm.cp_scc[scc_index].scc_gsmrl = (SCC_GSMRL_TCI |
+ SCC_GSMRL_TPL_48 |
+ SCC_GSMRL_TPP_10 |
+ SCC_GSMRL_DIAG_LOOP |
+ SCC_GSMRL_MODE_ENET);
+
+ /*
+ * Initialize the DSR -- see section 13.14.4 (pg. 513) v0.4
+ */
+
+ immr->im_cpm.cp_scc[scc_index].scc_dsr = 0xd555;
+
+ /*
+ * Initialize the PSMR
+ * Settings:
+ * CRC = 32-Bit CCITT
+ * NIB = Begin searching for SFD 22 bits after RENA
+ * LPB = Loopback Enable (Needed when FDE is set)
+ */
+ immr->im_cpm.cp_scc[scc_index].scc_psmr = SCC_PSMR_ENCRC |
+ SCC_PSMR_NIB22 | SCC_PSMR_LPB;
+
+#if 0
+ /*
+ * Configure Ethernet TENA Signal
+ */
+
+#if (defined(PC_ENET_TENA) && !defined(PB_ENET_TENA))
+ immr->im_ioport.iop_pcpar |= PC_ENET_TENA;
+ immr->im_ioport.iop_pcdir &= ~PC_ENET_TENA;
+#elif (defined(PB_ENET_TENA) && !defined(PC_ENET_TENA))
+ immr->im_cpm.cp_pbpar |= PB_ENET_TENA;
+ immr->im_cpm.cp_pbdir |= PB_ENET_TENA;
+#else
+#error Configuration Error: exactly ONE of PB_ENET_TENA, PC_ENET_TENA must be defined
+#endif
+
+#if defined(CONFIG_ADS) && defined(CONFIG_MPC860)
+ /*
+ * Port C is used to control the PHY,MC68160.
+ */
+ immr->im_ioport.iop_pcdir |=
+ (PC_ENET_ETHLOOP | PC_ENET_TPFLDL | PC_ENET_TPSQEL);
+
+ immr->im_ioport.iop_pcdat |= PC_ENET_TPFLDL;
+ immr->im_ioport.iop_pcdat &= ~(PC_ENET_ETHLOOP | PC_ENET_TPSQEL);
+ *((uint *) BCSR1) &= ~BCSR1_ETHEN;
+#endif /* MPC860ADS */
+
+#if defined(CONFIG_AMX860)
+ /*
+ * Port B is used to control the PHY,MC68160.
+ */
+ immr->im_cpm.cp_pbdir |=
+ (PB_ENET_ETHLOOP | PB_ENET_TPFLDL | PB_ENET_TPSQEL);
+
+ immr->im_cpm.cp_pbdat |= PB_ENET_TPFLDL;
+ immr->im_cpm.cp_pbdat &= ~(PB_ENET_ETHLOOP | PB_ENET_TPSQEL);
+
+ immr->im_ioport.iop_pddir |= PD_ENET_ETH_EN;
+ immr->im_ioport.iop_pddat &= ~PD_ENET_ETH_EN;
+#endif /* AMX860 */
+
+#endif /* 0 */
+
+#ifdef CONFIG_RPXCLASSIC
+ *((uchar *) BCSR0) &= ~BCSR0_ETHLPBK;
+ *((uchar *) BCSR0) |= (BCSR0_ETHEN | BCSR0_COLTEST | BCSR0_FULLDPLX);
+#endif
+
+#ifdef CONFIG_RPXLITE
+ *((uchar *) BCSR0) |= BCSR0_ETHEN;
+#endif
+
+#ifdef CONFIG_MBX
+ board_ether_init ();
+#endif
+
+ /*
+ * Set the ENT/ENR bits in the GSMR Low -- Enable Transmit/Receive
+ */
+
+ immr->im_cpm.cp_scc[scc_index].scc_gsmrl |=
+ (SCC_GSMRL_ENR | SCC_GSMRL_ENT);
+
+ /*
+ * Work around transmit problem with first eth packet
+ */
+#if defined (CONFIG_FADS)
+ udelay (10000); /* wait 10 ms */
+#elif defined (CONFIG_AMX860) || defined(CONFIG_RPXCLASSIC)
+ udelay (100000); /* wait 100 ms */
+#endif
+}
+
+static void scc_halt (int scc_index)
+{
+ volatile immap_t *immr = (immap_t *) CFG_IMMR;
+
+ immr->im_cpm.cp_scc[scc_index].scc_gsmrl &=
+ ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);
+ immr->im_ioport.iop_pcso &= ~(PC_ENET_CLSN | PC_ENET_RENA);
+}
+
+static int scc_send (int index, volatile void *packet, int length)
+{
+ int i, j = 0;
+
+ while ((rtx->txbd[txIdx].cbd_sc & BD_ENET_TX_READY) && (j < TOUT_LOOP)) {
+ udelay (1); /* will also trigger Wd if needed */
+ j++;
+ }
+ if (j >= TOUT_LOOP)
+ printf ("TX not ready\n");
+ rtx->txbd[txIdx].cbd_bufaddr = (uint) packet;
+ rtx->txbd[txIdx].cbd_datlen = length;
+ rtx->txbd[txIdx].cbd_sc |=
+ (BD_ENET_TX_READY | BD_ENET_TX_LAST | BD_ENET_TX_WRAP);
+ while ((rtx->txbd[txIdx].cbd_sc & BD_ENET_TX_READY) && (j < TOUT_LOOP)) {
+ udelay (1); /* will also trigger Wd if needed */
+ j++;
+ }
+ if (j >= TOUT_LOOP)
+ printf ("TX timeout\n");
+ i = (rtx->txbd[txIdx].
+ cbd_sc & BD_ENET_TX_STATS) /* return only status bits */ ;
+ return i;
+}
+
+static int scc_recv (int index, void *packet, int max_length)
+{
+ int length = -1;
+
+ if (rtx->rxbd[rxIdx].cbd_sc & BD_ENET_RX_EMPTY) {
+ goto Done; /* nothing received */
+ }
+
+ if (!(rtx->rxbd[rxIdx].cbd_sc & 0x003f)) {
+ length = rtx->rxbd[rxIdx].cbd_datlen - 4;
+ memcpy (packet,
+ (void *) (NetRxPackets[rxIdx]),
+ length < max_length ? length : max_length);
+ }
+
+ /* Give the buffer back to the SCC. */
+ rtx->rxbd[rxIdx].cbd_datlen = 0;
+
+ /* wrap around buffer index when necessary */
+ if ((rxIdx + 1) >= PKTBUFSRX) {
+ rtx->rxbd[PKTBUFSRX - 1].cbd_sc =
+ (BD_ENET_RX_WRAP | BD_ENET_RX_EMPTY);
+ rxIdx = 0;
+ } else {
+ rtx->rxbd[rxIdx].cbd_sc = BD_ENET_RX_EMPTY;
+ rxIdx++;
+ }
+
+Done:
+ return length;
+}
+
+ /*
+ * Test routines
+ */
+
+static void packet_fill (char *packet, int length)
+{
+ char c = (char) length;
+ int i;
+
+ packet[0] = 0xFF;
+ packet[1] = 0xFF;
+ packet[2] = 0xFF;
+ packet[3] = 0xFF;
+ packet[4] = 0xFF;
+ packet[5] = 0xFF;
+
+ for (i = 6; i < length; i++) {
+ packet[i] = c++;
+ }
+}
+
+static int packet_check (char *packet, int length)
+{
+ char c = (char) length;
+ int i;
+
+ for (i = 6; i < length; i++) {
+ if (packet[i] != c++)
+ return -1;
+ }
+
+ return 0;
+}
+
+static int test_ctlr (int ctlr, int index)
+{
+ int res = -1;
+ char packet_send[MAX_PACKET_LENGTH];
+ char packet_recv[MAX_PACKET_LENGTH];
+ int length;
+ int i;
+ int l;
+
+ ctlr_proc[ctlr].init (index);
+
+ for (i = 0; i < TEST_NUM; i++) {
+ for (l = MIN_PACKET_LENGTH; l <= MAX_PACKET_LENGTH; l++) {
+ packet_fill (packet_send, l);
+
+ ctlr_proc[ctlr].send (index, packet_send, l);
+
+ length = ctlr_proc[ctlr].recv (index, packet_recv,
+ MAX_PACKET_LENGTH);
+
+ if (length != l || packet_check (packet_recv, length) < 0) {
+ goto Done;
+ }
+ }
+ }
+
+ res = 0;
+
+Done:
+
+ ctlr_proc[ctlr].halt (index);
+
+ /*
+ * SCC2 Ethernet parameter RAM space overlaps
+ * the SPI parameter RAM space. So we need to restore
+ * the SPI configuration after SCC2 ethernet test.
+ */
+#if defined(CONFIG_SPI)
+ if (ctlr == CTLR_SCC && index == 1) {
+ spi_init_f ();
+ spi_init_r ();
+ }
+#endif
+
+ if (res != 0) {
+ post_log ("ethernet %s%d test failed\n", ctlr_name[ctlr],
+ index + 1);
+ }
+
+ return res;
+}
+
+int ether_post_test (int flags)
+{
+ int res = 0;
+ int i;
+
+ ctlr_proc[CTLR_SCC].init = scc_init;
+ ctlr_proc[CTLR_SCC].halt = scc_halt;
+ ctlr_proc[CTLR_SCC].send = scc_send;
+ ctlr_proc[CTLR_SCC].recv = scc_recv;
+
+ for (i = 0; i < CTRL_LIST_SIZE; i++) {
+ if (test_ctlr (ctlr_list[i][0], ctlr_list[i][1]) != 0) {
+ res = -1;
+ }
+ }
+
+#if !defined(CONFIG_8xx_CONS_NONE)
+ serial_reinit_all ();
+#endif
+ return res;
+}
+
+#endif /* CONFIG_POST & CFG_POST_ETHER */
+
+#endif /* CONFIG_POST */
diff --git a/post/cpu/mpc8xx/spr.c b/post/cpu/mpc8xx/spr.c
new file mode 100644
index 0000000000..330b977f1a
--- /dev/null
+++ b/post/cpu/mpc8xx/spr.c
@@ -0,0 +1,152 @@
+/*
+ * (C) Copyright 2002
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.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>
+
+/*
+ * SPR test
+ *
+ * The test checks the contents of Special Purpose Registers (SPR) listed
+ * in the spr_test_list array below.
+ * Each SPR value is read using mfspr instruction, some bits are masked
+ * according to the table and the resulting value is compared to the
+ * corresponding table value.
+ */
+
+#ifdef CONFIG_POST
+
+#include <post.h>
+
+#if CONFIG_POST & CFG_POST_SPR
+
+static struct
+{
+ int number;
+ char * name;
+ unsigned long mask;
+ unsigned long value;
+} spr_test_list [] = {
+ /* Standard Special-Purpose Registers */
+
+ {1, "XER", 0x00000000, 0x00000000},
+ {8, "LR", 0x00000000, 0x00000000},
+ {9, "CTR", 0x00000000, 0x00000000},
+ {18, "DSISR", 0x00000000, 0x00000000},
+ {19, "DAR", 0x00000000, 0x00000000},
+ {22, "DEC", 0x00000000, 0x00000000},
+ {26, "SRR0", 0x00000000, 0x00000000},
+ {27, "SRR1", 0x00000000, 0x00000000},
+ {272, "SPRG0", 0x00000000, 0x00000000},
+ {273, "SPRG1", 0x00000000, 0x00000000},
+ {274, "SPRG2", 0x00000000, 0x00000000},
+ {275, "SPRG3", 0x00000000, 0x00000000},
+ {287, "PVR", 0xFFFF0000, 0x00500000},
+
+ /* Additional Special-Purpose Registers */
+
+ {144, "CMPA", 0x00000000, 0x00000000},
+ {145, "CMPB", 0x00000000, 0x00000000},
+ {146, "CMPC", 0x00000000, 0x00000000},
+ {147, "CMPD", 0x00000000, 0x00000000},
+ {148, "ICR", 0xFFFFFFFF, 0x00000000},
+ {149, "DER", 0x00000000, 0x00000000},
+ {150, "COUNTA", 0xFFFFFFFF, 0x00000000},
+ {151, "COUNTB", 0xFFFFFFFF, 0x00000000},
+ {152, "CMPE", 0x00000000, 0x00000000},
+ {153, "CMPF", 0x00000000, 0x00000000},
+ {154, "CMPG", 0x00000000, 0x00000000},
+ {155, "CMPH", 0x00000000, 0x00000000},
+ {156, "LCTRL1", 0xFFFFFFFF, 0x00000000},
+ {157, "LCTRL2", 0xFFFFFFFF, 0x00000000},
+ {158, "ICTRL", 0xFFFFFFFF, 0x00000007},
+ {159, "BAR", 0x00000000, 0x00000000},
+ {630, "DPDR", 0x00000000, 0x00000000},
+ {631, "DPIR", 0x00000000, 0x00000000},
+ {638, "IMMR", 0xFFFF0000, CFG_IMMR },
+ {560, "IC_CST", 0x8E380000, 0x00000000},
+ {561, "IC_ADR", 0x00000000, 0x00000000},
+ {562, "IC_DAT", 0x00000000, 0x00000000},
+ {568, "DC_CST", 0xEF380000, 0x00000000},
+ {569, "DC_ADR", 0x00000000, 0x00000000},
+ {570, "DC_DAT", 0x00000000, 0x00000000},
+ {784, "MI_CTR", 0xFFFFFFFF, 0x00000000},
+ {786, "MI_AP", 0x00000000, 0x00000000},
+ {787, "MI_EPN", 0x00000000, 0x00000000},
+ {789, "MI_TWC", 0xFFFFFE02, 0x00000000},
+ {790, "MI_RPN", 0x00000000, 0x00000000},
+ {816, "MI_DBCAM", 0x00000000, 0x00000000},
+ {817, "MI_DBRAM0", 0x00000000, 0x00000000},
+ {818, "MI_DBRAM1", 0x00000000, 0x00000000},
+ {792, "MD_CTR", 0xFFFFFFFF, 0x04000000},
+ {793, "M_CASID", 0xFFFFFFF0, 0x00000000},
+ {794, "MD_AP", 0x00000000, 0x00000000},
+ {795, "MD_EPN", 0x00000000, 0x00000000},
+ {796, "M_TWB", 0x00000003, 0x00000000},
+ {797, "MD_TWC", 0x00000003, 0x00000000},
+ {798, "MD_RPN", 0x00000000, 0x00000000},
+ {799, "M_TW", 0x00000000, 0x00000000},
+ {824, "MD_DBCAM", 0x00000000, 0x00000000},
+ {825, "MD_DBRAM0", 0x00000000, 0x00000000},
+ {826, "MD_DBRAM1", 0x00000000, 0x00000000},
+};
+
+static int spr_test_list_size =
+ sizeof (spr_test_list) / sizeof (spr_test_list[0]);
+
+int spr_post_test (int flags)
+{
+ int ret = 0;
+ int ic = icache_status ();
+ int i;
+
+ unsigned long code[] = {
+ 0x7c6002a6, /* mfspr r3,SPR */
+ 0x4e800020 /* blr */
+ };
+ unsigned long (*get_spr) (void) = (void *) code;
+
+ if (ic)
+ icache_disable ();
+
+ for (i = 0; i < spr_test_list_size; i++) {
+ int num = spr_test_list[i].number;
+
+ /* mfspr r3,num */
+ code[0] = 0x7c6002a6 | ((num & 0x1F) << 16) | ((num & 0x3E0) << 6);
+
+ if ((get_spr () & spr_test_list[i].mask) !=
+ (spr_test_list[i].value & spr_test_list[i].mask)) {
+ post_log ("The value of %s special register "
+ "is incorrect: 0x%08X\n",
+ spr_test_list[i].name, get_spr ());
+ ret = -1;
+ }
+ }
+
+ if (ic)
+ icache_enable ();
+
+ return ret;
+}
+#endif /* CONFIG_POST & CFG_POST_SPR */
+#endif /* CONFIG_POST */
diff --git a/post/cpu/mpc8xx/uart.c b/post/cpu/mpc8xx/uart.c
new file mode 100644
index 0000000000..fd97e3899e
--- /dev/null
+++ b/post/cpu/mpc8xx/uart.c
@@ -0,0 +1,560 @@
+/*
+ * (C) Copyright 2002
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.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>
+
+/*
+ * UART test
+ *
+ * The Serial Management Controllers (SMC) and the Serial Communication
+ * Controllers (SCC) listed in ctlr_list array below are tested in
+ * the loopback UART mode.
+ * The controllers are configured accordingly and several characters
+ * are transmitted. The configurable test parameters are:
+ * MIN_PACKET_LENGTH - minimum size of packet to transmit
+ * MAX_PACKET_LENGTH - maximum size of packet to transmit
+ * TEST_NUM - number of tests
+ */
+
+#ifdef CONFIG_POST
+
+#include <post.h>
+#if CONFIG_POST & CFG_POST_UART
+#if defined(CONFIG_8xx)
+#include <commproc.h>
+#elif defined(CONFIG_MPC8260)
+#include <asm/cpm_8260.h>
+#else
+#error "Apparently a bad configuration, please fix."
+#endif
+#include <command.h>
+#include <serial.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define CTLR_SMC 0
+#define CTLR_SCC 1
+
+/* The list of controllers to test */
+#if defined(CONFIG_MPC823)
+static int ctlr_list[][2] =
+ { {CTLR_SMC, 0}, {CTLR_SMC, 1}, {CTLR_SCC, 1} };
+#else
+static int ctlr_list[][2] = { };
+#endif
+
+#define CTRL_LIST_SIZE (sizeof(ctlr_list) / sizeof(ctlr_list[0]))
+
+static struct {
+ void (*init) (int index);
+ void (*halt) (int index);
+ void (*putc) (int index, const char c);
+ int (*getc) (int index);
+} ctlr_proc[2];
+
+static char *ctlr_name[2] = { "SMC", "SCC" };
+
+static int proff_smc[] = { PROFF_SMC1, PROFF_SMC2 };
+static int proff_scc[] =
+ { PROFF_SCC1, PROFF_SCC2, PROFF_SCC3, PROFF_SCC4 };
+
+/*
+ * SMC callbacks
+ */
+
+static void smc_init (int smc_index)
+{
+ static int cpm_cr_ch[] = { CPM_CR_CH_SMC1, CPM_CR_CH_SMC2 };
+
+ volatile immap_t *im = (immap_t *) CFG_IMMR;
+ volatile smc_t *sp;
+ volatile smc_uart_t *up;
+ volatile cbd_t *tbdf, *rbdf;
+ volatile cpm8xx_t *cp = &(im->im_cpm);
+ uint dpaddr;
+
+ /* initialize pointers to SMC */
+
+ sp = (smc_t *) & (cp->cp_smc[smc_index]);
+ up = (smc_uart_t *) & cp->cp_dparam[proff_smc[smc_index]];
+
+ /* Disable transmitter/receiver.
+ */
+ sp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
+
+ /* Enable SDMA.
+ */
+ im->im_siu_conf.sc_sdcr = 1;
+
+ /* clear error conditions */
+#ifdef CFG_SDSR
+ im->im_sdma.sdma_sdsr = CFG_SDSR;
+#else
+ im->im_sdma.sdma_sdsr = 0x83;
+#endif
+
+ /* clear SDMA interrupt mask */
+#ifdef CFG_SDMR
+ im->im_sdma.sdma_sdmr = CFG_SDMR;
+#else
+ im->im_sdma.sdma_sdmr = 0x00;
+#endif
+
+#if defined(CONFIG_FADS)
+ /* Enable RS232 */
+ *((uint *) BCSR1) &=
+ ~(smc_index == 1 ? BCSR1_RS232EN_1 : BCSR1_RS232EN_2);
+#endif
+
+#if defined(CONFIG_RPXLITE) || defined(CONFIG_RPXCLASSIC)
+ /* Enable Monitor Port Transceiver */
+ *((uchar *) BCSR0) |= BCSR0_ENMONXCVR;
+#endif
+
+ /* Set the physical address of the host memory buffers in
+ * the buffer descriptors.
+ */
+
+#ifdef CFG_ALLOC_DPRAM
+ dpaddr = dpram_alloc_align (sizeof (cbd_t) * 2 + 2, 8);
+#else
+ dpaddr = CPM_POST_BASE;
+#endif
+
+ /* Allocate space for two buffer descriptors in the DP ram.
+ * For now, this address seems OK, but it may have to
+ * change with newer versions of the firmware.
+ * damm: allocating space after the two buffers for rx/tx data
+ */
+
+ rbdf = (cbd_t *) & cp->cp_dpmem[dpaddr];
+ rbdf->cbd_bufaddr = (uint) (rbdf + 2);
+ rbdf->cbd_sc = 0;
+ tbdf = rbdf + 1;
+ tbdf->cbd_bufaddr = ((uint) (rbdf + 2)) + 1;
+ tbdf->cbd_sc = 0;
+
+ /* Set up the uart parameters in the parameter ram.
+ */
+ up->smc_rbase = dpaddr;
+ up->smc_tbase = dpaddr + sizeof (cbd_t);
+ up->smc_rfcr = SMC_EB;
+ up->smc_tfcr = SMC_EB;
+
+#if defined(CONFIG_MBX)
+ board_serial_init ();
+#endif
+
+ /* Set UART mode, 8 bit, no parity, one stop.
+ * Enable receive and transmit.
+ * Set local loopback mode.
+ */
+ sp->smc_smcmr = smcr_mk_clen (9) | SMCMR_SM_UART | (ushort) 0x0004;
+
+ /* Mask all interrupts and remove anything pending.
+ */
+ sp->smc_smcm = 0;
+ sp->smc_smce = 0xff;
+
+ /* Set up the baud rate generator.
+ */
+ cp->cp_simode = 0x00000000;
+
+ cp->cp_brgc1 =
+ (((gd->cpu_clk / 16 / gd->baudrate) -
+ 1) << 1) | CPM_BRG_EN;
+
+ /* Make the first buffer the only buffer.
+ */
+ tbdf->cbd_sc |= BD_SC_WRAP;
+ rbdf->cbd_sc |= BD_SC_EMPTY | BD_SC_WRAP;
+
+ /* Single character receive.
+ */
+ up->smc_mrblr = 1;
+ up->smc_maxidl = 0;
+
+ /* Initialize Tx/Rx parameters.
+ */
+
+ while (cp->cp_cpcr & CPM_CR_FLG) /* wait if cp is busy */
+ ;
+
+ cp->cp_cpcr =
+ mk_cr_cmd (cpm_cr_ch[smc_index], CPM_CR_INIT_TRX) | CPM_CR_FLG;
+
+ while (cp->cp_cpcr & CPM_CR_FLG) /* wait if cp is busy */
+ ;
+
+ /* Enable transmitter/receiver.
+ */
+ sp->smc_smcmr |= SMCMR_REN | SMCMR_TEN;
+}
+
+static void smc_halt(int smc_index)
+{
+}
+
+static void smc_putc (int smc_index, const char c)
+{
+ volatile cbd_t *tbdf;
+ volatile char *buf;
+ volatile smc_uart_t *up;
+ volatile immap_t *im = (immap_t *) CFG_IMMR;
+ volatile cpm8xx_t *cpmp = &(im->im_cpm);
+
+ up = (smc_uart_t *) & cpmp->cp_dparam[proff_smc[smc_index]];
+
+ tbdf = (cbd_t *) & cpmp->cp_dpmem[up->smc_tbase];
+
+ /* Wait for last character to go.
+ */
+
+ buf = (char *) tbdf->cbd_bufaddr;
+#if 0
+ __asm__ ("eieio");
+ while (tbdf->cbd_sc & BD_SC_READY)
+ __asm__ ("eieio");
+#endif
+
+ *buf = c;
+ tbdf->cbd_datlen = 1;
+ tbdf->cbd_sc |= BD_SC_READY;
+ __asm__ ("eieio");
+#if 1
+ while (tbdf->cbd_sc & BD_SC_READY)
+ __asm__ ("eieio");
+#endif
+}
+
+static int smc_getc (int smc_index)
+{
+ volatile cbd_t *rbdf;
+ volatile unsigned char *buf;
+ volatile smc_uart_t *up;
+ volatile immap_t *im = (immap_t *) CFG_IMMR;
+ volatile cpm8xx_t *cpmp = &(im->im_cpm);
+ unsigned char c;
+ int i;
+
+ up = (smc_uart_t *) & cpmp->cp_dparam[proff_smc[smc_index]];
+
+ rbdf = (cbd_t *) & cpmp->cp_dpmem[up->smc_rbase];
+
+ /* Wait for character to show up.
+ */
+ buf = (unsigned char *) rbdf->cbd_bufaddr;
+#if 0
+ while (rbdf->cbd_sc & BD_SC_EMPTY);
+#else
+ for (i = 100; i > 0; i--) {
+ if (!(rbdf->cbd_sc & BD_SC_EMPTY))
+ break;
+ udelay (1000);
+ }
+
+ if (i == 0)
+ return -1;
+#endif
+ c = *buf;
+ rbdf->cbd_sc |= BD_SC_EMPTY;
+
+ return (c);
+}
+
+ /*
+ * SCC callbacks
+ */
+
+static void scc_init (int scc_index)
+{
+ static int cpm_cr_ch[] = {
+ CPM_CR_CH_SCC1,
+ CPM_CR_CH_SCC2,
+ CPM_CR_CH_SCC3,
+ CPM_CR_CH_SCC4,
+ };
+
+ volatile immap_t *im = (immap_t *) CFG_IMMR;
+ volatile scc_t *sp;
+ volatile scc_uart_t *up;
+ volatile cbd_t *tbdf, *rbdf;
+ volatile cpm8xx_t *cp = &(im->im_cpm);
+ uint dpaddr;
+
+ /* initialize pointers to SCC */
+
+ sp = (scc_t *) & (cp->cp_scc[scc_index]);
+ up = (scc_uart_t *) & cp->cp_dparam[proff_scc[scc_index]];
+
+ /* Disable transmitter/receiver.
+ */
+ sp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);
+
+
+ /* Allocate space for two buffer descriptors in the DP ram.
+ */
+
+#ifdef CFG_ALLOC_DPRAM
+ dpaddr = dpram_alloc_align (sizeof (cbd_t) * 2 + 2, 8);
+#else
+ dpaddr = CPM_POST_BASE;
+#endif
+
+ /* Enable SDMA.
+ */
+ im->im_siu_conf.sc_sdcr = 0x0001;
+
+ /* Set the physical address of the host memory buffers in
+ * the buffer descriptors.
+ */
+
+ rbdf = (cbd_t *) & cp->cp_dpmem[dpaddr];
+ rbdf->cbd_bufaddr = (uint) (rbdf + 2);
+ rbdf->cbd_sc = 0;
+ tbdf = rbdf + 1;
+ tbdf->cbd_bufaddr = ((uint) (rbdf + 2)) + 1;
+ tbdf->cbd_sc = 0;
+
+ /* Set up the baud rate generator.
+ */
+ cp->cp_sicr &= ~(0x000000FF << (8 * scc_index));
+ /* no |= needed, since BRG1 is 000 */
+
+ cp->cp_brgc1 =
+ (((gd->cpu_clk / 16 / gd->baudrate) -
+ 1) << 1) | CPM_BRG_EN;
+
+ /* Set up the uart parameters in the parameter ram.
+ */
+ up->scc_genscc.scc_rbase = dpaddr;
+ up->scc_genscc.scc_tbase = dpaddr + sizeof (cbd_t);
+
+ /* Initialize Tx/Rx parameters.
+ */
+ while (cp->cp_cpcr & CPM_CR_FLG) /* wait if cp is busy */
+ ;
+ cp->cp_cpcr =
+ mk_cr_cmd (cpm_cr_ch[scc_index], CPM_CR_INIT_TRX) | CPM_CR_FLG;
+
+ while (cp->cp_cpcr & CPM_CR_FLG) /* wait if cp is busy */
+ ;
+
+ up->scc_genscc.scc_rfcr = SCC_EB | 0x05;
+ up->scc_genscc.scc_tfcr = SCC_EB | 0x05;
+
+ up->scc_genscc.scc_mrblr = 1; /* Single character receive */
+ up->scc_maxidl = 0; /* disable max idle */
+ up->scc_brkcr = 1; /* send one break character on stop TX */
+ up->scc_parec = 0;
+ up->scc_frmec = 0;
+ up->scc_nosec = 0;
+ up->scc_brkec = 0;
+ up->scc_uaddr1 = 0;
+ up->scc_uaddr2 = 0;
+ up->scc_toseq = 0;
+ up->scc_char1 = 0x8000;
+ up->scc_char2 = 0x8000;
+ up->scc_char3 = 0x8000;
+ up->scc_char4 = 0x8000;
+ up->scc_char5 = 0x8000;
+ up->scc_char6 = 0x8000;
+ up->scc_char7 = 0x8000;
+ up->scc_char8 = 0x8000;
+ up->scc_rccm = 0xc0ff;
+
+ /* Set low latency / small fifo.
+ */
+ sp->scc_gsmrh = SCC_GSMRH_RFW;
+
+ /* Set UART mode
+ */
+ sp->scc_gsmrl &= ~0xF;
+ sp->scc_gsmrl |= SCC_GSMRL_MODE_UART;
+
+ /* Set local loopback mode.
+ */
+ sp->scc_gsmrl &= ~SCC_GSMRL_DIAG_LE;
+ sp->scc_gsmrl |= SCC_GSMRL_DIAG_LOOP;
+
+ /* Set clock divider 16 on Tx and Rx
+ */
+ sp->scc_gsmrl |= (SCC_GSMRL_TDCR_16 | SCC_GSMRL_RDCR_16);
+
+ sp->scc_psmr |= SCU_PSMR_CL;
+
+ /* Mask all interrupts and remove anything pending.
+ */
+ sp->scc_sccm = 0;
+ sp->scc_scce = 0xffff;
+ sp->scc_dsr = 0x7e7e;
+ sp->scc_psmr = 0x3000;
+
+ /* Make the first buffer the only buffer.
+ */
+ tbdf->cbd_sc |= BD_SC_WRAP;
+ rbdf->cbd_sc |= BD_SC_EMPTY | BD_SC_WRAP;
+
+ /* Enable transmitter/receiver.
+ */
+ sp->scc_gsmrl |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT);
+}
+
+static void scc_halt(int scc_index)
+{
+ volatile immap_t *im = (immap_t *) CFG_IMMR;
+ volatile cpm8xx_t *cp = &(im->im_cpm);
+ volatile scc_t *sp = (scc_t *) & (cp->cp_scc[scc_index]);
+
+ sp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT | SCC_GSMRL_DIAG_LE);
+}
+
+static void scc_putc (int scc_index, const char c)
+{
+ volatile cbd_t *tbdf;
+ volatile char *buf;
+ volatile scc_uart_t *up;
+ volatile immap_t *im = (immap_t *) CFG_IMMR;
+ volatile cpm8xx_t *cpmp = &(im->im_cpm);
+
+ up = (scc_uart_t *) & cpmp->cp_dparam[proff_scc[scc_index]];
+
+ tbdf = (cbd_t *) & cpmp->cp_dpmem[up->scc_genscc.scc_tbase];
+
+ /* Wait for last character to go.
+ */
+
+ buf = (char *) tbdf->cbd_bufaddr;
+#if 0
+ __asm__ ("eieio");
+ while (tbdf->cbd_sc & BD_SC_READY)
+ __asm__ ("eieio");
+#endif
+
+ *buf = c;
+ tbdf->cbd_datlen = 1;
+ tbdf->cbd_sc |= BD_SC_READY;
+ __asm__ ("eieio");
+#if 1
+ while (tbdf->cbd_sc & BD_SC_READY)
+ __asm__ ("eieio");
+#endif
+}
+
+static int scc_getc (int scc_index)
+{
+ volatile cbd_t *rbdf;
+ volatile unsigned char *buf;
+ volatile scc_uart_t *up;
+ volatile immap_t *im = (immap_t *) CFG_IMMR;
+ volatile cpm8xx_t *cpmp = &(im->im_cpm);
+ unsigned char c;
+ int i;
+
+ up = (scc_uart_t *) & cpmp->cp_dparam[proff_scc[scc_index]];
+
+ rbdf = (cbd_t *) & cpmp->cp_dpmem[up->scc_genscc.scc_rbase];
+
+ /* Wait for character to show up.
+ */
+ buf = (unsigned char *) rbdf->cbd_bufaddr;
+#if 0
+ while (rbdf->cbd_sc & BD_SC_EMPTY);
+#else
+ for (i = 100; i > 0; i--) {
+ if (!(rbdf->cbd_sc & BD_SC_EMPTY))
+ break;
+ udelay (1000);
+ }
+
+ if (i == 0)
+ return -1;
+#endif
+ c = *buf;
+ rbdf->cbd_sc |= BD_SC_EMPTY;
+
+ return (c);
+}
+
+ /*
+ * Test routines
+ */
+
+static int test_ctlr (int ctlr, int index)
+{
+ int res = -1;
+ char test_str[] = "*** UART Test String ***\r\n";
+ int i;
+
+ ctlr_proc[ctlr].init (index);
+
+ for (i = 0; i < sizeof (test_str) - 1; i++) {
+ ctlr_proc[ctlr].putc (index, test_str[i]);
+ if (ctlr_proc[ctlr].getc (index) != test_str[i])
+ goto Done;
+ }
+
+ res = 0;
+
+Done:
+ ctlr_proc[ctlr].halt (index);
+
+ if (res != 0) {
+ post_log ("uart %s%d test failed\n",
+ ctlr_name[ctlr], index + 1);
+ }
+
+ return res;
+}
+
+int uart_post_test (int flags)
+{
+ int res = 0;
+ int i;
+
+ ctlr_proc[CTLR_SMC].init = smc_init;
+ ctlr_proc[CTLR_SMC].halt = smc_halt;
+ ctlr_proc[CTLR_SMC].putc = smc_putc;
+ ctlr_proc[CTLR_SMC].getc = smc_getc;
+
+ ctlr_proc[CTLR_SCC].init = scc_init;
+ ctlr_proc[CTLR_SCC].halt = scc_halt;
+ ctlr_proc[CTLR_SCC].putc = scc_putc;
+ ctlr_proc[CTLR_SCC].getc = scc_getc;
+
+ for (i = 0; i < CTRL_LIST_SIZE; i++) {
+ if (test_ctlr (ctlr_list[i][0], ctlr_list[i][1]) != 0) {
+ res = -1;
+ }
+ }
+
+#if !defined(CONFIG_8xx_CONS_NONE)
+ serial_reinit_all ();
+#endif
+
+ return res;
+}
+
+#endif /* CONFIG_POST & CFG_POST_UART */
+
+#endif /* CONFIG_POST */
diff --git a/post/cpu/mpc8xx/usb.c b/post/cpu/mpc8xx/usb.c
new file mode 100644
index 0000000000..0c74cfa5da
--- /dev/null
+++ b/post/cpu/mpc8xx/usb.c
@@ -0,0 +1,269 @@
+/*
+ * (C) Copyright 2002
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.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>
+
+/*
+ * USB test
+ *
+ * The USB controller is tested in the local loopback mode.
+ * It is configured so that endpoint 0 operates as host and endpoint 1
+ * operates as function endpoint. After that an IN token transaction
+ * is performed.
+ * Refer to MPC850 User Manual, Section 32.11.1 USB Host Controller
+ * Initialization Example.
+ */
+
+#ifdef CONFIG_POST
+
+#include <post.h>
+
+#if CONFIG_POST & CFG_POST_USB
+
+#include <commproc.h>
+#include <command.h>
+
+#define TOUT_LOOP 100
+
+#define PROFF_USB ((uint)0x0000)
+
+#define CPM_USB_EP0_BASE 0x0a00
+#define CPM_USB_EP1_BASE 0x0a20
+
+#define CPM_USB_DT0_BASE 0x0a80
+#define CPM_USB_DT1_BASE 0x0a90
+#define CPM_USB_DR0_BASE 0x0aa0
+#define CPM_USB_DR1_BASE 0x0ab0
+
+#define CPM_USB_RX0_BASE 0x0b00
+#define CPM_USB_RX1_BASE 0x0b08
+#define CPM_USB_TX0_BASE 0x0b20
+#define CPM_USB_TX1_BASE 0x0b28
+
+#define USB_EXPECT(x) if (!(x)) goto Done;
+
+typedef struct usb_param {
+ ushort ep0ptr;
+ ushort ep1ptr;
+ ushort ep2ptr;
+ ushort ep3ptr;
+ uint rstate;
+ uint rptr;
+ ushort frame_n;
+ ushort rbcnt;
+ ushort rtemp;
+} usb_param_t;
+
+typedef struct usb_param_block {
+ ushort rbase;
+ ushort tbase;
+ uchar rfcr;
+ uchar tfcr;
+ ushort mrblr;
+ ushort rbptr;
+ ushort tbptr;
+ uint tstate;
+ uint tptr;
+ ushort tcrc;
+ ushort tbcnt;
+ uint res[2];
+} usb_param_block_t;
+
+typedef struct usb {
+ uchar usmod;
+ uchar usadr;
+ uchar uscom;
+ uchar res1;
+ ushort usep[4];
+ uchar res2[4];
+ ushort usber;
+ uchar res3[2];
+ ushort usbmr;
+ uchar res4;
+ uchar usbs;
+ uchar res5[8];
+} usb_t;
+
+int usb_post_test (int flags)
+{
+ int res = -1;
+ volatile immap_t *im = (immap_t *) CFG_IMMR;
+ volatile cpm8xx_t *cp = &(im->im_cpm);
+ volatile usb_param_t *pram_ptr;
+ uint dpram;
+ ushort DPRAM;
+ volatile cbd_t *tx;
+ volatile cbd_t *rx;
+ volatile usb_t *usbr;
+ volatile usb_param_block_t *ep0;
+ volatile usb_param_block_t *ep1;
+ int j;
+
+ pram_ptr = (usb_param_t *) & (im->im_cpm.cp_dparam[PROFF_USB]);
+ dpram = (uint) im->im_cpm.cp_dpmem;
+ DPRAM = dpram;
+ tx = (cbd_t *) (dpram + CPM_USB_TX0_BASE);
+ rx = (cbd_t *) (dpram + CPM_USB_RX0_BASE);
+ ep0 = (usb_param_block_t *) (dpram + CPM_USB_EP0_BASE);
+ ep1 = (usb_param_block_t *) (dpram + CPM_USB_EP1_BASE);
+ usbr = (usb_t *) & (im->im_cpm.cp_scc[0]);
+
+ /* 01 */
+ im->im_ioport.iop_padir &= ~(ushort) 0x0200;
+ im->im_ioport.iop_papar |= (ushort) 0x0200;
+
+ cp->cp_sicr &= ~0x000000FF;
+ cp->cp_sicr |= 0x00000018;
+
+ cp->cp_brgc4 = 0x00010001;
+
+ /* 02 */
+ im->im_ioport.iop_padir &= ~(ushort) 0x0002;
+ im->im_ioport.iop_padir &= ~(ushort) 0x0001;
+
+ im->im_ioport.iop_papar |= (ushort) 0x0002;
+ im->im_ioport.iop_papar |= (ushort) 0x0001;
+
+ /* 03 */
+ im->im_ioport.iop_pcdir &= ~(ushort) 0x0020;
+ im->im_ioport.iop_pcdir &= ~(ushort) 0x0010;
+
+ im->im_ioport.iop_pcpar &= ~(ushort) 0x0020;
+ im->im_ioport.iop_pcpar &= ~(ushort) 0x0010;
+
+ im->im_ioport.iop_pcso |= (ushort) 0x0020;
+ im->im_ioport.iop_pcso |= (ushort) 0x0010;
+
+ /* 04 */
+ im->im_ioport.iop_pcdir |= (ushort) 0x0200;
+ im->im_ioport.iop_pcdir |= (ushort) 0x0100;
+
+ im->im_ioport.iop_pcpar |= (ushort) 0x0200;
+ im->im_ioport.iop_pcpar |= (ushort) 0x0100;
+
+ /* 05 */
+ pram_ptr->frame_n = 0;
+
+ /* 06 */
+ pram_ptr->ep0ptr = DPRAM + CPM_USB_EP0_BASE;
+ pram_ptr->ep1ptr = DPRAM + CPM_USB_EP1_BASE;
+
+ /* 07-10 */
+ tx[0].cbd_sc = 0xB800;
+ tx[0].cbd_datlen = 3;
+ tx[0].cbd_bufaddr = dpram + CPM_USB_DT0_BASE;
+
+ tx[1].cbd_sc = 0xBC80;
+ tx[1].cbd_datlen = 3;
+ tx[1].cbd_bufaddr = dpram + CPM_USB_DT1_BASE;
+
+ rx[0].cbd_sc = 0xA000;
+ rx[0].cbd_datlen = 0;
+ rx[0].cbd_bufaddr = dpram + CPM_USB_DR0_BASE;
+
+ rx[1].cbd_sc = 0xA000;
+ rx[1].cbd_datlen = 0;
+ rx[1].cbd_bufaddr = dpram + CPM_USB_DR1_BASE;
+
+ /* 11-12 */
+ *(volatile int *) (dpram + CPM_USB_DT0_BASE) = 0x69856000;
+ *(volatile int *) (dpram + CPM_USB_DT1_BASE) = 0xABCD1234;
+
+ *(volatile int *) (dpram + CPM_USB_DR0_BASE) = 0;
+ *(volatile int *) (dpram + CPM_USB_DR1_BASE) = 0;
+
+ /* 13-16 */
+ ep0->rbase = DPRAM + CPM_USB_RX0_BASE;
+ ep0->tbase = DPRAM + CPM_USB_TX0_BASE;
+ ep0->rfcr = 0x18;
+ ep0->tfcr = 0x18;
+ ep0->mrblr = 0x100;
+ ep0->rbptr = DPRAM + CPM_USB_RX0_BASE;
+ ep0->tbptr = DPRAM + CPM_USB_TX0_BASE;
+ ep0->tstate = 0;
+
+ /* 17-20 */
+ ep1->rbase = DPRAM + CPM_USB_RX1_BASE;
+ ep1->tbase = DPRAM + CPM_USB_TX1_BASE;
+ ep1->rfcr = 0x18;
+ ep1->tfcr = 0x18;
+ ep1->mrblr = 0x100;
+ ep1->rbptr = DPRAM + CPM_USB_RX1_BASE;
+ ep1->tbptr = DPRAM + CPM_USB_TX1_BASE;
+ ep1->tstate = 0;
+
+ /* 21-24 */
+ usbr->usep[0] = 0x0000;
+ usbr->usep[1] = 0x1100;
+ usbr->usep[2] = 0x2200;
+ usbr->usep[3] = 0x3300;
+
+ /* 25 */
+ usbr->usmod = 0x06;
+
+ /* 26 */
+ usbr->usadr = 0x05;
+
+ /* 27 */
+ usbr->uscom = 0;
+
+ /* 28 */
+ usbr->usmod |= 0x01;
+ udelay (1);
+
+ /* 29-30 */
+ usbr->uscom = 0x80;
+ usbr->uscom = 0x81;
+
+ /* Wait for the data packet to be transmitted */
+ for (j = 0; j < TOUT_LOOP; j++) {
+ if (tx[1].cbd_sc & (ushort) 0x8000)
+ udelay (1);
+ else
+ break;
+ }
+
+ USB_EXPECT (j < TOUT_LOOP);
+
+ USB_EXPECT (tx[0].cbd_sc == 0x3800);
+ USB_EXPECT (tx[0].cbd_datlen == 3);
+
+ USB_EXPECT (tx[1].cbd_sc == 0x3C80);
+ USB_EXPECT (tx[1].cbd_datlen == 3);
+
+ USB_EXPECT (rx[0].cbd_sc == 0x2C00);
+ USB_EXPECT (rx[0].cbd_datlen == 5);
+
+ USB_EXPECT (*(volatile int *) (dpram + CPM_USB_DR0_BASE) ==
+ 0xABCD122B);
+ USB_EXPECT (*(volatile char *) (dpram + CPM_USB_DR0_BASE + 4) == 0x42);
+
+ res = 0;
+ Done:
+
+ return res;
+}
+
+#endif /* CONFIG_POST & CFG_POST_USB */
+
+#endif /* CONFIG_POST */
diff --git a/post/cpu/mpc8xx/watchdog.c b/post/cpu/mpc8xx/watchdog.c
new file mode 100644
index 0000000000..48c4282e1d
--- /dev/null
+++ b/post/cpu/mpc8xx/watchdog.c
@@ -0,0 +1,78 @@
+/*
+ * (C) Copyright 2002
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.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>
+
+/*
+ * Watchdog test
+ *
+ * The test verifies the watchdog timer operation.
+ * On the first iteration, the test routine disables interrupts and
+ * makes a 10-second delay. If the system does not reboot during this delay,
+ * the watchdog timer is not operational and the test fails. If the system
+ * reboots, on the second iteration the test routine reports a success.
+ */
+
+#ifdef CONFIG_POST
+
+#include <post.h>
+#include <watchdog.h>
+
+#if CONFIG_POST & CFG_POST_WATCHDOG
+
+static ulong gettbl (void)
+{
+ ulong r;
+
+ asm ("mftbl %0":"=r" (r));
+
+ return r;
+}
+
+int watchdog_post_test (int flags)
+{
+ if (flags & POST_REBOOT) {
+ /* Test passed */
+
+ return 0;
+ } else {
+ /* 10-second delay */
+ int ints = disable_interrupts ();
+ ulong base = gettbl ();
+ ulong clk = get_tbclk ();
+
+ while ((gettbl () - base) / 10 < clk);
+
+ if (ints)
+ enable_interrupts ();
+
+ /*
+ * If we have reached this point, the watchdog timer
+ * does not work
+ */
+ return -1;
+ }
+}
+
+#endif /* CONFIG_POST & CFG_POST_WATCHDOG */
+#endif /* CONFIG_POST */
OpenPOWER on IntegriCloud