From 5f8204394e39bbe8cd9f08b8f8d145b6c01f7c73 Mon Sep 17 00:00:00 2001 From: Dave Liu Date: Fri, 3 Nov 2006 19:33:44 -0600 Subject: mpc83xx: Add MPC8360EMDS basic board support Add support for the Freescale MPC8360EMDS board. Includes DDR, DUART, Local Bus, PCI. --- cpu/mpc83xx/cpu.c | 54 ++++++++- cpu/mpc83xx/spd_sdram.c | 304 ++++++++++++++++++++++++------------------------ cpu/mpc83xx/speed.c | 209 +++++++++++++++++---------------- 3 files changed, 309 insertions(+), 258 deletions(-) (limited to 'cpu/mpc83xx') diff --git a/cpu/mpc83xx/cpu.c b/cpu/mpc83xx/cpu.c index 4e82a8b789d..1de337b33c6 100644 --- a/cpu/mpc83xx/cpu.c +++ b/cpu/mpc83xx/cpu.c @@ -43,28 +43,70 @@ DECLARE_GLOBAL_DATA_PTR; int checkcpu(void) { + volatile immap_t *immr; ulong clock = gd->cpu_clk; u32 pvr = get_pvr(); + u32 spridr; char buf[32]; + immr = (immap_t *)CFG_IMMRBAR; + if ((pvr & 0xFFFF0000) != PVR_83xx) { puts("Not MPC83xx Family!!!\n"); return -1; } - puts("CPU: MPC83xx, "); - switch(pvr) { - case PVR_8349_REV10: + spridr = immr->sysconf.spridr; + puts("CPU: "); + switch(spridr) { + case SPR_8349E_REV10: + case SPR_8349E_REV11: + puts("MPC8349E, "); + break; + case SPR_8349_REV10: + case SPR_8349_REV11: + puts("MPC8349, "); + break; + case SPR_8347E_REV10_TBGA: + case SPR_8347E_REV11_TBGA: + case SPR_8347E_REV10_PBGA: + case SPR_8347E_REV11_PBGA: + puts("MPC8347E, "); + break; + case SPR_8347_REV10_TBGA: + case SPR_8347_REV11_TBGA: + case SPR_8347_REV10_PBGA: + case SPR_8347_REV11_PBGA: + puts("MPC8347, "); + break; + case SPR_8343E_REV10: + case SPR_8343E_REV11: + puts("MPC8343E, "); break; - case PVR_8349_REV11: + case SPR_8343_REV10: + case SPR_8343_REV11: + puts("MPC8343, "); + break; + case SPR_8360E_REV10: + case SPR_8360E_REV11: + case SPR_8360E_REV12: + puts("MPC8360E, "); + break; + case SPR_8360_REV10: + case SPR_8360_REV11: + case SPR_8360_REV12: + puts("MPC8360, "); break; default: puts("Rev: Unknown\n"); return -1; /* Not sure what this is */ } - printf("Rev: %d.%d at %s MHz\n", (pvr & 0xf0) >> 4, - (pvr & 0x0f), strmhz(buf, clock)); +#if defined(CONFIG_MPC8349) + printf("Rev: %02x at %s MHz\n", (spridr & 0x0000FFFF)>>4 |(spridr & 0x0000000F), strmhz(buf, clock)); +#else + printf("Rev: %02x at %s MHz\n", spridr & 0x0000FFFF, strmhz(buf, clock)); +#endif return 0; } diff --git a/cpu/mpc83xx/spd_sdram.c b/cpu/mpc83xx/spd_sdram.c index 3dfde8ac047..acc8c9e79b6 100644 --- a/cpu/mpc83xx/spd_sdram.c +++ b/cpu/mpc83xx/spd_sdram.c @@ -4,7 +4,7 @@ * (C) Copyright 2006 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * - * Copyright 2004 Freescale Semiconductor. + * Copyright (C) 2004-2006 Freescale Semiconductor, Inc. * (C) Copyright 2003 Motorola Inc. * Xianghua Xiao (X.Xiao@motorola.com) * @@ -112,14 +112,10 @@ static void spd_debug(spd_eeprom_t *spd) long int spd_sdram() { -#ifdef CONFIG_MPC834X - int caslat_83xx; /* For Errata DDR6 */ -#endif volatile immap_t *immap = (immap_t *)CFG_IMMRBAR; volatile ddr83xx_t *ddr = &immap->ddr; volatile law83xx_t *ecm = &immap->sysconf.ddrlaw[0]; spd_eeprom_t spd; - unsigned int tmp, tmp1; unsigned int memsize; unsigned int law_size; unsigned char caslat, caslat_ctrl; @@ -131,28 +127,7 @@ long int spd_sdram() unsigned sdram_cfg; unsigned int ddrc_ecc_enable; - /* Read SPD parameters with I2C */ -#ifdef CFG_83XX_DDR_USES_CS0 - ddr->csbnds[0].csbnds = (banksize(spd.row_dens) >> 24) - 1; - ddr->cs_config[0] = ( 1 << 31 - | (spd.nrow_addr - 12) << 8 - | (spd.ncol_addr - 8) ); - debug("\n"); - debug("cs0_bnds = 0x%08x\n",ddr->csbnds[0].csbnds); - debug("cs0_config = 0x%08x\n",ddr->cs_config[0]); - - if (spd.nrows == 2) { - ddr->csbnds[1].csbnds = ( (banksize(spd.row_dens) >> 8) - | ((banksize(spd.row_dens) >> 23) - 1) ); - ddr->cs_config[1] = ( 1<<31 - | (spd.nrow_addr-12) << 8 - | (spd.ncol_addr-8) ); - debug("cs1_bnds = 0x%08x\n",ddr->csbnds[1].csbnds); - debug("cs1_config = 0x%08x\n",ddr->cs_config[1]); - } - -#else CFG_READ_SPD(SPD_EEPROM_ADDRESS, 0, 1, (uchar *) & spd, sizeof (spd)); #ifdef SPD_DEBUG spd_debug(&spd); @@ -183,6 +158,26 @@ long int spd_sdram() return 0; } /* Setup DDR chip select register */ +#ifdef CFG_83XX_DDR_USES_CS0 + ddr->csbnds[0].csbnds = (banksize(spd.row_dens) >> 24) - 1; + ddr->cs_config[0] = ( 1 << 31 + | (spd.nrow_addr - 12) << 8 + | (spd.ncol_addr - 8) ); + debug("\n"); + debug("cs0_bnds = 0x%08x\n",ddr->csbnds[0].csbnds); + debug("cs0_config = 0x%08x\n",ddr->cs_config[0]); + + if (spd.nrows == 2) { + ddr->csbnds[1].csbnds = ( (banksize(spd.row_dens) >> 8) + | ((banksize(spd.row_dens) >> 23) - 1) ); + ddr->cs_config[1] = ( 1<<31 + | (spd.nrow_addr-12) << 8 + | (spd.ncol_addr-8) ); + debug("cs1_bnds = 0x%08x\n",ddr->csbnds[1].csbnds); + debug("cs1_config = 0x%08x\n",ddr->cs_config[1]); + } + +#else ddr->csbnds[2].csbnds = (banksize(spd.row_dens) >> 24) - 1; ddr->cs_config[2] = ( 1 << 31 | (spd.nrow_addr - 12) << 8 @@ -243,8 +238,9 @@ long int spd_sdram() */ caslat = __ilog2(spd.cas_lat); - if (caslat > 4 ) { - printf("DDR: Invalid SPD CAS Latency, caslat=%02X\n", caslat); + if (caslat > 6 ) { + printf("DDR: Invalid SPD CAS Latency, caslat=%02X\n", + spd.cas_lat); return 0; } max_bus_clk = 1000 *10 / (((spd.clk_cycle & 0xF0) >> 4) * 10 @@ -256,89 +252,110 @@ long int spd_sdram() ddrc_clk = get_ddr_clk(0) / 1000000; if (max_data_rate >= 390) { /* it is DDR 400 */ - printf("DDR: platform not support DDR 400\n"); - return 0; + if (ddrc_clk <= 410 && ddrc_clk > 350) { + /* DDR controller clk at 350~410 */ + effective_data_rate = 400; /* 5ns */ + caslat = caslat; + } else if (ddrc_clk <= 350 && ddrc_clk > 280) { + /* DDR controller clk at 280~350 */ + effective_data_rate = 333; /* 6ns */ + if (spd.clk_cycle2 == 0x60) { + caslat = caslat - 1; + } else { + caslat = caslat; + } + } else if (ddrc_clk <= 280 && ddrc_clk > 230) { + /* DDR controller clk at 230~280 */ + effective_data_rate = 266; /* 7.5ns */ + if (spd.clk_cycle3 == 0x75) { + caslat = caslat - 2; + } else if (spd.clk_cycle2 == 0x60) { + caslat = caslat - 1; + } else { + caslat = caslat; + } + } else if (ddrc_clk <= 230 && ddrc_clk > 90) { + /* DDR controller clk at 90~230 */ + effective_data_rate = 200; /* 10ns */ + if (spd.clk_cycle3 == 0x75) { + caslat = caslat - 2; + } else if (spd.clk_cycle2 == 0x60) { + caslat = caslat - 1; + } else { + caslat = caslat; + } + } } else if (max_data_rate >= 323) { /* it is DDR 333 */ if (ddrc_clk <= 350 && ddrc_clk > 280) { - /* DDRC clk at 280~350 */ + /* DDR controller clk at 280~350 */ effective_data_rate = 333; /* 6ns */ caslat = caslat; } else if (ddrc_clk <= 280 && ddrc_clk > 230) { - /* DDRC clk at 230~280 */ + /* DDR controller clk at 230~280 */ + effective_data_rate = 266; /* 7.5ns */ if (spd.clk_cycle2 == 0x75) { - effective_data_rate = 266; /* 7.5ns */ caslat = caslat - 1; + } else { + caslat = caslat; } } else if (ddrc_clk <= 230 && ddrc_clk > 90) { - /* DDRC clk at 90~230 */ + /* DDR controller clk at 90~230 */ + effective_data_rate = 200; /* 10ns */ if (spd.clk_cycle3 == 0xa0) { - effective_data_rate = 200; /* 10ns */ caslat = caslat - 2; + } else if (spd.clk_cycle2 == 0x75) { + caslat = caslat - 1; + } else { + caslat = caslat; } } } else if (max_data_rate >= 256) { /* it is DDR 266 */ if (ddrc_clk <= 350 && ddrc_clk > 280) { - /* DDRC clk at 280~350 */ + /* DDR controller clk at 280~350 */ printf("DDR: DDR controller freq is more than " "max data rate of the module\n"); return 0; } else if (ddrc_clk <= 280 && ddrc_clk > 230) { - /* DDRC clk at 230~280 */ + /* DDR controller clk at 230~280 */ effective_data_rate = 266; /* 7.5ns */ caslat = caslat; } else if (ddrc_clk <= 230 && ddrc_clk > 90) { - /* DDRC clk at 90~230 */ + /* DDR controller clk at 90~230 */ + effective_data_rate = 200; /* 10ns */ if (spd.clk_cycle2 == 0xa0) { - effective_data_rate = 200; /* 10ns */ caslat = caslat - 1; } } } else if (max_data_rate >= 190) { /* it is DDR 200 */ if (ddrc_clk <= 350 && ddrc_clk > 230) { - /* DDRC clk at 230~350 */ + /* DDR controller clk at 230~350 */ printf("DDR: DDR controller freq is more than " "max data rate of the module\n"); return 0; } else if (ddrc_clk <= 230 && ddrc_clk > 90) { - /* DDRC clk at 90~230 */ + /* DDR controller clk at 90~230 */ effective_data_rate = 200; /* 10ns */ caslat = caslat; } } -#ifdef CONFIG_MPC834X -/* Errata DDR6 - This errata affects all MPC8349E, MPC8343E and MPC8347E processors. -*/ - if ((tmp1 >= 280) && (tmp1 < 350)) /* CSB=333 */ - { - if (spd.mid[0] == 0x2c) { - /* Micron memory running at 333 MHz */ - /* Chances are, U-Boot will crash before we get here, - but just in case, display a message and return error. */ - printf("Micron DDR not supported at 333MHz CSB\n"); - return 0; - } else if (spd.mid[0] == 0xad) { - printf("Hynix DDR does not require Errata DDR6\n"); - } else { - /* enable 2 cycle Earlier for CL=2.5 or 3 */ - ddr->debug_reg = 0x202c0000; - printf("Errata DDR6 (debug_reg=0x%x)\n", ddr->debug_reg); - } - caslat_83xx = caslat; - } - - if ((tmp1 >= 230) && (tmp1 < 280)) { /* CSB=266 */ - if (spd.mid[0] != 0x2c) /* non-Micron */ - caslat_83xx = caslat - 1; + debug("DDR:Effective data rate is: %dMhz\n", effective_data_rate); + debug("DDR:The MSB 1 of CAS Latency is: %d\n", caslat); + /* + * Errata DDR6 work around: input enable 2 cycles earlier. + * including MPC834x Rev1.0/1.1 and MPC8360 Rev1.1/1.2. + */ + if (caslat == 2) { + ddr->debug_reg = 0x201c0000; /* CL=2 */ + } else if (caslat == 3) { + ddr->debug_reg = 0x202c0000; /* CL=2.5 */ + } else if (caslat == 4) { + ddr->debug_reg = 0x202c0000; /* CL=3.0 */ } + __asm__ __volatile__ ("sync"); - if ((tmp1 >= 90) && (tmp1 < 230)) { /* CSB=200 */ - caslat = 3; - caslat_83xx = 2; - } -#endif + debug("Errata DDR6 (debug_reg=0x%08x)\n", ddr->debug_reg); /* * note: caslat must also be programmed into ddr->sdram_mode @@ -353,11 +370,7 @@ long int spd_sdram() (((picos_to_clk(spd.trp * 250) & 0x07) << 28 ) | ((picos_to_clk(spd.tras * 1000) & 0x0f ) << 24 ) | ((picos_to_clk(spd.trcd * 250) & 0x07) << 20 ) | -#ifdef CONFIG_MPC834x - ((caslat_83xx & 0x07) << 16 ) | -#else ((caslat_ctrl & 0x07) << 16 ) | -#endif (((picos_to_clk(spd.trfc * 1000) - 8) & 0x0f) << 12 ) | ( 0x300 ) | ((picos_to_clk(spd.trrd * 250) & 0x07) << 4) | 1); @@ -370,13 +383,10 @@ long int spd_sdram() ddr->sdram_cfg = 0x42000000; /* Check DIMM data bus width */ - if (spd.dataw_lsb == 0x20) - { + if (spd.dataw_lsb == 0x20) { burstlen = 0x03; /* 32 bit data bus, burst len is 8 */ printf("\n DDR DIMM: data bus width is 32 bit"); - } - else - { + } else { burstlen = 0x02; /* Others act as 64 bit bus, burst len is 4 */ printf("\n DDR DIMM: data bus width is 64 bit"); } @@ -384,68 +394,67 @@ long int spd_sdram() /* Is this an ECC DDR chip? */ if (spd.config == 0x02) { printf(" with ECC\n"); - } - else + } else { printf(" without ECC\n"); + } /* Burst length is always 4 for 64 bit data bus, 8 for 32 bit data bus, Burst type is sequential */ - switch(caslat) { - case 1: - ddr->sdram_mode = 0x50 | burstlen; /* CL=1.5 */ - break; - case 2: - ddr->sdram_mode = 0x20 | burstlen; /* CL=2.0 */ - break; - case 3: - ddr->sdram_mode = 0x60 | burstlen; /* CL=2.5 */ - break; - case 4: - ddr->sdram_mode = 0x30 | burstlen; /* CL=3.0 */ - break; - default: - printf("DDR:only CAS Latency 1.5, 2.0, 2.5, 3.0 " - "is supported.\n"); - return 0; + switch (caslat) { + case 1: + ddr->sdram_mode = 0x50 | burstlen; /* CL=1.5 */ + break; + case 2: + ddr->sdram_mode = 0x20 | burstlen; /* CL=2.0 */ + break; + case 3: + ddr->sdram_mode = 0x60 | burstlen; /* CL=2.5 */ + break; + case 4: + ddr->sdram_mode = 0x30 | burstlen; /* CL=3.0 */ + break; + default: + printf("DDR:only CL 1.5, 2.0, 2.5, 3.0 is supported\n"); + return 0; } debug("DDR:sdram_mode=0x%08x\n", ddr->sdram_mode); - switch(spd.refresh) { - case 0x00: - case 0x80: - tmp = picos_to_clk(15625000); - break; - case 0x01: - case 0x81: - tmp = picos_to_clk(3900000); - break; - case 0x02: - case 0x82: - tmp = picos_to_clk(7800000); - break; - case 0x03: - case 0x83: - tmp = picos_to_clk(31300000); - break; - case 0x04: - case 0x84: - tmp = picos_to_clk(62500000); - break; - case 0x05: - case 0x85: - tmp = picos_to_clk(125000000); - break; - default: - tmp = 0x512; - break; + switch (spd.refresh) { + case 0x00: + case 0x80: + refresh_clk = picos_to_clk(15625000); + break; + case 0x01: + case 0x81: + refresh_clk = picos_to_clk(3900000); + break; + case 0x02: + case 0x82: + refresh_clk = picos_to_clk(7800000); + break; + case 0x03: + case 0x83: + refresh_clk = picos_to_clk(31300000); + break; + case 0x04: + case 0x84: + refresh_clk = picos_to_clk(62500000); + break; + case 0x05: + case 0x85: + refresh_clk = picos_to_clk(125000000); + break; + default: + refresh_clk = 0x512; + break; } /* * Set BSTOPRE to 0x100 for page mode * If auto-charge is used, set BSTOPRE = 0 */ - ddr->sdram_interval = ((tmp & 0x3fff) << 16) | 0x100; + ddr->sdram_interval = ((refresh_clk & 0x3fff) << 16) | 0x100; debug("DDR:sdram_interval=0x%08x\n", ddr->sdram_interval); /* SS_EN = 0, source synchronous disable @@ -459,8 +468,8 @@ long int spd_sdram() udelay(600); /* - * Figure out the settings for the sdram_cfg register. Build up - * the entire register in 'tmp' before writing since the write into + * Figure out the settings for the sdram_cfg register. Build up + * the value in 'sdram_cfg' before writing since the write into * the register will actually enable the memory controller, and all * settings must be done before enabling. * @@ -493,13 +502,13 @@ long int spd_sdram() /* set single bit error threshold to maximum value, * reset counter to zero */ ddr->err_sbe = (255 << ECC_ERROR_MAN_SBET_SHIFT) | - (0 << ECC_ERROR_MAN_SBEC_SHIFT); + (0 << ECC_ERROR_MAN_SBEC_SHIFT); } debug("DDR:err_disable=0x%08x\n", ddr->err_disable); debug("DDR:err_sbe=0x%08x\n", ddr->err_sbe); #endif - printf(" DDRC ECC mode: %s", ddrc_ecc_enable ? "ON":"OFF"); + printf(" DDRC ECC mode: %s\n", ddrc_ecc_enable ? "ON":"OFF"); #if defined(CONFIG_DDR_2T_TIMING) /* @@ -517,7 +526,6 @@ long int spd_sdram() } #endif /* CONFIG_SPD_EEPROM */ - #if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRC) /* * Use timebase counter, get_timer() is not availabe @@ -602,26 +610,16 @@ void ddr_enable_ecc(unsigned int dram_size) } } - /* 8K */ - dma_xfer((uint *)0x2000, 0x2000, (uint *)0); - /* 16K */ - dma_xfer((uint *)0x4000, 0x4000, (uint *)0); - /* 32K */ - dma_xfer((uint *)0x8000, 0x8000, (uint *)0); - /* 64K */ - dma_xfer((uint *)0x10000, 0x10000, (uint *)0); - /* 128k */ - dma_xfer((uint *)0x20000, 0x20000, (uint *)0); - /* 256k */ - dma_xfer((uint *)0x40000, 0x40000, (uint *)0); - /* 512k */ - dma_xfer((uint *)0x80000, 0x80000, (uint *)0); - /* 1M */ - dma_xfer((uint *)0x100000, 0x100000, (uint *)0); - /* 2M */ - dma_xfer((uint *)0x200000, 0x200000, (uint *)0); - /* 4M */ - dma_xfer((uint *)0x400000, 0x400000, (uint *)0); + dma_xfer((uint *)0x2000, 0x2000, (uint *)0); /* 8K */ + dma_xfer((uint *)0x4000, 0x4000, (uint *)0); /* 16K */ + dma_xfer((uint *)0x8000, 0x8000, (uint *)0); /* 32K */ + dma_xfer((uint *)0x10000, 0x10000, (uint *)0); /* 64K */ + dma_xfer((uint *)0x20000, 0x20000, (uint *)0); /* 128K */ + dma_xfer((uint *)0x40000, 0x40000, (uint *)0); /* 256K */ + dma_xfer((uint *)0x80000, 0x80000, (uint *)0); /* 512K */ + dma_xfer((uint *)0x100000, 0x100000, (uint *)0); /* 1M */ + dma_xfer((uint *)0x200000, 0x200000, (uint *)0); /* 2M */ + dma_xfer((uint *)0x400000, 0x400000, (uint *)0); /* 4M */ for (i = 1; i < dram_size / 0x800000; i++) { dma_xfer((uint *)(0x800000*i), 0x800000, (uint *)0); diff --git a/cpu/mpc83xx/speed.c b/cpu/mpc83xx/speed.c index 412713f322f..31fcadd1ea9 100644 --- a/cpu/mpc83xx/speed.c +++ b/cpu/mpc83xx/speed.c @@ -2,7 +2,7 @@ * (C) Copyright 2000-2002 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * - * Copyright 2004 Freescale Semiconductor, Inc. + * Copyright (C) 2004-2006 Freescale Semiconductor, Inc. * * See file CREDITS for list of people who contributed to this * project. @@ -104,79 +104,52 @@ int get_clocks (void) u32 lcrr; u32 csb_clk; +#if defined(CONFIG_MPC8349) u32 tsec1_clk; u32 tsec2_clk; - u32 core_clk; u32 usbmph_clk; u32 usbdr_clk; - u32 i2c_clk; +#endif + u32 core_clk; + u32 i2c1_clk; + u32 i2c2_clk; u32 enc_clk; u32 lbiu_clk; u32 lclk_clk; u32 ddr_clk; +#if defined (CONFIG_MPC8360) + u32 qepmf; + u32 qepdf; + u32 ddr_sec_clk; + u32 qe_clk; + u32 brg_clk; +#endif if ((im->sysconf.immrbar & IMMRBAR_BASE_ADDR) != (u32)im) return -1; -#ifndef CFG_HRCW_HIGH -# error "CFG_HRCW_HIGH must be defined in board config file" -#endif /* CFG_HCWD_HIGH */ - -#if (CFG_HRCW_HIGH & HRCWH_PCI_HOST) - -# ifndef CONFIG_83XX_CLKIN -# error "In PCI Host Mode, CONFIG_83XX_CLKIN must be defined in board config file" -# endif /* CONFIG_83XX_CLKIN */ -# ifdef CONFIG_83XX_PCICLK -# warning "In PCI Host Mode, CONFIG_83XX_PCICLK in board config file is igonred" -# endif /* CONFIG_83XX_PCICLK */ - - /* PCI Host Mode */ - if (!(im->reset.rcwh & RCWH_PCIHOST)) { - /* though RCWH_PCIHOST is defined in CFG_HRCW_HIGH - * the im->reset.rcwhr PCI Host Mode is disabled - * FIXME: findout if there is a way to issue some warning */ - return -2; - } - if (im->clk.spmr & SPMR_CKID) { - /* PCI Clock is half CONFIG_83XX_CLKIN */ - pci_sync_in = CONFIG_83XX_CLKIN / 2; - } - else { - pci_sync_in = CONFIG_83XX_CLKIN; - } - -#else /* (CFG_HRCW_HIGH & HRCWH_PCI_HOST) */ - -# ifdef CONFIG_83XX_CLKIN -# warning "In PCI Agent Mode, CONFIG_83XX_CLKIN in board config file is igonred" -# endif /* CONFIG_83XX_CLKIN */ -# ifndef CONFIG_83XX_PCICLK -# error "In PCI Agent Mode, CONFIG_83XX_PCICLK must be defined in board config file" -# endif /* CONFIG_83XX_PCICLK */ + clkin_div = ((im->clk.spmr & SPMR_CKID) >> SPMR_CKID_SHIFT); - /* PCI Agent Mode */ - if (im->reset.rcwh & RCWH_PCIHOST) { - /* though RCWH_PCIHOST is not defined in CFG_HRCW_HIGH - * the im->reset.rcwhr PCI Host Mode is enabled */ - return -3; + if (im->reset.rcwh & HRCWH_PCI_HOST) { +#if defined(CONFIG_83XX_CLKIN) + pci_sync_in = CONFIG_83XX_CLKIN / (1 + clkin_div); +#else + pci_sync_in = 0xDEADBEEF; +#endif + } else { +#if defined(CONFIG_83XX_PCICLK) + pci_sync_in = CONFIG_83XX_PCICLK; +#else + pci_sync_in = 0xDEADBEEF; +#endif } - pci_sync_in = CONFIG_83XX_PCICLK; - -#endif /* (CFG_HRCW_HIGH | RCWH_PCIHOST) */ - /* we have up to date pci_sync_in */ spmf = ((im->reset.rcwl & RCWL_SPMF) >> RCWL_SPMF_SHIFT); - clkin_div = ((im->clk.spmr & SPMR_CKID) >> SPMR_CKID_SHIFT); - - if ((im->reset.rcwl & RCWL_LBIUCM) || (im->reset.rcwl & RCWL_DDRCM)) { - csb_clk = (pci_sync_in * spmf * (1 + clkin_div)) / 2; - } - else { - csb_clk = pci_sync_in * spmf * (1 + clkin_div); - } + csb_clk = pci_sync_in * (1 + clkin_div) * spmf; sccr = im->clk.sccr; + +#if defined(CONFIG_MPC8349) switch ((sccr & SCCR_TSEC1CM) >> SCCR_TSEC1CM_SHIFT) { case 0: tsec1_clk = 0; @@ -212,25 +185,8 @@ int get_clocks (void) /* unkown SCCR_TSEC2CM value */ return -5; } - i2c_clk = tsec2_clk; - switch ((sccr & SCCR_ENCCM) >> SCCR_ENCCM_SHIFT) { - case 0: - enc_clk = 0; - break; - case 1: - enc_clk = csb_clk; - break; - case 2: - enc_clk = csb_clk / 2; - break; - case 3: - enc_clk = csb_clk / 3; - break; - default: - /* unkown SCCR_ENCCM value */ - return -6; - } + i2c1_clk = tsec2_clk; switch ((sccr & SCCR_USBMPHCM) >> SCCR_USBMPHCM_SHIFT) { case 0: @@ -274,8 +230,34 @@ int get_clocks (void) /* if USB MPH clock is not disabled and USB DR clock is not disabled than USB MPH & USB DR must have the same rate */ return -9; } +#endif +#if defined (CONFIG_MPC8360) + i2c1_clk = csb_clk; +#endif + i2c2_clk = csb_clk; /* i2c-2 clk is equal to csb clk */ + switch ((sccr & SCCR_ENCCM) >> SCCR_ENCCM_SHIFT) { + case 0: + enc_clk = 0; + break; + case 1: + enc_clk = csb_clk; + break; + case 2: + enc_clk = csb_clk / 2; + break; + case 3: + enc_clk = csb_clk / 3; + break; + default: + /* unkown SCCR_ENCCM value */ + return -6; + } +#if defined(CONFIG_MPC8349) || defined(CONFIG_MPC8360) lbiu_clk = csb_clk * (1 + ((im->reset.rcwl & RCWL_LBIUCM) >> RCWL_LBIUCM_SHIFT)); +#else +#error Unknown MPC83xx chip +#endif lcrr = (im->lbus.lcrr & LCRR_CLKDIV) >> LCRR_CLKDIV_SHIFT; switch (lcrr) { case 2: @@ -287,10 +269,16 @@ int get_clocks (void) /* unknown lcrr */ return -10; } - +#if defined(CONFIG_MPC8349) || defined(CONFIG_MPC8360) ddr_clk = csb_clk * (1 + ((im->reset.rcwl & RCWL_DDRCM) >> RCWL_DDRCM_SHIFT)); - corepll = (im->reset.rcwl & RCWL_COREPLL) >> RCWL_COREPLL_SHIFT; +#if defined (CONFIG_MPC8360) + ddr_sec_clk = csb_clk * (1 + ((im->reset.rcwl & RCWL_LBIUCM) >> RCWL_LBIUCM_SHIFT)); +#endif +#else +#error Unknown MPC83xx chip +#endif + corecnf_tab_index = ((corepll & 0x1F) << 2) | ((corepll & 0x60) >> 5); if (corecnf_tab_index > (sizeof(corecnf_tab)/sizeof(corecnf_t)) ) { /* corecnf_tab_index is too high, possibly worng value */ @@ -319,22 +307,36 @@ int get_clocks (void) return -12; } - gd->csb_clk = csb_clk ; - gd->tsec1_clk = tsec1_clk ; - gd->tsec2_clk = tsec2_clk ; - gd->core_clk = core_clk ; - gd->usbmph_clk = usbmph_clk; - gd->usbdr_clk = usbdr_clk ; - gd->i2c_clk = i2c_clk ; - gd->enc_clk = enc_clk ; - gd->lbiu_clk = lbiu_clk ; - gd->lclk_clk = lclk_clk ; - gd->ddr_clk = ddr_clk ; - gd->pci_clk = pci_sync_in; - - gd->cpu_clk = gd->core_clk; - gd->bus_clk = gd->lbiu_clk; +#if defined (CONFIG_MPC8360) + qepmf = (im->reset.rcwl & RCWL_CEPMF) >> RCWL_CEPMF_SHIFT; + qepdf = (im->reset.rcwl & RCWL_CEPDF) >> RCWL_CEPDF_SHIFT; + qe_clk = (pci_sync_in * qepmf)/(1+qepdf); + brg_clk = qe_clk / 2; +#endif + + gd->csb_clk = csb_clk; +#if defined(CONFIG_MPC8349) + gd->tsec1_clk = tsec1_clk; + gd->tsec2_clk = tsec2_clk; + gd->usbmph_clk = usbmph_clk; + gd->usbdr_clk = usbdr_clk; +#endif + gd->core_clk = core_clk; + gd->i2c1_clk = i2c1_clk; + gd->i2c2_clk = i2c2_clk; + gd->enc_clk = enc_clk; + gd->lbiu_clk = lbiu_clk; + gd->lclk_clk = lclk_clk; + gd->ddr_clk = ddr_clk; +#if defined (CONFIG_MPC8360) + gd->ddr_sec_clk = ddr_sec_clk; + gd->qe_clk = qe_clk; + gd->brg_clk = brg_clk; +#endif + gd->cpu_clk = gd->core_clk; + gd->bus_clk = gd->csb_clk; return 0; + } ulong get_ddr_clk(ulong dummy) @@ -357,14 +359,23 @@ int print_clock_conf (void) printf("Clock configuration:\n"); printf(" Coherent System Bus: %4d MHz\n",gd->csb_clk/1000000); printf(" Core: %4d MHz\n",gd->core_clk/1000000); - debug(" Local Bus Controller:%4d MHz\n",gd->lbiu_clk/1000000); +#if defined (CONFIG_MPC8360) + printf(" QE: %4d MHz\n",gd->qe_clk/1000000); +#endif + printf(" Local Bus Controller:%4d MHz\n",gd->lbiu_clk/1000000); printf(" Local Bus: %4d MHz\n",gd->lclk_clk/1000000); - debug(" DDR: %4d MHz\n",gd->ddr_clk/1000000); - debug(" I2C: %4d MHz\n",gd->i2c_clk/1000000); - debug(" TSEC1: %4d MHz\n",gd->tsec1_clk/1000000); - debug(" TSEC2: %4d MHz\n",gd->tsec2_clk/1000000); - debug(" USB MPH: %4d MHz\n",gd->usbmph_clk/1000000); - debug(" USB DR: %4d MHz\n",gd->usbdr_clk/1000000); - + printf(" DDR: %4d MHz\n",gd->ddr_clk/1000000); +#if defined (CONFIG_MPC8360) + printf(" DDR Secondary: %4d MHz\n",gd->ddr_sec_clk/1000000); +#endif + printf(" SEC: %4d MHz\n",gd->enc_clk/1000000); + printf(" I2C1: %4d MHz\n",gd->i2c1_clk/1000000); + printf(" I2C2: %4d MHz\n",gd->i2c2_clk/1000000); +#if defined(CONFIG_MPC8349) + printf(" TSEC1: %4d MHz\n",gd->tsec1_clk/1000000); + printf(" TSEC2: %4d MHz\n",gd->tsec2_clk/1000000); + printf(" USB MPH: %4d MHz\n",gd->usbmph_clk/1000000); + printf(" USB DR: %4d MHz\n",gd->usbdr_clk/1000000); +#endif return 0; } -- cgit v1.2.3