(and it uses default address).
======================================================================
-Modifications since 0.6.3:
+Modifications for 0.6.4:
======================================================================
+* Added support for console on SCCx
+
+* Added configuration for ADS860 board
+
+* Add support for MPC860TFADS with ethernet on FEC (but default is
+ still on SCC1)
+
+* Add PHY type checking.
+
+* Fix typos in mpc8260.h
+
+* Check mask revision in mpc8260/cpu.c
+
+* Add support for OR/BR[45] in mpc8260/cpu_init.c
+
+* Map ELIC and SHARC regions for IVMS8
+
* Fix timeout handling in TFTP code
* Fix Bug in Boot File Size calculation
echo "CPU = mpc8xx" >>config.mk ; \
echo "#include <config_$(@:_config=).h>" >config.h
+ADS860_config: unconfig
+ @echo "Configuring for $(@:_config=) Board..." ; \
+ cd include ; \
+ echo "ARCH = ppc" > config.mk ; \
+ echo "BOARD = fads" >>config.mk ; \
+ echo "CPU = mpc8xx" >>config.mk ; \
+ echo "#include <config_$(@:_config=).h>" >config.h
+
CPCI405_config: unconfig
@echo "Configuring for $(@:_config=) Board..." ; \
cd include ; \
init_data_t *idata = (init_data_t *)(CFG_INIT_RAM_ADDR + CFG_INIT_DATA_OFFSET);
extern void malloc_bin_reloc (ulong);
+#if defined(CONFIG_SPD823TS) || defined(CONFIG_IVMS8)
+ void reset_phy(void);
+#endif
#ifdef DEBUG
printf(" Now running in RAM - dest_addr = 0x%08lx\n", dest_addr);
reset_phy ();
#endif
+#ifdef CONFIG_PCMCIA
+ printf(" PCMCIA: ");
+ pcmcia_init();
+#endif
+
#if (CONFIG_COMMANDS & CFG_CMD_IDE)
printf (" IDE: ");
ide_init(bd);
bd->bi_mon_fnc->free_hdlr = irq_free_handler;
/* Initialize other board modules */
-#ifdef CONFIG_PCMCIA
- printf(" PCMCIA: ");
- pcmcia_init();
-#endif
-
#ifdef CONFIG_PCI_PNP
/*
* Do pci plug-n-play configuration
if ((i >= 100) && ((i%100)==0)) {
putc ('.');
}
+ i++;
} while (c & ATA_STAT_BUSY);
if (c & (ATA_STAT_BUSY | ATA_STAT_FAULT)) {
return (val);
}
+__inline__ unsigned ld_le16(const volatile unsigned short *addr)
+{
+ unsigned val;
+
+ __asm__ __volatile__ ("lhbrx %0,0,%1" : "=r"(val) : "r"(addr), "m"(*addr));
+ return val;
+}
+
static void
input_swap_data(int dev, ulong *sect_buf, int words)
{
}
#endif /* CFG_PB_IDE_MOTOR */
- udelay (100000);
+ for (i=0; i<25; ++i) {
+ udelay (10000);
+ }
}
#endif /* CONFIG_IDE_RESET */
{
uint k;
+#ifdef CONFIG_FADS
k = (*((uint *)BCSR3) >> 24) & 0x3f;
switch(k)
}
return 0;
+#endif /* CONFIG_FADS */
+
+#ifdef CONFIG_ADS
+ printf("ADS rev ");
+
+ k = (((*((uint *)BCSR3) >> 23) & 1) << 3)
+ | (((*((uint *)BCSR3) >> 19) & 1) << 2)
+ | (((*((uint *)BCSR3) >> 16) & 3));
+
+ switch(k)
+ {
+ case 0x00 : printf("ENG - this board suck, check the errata, no support\n");
+ return -1;
+ case 0x01 : printf("PILOT - warning, read errata \n"); break;
+ case 0x02 : printf("A - warning, read errata \n"); break;
+ case 0x03 : printf("B \n"); break;
+ default: printf("unknown revision (0x%x)\n", k); return -1;
+ }
+
+ return 0;
+#endif /* CONFIG_ADS */
+
}
/* ------------------------------------------------------------------------- */
break;
}
- case 16: /* 16 Mbyte uses only CS2 */
+ case 16: /* 16 Mbyte uses both CS2 and CS3 */
{
- memctl->memc_mamr = 0x13b01114;
+ memctl->memc_mamr = 0x60b21114;
memctl->memc_or2 = 0xff000800;
break;
}
}
memctl->memc_br2 = 0x81 + base; /* use upma */
-
return 0;
}
long int initdram (int board_type)
{
- uint base = (unsigned long)0x00400000;
+ uint base = (unsigned long)0x0;
uint k, m, s;
k = (*((uint *)BCSR2) >> 23) & 0x0f;
if(!_draminit(base, m, s, k))
{
+#ifdef CONFIG_FADS
uint sdramsz;
-
- *((uint *)BCSR1) &= ~BCSR1_DRAM_EN; /* enable dram */
+#endif
+ *((uint *)BCSR1) &= ~BCSR1_DRAM_EN; /* enable dram */
#ifdef CONFIG_FADS
if (!initsdram(0x00000000, &sdramsz)) {
return (0);
}
+
#ifdef CONFIG_PCMCIA
#ifdef CFG_PCMCIA_MEM_ADDR
return -1;
}
else
- printf("Unknown card (");
+ printf("Card present (");
v = 0;
/* This ENET stuff is for the MPC860TFADS with ethernet on SCC1.
*/
+#ifdef CONFIG_SCC1_ENET
+#define SCC_ENET 0
+#endif /* CONFIG_SCC1_ETHERNET */
#define PROFF_ENET PROFF_SCC1
#define CPM_CR_ENET CPM_CR_CH_SCC1
-#define SCC_ENET 0
#define PA_ENET_RXD ((ushort)0x0001)
#define PA_ENET_TXD ((ushort)0x0002)
#define SICR_ENET_MASK ((uint)0x000000ff)
#define SICR_ENET_CLKRT ((uint)0x0000002c)
+/* This ENET stuff is for the MPC860TFADS with ethernet on FEC.
+ */
+
+#ifdef CONFIG_FEC_ENET
+#define FEC_ENET /* use FEC for EThernet */
+#endif /* CONFIG_FEC_ETHERNET */
+
#endif /* CONFIG_FADS860T */
/*** MPC860ADS ********************************************************/
#undef CONFIG_WATCHDOG /* watchdog disabled */
+/* choose SCC1 ethernet (10BASET on motherboard)
+ * or FEC ethernet (10/100 on daughterboard)
+ */
+#if 1
+#define CONFIG_SCC1_ENET 1 /* use SCC1 ethernet */
+#undef CONFIG_FEC_ENET /* disable FEC ethernet */
+#else
+#undef CONFIG_SCC1_ENET /* disable SCC1 ethernet */
+#define CONFIG_FEC_ENET 1 /* use FEC ethernet */
+#define CFG_DISCOVER_PHY
+#endif
+#if defined(CONFIG_SCC1_ENET) && defined(CONFIG_FEC_ENET)
+#error Both CONFIG_SCC1_ENET and CONFIG_FEC_ENET configured
+#endif
+
/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
#include <cmd_confdefs.h>
*-----------------------------------------------------------------------
* set the PLL, the low-power modes and the reset control (15-29)
*/
-#define CFG_PLPRCR (((MPC8XX_FACT-1) << 20) | \
+#define CFG_PLPRCR (((MPC8XX_FACT-1) << PLPRCR_MF_SHIFT) | \
PLPRCR_SPLSS | PLPRCR_TEXPS | PLPRCR_TMIST)
/*-----------------------------------------------------------------------
#define CFG_BR0_PRELIM ((FLASH_BASE0_PRELIM & BR_BA_MSK) | BR_PS_16 | BR_V )
/*
- * BR2-5 and OR2-5 (SRAM/SDRAM/PER8/SHARC)
+ * BR1/OR1 - ELIC SACCO bank @ 0xFE000000
*
+ * AM=0xFFFF8 ATM=0 CSNT/SAM=1 ACS/G5LA/G5LS=3 BIH=1 SCY=2 SETA=0 TRLX=1 EHTR=1
*/
-#define SRAM_BASE 0xFE200000 /* SRAM bank */
-#define SRAM_OR_AM 0xFFE00000 /* SRAM is 2 MB */
+#define ELIC_SACCO_BASE 0xFE000000
+#define ELIC_SACCO_OR_AM 0xFFFF8000
+#define ELIC_SACCO_TIMING 0x00000F26
-#define SDRAM_BASE3_PRELIM 0x00000000 /* SDRAM bank */
-#define SDRAM_PRELIM_OR_AM 0xF8000000 /* map max. 128 MB */
-#define SDRAM_MAX_SIZE 0x04000000 /* max 64 MB SDRAM */
-
-#define PER8_BASE 0xFE000000 /* PER8 bank */
-#define PER8_OR_AM 0xFFF00000 /* PER8 is 1 MB */
+#define CFG_OR1 (ELIC_SACCO_OR_AM | ELIC_SACCO_TIMING)
+#define CFG_BR1 ((ELIC_SACCO_BASE & BR_BA_MSK) | BR_PS_8 | BR_V )
-#define SHARC_BASE 0xFE400000 /* SHARC bank */
-#define SHARC_OR_AM 0xFFC00000 /* SHARC is 4 MB */
+/*
+ * BR2/OR2 - ELIC EPIC bank @ 0xFE008000
+ *
+ * AM=0xFFFF8 ATM=0 CSNT/SAM=1 ACS/G5LA/G5LS=3 BIH=1 SCY=2 SETA=0 TRLX=1 EHTR=1
+ */
+#define ELIC_EPIC_BASE 0xFE000000
+#define ELIC_EPIC_OR_AM 0xFFFF8000
+#define ELIC_EPIC_TIMING 0x00000F26
-/* SRAM timing: Multiplexed addresses, GPL5 output to GPL5_A (don't care) */
+#define CFG_OR2 (ELIC_EPIC_OR_AM | ELIC_EPIC_TIMING)
+#define CFG_BR2 ((ELIC_EPIC_BASE & BR_BA_MSK) | BR_PS_8 | BR_V )
-#define CFG_OR_TIMING_SRAM 0x00000D42 /* SRAM-Timing */
-#define CFG_OR2 (SRAM_OR_AM | CFG_OR_TIMING_SRAM )
-#define CFG_BR2 ((SRAM_BASE & BR_BA_MSK) | BR_PS_16 | BR_V )
+/*
+ * BR3/OR3: SDRAM
+ *
+ * Multiplexed addresses, GPL5 output to GPL5_A (don't care)
+ */
+#define SDRAM_BASE3_PRELIM 0x00000000 /* SDRAM bank */
+#define SDRAM_PRELIM_OR_AM 0xF8000000 /* map max. 128 MB */
+#define SDRAM_TIMING 0x00000A00 /* SDRAM-Timing */
-/* SDRAM timing: Multiplexed addresses, GPL5 output to GPL5_A (don't care) */
+#define SDRAM_MAX_SIZE 0x04000000 /* max 64 MB SDRAM */
-#define CFG_OR_TIMING_SDRAM 0x00000A00 /* SDRAM-Timing */
-#define CFG_OR3_PRELIM (SDRAM_PRELIM_OR_AM | CFG_OR_TIMING_SDRAM )
+#define CFG_OR3_PRELIM (SDRAM_PRELIM_OR_AM | SDRAM_TIMING )
#define CFG_BR3_PRELIM ((SDRAM_BASE3_PRELIM & BR_BA_MSK) | BR_MS_UPMB | BR_V )
-#define CFG_OR_TIMING_PER8 0x00000F32 /* PER8-Timing */
-#define CFG_OR4 (PER8_OR_AM | CFG_OR_TIMING_PER8 )
-#define CFG_BR4 ((PER8_BASE & BR_BA_MSK) | BR_PS_8 | BR_V )
+/*
+ * BR4/OR4: not used
+ */
-#define CFG_OR_TIMING_SHARC 0x00000700 /* SHARC-Timing */
-#define CFG_OR5 (SHARC_OR_AM | CFG_OR_TIMING_SHARC )
+/*
+ * BR5/OR5: SHARC ADSP-2165L
+ *
+ * AM=0xFFC00 ATM=0 CSNT/SAM=0 ACS/G5LA/G5LS=3 BIH=1 SCY=0 SETA=0 TRLX=0 EHTR=0
+ */
+#define SHARC_BASE 0xFE400000
+#define SHARC_OR_AM 0xFFC00000
+#define SHARC_TIMING 0x00000700
+
+#define CFG_OR5 (SHARC_OR_AM | SHARC_TIMING )
#define CFG_BR5 ((SHARC_BASE & BR_BA_MSK) | BR_PS_32 | BR_MS_UPMA | BR_V )
+
/*
* Memory Periodic Timer Prescaler
*/
#define ORxS_NUMR_15 0x00000180 /* 15 Row Address Lines */
#define ORxS_NUMR_16 0x000001c0 /* 16 Row Address Lines */
+/* helper to determine the AM for a given size (SDRAM mode) */
+#define ORxS_SIZE_TO_AM(s) ((~((s) - 1)) & 0xffff8000) /* must be pow of 2 */
+
/*-----------------------------------------------------------------------
* ORx - Memory Controller: Option Register - GPCM Mode 10-18
*/
#define PSDMR_CL_2 0x00000002 /* CAS Latency = 2 */
#define PSDMR_CL_3 0x00000003 /* CAS Latency = 3 */
+/*-----------------------------------------------------------------------
+ * LSDMR - Local Bus SDRAM Mode Register 10-24
+ */
+
+/*
+ * No definitions here - the LSDMR has the same fields as the PSDMR.
+ */
+
/*-----------------------------------------------------------------------
* MPTPR - Memory Refresh Timer Prescaler Register 10-32
*/
#define CMXFCR_RF1CS_CLK11 0x30000000 /* Receive FCC1 Clock Source is CLK11 */
#define CMXFCR_RF1CS_CLK12 0x38000000 /* Receive FCC1 Clock Source is CLK12 */
-#define CMXFCR_TF1CS_BRG5 0x00000000 /* Receive FCC1 Clock Source is BRG5 */
-#define CMXFCR_TF1CS_BRG6 0x01000000 /* Receive FCC1 Clock Source is BRG6 */
-#define CMXFCR_TF1CS_BRG7 0x02000000 /* Receive FCC1 Clock Source is BRG7 */
-#define CMXFCR_TF1CS_BRG8 0x03000000 /* Receive FCC1 Clock Source is BRG8 */
-#define CMXFCR_TF1CS_CLK9 0x04000000 /* Receive FCC1 Clock Source is CLK9 */
-#define CMXFCR_TF1CS_CLK10 0x05000000 /* Receive FCC1 Clock Source is CLK10 */
-#define CMXFCR_TF1CS_CLK11 0x06000000 /* Receive FCC1 Clock Source is CLK11 */
-#define CMXFCR_TF1CS_CLK12 0x07000000 /* Receive FCC1 Clock Source is CLK12 */
+#define CMXFCR_TF1CS_BRG5 0x00000000 /* Transmit FCC1 Clock Source is BRG5 */
+#define CMXFCR_TF1CS_BRG6 0x01000000 /* Transmit FCC1 Clock Source is BRG6 */
+#define CMXFCR_TF1CS_BRG7 0x02000000 /* Transmit FCC1 Clock Source is BRG7 */
+#define CMXFCR_TF1CS_BRG8 0x03000000 /* Transmit FCC1 Clock Source is BRG8 */
+#define CMXFCR_TF1CS_CLK9 0x04000000 /* Transmit FCC1 Clock Source is CLK9 */
+#define CMXFCR_TF1CS_CLK10 0x05000000 /* Transmit FCC1 Clock Source is CLK10 */
+#define CMXFCR_TF1CS_CLK11 0x06000000 /* Transmit FCC1 Clock Source is CLK11 */
+#define CMXFCR_TF1CS_CLK12 0x07000000 /* Transmit FCC1 Clock Source is CLK12 */
#define CMXFCR_RF2CS_BRG5 0x00000000 /* Receive FCC2 Clock Source is BRG5 */
#define CMXFCR_RF2CS_BRG6 0x00080000 /* Receive FCC2 Clock Source is BRG6 */
#define CMXFCR_RF2CS_CLK15 0x00300000 /* Receive FCC2 Clock Source is CLK15 */
#define CMXFCR_RF2CS_CLK16 0x00380000 /* Receive FCC2 Clock Source is CLK16 */
-#define CMXFCR_TF2CS_BRG5 0x00000000 /* Receive FCC2 Clock Source is BRG5 */
-#define CMXFCR_TF2CS_BRG6 0x00010000 /* Receive FCC2 Clock Source is BRG6 */
-#define CMXFCR_TF2CS_BRG7 0x00020000 /* Receive FCC2 Clock Source is BRG7 */
-#define CMXFCR_TF2CS_BRG8 0x00030000 /* Receive FCC2 Clock Source is BRG8 */
-#define CMXFCR_TF2CS_CLK13 0x00040000 /* Receive FCC2 Clock Source is CLK13 */
-#define CMXFCR_TF2CS_CLK14 0x00050000 /* Receive FCC2 Clock Source is CLK14 */
-#define CMXFCR_TF2CS_CLK15 0x00060000 /* Receive FCC2 Clock Source is CLK15 */
-#define CMXFCR_TF2CS_CLK16 0x00070000 /* Receive FCC2 Clock Source is CLK16 */
+#define CMXFCR_TF2CS_BRG5 0x00000000 /* Transmit FCC2 Clock Source is BRG5 */
+#define CMXFCR_TF2CS_BRG6 0x00010000 /* Transmit FCC2 Clock Source is BRG6 */
+#define CMXFCR_TF2CS_BRG7 0x00020000 /* Transmit FCC2 Clock Source is BRG7 */
+#define CMXFCR_TF2CS_BRG8 0x00030000 /* Transmit FCC2 Clock Source is BRG8 */
+#define CMXFCR_TF2CS_CLK13 0x00040000 /* Transmit FCC2 Clock Source is CLK13 */
+#define CMXFCR_TF2CS_CLK14 0x00050000 /* Transmit FCC2 Clock Source is CLK14 */
+#define CMXFCR_TF2CS_CLK15 0x00060000 /* Transmit FCC2 Clock Source is CLK15 */
+#define CMXFCR_TF2CS_CLK16 0x00070000 /* Transmit FCC2 Clock Source is CLK16 */
#define CMXFCR_RF3CS_BRG5 0x00000000 /* Receive FCC3 Clock Source is BRG5 */
#define CMXFCR_RF3CS_BRG6 0x00000800 /* Receive FCC3 Clock Source is BRG6 */
#define CMXFCR_RF3CS_CLK15 0x00003000 /* Receive FCC3 Clock Source is CLK15 */
#define CMXFCR_RF3CS_CLK16 0x00003800 /* Receive FCC3 Clock Source is CLK16 */
-#define CMXFCR_TF3CS_BRG5 0x00000000 /* Receive FCC3 Clock Source is BRG5 */
-#define CMXFCR_TF3CS_BRG6 0x00000100 /* Receive FCC3 Clock Source is BRG6 */
-#define CMXFCR_TF3CS_BRG7 0x00000200 /* Receive FCC3 Clock Source is BRG7 */
-#define CMXFCR_TF3CS_BRG8 0x00000300 /* Receive FCC3 Clock Source is BRG8 */
-#define CMXFCR_TF3CS_CLK13 0x00000400 /* Receive FCC3 Clock Source is CLK13 */
-#define CMXFCR_TF3CS_CLK14 0x00000500 /* Receive FCC3 Clock Source is CLK14 */
-#define CMXFCR_TF3CS_CLK15 0x00000600 /* Receive FCC3 Clock Source is CLK15 */
-#define CMXFCR_TF3CS_CLK16 0x00000700 /* Receive FCC3 Clock Source is CLK16 */
+#define CMXFCR_TF3CS_BRG5 0x00000000 /* Transmit FCC3 Clock Source is BRG5 */
+#define CMXFCR_TF3CS_BRG6 0x00000100 /* Transmit FCC3 Clock Source is BRG6 */
+#define CMXFCR_TF3CS_BRG7 0x00000200 /* Transmit FCC3 Clock Source is BRG7 */
+#define CMXFCR_TF3CS_BRG8 0x00000300 /* Transmit FCC3 Clock Source is BRG8 */
+#define CMXFCR_TF3CS_CLK13 0x00000400 /* Transmit FCC3 Clock Source is CLK13 */
+#define CMXFCR_TF3CS_CLK14 0x00000500 /* Transmit FCC3 Clock Source is CLK14 */
+#define CMXFCR_TF3CS_CLK15 0x00000600 /* Transmit FCC3 Clock Source is CLK15 */
+#define CMXFCR_TF3CS_CLK16 0x00000700 /* Transmit FCC3 Clock Source is CLK16 */
/*-----------------------------------------------------------------------
* CMXSCR - CMX SCC Clock Route Register 15-14
#ifndef __VERSION_H__
#define __VERSION_H__
-#define PPCBOOT_VERSION "ppcboot 0.6.3+"
+#define PPCBOOT_VERSION "ppcboot 0.6.4"
#endif /* __VERSION_H__ */
immr->im_cpm.cp_pbdat |= CFG_PB_SDRAM_CLKE ; /* assert SDRAM CLKE */
udelay(1);
-#if 0
/*
- * Map controller bank 2 to the SRAM bank at preliminary address.
+ * Map controller bank 1 for ELIC SACCO
+ */
+ memctl->memc_or1 = CFG_OR1;
+ memctl->memc_br1 = CFG_BR1;
+
+ /*
+ * Map controller bank 2 for ELIC EPIC
*/
memctl->memc_or2 = CFG_OR2;
memctl->memc_br2 = CFG_BR2;
-#endif
-#if 0
/*
- * Map controller bank 4 to the PER8 bank.
+ * Configure UPMA for SHARC
*/
- memctl->memc_or4 = CFG_OR4;
- memctl->memc_br4 = CFG_BR4;
-#endif
-
-#if 0
- /* Configure SHARC at UMA */
upmconfig(UPMA, (uint *)sharc_table, sizeof(sharc_table)/sizeof(uint));
- /* Map controller bank 5 to the SHARC */
+
+ /*
+ * Map controller bank 5 for SHARC
+ */
memctl->memc_or5 = CFG_OR5;
memctl->memc_br5 = CFG_BR5;
-#endif
memctl->memc_mamr = 0x00001000;
- /* Configure SDRAM at UMB */
+ /*
+ * Configure UPMB for SDRAM
+ */
upmconfig(UPMB, (uint *)sdram_table, sizeof(sdram_table)/sizeof(uint));
memctl->memc_mptpr = CFG_MPTPR_1BK_8K;
*/
/*
- * m8xx.c
- *
- * CPU specific code
+ * CPU specific code for the MPC8260
*
* written or collected and sometimes rewritten by
* Magnus Damm <damm@bitsmart.com>
*
* modified for 8260 by
* Murray Jensen <Murray.Jensen@cmst.csiro.au>
+ *
+ * added 8260 masks by
+ * Marius Groeger <mag@sysgo.de>
*/
#include <ppcboot.h>
{
volatile immap_t *immap = (immap_t *)CFG_IMMR;
uint pvr = get_pvr();
- uint immr, rev, k;
+ uint immr, rev, m, k;
char buf[32];
if ((pvr >> 16) != 0x0081)
if ((immr & IMMR_ISB_MSK) != CFG_IMMR)
return -1; /* whoops! someone moved the IMMR */
- printf("MPC8260 (REV %02x) ", rev);
+ printf("MPC8260 (Rev %02x, Mask ", rev);
/*
* the bottom 16 bits of the immr are the Part Number and Mask Number
* (4-34); the 16 bits at PROFF_REVNUM (0x8af0) in dual port ram is the
* RISC Microcode Revision Number (13-10).
+ * For the 8260, Motorola doesn't include the Microcode Revision
+ * in the mask.
*/
- k = (immr << 16) | *((ushort *)&immap->im_dprambase[PROFF_REVNUM]);
-
- switch(k) {
- default: printf("unknown (k=0x%08x)", k); break;
+ m = immr & (IMMR_PARTNUM_MSK|IMMR_MASKNUM_MSK);
+ k = *((ushort *)&immap->im_dprambase[PROFF_REVNUM]);
+
+ switch(m) {
+ case 0x0000: printf("0.2 2J24M"); break;
+ case 0x0010: printf("A.0 K22A"); break;
+ case 0x0011: printf("A.1 1K22A-XC"); break;
+ case 0x0001: printf("B.1 1K23A"); break;
+ case 0x0021: printf("B.2 2K23A-XC"); break;
+ case 0x0023: printf("B.3 3K23A"); break;
+ default: printf("unknown [immr=0x%04x,k=0x%04x]", m, k); break;
}
- printf(" at %s MHz\n", strmhz(buf, clock));
+ printf(") at %s MHz\n", strmhz(buf, clock));
return 0;
}
memctl->memc_br3 = CFG_BR3_PRELIM;
#endif
+#if defined(CFG_BR4_PRELIM) && defined(CFG_OR4_PRELIM)
+ memctl->memc_or4 = CFG_OR4_PRELIM;
+ memctl->memc_br4 = CFG_BR4_PRELIM;
+#endif
+
+#if defined(CFG_BR5_PRELIM) && defined(CFG_OR5_PRELIM)
+ memctl->memc_or5 = CFG_OR5_PRELIM;
+ memctl->memc_br5 = CFG_BR5_PRELIM;
+#endif
+
/*
* Reset CPM
*/
#include <net.h>
#include <command.h>
+#ifdef CFG_DISCOVER_PHY
+static void mii_discover_phy(void);
+#endif
+
#undef ET_DEBUG
#if (CONFIG_COMMANDS & CFG_CMD_NET) && defined(FEC_ENET)
#define PKT_MAXBLR_SIZE 1520
-/* static char rxbuf[PKTBUFSRX][ DBUF_LENGTH ]; */
-static char txbuf[TX_BUF_CNT][ DBUF_LENGTH ];
+static char txbuf[DBUF_LENGTH];
static uint rxIdx; /* index of the current RX buffer */
static uint txIdx; /* index of the current TX buffer */
{
int i;
+ int busfreq;
volatile immap_t *immr = (immap_t *) CFG_IMMR;
volatile fec_t *fecp = &(immr->im_cpm.cp_fec);
+#if defined(CONFIG_FADS) && defined(CONFIG_MPC860T)
+ /* configure FADS for fast (FEC) ethernet, half-duplex */
+ /* The LXT970 needs about 50ms to recover from reset, so
+ * wait for it by discovering the PHY before leaving eth_init().
+ */
+ {
+ volatile uint *bcsr4 = (volatile uint *) BCSR4;
+ *bcsr4 = (*bcsr4 & ~(BCSR4_FETH_EN | BCSR4_FETHCFG1))
+ | (BCSR4_FETHCFG0 | BCSR4_FETHFDE | BCSR4_FETHRST);
+
+ /* reset the LXT970 PHY */
+ *bcsr4 &= ~BCSR4_FETHRST;
+ udelay (10);
+ *bcsr4 |= BCSR4_FETHRST;
+ udelay (10);
+ }
+#endif
/* Whack a reset.
* A delay is required between a reset of the FEC block and
* initialization of other FEC registers because the reset takes
/*
* Setup Ethernet Transmitter Buffer Descriptors (13.14.24.19)
* Settings:
- * Add PADs to Short FRAMES, Wrap, Last, Tx CRC
+ * Last, Tx CRC
*/
for (i = 0; i < TX_BUF_CNT; i++) {
rtx->txbd[i].cbd_sc = BD_ENET_TX_LAST | BD_ENET_TX_TC;
rtx->txbd[i].cbd_datlen = 0; /* Reset */
- rtx->txbd[i].cbd_bufaddr = (uint) (&(txbuf[i][0]));
+ rtx->txbd[i].cbd_bufaddr = (uint) (&txbuf[0]);
}
rtx->txbd[TX_BUF_CNT - 1].cbd_sc |= BD_ENET_TX_WRAP;
*/
fecp->fec_fun_code = 0x78000000;
- /* Set MII speed to 2.5 MHz
+ /* Set MII speed to 2.5 MHz or slightly below.
+ * This rounds up to a multiple of 5MHz so MII speed never
+ * exceeds 2.5MHz for 48 MHz and other non-multiples of 5MHz.
*/
- fecp->fec_mii_speed = ((bd->bi_busfreq * 1000000) / 2500000) & 0x7e;
+ busfreq = (bd->bi_busfreq * 1000000 + 4999999) / 5000000;
+ fecp->fec_mii_speed = ((busfreq * 1000000) / 2500000) & 0x7e;
/* Configure all of port D for MII.
*/
/* Try to fill Rx Buffer Descriptors */
fecp->fec_r_des_active = 0x01000000; /* Descriptor polling active */
+#ifdef CFG_DISCOVER_PHY
+ /* wait for the PHY to wake up after reset
+ */
+ mii_discover_phy();
+#endif
+
return 1;
}
}
#endif
+#ifdef CFG_DISCOVER_PHY
+
+static int phyaddr = -1; /* didn't find a PHY yet */
+static uint phytype;
+
+/* Make MII read/write commands for the FEC.
+*/
+
+#define mk_mii_phyaddr(ADDR) (0x60020000 | ((ADDR) << 23) | (2 << 18))
+
+#define mk_mii_read(REG) (0x60020000 | ((phyaddr << 23) | \
+ (REG & 0x1f) << 18))
+
+#define mk_mii_write(REG, VAL) (0x50020000 | ((phyaddr << 23) | \
+ (REG & 0x1f) << 18) | \
+ (VAL & 0xffff))
+
+/* Interrupt events/masks.
+*/
+#define FEC_ENET_HBERR ((uint)0x80000000) /* Heartbeat error */
+#define FEC_ENET_BABR ((uint)0x40000000) /* Babbling receiver */
+#define FEC_ENET_BABT ((uint)0x20000000) /* Babbling transmitter */
+#define FEC_ENET_GRA ((uint)0x10000000) /* Graceful stop complete */
+#define FEC_ENET_TXF ((uint)0x08000000) /* Full frame transmitted */
+#define FEC_ENET_TXB ((uint)0x04000000) /* A buffer was transmitted */
+#define FEC_ENET_RXF ((uint)0x02000000) /* Full frame received */
+#define FEC_ENET_RXB ((uint)0x01000000) /* A buffer was received */
+#define FEC_ENET_MII ((uint)0x00800000) /* MII interrupt */
+#define FEC_ENET_EBERR ((uint)0x00400000) /* SDMA bus error */
+
+/* PHY identification
+ */
+#define PHY_ID_LXT970 0x78100000 /* LXT970 */
+#define PHY_ID_LXT971 0x001378e0 /* LXT971 and 972 */
+#define PHY_ID_82555 0x02a80150 /* Intel 82555 */
+#define PHY_ID_QS6612 0x01814400 /* QS6612 */
+
+/* send command to phy using mii, wait for result */
+static uint
+mii_send(uint mii_cmd)
+{
+ uint mii_reply;
+ volatile fec_t *ep;
+
+ ep = &(((immap_t *)CFG_IMMR)->im_cpm.cp_fec);
+
+ ep->fec_mii_data = mii_cmd; /* command to phy */
+
+ /* wait for mii complete */
+ while (!(ep->fec_ievent & FEC_ENET_MII))
+ ; /* spin until done */
+ mii_reply = ep->fec_mii_data; /* result from phy */
+ ep->fec_ievent = FEC_ENET_MII; /* clear MII complete */
+#if 0
+ printf("%s[%d] %s: sent=0x%8.8x, reply=0x%8.8x\n",
+ __FILE__,__LINE__,__FUNCTION__,mii_cmd,mii_reply);
+#endif
+ return (mii_reply & 0xffff); /* data read from phy */
+}
+
+static void
+mii_discover_phy(void)
+{
+#define MAX_PHY_PASSES 11
+ uint phyno;
+ int pass;
+
+ phyaddr = -1; /* didn't find a PHY yet */
+ for (pass = 1; pass <= MAX_PHY_PASSES && phyaddr < 0; ++pass) {
+ if (pass > 1) {
+ /* PHY may need more time to recover from reset.
+ * The LXT970 needs 50ms typical, no maximum is
+ * specified, so wait 10ms before try again.
+ * With 11 passes this gives it 100ms to wake up.
+ */
+ udelay(10000); /* wait 10ms */
+ }
+ for (phyno = 0; phyno < 32 && phyaddr < 0; ++phyno) {
+ phytype = mii_send(mk_mii_phyaddr(phyno));
+ if (phytype != 0xffff) {
+ phyaddr = phyno;
+ phytype <<= 16;
+ phytype |= mii_send(mk_mii_read(3));
+
+#ifdef ET_DEBUG
+ printf("PHY @ 0x%x pass %d type ",phyno,pass);
+ switch (phytype & 0xfffffff0) {
+ case PHY_ID_LXT970:
+ printf("LXT970\n");
+ break;
+ case PHY_ID_LXT971:
+ printf("LXT971\n");
+ break;
+ case PHY_ID_82555:
+ printf("82555\n");
+ break;
+ case PHY_ID_QS6612:
+ printf("QS6612\n");
+ break;
+ default:
+ printf("0x%08x\n", phytype);
+ break;
+ }
+#endif
+ }
+ }
+ }
+ if (phyaddr < 0)
+ printf("No PHY device found.\n");
+}
+#endif
+
+
#endif /* CFG_CMD_NET */
/*
- *
- * File: scc.c
- * Description:
- * Basic ET HW initialization and packet RX/TX routines
- *
- * NOTES <<<IMPORTANT: PLEASE READ>>>:
- * 1) Specifically Designed to run on TQM823L/STK8xxL board.
- * 2) Do not cache Rx/Tx buffers.
- *
- *
- * History
- * 8/13/99 saw Ported driver from MPC821/MPC821ADS (SCC1)
- * 8/16/00 bor Ported driver from MPC823FADS board
- *
- */
+ * File: scc.c
+ * Description:
+ * Basic ET HW initialization and packet RX/TX routines
+ *
+ * NOTE <<<IMPORTANT: PLEASE READ>>>:
+ * Do not cache Rx/Tx buffers!
+ */
/*
* MPC823 <-> MC68160 Connections:
#define TOUT_LOOP 1000000
-/* static char rxbuf[PKTBUFSRX][ DBUF_LENGTH ]; */
-static char txbuf[TX_BUF_CNT][ DBUF_LENGTH ];
+static char txbuf[DBUF_LENGTH];
static uint rxIdx; /* index of the current RX buffer */
static uint txIdx; /* index of the current TX buffer */
{
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[i][0];
+ rtx->txbd[i].cbd_bufaddr = (uint) (&txbuf[0]);
}
rtx->txbd[TX_BUF_CNT - 1].cbd_sc |= BD_ENET_TX_WRAP;
#if !defined(CONFIG_8xx_CONS_NONE) /* No Console at all */
#if defined(CONFIG_8xx_CONS_SMC1) /* Console on SMC1 */
-
#define SMC_INDEX 0
+#undef SCC_INDEX
#define PROFF_SMC PROFF_SMC1
#define CPM_CR_CH_SMC CPM_CR_CH_SMC1
#elif defined(CONFIG_8xx_CONS_SMC2) /* Console on SMC2 */
-
#define SMC_INDEX 1
+#undef SCC_INDEX
#define PROFF_SMC PROFF_SMC2
#define CPM_CR_CH_SMC CPM_CR_CH_SMC2
+#elif defined(CONFIG_8xx_CONS_SCC1) /* Console on SCC1 */
+#undef SMC_INDEX
+#define SCC_INDEX 0
+#define PROFF_SCC PROFF_SCC1
+#define CPM_CR_CH_SCC CPM_CR_CH_SCC1
+
+#elif defined(CONFIG_8xx_CONS_SCC2) /* Console on SCC2 */
+#undef SMC_INDEX
+#define SCC_INDEX 1
+#define PROFF_SCC PROFF_SCC2
+#define CPM_CR_CH_SCC CPM_CR_CH_SCC2
+
+#elif defined(CONFIG_8xx_CONS_SCC3) /* Console on SCC3 */
+#undef SMC_INDEX
+#define SCC_INDEX 2
+#define PROFF_SCC PROFF_SCC3
+#define CPM_CR_CH_SCC CPM_CR_CH_SCC3
+
+#elif defined(CONFIG_8xx_CONS_SCC4) /* Console on SCC4 */
+#undef SMC_INDEX
+#define SCC_INDEX 3
+#define PROFF_SCC PROFF_SCC4
+#define CPM_CR_CH_SCC CPM_CR_CH_SCC4
+
#else /* CONFIG_8xx_CONS_? */
#error "console not correctly defined"
#endif
+#if (defined (CONFIG_8xx_CONS_SMC1) || defined (CONFIG_8xx_CONS_SMC2))
+
/*
* Minimal serial functions needed to use one of the SMC ports
* as serial console interface.
#else
cp->cp_brgc2 = /* Console on SMC2 */
#endif
- ((((cpu_clock/16) / baudrate)-1) << 1) | CPM_BRG_EN;
+ ((((cpu_clock / 16) / baudrate)-1) << 1) | CPM_BRG_EN;
}
void
return(!(rbdf->cbd_sc & BD_SC_EMPTY));
}
+#else /* ! CONFIG_8xx_CONS_SMC1, CONFIG_8xx_CONS_SMC2 */
+
+void
+serial_init (ulong cpu_clock, int baudrate)
+{
+ 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;
+ volatile iop8xx_t *ip = (iop8xx_t *)&(im->im_ioport);
+
+ /* initialize pointers to SCC */
+
+ sp = (scc_t *) &(cp->cp_scc[SCC_INDEX]);
+ up = (scc_uart_t *) &cp->cp_dparam[PROFF_SCC];
+
+ /* Disable transmitter/receiver.
+ */
+ sp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);
+
+ /* Enable SDMA.
+ */
+ im->im_siu_conf.sc_sdcr = 1;
+
+ ip->iop_papar |= ((3 << (2 * SCC_INDEX)));
+ ip->iop_padir &= ~((3 << (2 * SCC_INDEX)));
+ ip->iop_paodr &= ~((3 << (2 * SCC_INDEX)));
+
+ /* 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
+ */
+
+ dpaddr = 0x800;
+
+ /* 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 uart parameters in the parameter ram.
+ */
+ up->scc_genscc.scc_rbase = dpaddr;
+ up->scc_genscc.scc_tbase = dpaddr+sizeof(cbd_t);
+ up->scc_genscc.scc_rfcr = SCC_EB;
+ up->scc_genscc.scc_tfcr = SCC_EB;
+
+
+ /* Set SCC(x) clock mode to 16x
+ * Set up the baud rate generator.
+ * See 8xx_io/commproc.c for details.
+ *
+ * Wire BRG1 to SCC
+ */
+
+ /* Set up the baud rate generator.
+ */
+
+ sp->scc_gsmrl |= (SCC_GSMRL_TDCR_16 | SCC_GSMRL_RDCR_16);
+ cp->cp_simode = SICR_UART_CLKRT;
+ cp->cp_brgc1 =
+ ((((cpu_clock / 16) / baudrate)-1) << 1) | CPM_BRG_EN;
+
+ /* Set UART mode, 8 bit, no parity, one stop.
+ * Enable receive and transmit.
+ */
+ sp->scc_gsmrl |= SCC_GSMRL_MODE_UART;
+ sp->scc_pmsr |= SCU_PMSR_CL;
+
+ /* Mask all interrupts and remove anything pending.
+ */
+ sp->scc_sccm = 0;
+ sp->scc_scce = 0xffff;
+
+ /* 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->scc_genscc.scc_mrblr = 1;
+ up->scc_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_SCC, CPM_CR_INIT_TRX) | CPM_CR_FLG;
+
+ while (cp->cp_cpcr & CPM_CR_FLG) /* wait if cp is busy */
+ ;
+
+ /* Enable transmitter/receiver.
+ */
+ sp->scc_gsmrl |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT);
+}
+
+
+void
+serial_putc(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);
+
+ if (c == '\n')
+ serial_putc ('\r');
+
+ up = (scc_uart_t *)&cpmp->cp_dparam[PROFF_SCC];
+
+ 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
+}
+
+void
+serial_putstr (const char *s)
+{
+ while (*s) {
+ serial_putc (*s++);
+ }
+}
+
+int
+serial_getc(void)
+{
+ 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;
+
+ up = (scc_uart_t *)&cpmp->cp_dparam[PROFF_SCC];
+
+ rbdf = (cbd_t *)&cpmp->cp_dpmem[up->scc_genscc.scc_rbase];
+
+ /* Wait for character to show up.
+ */
+ buf = (unsigned char *)rbdf->cbd_bufaddr;
+ while (rbdf->cbd_sc & BD_SC_EMPTY)
+ ;
+ c = *buf;
+ rbdf->cbd_sc |= BD_SC_EMPTY;
+
+ return(c);
+}
+
+int
+serial_tstc()
+{
+ volatile cbd_t *rbdf;
+ 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];
+
+ rbdf = (cbd_t *)&cpmp->cp_dpmem[up->scc_genscc.scc_rbase];
+
+ return(!(rbdf->cbd_sc & BD_SC_EMPTY));
+}
+
+#endif /* CONFIG_8xx_CONS_SMC1, CONFIG_8xx_CONS_SMC2 */
+
+
#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
void
#ifdef CONFIG_8xx_CONS_SMC2
serial_printf("[on SMC2] ");
#endif
+#ifdef CONFIG_8xx_CONS_SCC3
+ printf("[on SCC3] ");
+#endif
}
void
/* ------------------------------------------------------------------------- */
-void reset_phy()
+void reset_phy(void)
{
immap_t *immr = (immap_t *)CFG_IMMR;
ushort sreg;