stxssa \
TQM8540 \
TQM8541 \
+ TQM8548 \
TQM8555 \
TQM8560 \
"
TQM8540_config \
TQM8541_config \
+TQM8548_config \
TQM8555_config \
TQM8560_config: unconfig
@mkdir -p $(obj)include
struct sdram_conf_s {
unsigned long size;
unsigned long reg;
+#ifdef CONFIG_TQM8548
+ unsigned long refresh;
+#endif /* CONFIG_TQM8548 */
};
typedef struct sdram_conf_s sdram_conf_t;
+#ifdef CONFIG_TQM8548
+sdram_conf_t ddr_cs_conf[] = {
+ {(512 << 20), 0x80044102, 0x0001A000}, /* 512MB, 13x10(4) */
+ {(256 << 20), 0x80040102, 0x00014000}, /* 256MB, 13x10(4) */
+ {(128 << 20), 0x80040101, 0x0000C000}, /* 128MB, 13x9(4) */
+};
+#else /* !CONFIG_TQM8548 */
sdram_conf_t ddr_cs_conf[] = {
{(512 << 20), 0x80000202}, /* 512MB, 14x10(4) */
{(256 << 20), 0x80000102}, /* 256MB, 13x10(4) */
{(128 << 20), 0x80000101}, /* 128MB, 13x9(4) */
{( 64 << 20), 0x80000001}, /* 64MB, 12x9(4) */
};
+#endif /* CONFIG_TQM8548 */
#define N_DDR_CS_CONF (sizeof(ddr_cs_conf) / sizeof(ddr_cs_conf[0]))
{
int i;
volatile ccsr_ddr_t *ddr = (void *)(CFG_MPC85xx_DDR_ADDR);
+#ifdef CONFIG_TQM8548
+ volatile ccsr_gur_t *gur = (void *)(CFG_MPC85xx_GUTS_ADDR);
+#else /* !CONFIG_TQM8548 */
unsigned long cfg_ddr_timing1;
unsigned long cfg_ddr_mode;
+#endif /* CONFIG_TQM8548 */
/*
* Disable memory controller.
ddr->cs0_config = 0;
ddr->sdram_cfg = 0;
+#ifdef CONFIG_TQM8548
+ ddr->cs0_bnds = (ddr_cs_conf[0].size - 1) >> 24;
+ ddr->cs0_config = ddr_cs_conf[0].reg;
+ ddr->timing_cfg_3 = 0x00010000;
+
+ /* TIMING CFG 1, 533MHz
+ * PRETOACT: 4 Clocks
+ * ACTTOPRE: 12 Clocks
+ * ACTTORW: 4 Clocks
+ * CASLAT: 4 Clocks
+ * REFREC: 34 Clocks
+ * WRREC: 4 Clocks
+ * ACTTOACT: 3 Clocks
+ * WRTORD: 2 Clocks
+ */
+ ddr->timing_cfg_1 = 0x4C47A432;
+
+ /* TIMING CFG 2, 533MHz
+ * ADD_LAT: 3 Clocks
+ * CPO: READLAT + 1
+ * WR_LAT: 3 Clocks
+ * RD_TO_PRE: 2 Clocks
+ * WR_DATA_DELAY: 1/2 Clock
+ * CKE_PLS: 1 Clock
+ * FOUR_ACT: 13 Clocks
+ */
+ ddr->timing_cfg_2 = 0x3318484D;
+
+ /* DDR SDRAM Mode, 533MHz
+ * MRS: Extended Mode Register
+ * OUT: Outputs enabled
+ * RDQS: no
+ * DQS: enabled
+ * OCD: default state
+ * RTT: 75 Ohms
+ * Posted CAS: 3 Clocks
+ * ODS: reduced strength
+ * DLL: enabled
+ * MR: Mode Register
+ * PD: fast exit
+ * WR: 4 Clocks
+ * DLL: no DLL reset
+ * TM: normal
+ * CAS latency: 4 Clocks
+ * BT: sequential
+ * Burst length: 4
+ */
+ ddr->sdram_mode = 0x439E0642;
+
+ /* DDR SDRAM Interval, 533MHz
+ * REFINT: 1040 Clocks
+ * BSTOPRE: 256
+ */
+ ddr->sdram_interval = (1040 << 16) | 0x100;
+
+ /*
+ * workaround for erratum DD10 of MPC8458 family below rev. 2.0:
+ * DDR IO receiver must be set to an acceptable bias point by modifying
+ * a hidden register.
+ */
+ if (SVR_REV (get_svr ()) < 0x20) {
+ gur->ddrioovcr = 0x90000000; /* enable, VSEL 1.8V */
+ }
+
+ /* DDR SDRAM CFG 2
+ * FRC_SR: normal mode
+ * SR_IE: no self-refresh interrupt
+ * DLL_RST_DIS: don't care, leave at reset value
+ * DQS_CFG: differential DQS signals
+ * ODT_CFG: assert ODT to internal IOs only during reads to DRAM
+ * LVWx_CFG: don't care, leave at reset value
+ * NUM_PR: 1 refresh will be issued at a time
+ * DM_CFG: don't care, leave at reset value
+ * D_INIT: no data initialization
+ */
+ ddr->sdram_cfg_2 = 0x04401000;
+
+ /* DDR SDRAM MODE 2
+ * MRS: Extended Mode Register 2
+ */
+ ddr->sdram_mode_2 = 0x8000C000;
+
+ /* DDR SDRAM CLK CNTL
+ * CLK_ADJUST: 1/2 Clock 0x02000000
+ * CLK_ADJUST: 5/8 Clock 0x02800000
+ */
+ ddr->sdram_clk_cntl = 0x02800000;
+
+ /* wait for clock stabilization */
+ asm ("sync;isync;msync");
+ udelay(1000);
+
+ /* DDR SDRAM CLK CNTL
+ * MEM_EN: enabled
+ * SREN: don't care, leave at reset value
+ * ECC_EN: no error report
+ * RD_EN: no register DIMMs
+ * SDRAM_TYPE: DDR2
+ * DYN_PWR: no power management
+ * 32_BE: don't care, leave at reset value
+ * 8_BE: 4 beat burst
+ * NCAP: don't care, leave at reset value
+ * 2T_EN: 1T Timing
+ * BA_INTLV_CTL: no interleaving
+ * x32_EN: x16 organization
+ * PCHB8: MA[10] for auto-precharge
+ * HSE: half strength for single and 2-layer stacks
+ * (full strength for 3- and 4-layer stacks no yet considered)
+ * MEM_HALT: no halt
+ * BI: automatic initialization
+ */
+ ddr->sdram_cfg = 0x83000008;
+ asm ("sync; isync; msync");
+ udelay(1000);
+
+#else /* !CONFIG_TQM8548 */
switch (casl) {
case 20:
cfg_ddr_timing1 = 0x47405331 | (3 << 16);
ddr->sdram_cfg = 0xc2000000; /* unbuffered,no DYN_PWR */
asm ("sync; isync; msync");
udelay (1000);
+#endif /* CONFIG_TQM8548 */
for (i = 0; i < N_DDR_CS_CONF; i++) {
ddr->cs0_config = ddr_cs_conf[i].reg;
*/
ddr->cs0_bnds = (ddr_cs_conf[i].size - 1) >> 24;
- return ddr_cs_conf[i].size;
+ break;
}
}
- return 0; /* nothing found ! */
+#ifdef CONFIG_TQM8548
+ if (i < N_DDR_CS_CONF) {
+ /* Adjust refresh rate for DDR2 */
+
+ ddr->timing_cfg_3 = ddr_cs_conf[i].refresh & 0x00070000;
+
+ ddr->timing_cfg_1 = (ddr->timing_cfg_1 & 0xFFFF0FFF) |
+ (ddr_cs_conf[i].refresh & 0x0000F000);
+
+ return ddr_cs_conf[i].size;
+ }
+#endif /* CONFIG_TQM8548 */
+
+ /* return size if detected, else return 0 */
+ return (i < N_DDR_CS_CONF) ? ddr_cs_conf[i].size : 0;
}
void board_add_ram_info (int use_default)
/*
+ * (C) Copyright 2008 Wolfgang Grandegger <wg@denx.de>
+ *
+ * (C) Copyright 2006
+ * Thomas Waehner, TQ-Systems GmbH, thomas.waehner@tqs.de.
+ *
* (C) Copyright 2005
* Stefan Roese, DENX Software Engineering, sr@denx.de.
*
}
#endif /* CONFIG_CAN_DRIVER */
+uint get_lbc_clock (void)
+{
+ volatile ccsr_lbc_t *lbc = (void *)(CFG_MPC85xx_LBC_ADDR);
+ sys_info_t sys_info;
+ ulong clkdiv = lbc->lcrr & 0x0f;
+
+ get_sys_info (&sys_info);
+
+ if (clkdiv == 2 || clkdiv == 4 || clkdiv == 8) {
+#ifdef CONFIG_MPC8548
+ /*
+ * Yes, the entire PQ38 family use the same
+ * bit-representation for twice the clock divider value.
+ */
+ clkdiv *= 2;
+#endif
+ return sys_info.freqSystemBus / clkdiv;
+ }
+
+ puts("Invalid clock divider value in CFG_LBC_LCRR\n");
+
+ return 0;
+}
+
/*
* Initialize Local Bus
*/
{
volatile ccsr_gur_t *gur = (void *)(CFG_MPC85xx_GUTS_ADDR);
volatile ccsr_lbc_t *lbc = (void *)(CFG_MPC85xx_LBC_ADDR);
+ uint lbc_mhz = get_lbc_clock () / 1000000;
+
+#ifdef CONFIG_MPC8548
+ uint svr = get_svr ();
+ uint lcrr;
+
+ /*
+ * MPC revision < 2.0
+ * According to MPC8548E_Device_Errata Rev. L, Erratum LBIU1:
+ * Modify engineering use only register at address 0xE_0F20.
+ * "1. Read register at offset 0xE_0F20
+ * 2. And value with 0x0000_FFFF
+ * 3. OR result with 0x0000_0004
+ * 4. Write result back to offset 0xE_0F20."
+ *
+ * According to MPC8548E_Device_Errata Rev. L, Erratum LBIU2:
+ * Modify engineering use only register at address 0xE_0F20.
+ * "1. Read register at offset 0xE_0F20
+ * 2. And value with 0xFFFF_FFDF
+ * 3. Write result back to offset 0xE_0F20."
+ *
+ * Since it is the same register, we do the modification in one step.
+ */
+ if (SVR_MAJ (svr) < 2) {
+ uint dummy = gur->lbiuiplldcr1;
+ dummy &= 0x0000FFDF;
+ dummy |= 0x00000004;
+ gur->lbiuiplldcr1 = dummy;
+ }
- uint clkdiv;
- uint lbc_hz;
- sys_info_t sysinfo;
+ lcrr = CFG_LBC_LCRR;
+
+ /*
+ * Local Bus Clock > 83.3 MHz. According to timing
+ * specifications set LCRR[EADC] to 2 delay cycles.
+ */
+ if (lbc_mhz > 83) {
+ lcrr &= ~LCRR_EADC;
+ lcrr |= LCRR_EADC_2;
+ }
+
+ /*
+ * According to MPC8548ERMAD Rev. 1.3, 13.3.1.16, 13-30
+ * disable PLL bypass for Local Bus Clock > 83 MHz.
+ */
+ if (lbc_mhz >= 66)
+ lcrr &= (~LCRR_DBYP); /* DLL Enabled */
+
+ else
+ lcrr |= LCRR_DBYP; /* DLL Bypass */
+
+ lbc->lcrr = lcrr;
+ asm ("sync;isync;msync");
+
+ /*
+ * According to MPC8548ERMAD Rev.1.3 read back LCRR
+ * and terminate with isync
+ */
+ lcrr = lbc->lcrr;
+ asm ("isync;");
+
+ /* let DLL stabilize */
+ udelay (500);
+
+#else /* !CONFIG_MPC8548 */
/*
* Errata LBC11.
* Between 66 and 133, the DLL is enabled with an override workaround.
*/
- get_sys_info (&sysinfo);
- clkdiv = lbc->lcrr & 0x0f;
- lbc_hz = sysinfo.freqSystemBus / 1000000 / clkdiv;
-
- if (lbc_hz < 66) {
- lbc->lcrr = CFG_LBC_LCRR | 0x80000000; /* DLL Bypass */
+ if (lbc_mhz < 66) {
+ lbc->lcrr = CFG_LBC_LCRR | LCRR_DBYP; /* DLL Bypass */
lbc->ltedr = 0xa4c80000; /* DK: !!! */
- } else if (lbc_hz >= 133) {
- lbc->lcrr = CFG_LBC_LCRR & (~0x80000000); /* DLL Enabled */
+ } else if (lbc_mhz >= 133) {
+ lbc->lcrr = CFG_LBC_LCRR & (~LCRR_DBYP); /* DLL Enabled */
} else {
/*
lbc->lcrr = 0x10000004;
}
- lbc->lcrr = CFG_LBC_LCRR & (~0x80000000); /* DLL Enabled */
+ lbc->lcrr = CFG_LBC_LCRR & (~LCRR_DBYP); /* DLL Enabled */
udelay (200);
/*
gur->lbcdllcr = (((temp_lbcdll & 0xff) << 16) | 0x80000000);
asm ("sync;isync;msync");
}
+#endif /* !CONFIG_MPC8548 */
#ifdef CONFIG_CAN_DRIVER
/*
* According to timing specifications EAD must be
* set if Local Bus Clock is > 83 MHz.
*/
- if (lbc_hz > 83)
+ if (lbc_mhz > 83)
out_be32 (&lbc->or2, CFG_OR2_CAN | OR_UPM_EAD);
else
out_be32 (&lbc->or2, CFG_OR2_CAN);
#error CONFIG_PS2SERIAL must be in 1 ... 6
#endif
-#elif defined(CONFIG_MPC8540) || defined(CONFIG_MPC8541) || defined(CONFIG_MPC8555)
+#elif defined(CONFIG_MPC8540) || defined(CONFIG_MPC8541) || \
+ defined(CONFIG_MPC8548) || defined(CONFIG_MPC8555)
#if CONFIG_PS2SERIAL == 1
#define COM_BASE (CFG_CCSRBAR+0x4500)
static void ps2ser_interrupt(void *dev_id);
extern struct serial_state rs_table[]; /* in serial.c */
-#if !defined(CONFIG_MPC5xxx) && !defined(CONFIG_MPC8540) && !defined(CONFIG_MPC8541) && !defined(CONFIG_MPC8555)
+#if !defined(CONFIG_MPC5xxx) && !defined(CONFIG_MPC8540) && \
+ !defined(CONFIG_MPC8541) && !defined(CONFIG_MPC8548) && \
+ !defined(CONFIG_MPC8555)
static struct serial_state *state;
#endif
return (0);
}
-#elif defined(CONFIG_MPC8540) || defined(CONFIG_MPC8541) || defined(CONFIG_MPC8555)
+#elif defined(CONFIG_MPC8540) || defined(CONFIG_MPC8541) || \
+ defined(CONFIG_MPC8548) || defined(CONFIG_MPC8555)
int ps2ser_init(void)
{
NS16550_t com_port = (NS16550_t)COM_BASE;
{
#ifdef CONFIG_MPC5xxx
volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)PSC_BASE;
-#elif defined(CONFIG_MPC8540) || defined(CONFIG_MPC8541) || defined(CONFIG_MPC8555)
+#elif defined(CONFIG_MPC8540) || defined(CONFIG_MPC8541) || \
+ defined(CONFIG_MPC8548) || defined(CONFIG_MPC8555)
NS16550_t com_port = (NS16550_t)COM_BASE;
#endif
#ifdef DEBUG
while (!(psc->psc_status & PSC_SR_TXRDY));
psc->psc_buffer_8 = chr;
-#elif defined(CONFIG_MPC8540) || defined(CONFIG_MPC8541) || defined(CONFIG_MPC8555)
+#elif defined(CONFIG_MPC8540) || defined(CONFIG_MPC8541) || \
+ defined(CONFIG_MPC8548) || defined(CONFIG_MPC8555)
while ((com_port->lsr & LSR_THRE) == 0);
com_port->thr = chr;
#else
{
#ifdef CONFIG_MPC5xxx
volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)PSC_BASE;
-#elif defined(CONFIG_MPC8540) || defined(CONFIG_MPC8541) || defined(CONFIG_MPC8555)
+#elif defined(CONFIG_MPC8540) || defined(CONFIG_MPC8541) || \
+ defined(CONFIG_MPC8548) || defined(CONFIG_MPC8555)
NS16550_t com_port = (NS16550_t)COM_BASE;
#endif
int res = -1;
if (psc->psc_status & PSC_SR_RXRDY) {
res = (psc->psc_buffer_8);
}
-#elif defined(CONFIG_MPC8540) || defined(CONFIG_MPC8541) || defined(CONFIG_MPC8555)
+#elif defined(CONFIG_MPC8540) || defined(CONFIG_MPC8541) || \
+ defined(CONFIG_MPC8548) || defined(CONFIG_MPC8555)
if (com_port->lsr & LSR_DR) {
res = com_port->rbr;
}
{
#ifdef CONFIG_MPC5xxx
volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)PSC_BASE;
-#elif defined(CONFIG_MPC8540) || defined(CONFIG_MPC8541) || defined(CONFIG_MPC8555)
+#elif defined(CONFIG_MPC8540) || defined(CONFIG_MPC8541) || \
+ defined(CONFIG_MPC8548) || defined(CONFIG_MPC8555)
NS16550_t com_port = (NS16550_t)COM_BASE;
#endif
int chr;
chr = ps2ser_getc_hw();
#ifdef CONFIG_MPC5xxx
status = psc->psc_status;
-#elif defined(CONFIG_MPC8540) || defined(CONFIG_MPC8541) || defined(CONFIG_MPC8555)
+#elif defined(CONFIG_MPC8540) || defined(CONFIG_MPC8541) || \
+ defined(CONFIG_MPC8548) || defined(CONFIG_MPC8555)
status = com_port->lsr;
#else
status = ps2ser_in(UART_IIR);
}
#ifdef CONFIG_MPC5xxx
} while (status & PSC_SR_RXRDY);
-#elif defined(CONFIG_MPC8540) || defined(CONFIG_MPC8541) || defined(CONFIG_MPC8555)
+#elif defined(CONFIG_MPC8540) || defined(CONFIG_MPC8541) || \
+ defined(CONFIG_MPC8548) || defined(CONFIG_MPC8555)
} while (status & LSR_DR);
#else
} while (status & UART_IIR_RDI);
/*
+ * (C) Copyright 2007
+ * Thomas Waehner, TQ-System GmbH, thomas.waehner@tqs.de.
+ *
* (C) Copyright 2005
* Stefan Roese, DENX Software Engineering, sr@denx.de.
*
*/
/*
- * TQM85xx (8560/40/55/41) board configuration file
+ * TQM85xx (8560/40/55/41/48) board configuration file
*/
#ifndef __CONFIG_H
#define CONFIG_MISC_INIT_R 1 /* Call misc_init_r */
/*
- * Only MPC8540 doesn't have CPM module
+ * MPC8540 and MPC8548 don't have CPM module
*/
-#ifndef CONFIG_MPC8540
+#if !defined(CONFIG_MPC8540) && !defined(CONFIG_MPC8548)
#define CONFIG_CPM2 1 /* has CPM2 */
#endif
* sysclk for MPC85xx
*
* Two valid values are:
- * 33000000
- * 66000000
+ * 33333333
+ * 66666666
*
* Most PCI cards are still 33Mhz, so in the presence of PCI, 33MHz
* is likely the desired value here, so that is now the default.
#define CONFIG_DDR_DEFAULT_CL 25 /* CAS latency 2,5 */
#endif /* CONFIG_TQM8540 || CONFIG_TQM8560 */
-#if defined(CONFIG_TQM8541) || defined(CONFIG_TQM8555)
+#if defined(CONFIG_TQM8541) || defined(CONFIG_TQM8555) || \
+ defined(CONFIG_TQM8548)
#define CONFIG_DDR_DEFAULT_CL 30 /* CAS latency 3 */
-#endif /* CONFIG_TQM8541 || CONFIG_TQM8555 */
+#endif /* CONFIG_TQM8541 || CONFIG_TQM8555 || CONFIG_TQM8548 */
/*
* Old TQM85xx boards have 'M' type Spansion Flashes from the S29GLxxxM
* series while new boards have 'N' type Flashes from the S29GLxxxN
* series, which have bigger sectors: 2 x 128 instead of 2 x 64 KB.
*/
-#undef CONFIG_TQM_FLASH_N_TYPE
+#ifdef CONFIG_TQM8548
+#define CONFIG_TQM_FLASH_N_TYPE
+#endif /* CONFIG_TQM8548 */
/*
* Flash on the Local Bus
#define CFG_LBC_FLASH_BASE CFG_FLASH1 /* Localbus flash start */
#define CFG_FLASH_BASE CFG_LBC_FLASH_BASE /* start of FLASH */
+/* Default ORx timings are for <= 41.7 MHz Local Bus Clock.
+ *
+ * Note: According to timing specifications external addr latch delay
+ * (EAD, bit #0) must be set if Local Bus Clock is > 83 MHz.
+ *
+ * For other Local Bus Clocks see following table:
+ *
+ * Clock/MHz CFG_ORx_PRELIM
+ * 166 0x.....CA5
+ * 133 0x.....C85
+ * 100 0x.....C65
+ * 83 0x.....FA2
+ * 66 0x.....C82
+ * 50 0x.....C60
+ * 42 0x.....040
+ * 33 0x.....030
+ * 25 0x.....020
+ *
+ */
#define CFG_BR0_PRELIM 0xfc001801 /* port size 32bit */
#define CFG_OR0_PRELIM 0xfc000040 /* 64MB Flash */
#define CFG_BR1_PRELIM 0xf8001801 /* port size 32bit */
#define CFG_FLASH_CFI_DRIVER /* Use common CFI driver */
#define CFG_FLASH_EMPTY_INFO /* print 'E' for empty sector */
#define CFG_FLASH_QUIET_TEST 1 /* don't warn upon unknown flash*/
+#define CFG_FLASH_USE_BUFFER_WRITE 1 /* speed up output to Flash */
#define CFG_MAX_FLASH_BANKS 2 /* number of banks */
#define CFG_MAX_FLASH_SECT 512 /* sectors per device */
#define CFG_MONITOR_BASE TEXT_BASE /* start of monitor */
+/*
+ * Note: when changing the Local Bus clock divider you have to
+ * change the timing values in CFG_ORx_PRELIM.
+ *
+ * LCRR[00:03] CLKDIV: System (CCB) clock divider. Valid values are 2, 4, 8.
+ * LCRR[16:17] EADC : External address delay cycles. It should be set to 2
+ * for Local Bus Clock > 83.3 MHz.
+ */
#define CFG_LBC_LCRR 0x00030008 /* LB clock ratio reg */
#define CFG_LBC_LBCR 0x00000000 /* LB config reg */
#define CFG_LBC_LSRT 0x20000000 /* LB sdram refresh timer */
#define CONFIG_HAS_ETH1
#define CONFIG_HAS_ETH2
+#ifdef CONFIG_TQM8548
+/*
+ * TQM8548 has 4 ethernet ports. 4 ETSEC's.
+ *
+ * On the STK85xx Starterkit the ETSEC3/4 ports are on an
+ * additional adapter (AIO) between module and Starterkit.
+ */
+#define CONFIG_TSEC3 1
+#define CONFIG_TSEC3_NAME "TSEC2"
+#define CONFIG_TSEC4 1
+#define CONFIG_TSEC4_NAME "TSEC3"
+#define TSEC3_PHY_ADDR 4
+#define TSEC4_PHY_ADDR 5
+#define TSEC3_PHYIDX 0
+#define TSEC4_PHYIDX 0
+#define TSEC3_FLAGS (TSEC_GIGABIT | TSEC_REDUCED)
+#define TSEC4_FLAGS (TSEC_GIGABIT | TSEC_REDUCED)
+#define CONFIG_HAS_ETH3
+#define CONFIG_HAS_ETH4
+#endif /* CONFIG_TQM8548 */
+
/* Options are TSEC[0-1], FEC */
#define CONFIG_ETHPRIME "TSEC0"