From debb7354d1ea4f694154818df5e5b523f5c1cc1d Mon Sep 17 00:00:00 2001 From: Jon Loeliger Date: Wed, 26 Apr 2006 17:58:56 -0500 Subject: Initial support for MPC8641 HPCN board. --- cpu/mpc86xx/spd_sdram.c | 1017 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1017 insertions(+) create mode 100644 cpu/mpc86xx/spd_sdram.c (limited to 'cpu/mpc86xx/spd_sdram.c') diff --git a/cpu/mpc86xx/spd_sdram.c b/cpu/mpc86xx/spd_sdram.c new file mode 100644 index 0000000000..9c07f200fb --- /dev/null +++ b/cpu/mpc86xx/spd_sdram.c @@ -0,0 +1,1017 @@ +/* + * Copyright 2004 Freescale Semiconductor. + * (C) Copyright 2003 Motorola Inc. + * Xianghua Xiao (X.Xiao@motorola.com) + * + * 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 +#include +#include +#include +#include + + +#if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER) +extern void dma_init(void); +extern uint dma_check(void); +extern int dma_xfer(void *dest, uint count, void *src); +#endif + +#ifdef CONFIG_SPD_EEPROM + +#ifndef CFG_READ_SPD +#define CFG_READ_SPD i2c_read +#endif + +/* + * Convert picoseconds into clock cycles (rounding up if needed). + */ + +int +picos_to_clk(int picos) +{ + int clks; + + clks = picos / (2000000000 / (get_bus_freq(0) / 1000)); + if (picos % (2000000000 / (get_bus_freq(0) / 1000)) != 0) { + clks++; + } + + return clks; +} + + +/* + * Calculate the Density of each Physical Rank. + * Returned size is in bytes. + * + * Study these table from Byte 31 of JEDEC SPD Spec. + * + * DDR I DDR II + * Bit Size Size + * --- ----- ------ + * 7 high 512MB 512MB + * 6 256MB 256MB + * 5 128MB 128MB + * 4 64MB 16GB + * 3 32MB 8GB + * 2 16MB 4GB + * 1 2GB 2GB + * 0 low 1GB 1GB + * + * Reorder Table to be linear by stripping the bottom + * 2 or 5 bits off and shifting them up to the top. + */ + +unsigned int +compute_banksize(unsigned int mem_type, unsigned char row_dens) +{ + unsigned int bsize; + + if (mem_type == SPD_MEMTYPE_DDR) { + /* Bottom 2 bits up to the top. */ + bsize = ((row_dens >> 2) | ((row_dens & 3) << 6)) << 24; + debug("DDR: DDR I rank density = 0x%08x\n", bsize); + } else { + /* Bottom 5 bits up to the top. */ + bsize = ((row_dens >> 5) | ((row_dens & 31) << 3)) << 27; + debug("DDR: DDR II rank density = 0x%08x\n", bsize); + } + return bsize; +} + + +/* + * Convert a two-nibble BCD value into a cycle time. + * While the spec calls for nano-seconds, picos are returned. + * + * This implements the tables for bytes 9, 23 and 25 for both + * DDR I and II. No allowance for distinguishing the invalid + * fields absent for DDR I yet present in DDR II is made. + * (That is, cycle times of .25, .33, .66 and .75 ns are + * allowed for both DDR II and I.) + */ + +unsigned int +convert_bcd_tenths_to_cycle_time_ps(unsigned int spd_val) +{ + /* + * Table look up the lower nibble, allow DDR I & II. + */ + unsigned int tenths_ps[16] = { + 0, + 100, + 200, + 300, + 400, + 500, + 600, + 700, + 800, + 900, + 250, + 330, /* FIXME: Is 333 better/valid? */ + 660, /* FIXME: Is 667 better/valid? */ + 750, + 0, /* undefined */ + 0 /* undefined */ + }; + + unsigned int whole_ns = (spd_val & 0xF0) >> 4; + unsigned int tenth_ns = spd_val & 0x0F; + unsigned int ps = whole_ns * 1000 + tenths_ps[tenth_ns]; + + return ps; +} + + +long int +spd_sdram(void) +{ + volatile immap_t *immap = (immap_t *)CFG_IMMR; + volatile ccsr_ddr_t *ddr1 = &immap->im_ddr1; + volatile ccsr_gur_t *gur = &immap->im_gur; + spd_eeprom_t spd; + unsigned int n_ranks; + unsigned int rank_density; + unsigned int odt_rd_cfg, odt_wr_cfg; + unsigned int odt_cfg, mode_odt_enable; + unsigned int dqs_cfg; + unsigned char twr_clk, twtr_clk, twr_auto_clk; + unsigned int tCKmin_ps, tCKmax_ps; + unsigned int max_data_rate, effective_data_rate; + unsigned int busfreq; + unsigned sdram_cfg_1; + unsigned int memsize; + unsigned char caslat, caslat_ctrl; + unsigned int trfc, trfc_clk, trfc_low, trfc_high; + unsigned int trcd_clk; + unsigned int trtp_clk; + unsigned char cke_min_clk; + unsigned char add_lat; + unsigned char wr_lat; + unsigned char wr_data_delay; + unsigned char four_act; + unsigned char cpo; + unsigned char burst_len; + unsigned int mode_caslat; + unsigned char sdram_type; + unsigned char d_init; + + + unsigned int law_size; + volatile ccsr_local_mcm_t *mcm = &immap->im_local_mcm; + + /* + * Read SPD information. + */ + + CFG_READ_SPD(SPD_EEPROM_ADDRESS, 0, 1, (uchar *) &spd, sizeof(spd)); + + /* + * Check for supported memory module types. + */ + if (spd.mem_type != SPD_MEMTYPE_DDR && + spd.mem_type != SPD_MEMTYPE_DDR2) { + printf("Unable to locate DDR I or DDR II module.\n" + " Fundamental memory type is 0x%0x\n", + spd.mem_type); + return 0; + } + + /* + * These test gloss over DDR I and II differences in interpretation + * of bytes 3 and 4, but irrelevantly. Multiple asymmetric banks + * are not supported on DDR I; and not encoded on DDR II. + * + * Also note that the 8548 controller can support: + * 12 <= nrow <= 16 + * and + * 8 <= ncol <= 11 (still, for DDR) + * 6 <= ncol <= 9 (for FCRAM) + */ + if (spd.nrow_addr < 12 || spd.nrow_addr > 14) { + printf("DDR: Unsupported number of Row Addr lines: %d.\n", + spd.nrow_addr); + return 0; + } + if (spd.ncol_addr < 8 || spd.ncol_addr > 11) { + printf("DDR: Unsupported number of Column Addr lines: %d.\n", + spd.ncol_addr); + return 0; + } + + /* + * Determine the number of physical banks controlled by + * different Chip Select signals. This is not quite the + * same as the number of DIMM modules on the board. Feh. + */ + if (spd.mem_type == SPD_MEMTYPE_DDR) { + n_ranks = spd.nrows; + } else { + n_ranks = (spd.nrows & 0x7) + 1; + } + + debug("DDR: number of ranks = %d\n", n_ranks); + + if (n_ranks > 2) { + printf("DDR: Only 2 chip selects are supported: %d\n", + n_ranks); + return 0; + } + + /* + * Adjust DDR II IO voltage biasing. It just makes it work. + */ + if (spd.mem_type == SPD_MEMTYPE_DDR2) { + gur->ddrioovcr = (0 + | 0x80000000 /* Enable */ + | 0x10000000 /* VSEL to 1.8V */ + ); + } + + /* + * Determine the size of each Rank in bytes. + */ + rank_density = compute_banksize(spd.mem_type, spd.row_dens); + + + /* + * Eg: Bounds: 0x0000_0000 to 0x0f000_0000 first 256 Meg + */ + ddr1->cs0_bnds = (rank_density >> 24) - 1; + + /* + * ODT configuration recommendation from DDR Controller Chapter. + */ + odt_rd_cfg = 0; /* Never assert ODT */ + odt_wr_cfg = 0; /* Never assert ODT */ + if (spd.mem_type == SPD_MEMTYPE_DDR2) { + odt_wr_cfg = 1; /* Assert ODT on writes to CS0 */ + } + + ddr1->cs0_config = ( 1 << 31 + | (odt_rd_cfg << 20) + | (odt_wr_cfg << 16) + | (spd.nrow_addr - 12) << 8 + | (spd.ncol_addr - 8) ); + debug("\n"); + debug("DDR: cs0_bnds = 0x%08x\n", ddr1->cs0_bnds); + debug("DDR: cs0_config = 0x%08x\n", ddr1->cs0_config); + + if (n_ranks == 2) { + /* + * Eg: Bounds: 0x0f00_0000 to 0x1e0000_0000, second 256 Meg + */ + ddr1->cs1_bnds = ( (rank_density >> 8) + | ((rank_density >> (24 - 1)) - 1) ); + ddr1->cs1_config = ( 1<<31 + | (odt_rd_cfg << 20) + | (odt_wr_cfg << 16) + | (spd.nrow_addr - 12) << 8 + | (spd.ncol_addr - 8) ); + debug("DDR: cs1_bnds = 0x%08x\n", ddr1->cs1_bnds); + debug("DDR: cs1_config = 0x%08x\n", ddr1->cs1_config); + } + + + /* + * Find the largest CAS by locating the highest 1 bit + * in the spd.cas_lat field. Translate it to a DDR + * controller field value: + * + * CAS Lat DDR I DDR II Ctrl + * Clocks SPD Bit SPD Bit Value + * ------- ------- ------- ----- + * 1.0 0 0001 + * 1.5 1 0010 + * 2.0 2 2 0011 + * 2.5 3 0100 + * 3.0 4 3 0101 + * 3.5 5 0110 + * 4.0 4 0111 + * 4.5 1000 + * 5.0 5 1001 + */ + caslat = __ilog2(spd.cas_lat); + if ((spd.mem_type == SPD_MEMTYPE_DDR) + && (caslat > 5)) { + printf("DDR I: Invalid SPD CAS Latency: 0x%x.\n", spd.cas_lat); + return 0; + + } else if (spd.mem_type == SPD_MEMTYPE_DDR2 + && (caslat < 2 || caslat > 5)) { + printf("DDR II: Invalid SPD CAS Latency: 0x%x.\n", + spd.cas_lat); + return 0; + } + debug("DDR: caslat SPD bit is %d\n", caslat); + + /* + * Calculate the Maximum Data Rate based on the Minimum Cycle time. + * The SPD clk_cycle field (tCKmin) is measured in tenths of + * nanoseconds and represented as BCD. + */ + tCKmin_ps = convert_bcd_tenths_to_cycle_time_ps(spd.clk_cycle); + debug("DDR: tCKmin = %d ps\n", tCKmin_ps); + + /* + * Double-data rate, scaled 1000 to picoseconds, and back down to MHz. + */ + max_data_rate = 2 * 1000 * 1000 / tCKmin_ps; + debug("DDR: Module max data rate = %d Mhz\n", max_data_rate); + + + /* + * Adjust the CAS Latency to allow for bus speeds that + * are slower than the DDR module. + */ + busfreq = get_bus_freq(0) / 1000000; /* MHz */ + + effective_data_rate = max_data_rate; + if (busfreq < 90) { + /* DDR rate out-of-range */ + puts("DDR: platform frequency is not fit for DDR rate\n"); + return 0; + + } else if (90 <= busfreq && busfreq < 230 && max_data_rate >= 230) { + /* + * busfreq 90~230 range, treated as DDR 200. + */ + effective_data_rate = 200; + if (spd.clk_cycle3 == 0xa0) /* 10 ns */ + caslat -= 2; + else if (spd.clk_cycle2 == 0xa0) + caslat--; + + } else if (230 <= busfreq && busfreq < 280 && max_data_rate >= 280) { + /* + * busfreq 230~280 range, treated as DDR 266. + */ + effective_data_rate = 266; + if (spd.clk_cycle3 == 0x75) /* 7.5 ns */ + caslat -= 2; + else if (spd.clk_cycle2 == 0x75) + caslat--; + + } else if (280 <= busfreq && busfreq < 350 && max_data_rate >= 350) { + /* + * busfreq 280~350 range, treated as DDR 333. + */ + effective_data_rate = 333; + if (spd.clk_cycle3 == 0x60) /* 6.0 ns */ + caslat -= 2; + else if (spd.clk_cycle2 == 0x60) + caslat--; + + } else if (350 <= busfreq && busfreq < 460 && max_data_rate >= 460) { + /* + * busfreq 350~460 range, treated as DDR 400. + */ + effective_data_rate = 400; + if (spd.clk_cycle3 == 0x50) /* 5.0 ns */ + caslat -= 2; + else if (spd.clk_cycle2 == 0x50) + caslat--; + + } else if (460 <= busfreq && busfreq < 560 && max_data_rate >= 560) { + /* + * busfreq 460~560 range, treated as DDR 533. + */ + effective_data_rate = 533; + if (spd.clk_cycle3 == 0x3D) /* 3.75 ns */ + caslat -= 2; + else if (spd.clk_cycle2 == 0x3D) + caslat--; + + } else if (560 <= busfreq && busfreq < 700 && max_data_rate >= 700) { + /* + * busfreq 560~700 range, treated as DDR 667. + */ + effective_data_rate = 667; + if (spd.clk_cycle3 == 0x30) /* 3.0 ns */ + caslat -= 2; + else if (spd.clk_cycle2 == 0x30) + caslat--; + + } else if (700 <= busfreq) { + /* + * DDR rate out-of-range + */ + printf("DDR: Bus freq %d MHz is not fit for DDR rate %d MHz\n", + busfreq, max_data_rate); + return 0; + } + + + /* + * Convert caslat clocks to DDR controller value. + * Force caslat_ctrl to be DDR Controller field-sized. + */ + if (spd.mem_type == SPD_MEMTYPE_DDR) { + caslat_ctrl = (caslat + 1) & 0x07; + } else { + caslat_ctrl = (2 * caslat - 1) & 0x0f; + } + + debug("DDR: effective data rate is %d MHz\n", effective_data_rate); + debug("DDR: caslat SPD bit is %d, controller field is 0x%x\n", + caslat, caslat_ctrl); + + /* + * Timing Config 0. + * Avoid writing for DDR I. The new PQ38 DDR controller + * dreams up non-zero default values to be backwards compatible. + */ + if (spd.mem_type == SPD_MEMTYPE_DDR2) { + unsigned char taxpd_clk = 8; /* By the book. */ + unsigned char tmrd_clk = 2; /* By the book. */ + unsigned char act_pd_exit = 2; /* Empirical? */ + unsigned char pre_pd_exit = 6; /* Empirical? */ + + ddr1->timing_cfg_0 = (0 + | ((act_pd_exit & 0x7) << 20) /* ACT_PD_EXIT */ + | ((pre_pd_exit & 0x7) << 16) /* PRE_PD_EXIT */ + | ((taxpd_clk & 0xf) << 8) /* ODT_PD_EXIT */ + | ((tmrd_clk & 0xf) << 0) /* MRS_CYC */ + ); + debug("DDR: timing_cfg_0 = 0x%08x\n", ddr1->timing_cfg_0); + + } else { + } + + + /* + * Some Timing Config 1 values now. + * Sneak Extended Refresh Recovery in here too. + */ + + /* + * For DDR I, WRREC(Twr) and WRTORD(Twtr) are not in SPD, + * use conservative value. + * For DDR II, they are bytes 36 and 37, in quarter nanos. + */ + + if (spd.mem_type == SPD_MEMTYPE_DDR) { + twr_clk = 3; /* Clocks */ + twtr_clk = 1; /* Clocks */ + } else { + twr_clk = picos_to_clk(spd.twr * 250); + twtr_clk = picos_to_clk(spd.twtr * 250); + } + + /* + * Calculate Trfc, in picos. + * DDR I: Byte 42 straight up in ns. + * DDR II: Byte 40 and 42 swizzled some, in ns. + */ + if (spd.mem_type == SPD_MEMTYPE_DDR) { + trfc = spd.trfc * 1000; /* up to ps */ + } else { + unsigned int byte40_table_ps[8] = { + 0, + 250, + 330, + 500, + 660, + 750, + 0, + 0 + }; + + trfc = (((spd.trctrfc_ext & 0x1) * 256) + spd.trfc) * 1000 + + byte40_table_ps[(spd.trctrfc_ext >> 1) & 0x7]; + } + trfc_clk = picos_to_clk(trfc); + + /* + * Trcd, Byte 29, from quarter nanos to ps and clocks. + */ + trcd_clk = picos_to_clk(spd.trcd * 250) & 0x7; + + /* + * Convert trfc_clk to DDR controller fields. DDR I should + * fit in the REFREC field (16-19) of TIMING_CFG_1, but the + * 8548 controller has an extended REFREC field of three bits. + * The controller automatically adds 8 clocks to this value, + * so preadjust it down 8 first before splitting it up. + */ + trfc_low = (trfc_clk - 8) & 0xf; + trfc_high = ((trfc_clk - 8) >> 4) & 0x3; + + /* + * Sneak in some Extended Refresh Recovery. + */ + ddr1->ext_refrec = (trfc_high << 16); + debug("DDR: ext_refrec = 0x%08x\n", ddr1->ext_refrec); + + ddr1->timing_cfg_1 = + (0 + | ((picos_to_clk(spd.trp * 250) & 0x07) << 28) /* PRETOACT */ + | ((picos_to_clk(spd.tras * 1000) & 0x0f ) << 24) /* ACTTOPRE */ + | (trcd_clk << 20) /* ACTTORW */ + | (caslat_ctrl << 16) /* CASLAT */ + | (trfc_low << 12) /* REFEC */ + | ((twr_clk & 0x07) << 8) /* WRRREC */ + | ((picos_to_clk(spd.trrd * 250) & 0x07) << 4) /* ACTTOACT */ + | ((twtr_clk & 0x07) << 0) /* WRTORD */ + ); + + debug("DDR: timing_cfg_1 = 0x%08x\n", ddr1->timing_cfg_1); + + + /* + * Timing_Config_2 + * Was: 0x00000800; + */ + + /* + * Additive Latency + * For DDR I, 0. + * For DDR II, with ODT enabled, use "a value" less than ACTTORW, + * which comes from Trcd, and also note that: + * add_lat + caslat must be >= 4 + */ + add_lat = 0; + if (spd.mem_type == SPD_MEMTYPE_DDR2 + && (odt_wr_cfg || odt_rd_cfg) + && (caslat < 4)) { + add_lat = 4 - caslat; + if (add_lat > trcd_clk) { + add_lat = trcd_clk - 1; + } + } + + /* + * Write Data Delay + * Historically 0x2 == 4/8 clock delay. + * Empirically, 0x3 == 6/8 clock delay is suggested for DDR I 266. + */ + wr_data_delay = 3; + + /* + * Write Latency + * Read to Precharge + * Minimum CKE Pulse Width. + * Four Activate Window + */ + if (spd.mem_type == SPD_MEMTYPE_DDR) { + /* + * This is a lie. It should really be 1, but if it is + * set to 1, bits overlap into the old controller's + * otherwise unused ACSM field. If we leave it 0, then + * the HW will magically treat it as 1 for DDR 1. Oh Yea. + */ + wr_lat = 0; + + trtp_clk = 2; /* By the book. */ + cke_min_clk = 1; /* By the book. */ + four_act = 1; /* By the book. */ + + } else { + wr_lat = caslat - 1; + + /* Convert SPD value from quarter nanos to picos. */ + trtp_clk = picos_to_clk(spd.trtp * 250); + + cke_min_clk = 3; /* By the book. */ + four_act = picos_to_clk(37500); /* By the book. 1k pages? */ + } + + /* + * Empirically set ~MCAS-to-preamble override for DDR 2. + * Your milage will vary. + */ + cpo = 0; + if (spd.mem_type == SPD_MEMTYPE_DDR2) { + if (effective_data_rate == 266 || effective_data_rate == 333) { + cpo = 0x7; /* READ_LAT + 5/4 */ + } else if (effective_data_rate == 400) { + cpo = 0x9; /* READ_LAT + 7/4 */ + } else { + /* Pure speculation */ + cpo = 0xb; + } + } + + ddr1->timing_cfg_2 = (0 + | ((add_lat & 0x7) << 28) /* ADD_LAT */ + | ((cpo & 0x1f) << 23) /* CPO */ + | ((wr_lat & 0x7) << 19) /* WR_LAT */ + | ((trtp_clk & 0x7) << 13) /* RD_TO_PRE */ + | ((wr_data_delay & 0x7) << 10) /* WR_DATA_DELAY */ + | ((cke_min_clk & 0x7) << 6) /* CKE_PLS */ + | ((four_act & 0x1f) << 0) /* FOUR_ACT */ + ); + + debug("DDR: timing_cfg_2 = 0x%08x\n", ddr1->timing_cfg_2); + + + /* + * Determine the Mode Register Set. + * + * This is nominally part specific, but it appears to be + * consistent for all DDR I devices, and for all DDR II devices. + * + * caslat must be programmed + * burst length is always 4 + * burst type is sequential + * + * For DDR I: + * operating mode is "normal" + * + * For DDR II: + * other stuff + */ + + mode_caslat = 0; + + /* + * Table lookup from DDR I or II Device Operation Specs. + */ + if (spd.mem_type == SPD_MEMTYPE_DDR) { + if (1 <= caslat && caslat <= 4) { + unsigned char mode_caslat_table[4] = { + 0x5, /* 1.5 clocks */ + 0x2, /* 2.0 clocks */ + 0x6, /* 2.5 clocks */ + 0x3 /* 3.0 clocks */ + }; + mode_caslat = mode_caslat_table[caslat - 1]; + } else { + puts("DDR I: Only CAS Latencies of 1.5, 2.0, " + "2.5 and 3.0 clocks are supported.\n"); + return 0; + } + + } else { + if (2 <= caslat && caslat <= 5) { + mode_caslat = caslat; + } else { + puts("DDR II: Only CAS Latencies of 2.0, 3.0, " + "4.0 and 5.0 clocks are supported.\n"); + return 0; + } + } + + /* + * Encoded Burst Lenght of 4. + */ + burst_len = 2; /* Fiat. */ + + if (spd.mem_type == SPD_MEMTYPE_DDR) { + twr_auto_clk = 0; /* Historical */ + } else { + /* + * Determine tCK max in picos. Grab tWR and convert to picos. + * Auto-precharge write recovery is: + * WR = roundup(tWR_ns/tCKmax_ns). + * + * Ponder: Is twr_auto_clk different than twr_clk? + */ + tCKmax_ps = convert_bcd_tenths_to_cycle_time_ps(spd.tckmax); + twr_auto_clk = (spd.twr * 250 + tCKmax_ps - 1) / tCKmax_ps; + } + + + /* + * Mode Reg in bits 16 ~ 31, + * Extended Mode Reg 1 in bits 0 ~ 15. + */ + mode_odt_enable = 0x0; /* Default disabled */ + if (odt_wr_cfg || odt_rd_cfg) { + /* + * Bits 6 and 2 in Extended MRS(1) + * Bit 2 == 0x04 == 75 Ohm, with 2 DIMM modules. + * Bit 6 == 0x40 == 150 Ohm, with 1 DIMM module. + */ + mode_odt_enable = 0x40; /* 150 Ohm */ + } + + ddr1->sdram_mode_1 = + (0 + | (add_lat << (16 + 3)) /* Additive Latency in EMRS1 */ + | (mode_odt_enable << 16) /* ODT Enable in EMRS1 */ + | (twr_auto_clk << 9) /* Write Recovery Autopre */ + | (mode_caslat << 4) /* caslat */ + | (burst_len << 0) /* Burst length */ + ); + + debug("DDR: sdram_mode = 0x%08x\n", ddr1->sdram_mode_1); + + + /* + * Clear EMRS2 and EMRS3. + */ + ddr1->sdram_mode_2 = 0; + debug("DDR: sdram_mode_2 = 0x%08x\n", ddr1->sdram_mode_2); + + + /* + * Determine Refresh Rate. Ignore self refresh bit on DDR I. + * Table from SPD Spec, Byte 12, converted to picoseconds and + * filled in with "default" normal values. + */ + { + unsigned int refresh_clk; + unsigned int refresh_time_ns[8] = { + 15625000, /* 0 Normal 1.00x */ + 3900000, /* 1 Reduced .25x */ + 7800000, /* 2 Extended .50x */ + 31300000, /* 3 Extended 2.00x */ + 62500000, /* 4 Extended 4.00x */ + 125000000, /* 5 Extended 8.00x */ + 15625000, /* 6 Normal 1.00x filler */ + 15625000, /* 7 Normal 1.00x filler */ + }; + + refresh_clk = picos_to_clk(refresh_time_ns[spd.refresh & 0x7]); + + /* + * Set BSTOPRE to 0x100 for page mode + * If auto-charge is used, set BSTOPRE = 0 + */ + ddr1->sdram_interval = + (0 + | (refresh_clk & 0x3fff) << 16 + | 0x100 + ); + debug("DDR: sdram_interval = 0x%08x\n", ddr1->sdram_interval); + } + + /* + * Is this an ECC DDR chip? + * But don't mess with it if the DDR controller will init mem. + */ +#if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER) + if (spd.config == 0x02) { + ddr1->err_disable = 0x0000000d; + ddr1->err_sbe = 0x00ff0000; + } + debug("DDR: err_disable = 0x%08x\n", ddr1->err_disable); + debug("DDR: err_sbe = 0x%08x\n", ddr1->err_sbe); +#endif + + asm("sync;isync"); + udelay(500); + + /* + * SDRAM Cfg 2 + */ + + /* + * When ODT is enabled, Chap 9 suggests asserting ODT to + * internal IOs only during reads. + */ + odt_cfg = 0; + if (odt_rd_cfg | odt_wr_cfg) { + odt_cfg = 0x2; /* ODT to IOs during reads */ + } + + /* + * Try to use differential DQS with DDR II. + */ + if (spd.mem_type == SPD_MEMTYPE_DDR) { + dqs_cfg = 0; /* No Differential DQS for DDR I */ + } else { + dqs_cfg = 0x1; /* Differential DQS for DDR II */ + } + +#if defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER) + /* + * Use the DDR controller to auto initialize memory. + */ + d_init = 1; + ddr1->sdram_data_init = CONFIG_MEM_INIT_VALUE; + debug("DDR: ddr_data_init = 0x%08x\n", ddr1->sdram_data_init); +#else + /* + * Memory will be initialized via DMA, or not at all. + */ + d_init = 0; +#endif + + ddr1->sdram_cfg_2 = (0 + | (dqs_cfg << 26) /* Differential DQS */ + | (odt_cfg << 21) /* ODT */ + | (d_init << 4) /* D_INIT auto init DDR */ + ); + + debug("DDR: sdram_cfg_2 = 0x%08x\n", ddr1->sdram_cfg_2); + + +#ifdef MPC86xx_DDR_SDRAM_CLK_CNTL + { + unsigned char clk_adjust; + + /* + * Setup the clock control. + * SDRAM_CLK_CNTL[0] = Source synchronous enable == 1 + * SDRAM_CLK_CNTL[5-7] = Clock Adjust + * 0110 3/4 cycle late + * 0111 7/8 cycle late + */ + if (spd.mem_type == SPD_MEMTYPE_DDR) { + clk_adjust = 0x6; + } else { + clk_adjust = 0x7; + } + + ddr1->sdram_clk_cntl = (0 + | 0x80000000 + | (clk_adjust << 23) + ); + debug("DDR: sdram_clk_cntl = 0x%08x\n", ddr1->sdram_clk_cntl); + } +#endif + + /* + * Figure out the settings for the sdram_cfg register. + * Build up the entire register in 'sdram_cfg' before writing + * since the write into the register will actually enable the + * memory controller; all settings must be done before enabling. + * + * sdram_cfg[0] = 1 (ddr sdram logic enable) + * sdram_cfg[1] = 1 (self-refresh-enable) + * sdram_cfg[5:7] = (SDRAM type = DDR SDRAM) + * 010 DDR 1 SDRAM + * 011 DDR 2 SDRAM + */ + sdram_type = (spd.mem_type == SPD_MEMTYPE_DDR) ? 2 : 3; + sdram_cfg_1 = (0 + | (1 << 31) /* Enable */ + | (1 << 30) /* Self refresh */ + | (sdram_type << 24) /* SDRAM type */ + ); + + /* + * sdram_cfg[3] = RD_EN - registered DIMM enable + * A value of 0x26 indicates micron registered DIMMS (micron.com) + */ + if (spd.mem_type == SPD_MEMTYPE_DDR && spd.mod_attr == 0x26) { + sdram_cfg_1 |= 0x10000000; /* RD_EN */ + } + +#if defined(CONFIG_DDR_ECC) + /* + * If the user wanted ECC (enabled via sdram_cfg[2]) + */ + if (spd.config == 0x02) { + sdram_cfg_1 |= 0x20000000; /* ECC_EN */ + } +#endif + + /* + * REV1 uses 1T timing. + * REV2 may use 1T or 2T as configured by the user. + */ + { + uint pvr = get_pvr(); + + if (pvr != PVR_85xx_REV1) { +#if defined(CONFIG_DDR_2T_TIMING) + /* + * Enable 2T timing by setting sdram_cfg[16]. + */ + sdram_cfg_1 |= 0x8000; /* 2T_EN */ +#endif + } + } + + /* + * 200 painful micro-seconds must elapse between + * the DDR clock setup and the DDR config enable. + */ + udelay(200); + + /* + * Go! + */ + ddr1->sdram_cfg_1 = sdram_cfg_1; + + asm("sync;isync"); + udelay(500); + + debug("DDR: sdram_cfg = 0x%08x\n", ddr1->sdram_cfg_1); + + +#if defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER) + debug("DDR: memory initializing\n"); + /* + * Poll until memory is initialized. + * 512 Meg at 400 might hit this 200 times or so. + */ + while ((ddr1->sdram_cfg_2 & (d_init << 4)) != 0) { + udelay(1000); + } + debug("DDR: memory initialized\n"); +#endif + + + /* + * Figure out memory size in Megabytes. + */ + memsize = n_ranks * rank_density / 0x100000; + + + /* + * First supported LAW size is 16M, at LAWAR_SIZE_16M == 23. Fnord. + */ + law_size = 19 + __ilog2(memsize); + + /* + * Set up LAWBAR for all of DDR. + */ + mcm->lawbar1 = ((CFG_DDR_SDRAM_BASE >> 12) & 0xfffff); + mcm->lawar1 = (LAWAR_EN + | LAWAR_TRGT_IF_DDR + | (LAWAR_SIZE & law_size)); + debug("DDR: LAWBAR1=0x%08x\n", mcm->lawbar1); + debug("DDR: LARAR1=0x%08x\n", mcm->lawar1); + + + return memsize * 1024 * 1024; +} + +#endif /* CONFIG_SPD_EEPROM */ + + +#if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER) + +/* + * Initialize all of memory for ECC, then enable errors. + */ + +void +ddr_enable_ecc(unsigned int dram_size) +{ + uint *p = 0; + uint i = 0; + volatile immap_t *immap = (immap_t *)CFG_IMMR; + volatile ccsr_ddr_t *ddr1= &immap->im_ddr1; + + dma_init(); + + for (*p = 0; p < (uint *)(8 * 1024); p++) { + if (((unsigned int)p & 0x1f) == 0) { + ppcDcbz((unsigned long) p); + } + *p = (unsigned int)CONFIG_MEM_INIT_VALUE; + if (((unsigned int)p & 0x1c) == 0x1c) { + ppcDcbf((unsigned long) p); + } + } + + /* 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); + + for (i = 1; i < dram_size / 0x800000; i++) { + dma_xfer((uint *)(0x800000*i), 0x800000, (uint *)0); + } + + /* + * Enable errors for ECC. + */ + debug("DMA DDR: err_disable = 0x%08x\n", ddr1->err_disable); + ddr1->err_disable = 0x00000000; + asm("sync;isync;msync"); + debug("DMA DDR: err_disable = 0x%08x\n", ddr1->err_disable); +} + +#endif /* CONFIG_DDR_ECC && ! CONFIG_ECC_INIT_VIA_DDRCONTROLLER */ -- cgit v1.2.3 From 5c9efb36a6b5431423f52888a0e3b4b515fe7eca Mon Sep 17 00:00:00 2001 From: Jon Loeliger Date: Thu, 27 Apr 2006 10:15:16 -0500 Subject: Cleanup whitespaces and style issues. Removed //-style comments. Use 80-column lines. Remove trailing whitespace. Remove dead code and debug cruft. --- board/mpc8641hpcn/mpc8641hpcn.c | 33 ++--- board/mpc8641hpcn/oftree.dts | 2 +- cpu/mpc86xx/cpu.c | 262 +++++++++++++++++++--------------------- cpu/mpc86xx/cpu_init.c | 17 ++- cpu/mpc86xx/i2c.c | 68 +++++------ cpu/mpc86xx/interrupts.c | 23 ++-- cpu/mpc86xx/pci.c | 105 ++++++---------- cpu/mpc86xx/spd_sdram.c | 9 +- cpu/mpc86xx/speed.c | 260 +++++++++++++++++++-------------------- cpu/mpc86xx/start.S | 4 +- cpu/mpc86xx/traps.c | 2 - include/configs/MPC8641HPCN.h | 203 +++++++++++++------------------ include/mpc86xx.h | 6 +- 13 files changed, 439 insertions(+), 555 deletions(-) (limited to 'cpu/mpc86xx/spd_sdram.c') diff --git a/board/mpc8641hpcn/mpc8641hpcn.c b/board/mpc8641hpcn/mpc8641hpcn.c index cdfce6c1fd..ace6d47fde 100644 --- a/board/mpc8641hpcn/mpc8641hpcn.c +++ b/board/mpc8641hpcn/mpc8641hpcn.c @@ -57,9 +57,6 @@ int checkboard (void) #ifdef CONFIG_PCI - /* Sri: Note that at this point we will only test on PCI1 - */ - volatile immap_t *immap = (immap_t *) CFG_CCSRBAR; volatile ccsr_gur_t *gur = &immap->im_gur; volatile ccsr_pex_t *pex1 = &immap->im_pex1; @@ -70,13 +67,16 @@ int checkboard (void) uint pex1_agent = (host1_agent == 0) || (host1_agent == 1); - if ((io_sel==2 || io_sel==3 || io_sel==5 || io_sel==6 || io_sel==7 || io_sel==0xF ) && !(devdisr & MPC86xx_DEVDISR_PCIEX1)){ - debug ("PCI-EXPRESS 1: %s \n", - pex1_agent ? "Agent" : "Host"); + if ((io_sel==2 || io_sel==3 || io_sel==5 \ + || io_sel==6 || io_sel==7 || io_sel==0xF) + && !(devdisr & MPC86xx_DEVDISR_PCIEX1)){ + debug ("PCI-EXPRESS 1: %s \n", + pex1_agent ? "Agent" : "Host"); debug("0x%08x=0x%08x ", &pex1->pme_msg_det,pex1->pme_msg_det); if (pex1->pme_msg_det) { pex1->pme_msg_det = 0xffffffff; - debug (" with errors. Clearing. Now 0x%08x",pex1->pme_msg_det); + debug (" with errors. Clearing. Now 0x%08x", + pex1->pme_msg_det); } debug ("\n"); } else { @@ -120,15 +120,6 @@ initdram(int board_type) ddr_enable_ecc(dram_size); #endif - /* - * Initialize SDRAM. Currently HPCN doesn't have - * SDRAM but we'll leave this here for now - * in case someone changes their mind - */ -#if !defined(CONFIG_MPC8641HPCN) - // sdram_init(); -#endif - puts(" DDR: "); return dram_size; } @@ -163,7 +154,7 @@ local_bus_init(void) } #if defined(CFG_DRAM_TEST) -int testdram (void) +int testdram(void) { uint *pstart = (uint *) CFG_MEMTEST_START; uint *pend = (uint *) CFG_MEMTEST_END; @@ -198,10 +189,10 @@ int testdram (void) #if !defined(CONFIG_SPD_EEPROM) -/************************************************************************* - * fixed sdram init -- doesn't use serial presence detect. - ************************************************************************/ -long int fixed_sdram (void) +/* + * Fixed sdram init -- doesn't use serial presence detect. + */ +long int fixed_sdram(void) { #if !defined(CFG_RAMBOOT) volatile immap_t *immap = (immap_t *)CFG_IMMR; diff --git a/board/mpc8641hpcn/oftree.dts b/board/mpc8641hpcn/oftree.dts index 6c32ade0ca..8e38047e72 100644 --- a/board/mpc8641hpcn/oftree.dts +++ b/board/mpc8641hpcn/oftree.dts @@ -1,5 +1,5 @@ /* - * MPC8641 HPCn Device Tree Source + * MPC8641 HPCN Device Tree Source * * Copyright 2006 Freescale Semiconductor Inc. * diff --git a/cpu/mpc86xx/cpu.c b/cpu/mpc86xx/cpu.c index b0fe8abb2c..36da7774ea 100644 --- a/cpu/mpc86xx/cpu.c +++ b/cpu/mpc86xx/cpu.c @@ -32,31 +32,30 @@ #include #endif +extern unsigned long get_board_sys_clk(ulong dummy); -// SS: For debug only, remove after use static __inline__ unsigned long get_dbat3u (void) { - unsigned long dbat3u; - asm volatile("mfspr %0, 542" : "=r" (dbat3u) :); - return dbat3u; + unsigned long dbat3u; + asm volatile("mfspr %0, 542" : "=r" (dbat3u) :); + return dbat3u; } static __inline__ unsigned long get_dbat3l (void) { - unsigned long dbat3l; - asm volatile("mfspr %0, 543" : "=r" (dbat3l) :); - return dbat3l; + unsigned long dbat3l; + asm volatile("mfspr %0, 543" : "=r" (dbat3l) :); + return dbat3l; } static __inline__ unsigned long get_msr (void) { - unsigned long msr; - asm volatile("mfmsr %0" : "=r" (msr) :); - return msr; + unsigned long msr; + asm volatile("mfmsr %0" : "=r" (msr) :); + return msr; } -extern unsigned long get_board_sys_clk(ulong dummy); int checkcpu (void) { @@ -66,7 +65,7 @@ int checkcpu (void) uint major, minor; uint lcrr; /* local bus clock ratio register */ uint clkdiv; /* clock divider portion of lcrr */ - + puts("Freescale PowerPC\n"); pvr = get_pvr(); @@ -74,10 +73,10 @@ int checkcpu (void) major = PVR_MAJ(pvr); minor = PVR_MIN(pvr); - puts ("CPU:\n"); + puts("CPU:\n"); printf(" Core: "); - + switch (ver) { case PVR_VER(PVR_86xx): puts("E600"); @@ -94,7 +93,7 @@ int checkcpu (void) minor = SVR_MIN(svr); puts(" System: "); - switch (ver) { + switch (ver) { case SVR_8641: puts("8641"); break; @@ -113,7 +112,7 @@ int checkcpu (void) printf("CPU:%4lu MHz, ", sysinfo.freqProcessor / 1000000); printf("MPX:%4lu MHz, ", sysinfo.freqSystemBus / 1000000); printf("DDR:%4lu MHz, ", sysinfo.freqSystemBus / 2000000); - + #if defined(CFG_LBC_LCRR) lcrr = CFG_LBC_LCRR; #else @@ -134,11 +133,11 @@ int checkcpu (void) printf(" L2: "); if (get_l2cr() & 0x80000000) - printf("Enabled\n"); + printf("Enabled\n"); else - printf("Disabled\n"); - - return (0); + printf("Disabled\n"); + + return 0; } @@ -149,7 +148,7 @@ soft_restart(unsigned long addr) { #ifndef CONFIG_MPC8641HPCN - + /* SRR0 has system reset vector, SRR1 has default MSR value */ /* rfi restores MSR from SRR1 and sets the PC to the SRR0 value */ @@ -215,7 +214,7 @@ int set_px_sysclk(ulong sysclk) sysclk_s = 0x06; sysclk_r = 0x1F; sysclk_v = 0x3B; - sysclk_aux = 0x06; + sysclk_aux = 0x06; break; case 166: sysclk_s = 0x06; @@ -227,14 +226,14 @@ int set_px_sysclk(ulong sysclk) printf("Unsupported SYSCLK frequency.\n"); return 0; } - + vclkh = (sysclk_s << 5) | sysclk_r ; vclkl = sysclk_v; out8(PIXIS_BASE+PIXIS_VCLKH,vclkh); out8(PIXIS_BASE+PIXIS_VCLKL,vclkl); out8(PIXIS_BASE+PIXIS_AUX,sysclk_aux); - + return 1; } @@ -262,7 +261,7 @@ int set_px_mpxpll(ulong mpxpll) tmp = in8(PIXIS_BASE+PIXIS_VSPEED1); tmp = (tmp & 0xF0) | (val & 0x0F); out8(PIXIS_BASE+PIXIS_VSPEED1,tmp); - + return 1; } @@ -270,9 +269,8 @@ int set_px_corepll(ulong corepll) { u8 tmp; u8 val; - - switch((int)corepll) - { + + switch ((int)corepll) { case 20: val = 0x08; break; @@ -295,11 +293,11 @@ int set_px_corepll(ulong corepll) printf("Unsupported COREPLL ratio.\n"); return 0; } - + tmp = in8(PIXIS_BASE+PIXIS_VSPEED0); tmp = (tmp & 0xE0) | (val & 0x1F); out8(PIXIS_BASE+PIXIS_VSPEED0,tmp); - + return 1; } @@ -311,7 +309,7 @@ void read_from_px_regs(int set) tmp = tmp | mask; else tmp = tmp & ~mask; - out8(PIXIS_BASE+PIXIS_VCFGEN0,tmp); + out8(PIXIS_BASE+PIXIS_VCFGEN0,tmp); } void read_from_px_regs_altbank(int set) @@ -322,7 +320,7 @@ void read_from_px_regs_altbank(int set) tmp = tmp | mask; else tmp = tmp & ~mask; - out8(PIXIS_BASE+PIXIS_VCFGEN1,tmp); + out8(PIXIS_BASE+PIXIS_VCFGEN1,tmp); } void set_altbank(void) @@ -342,7 +340,7 @@ void set_px_go(void) out8(PIXIS_BASE+PIXIS_VCTL,tmp); tmp = in8(PIXIS_BASE+PIXIS_VCTL); tmp = tmp | 0x01; - out8(PIXIS_BASE+PIXIS_VCTL,tmp); + out8(PIXIS_BASE+PIXIS_VCTL,tmp); } void set_px_go_with_watchdog(void) @@ -353,7 +351,7 @@ void set_px_go_with_watchdog(void) out8(PIXIS_BASE+PIXIS_VCTL,tmp); tmp = in8(PIXIS_BASE+PIXIS_VCTL); tmp = tmp | 0x09; - out8(PIXIS_BASE+PIXIS_VCTL,tmp); + out8(PIXIS_BASE+PIXIS_VCTL,tmp); } /* This function takes the non-integral cpu:mpx pll ratio @@ -381,11 +379,11 @@ ulong strfractoint(uchar *strptr) no_dec = 1; break; /* Break from loop once the end of string is reached */ } - + intarr[i] = strptr[i]; i++; } - + intarr_len = i; /* Assign length of integer part to intarr_len*/ intarr[i] = '\0'; /* */ @@ -404,14 +402,14 @@ ulong strfractoint(uchar *strptr) i++; j++; } - + decarr_len = j; decarr[j] = '\0'; - + mulconst=1; for(i=0; i 1) - { - cmd = argv[1][1]; - switch(cmd) - { - case 'f': /* reset with frequency changed */ - - if (argc < 5) - goto my_usage; - - read_from_px_regs(0); - - val = set_px_sysclk(simple_strtoul(argv[2],NULL,10)); - - corepll = strfractoint(argv[3]); - val = val + set_px_corepll(corepll); - val = val + set_px_mpxpll(simple_strtoul(argv[4],NULL,10)); - if(val == 3) - { - printf("Setting registers VCFGEN0 and VCTL\n"); - read_from_px_regs(1); - printf("Resetting board with values from VSPEED0, VSPEED1, VCLKH, and VCLKL ....\n"); - set_px_go(); - } - else - goto my_usage; - - while(1); /* Not reached */ - - case 'l': - if(argv[2][1] == 'f') - { - read_from_px_regs(0); - read_from_px_regs_altbank(0); - /* reset with frequency changed */ - val = set_px_sysclk(simple_strtoul(argv[3],NULL,10)); - - corepll = strfractoint(argv[4]); - val = val + set_px_corepll(corepll); - val = val + set_px_mpxpll(simple_strtoul(argv[5],NULL,10)); - if(val == 3) - { - printf("Setting registers VCFGEN0, VCFGEN1, VBOOT, and VCTL\n"); - set_altbank(); - read_from_px_regs(1); - read_from_px_regs_altbank(1); - printf("Enabling watchdog timer on the FPGA and resetting board with values from VSPEED0, VSPEED1, VCLKH, and VCLKL to boot from the other bank ....\n"); - set_px_go_with_watchdog(); - - } - else - goto my_usage; - - while(1); /* Not reached */ - } - else /* Reset from next bank without changing frequencies */ - { - read_from_px_regs(0); - read_from_px_regs_altbank(0); - if(argc > 2) - goto my_usage; - printf("Setting registers VCFGEN1, VBOOT, and VCTL\n"); - set_altbank(); - read_from_px_regs_altbank(1); - printf("Enabling watchdog timer on the FPGA and resetting board to boot from the other bank....\n"); - set_px_go_with_watchdog(); - while(1); /* Not reached */ - } - - default: - goto my_usage; - } + + if (argc > 1) { + cmd = argv[1][1]; + switch(cmd) { + case 'f': /* reset with frequency changed */ + if (argc < 5) + goto my_usage; + read_from_px_regs(0); + + val = set_px_sysclk(simple_strtoul(argv[2],NULL,10)); + + corepll = strfractoint(argv[3]); + val = val + set_px_corepll(corepll); + val = val + set_px_mpxpll(simple_strtoul(argv[4], + NULL, 10)); + if (val == 3) { + printf("Setting registers VCFGEN0 and VCTL\n"); + read_from_px_regs(1); + printf("Resetting board with values from VSPEED0, VSPEED1, VCLKH, and VCLKL ....\n"); + set_px_go(); + } else + goto my_usage; + + while (1); /* Not reached */ + + case 'l': + if (argv[2][1] == 'f') { + read_from_px_regs(0); + read_from_px_regs_altbank(0); + /* reset with frequency changed */ + val = set_px_sysclk(simple_strtoul(argv[3],NULL,10)); + + corepll = strfractoint(argv[4]); + val = val + set_px_corepll(corepll); + val = val + set_px_mpxpll(simple_strtoul(argv[5],NULL,10)); + if (val == 3) { + printf("Setting registers VCFGEN0, VCFGEN1, VBOOT, and VCTL\n"); + set_altbank(); + read_from_px_regs(1); + read_from_px_regs_altbank(1); + printf("Enabling watchdog timer on the FPGA and resetting board with values from VSPEED0, VSPEED1, VCLKH, and VCLKL to boot from the other bank ....\n"); + set_px_go_with_watchdog(); + } else + goto my_usage; + + while(1); /* Not reached */ + } else { + /* Reset from next bank without changing frequencies */ + read_from_px_regs(0); + read_from_px_regs_altbank(0); + if(argc > 2) + goto my_usage; + printf("Setting registers VCFGEN1, VBOOT, and VCTL\n"); + set_altbank(); + read_from_px_regs_altbank(1); + printf("Enabling watchdog timer on the FPGA and resetting board to boot from the other bank....\n"); + set_px_go_with_watchdog(); + while(1); /* Not reached */ + } + + default: + goto my_usage; + } + my_usage: - printf("\nUsage: reset cf \n"); - printf(" reset altbank [cf ]\n"); - printf("For example: reset cf 40 2.5 10\n"); - printf("See MPC8641HPCN Design Workbook for valid values of command line parameters.\n"); - return; - } - else - out8(PIXIS_BASE+PIXIS_RST,0); - + printf("\nUsage: reset cf \n"); + printf(" reset altbank [cf ]\n"); + printf("For example: reset cf 40 2.5 10\n"); + printf("See MPC8641HPCN Design Workbook for valid values of command line parameters.\n"); + return; + } else + out8(PIXIS_BASE+PIXIS_RST,0); + #endif /* !CONFIG_MPC8641HPCN */ - + while(1); /* not reached */ } -/* ------------------------------------------------------------------------- */ - /* * Get timebase clock frequency */ @@ -566,24 +550,21 @@ unsigned long get_tbclk(void) sys_info_t sys_info; get_sys_info(&sys_info); - return ((sys_info.freqSystemBus + 3L) / 4L); - + return (sys_info.freqSystemBus + 3L) / 4L; } -/* ------------------------------------------------------------------------- */ #if defined(CONFIG_WATCHDOG) void watchdog_reset(void) { - } #endif /* CONFIG_WATCHDOG */ -/* ------------------------------------------------------------------------- */ #if defined(CONFIG_DDR_ECC) -void dma_init(void) { +void dma_init(void) +{ volatile immap_t *immap = (immap_t *)CFG_IMMR; volatile ccsr_dma_t *dma = &immap->im_dma; @@ -593,7 +574,8 @@ void dma_init(void) { return; } -uint dma_check(void) { +uint dma_check(void) +{ volatile immap_t *immap = (immap_t *)CFG_IMMR; volatile ccsr_dma_t *dma = &immap->im_dma; volatile uint status = dma->sr0; @@ -609,7 +591,8 @@ uint dma_check(void) { return status; } -int dma_xfer(void *dest, uint count, void *src) { +int dma_xfer(void *dest, uint count, void *src) +{ volatile immap_t *immap = (immap_t *)CFG_IMMR; volatile ccsr_dma_t *dma = &immap->im_dma; @@ -622,6 +605,7 @@ int dma_xfer(void *dest, uint count, void *src) { asm("sync;isync"); return dma_check(); } + #endif /* CONFIG_DDR_ECC */ @@ -631,7 +615,7 @@ void ft_cpu_setup(void *blob, bd_t *bd) u32 *p; ulong clock; int len; - + clock = bd->bi_busfreq; p = ft_get_prop(blob, "/cpus/" OF_CPU "/bus-frequency", &len); if (p != NULL) @@ -649,7 +633,7 @@ void ft_cpu_setup(void *blob, bd_t *bd) p = ft_get_prop(blob, "/" OF_SOC "/ethernet@24000/address", &len); memcpy(p, bd->bi_enetaddr, 6); #endif - + #if defined(CONFIG_MPC86XX_TSEC2) p = ft_get_prop(blob, "/" OF_SOC "/ethernet@25000/address", &len); memcpy(p, bd->bi_enet1addr, 6); diff --git a/cpu/mpc86xx/cpu_init.c b/cpu/mpc86xx/cpu_init.c index 582ac6ba95..c816c18974 100644 --- a/cpu/mpc86xx/cpu_init.c +++ b/cpu/mpc86xx/cpu_init.c @@ -36,13 +36,12 @@ * initialize a bunch of registers */ -void cpu_init_f (void) +void cpu_init_f(void) { DECLARE_GLOBAL_DATA_PTR; volatile immap_t *immap = (immap_t *)CFG_IMMR; volatile ccsr_lbc_t *memctl = &immap->im_lbc; - //u8 val; - + /* Pointer is writable since we allocated a register for it */ gd = (gd_t *) (CFG_INIT_RAM_ADDR + CFG_GBL_DATA_OFFSET); @@ -72,23 +71,21 @@ void cpu_init_f (void) memctl->br1 = CFG_BR1_PRELIM; #endif - //#if !defined(CONFIG_MPC86xx) #if defined(CFG_BR2_PRELIM) && defined(CFG_OR2_PRELIM) memctl->or2 = CFG_OR2_PRELIM; memctl->br2 = CFG_BR2_PRELIM; #endif - //#endif - + #if defined(CFG_BR3_PRELIM) && defined(CFG_OR3_PRELIM) memctl->or3 = CFG_OR3_PRELIM; memctl->br3 = CFG_BR3_PRELIM; #endif - + #if defined(CFG_BR4_PRELIM) && defined(CFG_OR4_PRELIM) memctl->or4 = CFG_OR4_PRELIM; memctl->br4 = CFG_BR4_PRELIM; #endif - + #if defined(CFG_BR5_PRELIM) && defined(CFG_OR5_PRELIM) memctl->or5 = CFG_OR5_PRELIM; memctl->br5 = CFG_BR5_PRELIM; @@ -123,9 +120,9 @@ void cpu_init_f (void) /* * initialize higher level parts of CPU like timers */ -int cpu_init_r (void) +int cpu_init_r(void) { - return (0); + return 0; } diff --git a/cpu/mpc86xx/i2c.c b/cpu/mpc86xx/i2c.c index c5d4642b9a..f2b4b0f6da 100644 --- a/cpu/mpc86xx/i2c.c +++ b/cpu/mpc86xx/i2c.c @@ -74,29 +74,27 @@ i2c_init(int speed, int slaveadd) } static __inline__ int -i2c_wait4bus (void) +i2c_wait4bus(void) { ulong timeval = get_timer (0); - // debug("I2C: Wait for bus\n"); while (readb(I2CCSR) & MPC86xx_I2CSR_MBB) { - if (get_timer (timeval) > TIMEOUT) { + if (get_timer(timeval) > TIMEOUT) { return -1; } } - return 0; + return 0; } static __inline__ int -i2c_wait (int write) +i2c_wait(int write) { u32 csr; ulong timeval = get_timer (0); do { csr = readb(I2CCSR); - if (!(csr & MPC86xx_I2CSR_MIF)) continue; @@ -118,7 +116,7 @@ i2c_wait (int write) } return 0; - } while (get_timer (timeval) < TIMEOUT); + } while (get_timer(timeval) < TIMEOUT); debug("i2c_wait: timed out\n"); return -1; @@ -127,14 +125,13 @@ i2c_wait (int write) static __inline__ int i2c_write_addr (u8 dev, u8 dir, int rsta) { - // debug("I2C: Write Addr\n"); - writeb(MPC86xx_I2CCR_MEN | MPC86xx_I2CCR_MSTA | MPC86xx_I2CCR_MTX | - (rsta?MPC86xx_I2CCR_RSTA:0), + writeb(MPC86xx_I2CCR_MEN | MPC86xx_I2CCR_MSTA | MPC86xx_I2CCR_MTX + | (rsta ? MPC86xx_I2CCR_RSTA : 0), I2CCCR); writeb((dev << 1) | dir, I2CCDR); - if (i2c_wait (I2C_WRITE) < 0) + if (i2c_wait(I2C_WRITE) < 0) return 0; return 1; @@ -144,14 +141,14 @@ static __inline__ int __i2c_write (u8 *data, int length) { int i; - // debug("I2C: __i2c_write\n"); + writeb(MPC86xx_I2CCR_MEN | MPC86xx_I2CCR_MSTA | MPC86xx_I2CCR_MTX, I2CCCR); - for (i=0; i < length; i++) { + for (i = 0; i < length; i++) { writeb(data[i], I2CCDR); - if (i2c_wait (I2C_WRITE) < 0) + if (i2c_wait(I2C_WRITE) < 0) break; } @@ -163,33 +160,30 @@ __i2c_read (u8 *data, int length) { int i; - writeb(MPC86xx_I2CCR_MEN | MPC86xx_I2CCR_MSTA | - ((length == 1) ? MPC86xx_I2CCR_TXAK : 0), + writeb(MPC86xx_I2CCR_MEN | MPC86xx_I2CCR_MSTA + | ((length == 1) ? MPC86xx_I2CCR_TXAK : 0), I2CCCR); /* dummy read */ readb(I2CCDR); - // debug("length = %d\n", length); - for (i=0; i < length; i++) { - if (i2c_wait (I2C_READ) < 0) + for (i = 0; i < length; i++) { + if (i2c_wait(I2C_READ) < 0) break; /* Generate ack on last next to last byte */ if (i == length - 2) - writeb(MPC86xx_I2CCR_MEN | MPC86xx_I2CCR_MSTA | - MPC86xx_I2CCR_TXAK, + writeb(MPC86xx_I2CCR_MEN | MPC86xx_I2CCR_MSTA + | MPC86xx_I2CCR_TXAK, I2CCCR); /* Generate stop on last byte */ if (i == length - 1) writeb(MPC86xx_I2CCR_MEN | MPC86xx_I2CCR_TXAK, I2CCCR); - // debug("I2CCR = 0x%08x\n", readb(I2CCCR)); data[i] = readb(I2CCDR); - // debug("data[i] = 0x%08x\n", data[i]); } - // debug("Returning i = %d\n", i); + return i; } @@ -199,19 +193,19 @@ i2c_read (u8 dev, uint addr, int alen, u8 *data, int length) int i = 0; u8 *a = (u8*)&addr; - if (i2c_wait4bus () < 0) + if (i2c_wait4bus() < 0) goto exit; - if (i2c_write_addr (dev, I2C_WRITE, 0) == 0) + if (i2c_write_addr(dev, I2C_WRITE, 0) == 0) goto exit; - if (__i2c_write (&a[4 - alen], alen) != alen) + if (__i2c_write(&a[4 - alen], alen) != alen) goto exit; - if (i2c_write_addr (dev, I2C_READ, 1) == 0) + if (i2c_write_addr(dev, I2C_READ, 1) == 0) goto exit; - i = __i2c_read (data, length); + i = __i2c_read(data, length); exit: writeb(MPC86xx_I2CCR_MEN, I2CCCR); @@ -225,16 +219,16 @@ i2c_write (u8 dev, uint addr, int alen, u8 *data, int length) int i = 0; u8 *a = (u8*)&addr; - if (i2c_wait4bus () < 0) + if (i2c_wait4bus() < 0) goto exit; - if (i2c_write_addr (dev, I2C_WRITE, 0) == 0) + if (i2c_write_addr(dev, I2C_WRITE, 0) == 0) goto exit; - if (__i2c_write (&a[4 - alen], alen) != alen) + if (__i2c_write(&a[4 - alen], alen) != alen) goto exit; - i = __i2c_write (data, length); + i = __i2c_write(data, length); exit: writeb(MPC86xx_I2CCR_MEN, I2CCCR); @@ -253,21 +247,21 @@ int i2c_probe (uchar chip) */ udelay(10000); - return i2c_read (chip, 0, 1, (char *)&tmp, 1); + return i2c_read(chip, 0, 1, (char *)&tmp, 1); } uchar i2c_reg_read (uchar i2c_addr, uchar reg) { char buf[1]; - i2c_read (i2c_addr, reg, 1, buf, 1); + i2c_read(i2c_addr, reg, 1, buf, 1); - return (buf[0]); + return buf[0]; } void i2c_reg_write (uchar i2c_addr, uchar reg, uchar val) { - i2c_write (i2c_addr, reg, 1, &val, 1); + i2c_write(i2c_addr, reg, 1, &val, 1); } #endif /* CONFIG_HARD_I2C */ diff --git a/cpu/mpc86xx/interrupts.c b/cpu/mpc86xx/interrupts.c index 759a30f9f0..b5cd439e53 100644 --- a/cpu/mpc86xx/interrupts.c +++ b/cpu/mpc86xx/interrupts.c @@ -75,7 +75,7 @@ static __inline__ void set_dec (unsigned long val) /* interrupt is not supported yet */ int interrupt_init_cpu (unsigned *decrementer_count) { - return (0); + return 0; } @@ -91,14 +91,14 @@ int interrupt_init (void) decrementer_count = get_tbclk()/CFG_HZ; debug("interrupt init: tbclk() = %d MHz, decrementer_count = %d\n", (get_tbclk()/1000000), decrementer_count); - + set_dec (decrementer_count); set_msr (get_msr () | MSR_EE); debug("MSR = 0x%08lx, Decrementer reg = 0x%08lx\n", get_msr(), get_dec()); - - return (0); + + return 0; } @@ -113,7 +113,7 @@ int disable_interrupts (void) ulong msr = get_msr (); set_msr (msr & ~MSR_EE); - return ((msr & MSR_EE) != 0); + return (msr & MSR_EE) != 0; } @@ -131,7 +131,6 @@ void timer_interrupt_cpu (struct pt_regs *regs) { /* nothing to do here */ - return; } @@ -139,14 +138,14 @@ void timer_interrupt (struct pt_regs *regs) { /* call cpu specific function from $(CPU)/interrupts.c */ timer_interrupt_cpu (regs); - + timestamp++; ppcDcbf(×tamp); - + /* Restore Decrementer Count */ set_dec (decrementer_count); - + #if defined(CONFIG_WATCHDOG) || defined (CONFIG_HW_WATCHDOG) if ((timestamp % (CFG_WATCHDOG_FREQ)) == 0) WATCHDOG_RESET (); @@ -169,8 +168,8 @@ void reset_timer (void) } ulong get_timer (ulong base) -{ - return (timestamp - base); +{ + return timestamp - base; } void set_timer (ulong t) @@ -185,13 +184,11 @@ void set_timer (ulong t) void irq_install_handler(int vec, interrupt_handler_t *handler, void *arg) { - return; } void irq_free_handler(int vec) { - return; } diff --git a/cpu/mpc86xx/pci.c b/cpu/mpc86xx/pci.c index 9cf5f7ca95..05976bdd4b 100644 --- a/cpu/mpc86xx/pci.c +++ b/cpu/mpc86xx/pci.c @@ -22,7 +22,7 @@ */ /* - * PEX Configuration space access support for MPC85xx PEX Bridge + * PEX Configuration space access support for PEX Bridge */ #include #include @@ -44,24 +44,25 @@ pci_mpc86xx_init(struct pci_controller *hose) ulong addr, data; - uint pex1_agent = (host1_agent == 0) || (host1_agent == 1); uint devdisr = gur->devdisr; uint io_sel = (gur->pordevsr & MPC86xx_PORDEVSR_IO_SEL) >> 16; - - if ((io_sel==2 || io_sel==3 || io_sel==5 || io_sel==6 || io_sel==7 || io_sel==0xF ) && !(devdisr & MPC86xx_DEVDISR_PCIEX1)){ + + if ((io_sel==2 || io_sel==3 || io_sel==5 + || io_sel==6 || io_sel==7 || io_sel==0xF ) + && !(devdisr & MPC86xx_DEVDISR_PCIEX1)){ printf ("PCI-EXPRESS 1: Configured as %s \n", pex1_agent ? "Agent" : "Host"); printf (" Scanning PCI bus"); debug("0x%08x=0x%08x ", &pex1->pme_msg_det,pex1->pme_msg_det); if (pex1->pme_msg_det) { pex1->pme_msg_det = 0xffffffff; - debug (" with errors. Clearing. Now 0x%08x",pex1->pme_msg_det); + debug (" with errors. Clearing. Now 0x%08x", + pex1->pme_msg_det); } debug ("\n"); } - - + hose->first_busno = 0; hose->last_busno = 0x7f; @@ -88,36 +89,26 @@ pci_mpc86xx_init(struct pci_controller *hose) */ pci_register_hose(hose); - //#define MPC8548_REV1_PEX12_ERRATA -#ifdef MPC8548_REV1_PEX12_ERRATA - /* can only read/write 4 bytes */ - pci_read_config_dword (PCI_BDF(0,0,0), PCI_VENDOR_ID, ®32); - printf("pex_mpc85xx_init: pex cr %2x %8x\n",PCI_VENDOR_ID, reg32); - - pci_read_config_word (PCI_BDF(0,0,0), PCI_COMMAND, ®32); - reg32 |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY; - pci_write_config_word(PCI_BDF(0,0,0), PCI_COMMAND, reg32); -#else pci_read_config_word (PCI_BDF(0,0,0), PCI_VENDOR_ID, ®16); debug("pex_mpc86xx_init: read %2x %4x\n",PCI_VENDOR_ID, reg16); pci_read_config_word (PCI_BDF(0,0,0), PCI_DEVICE_ID, ®16); debug("pex_mpc86xx_init: read %2x %4x\n",PCI_DEVICE_ID, reg16); pci_read_config_word (PCI_BDF(0,0,0), PCI_COMMAND, ®16); - reg16 |= PCI_COMMAND_SERR | PCI_COMMAND_PARITY | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY; + reg16 |= PCI_COMMAND_SERR | PCI_COMMAND_PARITY \ + | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY; pci_write_config_word(PCI_BDF(0,0,0), PCI_COMMAND, reg16); pci_read_config_word (PCI_BDF(0,0,0), PCI_COMMAND, ®16); debug("pex_mpc86xx_init: read %2x %4x\n",PCI_COMMAND, reg16); - -#endif - /* * Clear non-reserved bits in status register. */ - // pci_write_config_word(PCI_BDF(0,0,0), PCI_STATUS, 0xffff); - // pci_write_config_byte(PCI_BDF(0,0,0), PCI_LATENCY_TIMER,0x80); + /* + * pci_write_config_word(PCI_BDF(0,0,0), PCI_STATUS, 0xffff); + * pci_write_config_byte(PCI_BDF(0,0,0), PCI_LATENCY_TIMER,0x80); + */ pex1->powbar1 = (CFG_PCI1_MEM_BASE >> 12) & 0x000fffff; pex1->powar1 = 0x8004401c; /* 512M MEM space */ @@ -129,7 +120,6 @@ pci_mpc86xx_init(struct pci_controller *hose) pex1->potar2 = 0x00000000; pex1->potear2 = 0x00000000; - if (!pex1->piwar1) { pex1->pitar1 = 0x00000000; pex1->piwbar1 = (0x80000000 >> 12 ) & 0x000fffff; @@ -140,57 +130,34 @@ pci_mpc86xx_init(struct pci_controller *hose) pex1->pitar2 = 0x00000000; pex1->piwbar2 = (0xe2000000 >> 12 ) & 0x000fffff; pex1->piwar2 = 0xa0f5501e; /* Enable, Prefetch, Local Mem, - - - -/* if (pex1_host) { */ -/* #ifdef MPC8548_REV1_PEX12_ERRATA */ -/* pci_write_config_dword (PCI_BDF(0,0,0), 0x18, 0x00ff0100); */ -/* #else */ - - - - *(u32 *)(0xf8008000)= 0x80000000; - debug("Received data for addr 0x%08lx is 0x%08lx\n", *(u32*)(0xf8008000), *(u32*)(0xf8008004)); - - - pci_write_config_byte(PCI_BDF(0,0,0), PCI_PRIMARY_BUS,0x20); - pci_write_config_byte(PCI_BDF(0,0,0), PCI_SECONDARY_BUS,0x00); - pci_write_config_byte(PCI_BDF(0,0,0), PCI_SUBORDINATE_BUS,0x1F); -/* #endif */ - - - *(u32 *)(0xf8008000)= 0x80200000; - debug("Received data for addr 0x%08lx is 0x%08lx\n", *(u32*)(0xf8008000), *(u32*)(0xf8008004)); - - *(u32 *)(0xf8008000)= 0x80200000; - debug("Received data for addr 0x%08lx is 0x%08lx\n", *(u32*)(0xf8008000), *(u32*)(0xf8008004)); - - *(u32 *)(0xf8008000)= 0x80200000; - debug("Received data for addr 0x%08lx is 0x%08lx\n", *(u32*)(0xf8008000), *(u32*)(0xf8008004)); + * Snoop R/W, 2G */ + *(u32 *)(0xf8008000)= 0x80000000; + debug("Received data for addr 0x%08lx is 0x%08lx\n", + *(u32*)(0xf8008000), *(u32*)(0xf8008004)); - - hose->last_busno = pci_hose_scan(hose); - hose->last_busno = 0x21; - debug("pex_mpc86xx_init: last_busno %x\n",hose->last_busno); - debug("pex_mpc86xx init: current_busno %x\n ",hose->current_busno); + pci_write_config_byte(PCI_BDF(0,0,0), PCI_PRIMARY_BUS,0x20); + pci_write_config_byte(PCI_BDF(0,0,0), PCI_SECONDARY_BUS,0x00); + pci_write_config_byte(PCI_BDF(0,0,0), PCI_SUBORDINATE_BUS,0x1F); + *(u32 *)(0xf8008000)= 0x80200000; + debug("Received data for addr 0x%08lx is 0x%08lx\n", + *(u32*)(0xf8008000), *(u32*)(0xf8008004)); - printf("....PCI scan & enumeration done\n"); + *(u32 *)(0xf8008000)= 0x80200000; + debug("Received data for addr 0x%08lx is 0x%08lx\n", + *(u32*)(0xf8008000), *(u32*)(0xf8008004)); -/* *(u32 *)(0xf8008000)= 0x80000000 | (0x12 << 11); */ -/* printf("Received data for addr 0x%08lx is 0x%08lx\n", *(u32*)(0xf8008000), *(u32*)(0xf8008004)); */ - -/* if (hose->last_busno < 1) { */ -/* hose->last_busno=1; /\*Hack*\/ */ -/* } else { */ -/* hose->last_busno = 0; */ -/* } */ -/*}*/ -/* pci_read_config_dword (PCI_BDF(1,0,0), 0x18, ®32); */ -/* printf("pex_mpc86xx_init: pex cr %2x %8x\n",0x18, reg32); */ + *(u32 *)(0xf8008000)= 0x80200000; + debug("Received data for addr 0x%08lx is 0x%08lx\n", + *(u32*)(0xf8008000), *(u32*)(0xf8008004)); + hose->last_busno = pci_hose_scan(hose); + hose->last_busno = 0x21; + debug("pex_mpc86xx_init: last_busno %x\n",hose->last_busno); + debug("pex_mpc86xx init: current_busno %x\n ",hose->current_busno); + printf("....PCI scan & enumeration done\n"); } + #endif /* CONFIG_PCI */ diff --git a/cpu/mpc86xx/spd_sdram.c b/cpu/mpc86xx/spd_sdram.c index 9c07f200fb..9ce31d7c6f 100644 --- a/cpu/mpc86xx/spd_sdram.c +++ b/cpu/mpc86xx/spd_sdram.c @@ -179,7 +179,7 @@ spd_sdram(void) unsigned int law_size; volatile ccsr_local_mcm_t *mcm = &immap->im_local_mcm; - + /* * Read SPD information. */ @@ -614,7 +614,7 @@ spd_sdram(void) ddr1->timing_cfg_2 = (0 | ((add_lat & 0x7) << 28) /* ADD_LAT */ - | ((cpo & 0x1f) << 23) /* CPO */ + | ((cpo & 0x1f) << 23) /* CPO */ | ((wr_lat & 0x7) << 19) /* WR_LAT */ | ((trtp_clk & 0x7) << 13) /* RD_TO_PRE */ | ((wr_data_delay & 0x7) << 10) /* WR_DATA_DELAY */ @@ -806,7 +806,7 @@ spd_sdram(void) /* * Memory will be initialized via DMA, or not at all. */ - d_init = 0; + d_init = 0; #endif ddr1->sdram_cfg_2 = (0 @@ -946,8 +946,7 @@ spd_sdram(void) | (LAWAR_SIZE & law_size)); debug("DDR: LAWBAR1=0x%08x\n", mcm->lawbar1); debug("DDR: LARAR1=0x%08x\n", mcm->lawar1); - - + return memsize * 1024 * 1024; } diff --git a/cpu/mpc86xx/speed.c b/cpu/mpc86xx/speed.c index 0f5a6388ce..a08ae5f94b 100644 --- a/cpu/mpc86xx/speed.c +++ b/cpu/mpc86xx/speed.c @@ -33,9 +33,7 @@ unsigned long get_board_sys_clk(ulong dummy); unsigned long get_sysclk_from_px_regs(void); -/* --------------------------------------------------------------- */ - -void get_sys_info (sys_info_t * sysInfo) +void get_sys_info (sys_info_t *sysInfo) { volatile immap_t *immap = (immap_t *)CFG_IMMR; volatile ccsr_gur_t *gur = &immap->im_gur; @@ -43,7 +41,7 @@ void get_sys_info (sys_info_t * sysInfo) plat_ratio = (gur->porpllsr) & 0x0000003e; plat_ratio >>= 1; - + switch(plat_ratio) { case 0x0: sysInfo->freqSystemBus = 16 * CONFIG_SYS_CLK_FREQ; @@ -65,72 +63,77 @@ void get_sys_info (sys_info_t * sysInfo) break; } - // printf("assigned system bus freq = %d for plat ratio 0x%08lx\n", sysInfo->freqSystemBus, plat_ratio); +#if 0 + printf("assigned system bus freq = %d for plat ratio 0x%08lx\n", + sysInfo->freqSystemBus, plat_ratio); +#endif + e600_ratio = (gur->porpllsr) & 0x003f0000; e600_ratio >>= 16; - switch(e600_ratio) { + + switch (e600_ratio) { case 0x10: - sysInfo->freqProcessor = 2*sysInfo->freqSystemBus; + sysInfo->freqProcessor = 2 * sysInfo->freqSystemBus; break; - case 0x19: - sysInfo->freqProcessor = 5*sysInfo->freqSystemBus/2; + case 0x19: + sysInfo->freqProcessor = 5 * sysInfo->freqSystemBus/2; break; case 0x20: - sysInfo->freqProcessor = 3*sysInfo->freqSystemBus; + sysInfo->freqProcessor = 3 * sysInfo->freqSystemBus; break; case 0x39: - sysInfo->freqProcessor = 7*sysInfo->freqSystemBus/2; + sysInfo->freqProcessor = 7 * sysInfo->freqSystemBus/2; break; case 0x28: - sysInfo->freqProcessor = 4*sysInfo->freqSystemBus; + sysInfo->freqProcessor = 4 * sysInfo->freqSystemBus; break; case 0x1d: - sysInfo->freqProcessor = 9*sysInfo->freqSystemBus/2; + sysInfo->freqProcessor = 9 * sysInfo->freqSystemBus/2; break; default: - /* JB - Emulator workaround until real cop is plugged in */ - sysInfo->freqProcessor = e600_ratio + sysInfo->freqSystemBus; - //sysInfo->freqProcessor = 3*sysInfo->freqSystemBus; + /* JB - Emulator workaround until real cop is plugged in */ + /* sysInfo->freqProcessor = 3 * sysInfo->freqSystemBus; */ + sysInfo->freqProcessor = e600_ratio + sysInfo->freqSystemBus; break; } - // printf("assigned processor freq = %d for e600 ratio 0x%08lx\n", sysInfo->freqProcessor, e600_ratio); - +#if 0 + printf("assigned processor freq = %d for e600 ratio 0x%08lx\n", + sysInfo->freqProcessor, e600_ratio); +#endif } -/* ------------------------------------------------------------------------- */ - /* * Measure CPU clock speed (core clock GCLK1, GCLK2) - * * (Approx. GCLK frequency in Hz) */ -int get_clocks (void) +int get_clocks(void) { DECLARE_GLOBAL_DATA_PTR; sys_info_t sys_info; - get_sys_info (&sys_info); + get_sys_info(&sys_info); gd->cpu_clk = sys_info.freqProcessor; gd->bus_clk = sys_info.freqSystemBus; - - if(gd->cpu_clk != 0) return (0); - else return (1); + + if (gd->cpu_clk != 0) + return 0; + else + return 1; } -/* ------------------------------------------------------------------------- */ -/******************************************** + +/* * get_bus_freq - * return system bus freq in Hz - *********************************************/ -ulong get_bus_freq (ulong dummy) + * Return system bus freq in Hz + */ +ulong get_bus_freq(ulong dummy) { ulong val; - sys_info_t sys_info; - get_sys_info (&sys_info); + get_sys_info(&sys_info); val = sys_info.freqSystemBus; return val; @@ -138,111 +141,100 @@ ulong get_bus_freq (ulong dummy) unsigned long get_sysclk_from_px_regs() { - ulong val; - u8 vclkh,vclkl; - - vclkh = in8(PIXIS_BASE+PIXIS_VCLKH); - vclkl = in8(PIXIS_BASE+PIXIS_VCLKL); - - if((vclkh == 0x84) && (vclkl ==0x07)) - { - val = 33000000; - } - if((vclkh == 0x3F) && (vclkl ==0x20)) - { - val = 40000000; - } - if((vclkh == 0x3F) && (vclkl ==0x2A)) - { - val = 50000000; - } - if((vclkh == 0x24) && (vclkl ==0x04)) - { - val = 66000000; - } - if((vclkh == 0x3F) && (vclkl ==0x4B)) - { - val = 83000000; - } - if((vclkh == 0x3F) && (vclkl ==0x5C)) - { - val = 100000000; - } - if((vclkh == 0xDF) && (vclkl ==0x3B)) - { - val = 134000000; - } - if((vclkh == 0xDF) && (vclkl ==0x4B)) - { - val = 166000000; - } - - return val; + ulong val; + u8 vclkh, vclkl; + + vclkh = in8(PIXIS_BASE + PIXIS_VCLKH); + vclkl = in8(PIXIS_BASE + PIXIS_VCLKL); + + if ((vclkh == 0x84) && (vclkl == 0x07)) { + val = 33000000; + } + if ((vclkh == 0x3F) && (vclkl == 0x20)) { + val = 40000000; + } + if ((vclkh == 0x3F) && (vclkl == 0x2A)) { + val = 50000000; + } + if ((vclkh == 0x24) && (vclkl == 0x04)) { + val = 66000000; + } + if ((vclkh == 0x3F) && (vclkl == 0x4B)) { + val = 83000000; + } + if ((vclkh == 0x3F) && (vclkl == 0x5C)) { + val = 100000000; + } + if ((vclkh == 0xDF) && (vclkl == 0x3B)) { + val = 134000000; + } + if ((vclkh == 0xDF) && (vclkl == 0x4B)) { + val = 166000000; + } + + return val; } -/******* From MPC8641HPCN Design Workbook ************ - * + +/* * get_board_sys_clk - * reads the FPGA on board for CONFIG_SYS_CLK_FREQ - * - ********************************************************/ + * Reads the FPGA on board for CONFIG_SYS_CLK_FREQ + */ unsigned long get_board_sys_clk(ulong dummy) { - u8 i, go_bit, rd_clks; - ulong val; - - go_bit = in8(PIXIS_BASE+PIXIS_VCTL); - go_bit &= 0x01; - - rd_clks = in8(PIXIS_BASE+PIXIS_VCFGEN0); - rd_clks &= 0x1C; - - /* Only if both go bit and the SCLK bit in VCFGEN0 are set - * should we be using the AUX register. Remember, we also set the - * GO bit to boot from the alternate bank on the on-board flash - */ - - if(go_bit) - { - if(rd_clks == 0x1c) - i = in8(PIXIS_BASE+PIXIS_AUX); - else - i = in8(PIXIS_BASE+PIXIS_SPD); - //val = get_sysclk_from_px_regs(); - } - else - i = in8(PIXIS_BASE+PIXIS_SPD); - - i &= 0x07; - - switch(i) - { - case 0: - val = 33000000; - break; - case 1: - val = 40000000; - break; - case 2: - val = 50000000; - break; - case 3: - val = 66000000; - break; - case 4: - val = 83000000; - break; - case 5: - val = 100000000; - break; - case 6: - val = 134000000; - break; - case 7: - val = 166000000; - break; - } - - return val; + u8 i, go_bit, rd_clks; + ulong val; + + go_bit = in8(PIXIS_BASE + PIXIS_VCTL); + go_bit &= 0x01; + + rd_clks = in8(PIXIS_BASE + PIXIS_VCFGEN0); + rd_clks &= 0x1C; + + /* + * Only if both go bit and the SCLK bit in VCFGEN0 are set + * should we be using the AUX register. Remember, we also set the + * GO bit to boot from the alternate bank on the on-board flash + */ + + if (go_bit) { + if (rd_clks == 0x1c) + i = in8(PIXIS_BASE + PIXIS_AUX); + else + i = in8(PIXIS_BASE + PIXIS_SPD); + } else { + i = in8(PIXIS_BASE + PIXIS_SPD); + } + + i &= 0x07; + + switch (i) { + case 0: + val = 33000000; + break; + case 1: + val = 40000000; + break; + case 2: + val = 50000000; + break; + case 3: + val = 66000000; + break; + case 4: + val = 83000000; + break; + case 5: + val = 100000000; + break; + case 6: + val = 134000000; + break; + case 7: + val = 166000000; + break; + } + + return val; } diff --git a/cpu/mpc86xx/start.S b/cpu/mpc86xx/start.S index 531bd0c5fb..0a447a76b7 100644 --- a/cpu/mpc86xx/start.S +++ b/cpu/mpc86xx/start.S @@ -783,12 +783,12 @@ ppcDcbz: dcbz r0,r3 blr -/*------------------------------------------------------------------------------- */ +/*-------------------------------------------------------------------------- */ /* Function: ppcSync */ /* Description: Processor Synchronize */ /* Input: none. */ /* Output: none. */ -/*------------------------------------------------------------------------------- */ +/*-------------------------------------------------------------------------- */ .globl ppcSync ppcSync: sync diff --git a/cpu/mpc86xx/traps.c b/cpu/mpc86xx/traps.c index fdfc95dfc5..8113dfbcc3 100644 --- a/cpu/mpc86xx/traps.c +++ b/cpu/mpc86xx/traps.c @@ -1,6 +1,4 @@ /* - * linux/arch/ppc/kernel/traps.c - * * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) * * Modified by Cort Dougan (cort@cs.nmt.edu) diff --git a/include/configs/MPC8641HPCN.h b/include/configs/MPC8641HPCN.h index 8d2e08851e..76efd7c604 100644 --- a/include/configs/MPC8641HPCN.h +++ b/include/configs/MPC8641HPCN.h @@ -1,5 +1,6 @@ -/* - * Copyright 2004 Freescale Semiconductor. +/* + * Copyright 2006 Freescale Semiconductor. + * * Srikanth Srinivasan (srikanth.srinivasan@freescale.com) * * See file CREDITS for list of people who contributed to this @@ -22,8 +23,7 @@ */ /* - * mpc8641hpc3 board configuration file - * + * MPC8641HPCN board configuration file * * Make sure you change the MAC address and other network params first, * search for CONFIG_ETHADDR, CONFIG_SERVERIP, etc in this file. @@ -38,48 +38,38 @@ #define CONFIG_MPC8641HPCN 1 /* MPC8641HPCN board specific */ #define CONFIG_NUM_CPUS 2 /* Number of CPUs in the system */ #define CONFIG_LINUX_RESET_VEC 0x100 /* Reset vector used by Linux */ -#undef DEBUG +#undef DEBUG -//#define RUN_DIAG 1 #ifdef RUN_DIAG #define CFG_DIAG_ADDR 0xff800000 #endif + #define CFG_RESET_ADDRESS 0xfff00100 -//#define CONFIG_PCI +#undef CONFIG_PCI + #define CONFIG_TSEC_ENET /* tsec ethernet support */ #define CONFIG_ENV_OVERWRITE -/*#define CONFIG_DDR_ECC */ /* only for ECC DDR module */ -/*#define CONFIG_DDR_DLL */ /* possible DLL fix needed */ -#define CONFIG_DDR_2T_TIMING /* Sets the 2T timing bit */ - +#undef CONFIG_DDR_DLL /* possible DLL fix needed */ +#define CONFIG_DDR_2T_TIMING /* Sets the 2T timing bit */ #define CONFIG_DDR_ECC /* only for ECC DDR module */ #define CONFIG_ECC_INIT_VIA_DDRCONTROLLER /* DDR controller or DMA? */ #define CONFIG_MEM_INIT_VALUE 0xDeadBeef +#define CONFIG_ALTIVEC 1 -#define CONFIG_ALTIVEC 1 -/*----------------------------------------------------------------------- +/* * L2CR setup -- make sure this is right for your board! */ - -#define CFG_L2 +#define CFG_L2 #define L2_INIT 0 #define L2_ENABLE (L2CR_L2E) #ifndef CONFIG_SYS_CLK_FREQ -//#define CONFIG_SYS_CLK_FREQ 33000000 #define CONFIG_SYS_CLK_FREQ get_board_sys_clk(0) #endif -/* - * These can be toggled for performance analysis, otherwise use default. - */ -/* JB - XXX - Are these available on 86xx? */ -#define CONFIG_BTB /* toggle branch predition */ -#define CONFIG_ADDR_STREAMING /* toggle addr streaming */ - #define CONFIG_BOARD_EARLY_INIT_F 1 /* Call board_pre_init */ #undef CFG_DRAM_TEST /* memory test, takes time */ @@ -130,10 +120,10 @@ #define CFG_DDR_INTERVAL 0x06090100 #define CFG_DDR_DATA_INIT 0xdeadbeef #define CFG_DDR_CLK_CTRL 0x03800000 - #define CFG_DDR_OCD_CTRL 0x00000000 - #define CFG_DDR_OCD_STATUS 0x00000000 + #define CFG_DDR_OCD_CTRL 0x00000000 + #define CFG_DDR_OCD_STATUS 0x00000000 #define CFG_DDR_CONTROL 0xe3008000 /* Type = DDR2 */ - #define CFG_DDR_CONTROL2 0x04400000 + #define CFG_DDR_CONTROL2 0x04400000 //Not used in fixed_sdram function @@ -143,20 +133,12 @@ #define CFG_DDR_CS3_BNDS 0x00000FFF //Not done #define CFG_DDR_CS4_BNDS 0x00000FFF //Not done #define CFG_DDR_CS5_BNDS 0x00000FFF //Not done - - - #endif #endif /* - * SDRAM on the Local Bus - */ -//#define CFG_LBC_SDRAM_BASE 0xf0000000 /* Localbus SDRAM */ -//#define CFG_LBC_SDRAM_SIZE 64 /* LBC SDRAM is 64MB */ - -/* In MPC8641HPCN, we allocate 16MB flash spaces at fe000000 and ff000000 + * In MPC8641HPCN, we allocate 16MB flash spaces at fe000000 and ff000000 * We only have an 8MB flash. In effect, the addresses from fe000000 to fe7fffff * map to fe800000 to ffffffff, and ff000000 to ff7fffff map to ffffffff. * However, when u-boot comes up, the flash_init needs hard start addresses @@ -165,15 +147,12 @@ * knows where the flash is and the user can download u-boot code from promjet to * fef00000 <- more intuitive than fe700000. Note that, on switching the boot * location, fef00000 becomes fff00000. -*/ + */ #define CFG_FLASH_BASE 0xfe800000 /* start of FLASH 32M */ -#define CFG_FLASH_BASE2 0xff800000 +#define CFG_FLASH_BASE2 0xff800000 #define CFG_FLASH_BANKS_LIST {CFG_FLASH_BASE, CFG_FLASH_BASE2} - -/*Sri: This looks like a good place to init all the Local Bus chip selects*/ - #define CFG_BR0_PRELIM 0xff001001 /* port size 16bit */ #define CFG_OR0_PRELIM 0xff006ff7 /* 16MB Boot Flash area*/ @@ -186,25 +165,24 @@ #define CFG_BR3_PRELIM 0xf8100801 /* port size 8bit */ #define CFG_OR3_PRELIM 0xfff06ff7 /* 1MB PIXIS area*/ -#define PIXIS_BASE 0xf8100000 /* PIXIS registers*/ -#define PIXIS_ID 0x0 /* MPC8641HPCN Board ID at offset 0*/ -#define PIXIS_VER 0x1 /* MPC8641HPCN board version version at offset 1*/ -#define PIXIS_PVER 0x2 /* PIXIS FPGA version at offset 2*/ -#define PIXIS_RST 0x4 /* PIXIS Reset Control register*/ -#define PIXIS_AUX 0x6 /* PIXIS Auxiliary register; Scratch register */ -#define PIXIS_SPD 0x7 /* Register for SYSCLK speed */ -#define PIXIS_VCTL 0x10 /* VELA Control Register */ -#define PIXIS_VCFGEN0 0x12 /* VELA Config Enable 0 */ -#define PIXIS_VCFGEN1 0x13 /* VELA Config Enable 1 */ -#define PIXIS_VBOOT 0x16 /* VELA VBOOT Register */ -#define PIXIS_VSPEED0 0x17 /* VELA VSpeed 0 */ -#define PIXIS_VSPEED1 0x18 /* VELA VSpeed 1 */ -#define PIXIS_VCLKH 0x19 /* VELA VCLKH register */ -#define PIXIS_VCLKL 0x1A /* VELA VCLKL register */ +#define PIXIS_BASE 0xf8100000 /* PIXIS registers */ +#define PIXIS_ID 0x0 /* Board ID at offset 0 */ +#define PIXIS_VER 0x1 /* Board version at offset 1 */ +#define PIXIS_PVER 0x2 /* PIXIS FPGA version at offset 2 */ +#define PIXIS_RST 0x4 /* PIXIS Reset Control register */ +#define PIXIS_AUX 0x6 /* PIXIS Auxiliary register; Scratch register */ +#define PIXIS_SPD 0x7 /* Register for SYSCLK speed */ +#define PIXIS_VCTL 0x10 /* VELA Control Register */ +#define PIXIS_VCFGEN0 0x12 /* VELA Config Enable 0 */ +#define PIXIS_VCFGEN1 0x13 /* VELA Config Enable 1 */ +#define PIXIS_VBOOT 0x16 /* VELA VBOOT Register */ +#define PIXIS_VSPEED0 0x17 /* VELA VSpeed 0 */ +#define PIXIS_VSPEED1 0x18 /* VELA VSpeed 1 */ +#define PIXIS_VCLKH 0x19 /* VELA VCLKH register */ +#define PIXIS_VCLKL 0x1A /* VELA VCLKL register */ #define CFG_MAX_FLASH_BANKS 2 /* number of banks */ -//#define CFG_MAX_FLASH_SECT 64 /* sectors per device */ #define CFG_MAX_FLASH_SECT 128 /* sectors per device */ #undef CFG_FLASH_CHECKSUM @@ -212,11 +190,9 @@ #define CFG_FLASH_WRITE_TOUT 500 /* Flash Write Timeout (ms) */ #define CFG_MONITOR_BASE TEXT_BASE /* start of monitor */ -/*#define CFG_HPCN_FLASH_CFI_DRIVER */ #define CFG_FLASH_CFI #define CFG_FLASH_EMPTY_INFO - #if (CFG_MONITOR_BASE < CFG_FLASH_BASE) #define CFG_RAMBOOT #else @@ -230,7 +206,7 @@ #undef CONFIG_CLOCKS_IN_MHZ #define CONFIG_L1_INIT_RAM -#undef CFG_INIT_RAM_LOCK +#undef CFG_INIT_RAM_LOCK #ifndef CFG_INIT_RAM_LOCK #define CFG_INIT_RAM_ADDR 0x0fd00000 /* Initial RAM address */ #else @@ -265,20 +241,22 @@ #define CFG_PROMPT_HUSH_PS2 "> " #endif -/* pass open firmware flat tree */ -#define CONFIG_OF_FLAT_TREE 1 -#define CONFIG_OF_BOARD_SETUP 1 +/* + * Pass open firmware flat tree to kernel + */ +#define CONFIG_OF_FLAT_TREE 1 +#define CONFIG_OF_BOARD_SETUP 1 /* maximum size of the flat tree (8K) */ -#define OF_FLAT_TREE_MAX_SIZE 8192 +#define OF_FLAT_TREE_MAX_SIZE 8192 -#define OF_CPU "PowerPC,8641@0" -#define OF_SOC "soc8641@f8000000" -#define OF_TBCLK (bd->bi_busfreq / 8) -#define OF_STDOUT_PATH "/soc8641@f8000000/serial@4500" +#define OF_CPU "PowerPC,8641@0" +#define OF_SOC "soc8641@f8000000" +#define OF_TBCLK (bd->bi_busfreq / 8) +#define OF_STDOUT_PATH "/soc8641@f8000000/serial@4500" -#define CFG_64BIT_VSPRINTF 1 -#define CFG_64BIT_STRTOUL 1 +#define CFG_64BIT_VSPRINTF 1 +#define CFG_64BIT_STRTOUL 1 /* I2C */ #define CONFIG_HARD_I2C /* I2C with hardware support*/ @@ -297,13 +275,10 @@ * Addresses are mapped 1-1. */ #define CFG_PCI1_MEM_BASE 0x80000000 -//#define CFG_PCI1_MEM_BASE 0xd0000000 #define CFG_PCI1_MEM_PHYS CFG_PCI1_MEM_BASE #define CFG_PCI1_MEM_SIZE 0x20000000 /* 512M */ #define CFG_PCI1_IO_BASE 0xe2000000 -//#define CFG_PCI1_IO_BASE 0xe0000000 #define CFG_PCI1_IO_PHYS CFG_PCI1_IO_BASE -//#define CFG_PCI1_IO_BUS 0x00000000 #define CFG_PCI1_IO_SIZE 0x1000000 /* 16M */ /* For RTL8139 */ @@ -316,29 +291,18 @@ #define CFG_PCI2_IO_PHYS CFG_PCI2_IO_BASE #define CFG_PCI2_IO_SIZE 0x1000000 /* 16M */ -// #define CFG_PCI1_MEM_BASE 0x80000000 -// #define CFG_PCI1_MEM_PHYS CFG_PCI1_MEM_BASE -// #define CFG_PCI1_MEM_SIZE 0x20000000 /* 512M */ -// #define CFG_PCI1_IO_BASE 0xe2000000 -// #define CFG_PCI1_IO_PHYS CFG_PCI1_IO_BASE -// #define CFG_PCI1_IO_SIZE 0x1000000 /* 16M */ - - #if defined(CONFIG_PCI) - #define CONFIG_PCI_SCAN_SHOW /* show pci devices on startup */ -//#define CFG_SCSI_SCAN_BUS_REVERSE - +#undef CFG_SCSI_SCAN_BUS_REVERSE #define CONFIG_NET_MULTI #define CONFIG_PCI_PNP /* do pci plug-and-play */ #define CONFIG_RTL8139 - #undef CONFIG_EEPRO100 #undef CONFIG_TULIP @@ -349,7 +313,6 @@ #endif #undef CONFIG_PCI_SCAN_SHOW /* show pci devices on startup */ -//#define CFG_PCI_SUBSYS_VENDORID 0x1057 /* Motorola */ #endif /* CONFIG_PCI */ @@ -371,7 +334,6 @@ #define CONFIG_MPC86XX_TSEC4 1 #define CONFIG_MPC86XX_TSEC4_NAME "eTSEC4" - #define TSEC1_PHY_ADDR 0 #define TSEC2_PHY_ADDR 1 #define TSEC3_PHY_ADDR 2 @@ -389,12 +351,10 @@ /* BAT0 2G Cacheable, non-guarded * 0x0000_0000 2G DDR */ -//#define CFG_DBAT0L (0x0 | BATL_PP_RW | BATL_MEMCOHERENCE) -#define CFG_DBAT0L (0x0 | BATL_PP_RW | BATL_CACHEINHIBIT | BATL_GUARDEDSTORAGE | BATL_MEMCOHERENCE) -#define CFG_DBAT0U (0x0 | BATU_BL_512M | BATU_VS | BATU_VP) -//#define CFG_IBAT0L CFG_DBAT0L -//#define CFG_IBAT0L (0x0 | BATL_PP_RW | BATL_CACHEINHIBIT) -#define CFG_IBAT0L (0x0| BATL_PP_RW | BATL_CACHEINHIBIT | BATL_MEMCOHERENCE) +#define CFG_DBAT0L ( BATL_PP_RW | BATL_CACHEINHIBIT \ + | BATL_GUARDEDSTORAGE | BATL_MEMCOHERENCE ) +#define CFG_DBAT0U ( BATU_BL_512M | BATU_VS | BATU_VP ) +#define CFG_IBAT0L ( BATL_PP_RW | BATL_CACHEINHIBIT | BATL_MEMCOHERENCE) #define CFG_IBAT0U CFG_DBAT0U /* BAT1 1G Cache-inhibited, guarded @@ -402,7 +362,8 @@ * 0xa000_0000 512M PCI-Express 2 Memory ** SS - Changed it for operating from 0xd0000000 */ -#define CFG_DBAT1L (CFG_PCI1_MEM_BASE | BATL_PP_RW | BATL_CACHEINHIBIT | BATL_GUARDEDSTORAGE) +#define CFG_DBAT1L ( CFG_PCI1_MEM_BASE | BATL_PP_RW \ + | BATL_CACHEINHIBIT | BATL_GUARDEDSTORAGE) #define CFG_DBAT1U (CFG_PCI1_MEM_BASE | BATU_BL_256M | BATU_VS | BATU_VP) #define CFG_IBAT1L (CFG_PCI1_MEM_BASE | BATL_PP_RW | BATL_CACHEINHIBIT) #define CFG_IBAT1U CFG_DBAT1U @@ -410,7 +371,8 @@ /* BAT2 512M Cache-inhibited, guarded * 0xc000_0000 512M RapidIO Memory */ -#define CFG_DBAT2L (CFG_RIO_MEM_BASE | BATL_PP_RW | BATL_CACHEINHIBIT | BATL_GUARDEDSTORAGE) +#define CFG_DBAT2L (CFG_RIO_MEM_BASE | BATL_PP_RW \ + | BATL_CACHEINHIBIT | BATL_GUARDEDSTORAGE) #define CFG_DBAT2U (CFG_RIO_MEM_BASE | BATU_BL_512M | BATU_VS | BATU_VP) #define CFG_IBAT2L (CFG_RIO_MEM_BASE | BATL_PP_RW | BATL_CACHEINHIBIT) #define CFG_IBAT2U CFG_DBAT2U @@ -418,7 +380,8 @@ /* BAT3 4M Cache-inhibited, guarded * 0xf800_0000 4M CCSR */ -#define CFG_DBAT3L (CFG_CCSRBAR | BATL_PP_RW | BATL_CACHEINHIBIT | BATL_GUARDEDSTORAGE) +#define CFG_DBAT3L ( CFG_CCSRBAR | BATL_PP_RW \ + | BATL_CACHEINHIBIT | BATL_GUARDEDSTORAGE) #define CFG_DBAT3U (CFG_CCSRBAR | BATU_BL_4M | BATU_VS | BATU_VP) #define CFG_IBAT3L (CFG_CCSRBAR | BATL_PP_RW | BATL_CACHEINHIBIT) #define CFG_IBAT3U CFG_DBAT3U @@ -428,7 +391,8 @@ * 0xe300_0000 16M PCI-Express 2 I/0 ** SS - Note that this is at 0xe0000000 */ -#define CFG_DBAT4L (CFG_PCI1_IO_BASE | BATL_PP_RW | BATL_CACHEINHIBIT | BATL_GUARDEDSTORAGE) +#define CFG_DBAT4L ( CFG_PCI1_IO_BASE | BATL_PP_RW \ + | BATL_CACHEINHIBIT | BATL_GUARDEDSTORAGE) #define CFG_DBAT4U (CFG_PCI1_IO_BASE | BATU_BL_32M | BATU_VS | BATU_VP) #define CFG_IBAT4L (CFG_PCI1_IO_BASE | BATL_PP_RW | BATL_CACHEINHIBIT) #define CFG_IBAT4U CFG_DBAT4U @@ -444,12 +408,12 @@ /* BAT6 32M Cache-inhibited, guarded * 0xfe00_0000 32M FLASH */ -#define CFG_DBAT6L (CFG_FLASH_BASE | BATL_PP_RW | BATL_CACHEINHIBIT | BATL_GUARDEDSTORAGE) +#define CFG_DBAT6L ( CFG_FLASH_BASE | BATL_PP_RW \ + | BATL_CACHEINHIBIT | BATL_GUARDEDSTORAGE) #define CFG_DBAT6U (CFG_FLASH_BASE | BATU_BL_32M | BATU_VS | BATU_VP) #define CFG_IBAT6L (CFG_FLASH_BASE | BATL_PP_RW | BATL_MEMCOHERENCE) #define CFG_IBAT6U CFG_DBAT6U - #define CFG_DBAT7L 0x00000000 #define CFG_DBAT7U 0x00000000 #define CFG_IBAT7L 0x00000000 @@ -461,17 +425,17 @@ /* * Environment */ - #ifndef CFG_RAMBOOT - #define CFG_ENV_IS_IN_FLASH 1 - #define CFG_ENV_ADDR (CFG_MONITOR_BASE + 0x40000) - #define CFG_ENV_SECT_SIZE 0x40000 /* 256K(one sector) for env */ - #define CFG_ENV_SIZE 0x2000 - #else - #define CFG_NO_FLASH 1 /* Flash is not usable now */ - #define CFG_ENV_IS_NOWHERE 1 /* Store ENV in memory only */ - #define CFG_ENV_ADDR (CFG_MONITOR_BASE - 0x1000) - #define CFG_ENV_SIZE 0x2000 - #endif +#ifndef CFG_RAMBOOT + #define CFG_ENV_IS_IN_FLASH 1 + #define CFG_ENV_ADDR (CFG_MONITOR_BASE + 0x40000) + #define CFG_ENV_SECT_SIZE 0x40000 /* 256K(one sector) for env */ + #define CFG_ENV_SIZE 0x2000 +#else + #define CFG_NO_FLASH 1 /* Flash is not usable now */ + #define CFG_ENV_IS_NOWHERE 1 /* Store ENV in memory only */ + #define CFG_ENV_ADDR (CFG_MONITOR_BASE - 0x1000) + #define CFG_ENV_SIZE 0x2000 +#endif #define CONFIG_LOADS_ECHO 1 /* echo on for serial download */ #define CFG_LOADS_BAUD_CHANGE 1 /* allow baudrate change */ @@ -572,24 +536,25 @@ #define CONFIG_ETH3ADDR 00:E0:0C:00:03:FD #endif -#define CONFIG_HAS_ETH1 1 -#define CONFIG_HAS_ETH2 1 -#define CONFIG_HAS_ETH3 1 +#define CONFIG_HAS_ETH1 1 +#define CONFIG_HAS_ETH2 1 +#define CONFIG_HAS_ETH3 1 -#define CONFIG_IPADDR 10.82.193.138 +#define CONFIG_IPADDR 10.82.193.138 #define CONFIG_HOSTNAME unknown #define CONFIG_ROOTPATH /opt/nfsroot #define CONFIG_BOOTFILE uImage -#define CONFIG_SERVERIP 10.82.193.104 -#define CONFIG_GATEWAYIP 10.82.193.254 -#define CONFIG_NETMASK 255.255.252.0 +#define CONFIG_SERVERIP 192.168.1.1 +#define CONFIG_GATEWAYIP 10.82.193.104 +#define CONFIG_NETMASK 255.255.255.0 -#define CONFIG_LOADADDR 1000000 /* default location for tftp and bootm */ +/* default location for tftp and bootm */ +#define CONFIG_LOADADDR 1000000 #define CONFIG_BOOTDELAY 10 /* -1 disables auto-boot */ -//#undef CONFIG_BOOTARGS /* the boot command will set bootargs */ +//#undef CONFIG_BOOTARGS /* the boot command will set bootargs */ #define CONFIG_BOOTARGS "root=/dev/ram rw console=ttyS0,115200" #define CONFIG_BAUDRATE 115200 @@ -599,7 +564,7 @@ "consoledev=ttyS0\0" \ "ramdiskaddr=400000\0" \ "ramdiskfile=your.ramdisk.u-boot\0" \ - "pex0=echo ---------------------------; echo --------- PCI EXPRESS -----\0" \ + "pex0=echo ---------------------------; echo --------- PCI EXPRESS -----\0"\ "pexstat=mw f8008000 84000004; echo -expect:- 16000000; md f8008004 1\0" \ "pex1=pci write 1.0.0 4 146; pci write 1.0.0 10 80000000\0" \ "pexd=echo -expect:- xxx01002 00100146; pci display 1.0.0 0 2\0" \ diff --git a/include/mpc86xx.h b/include/mpc86xx.h index 61b527979c..4edeae1647 100644 --- a/include/mpc86xx.h +++ b/include/mpc86xx.h @@ -1,5 +1,5 @@ /* - * Copyright 2004 Freescale Semiconductor. + * Copyright 2006 Freescale Semiconductor. * Jeffrey Brown (jeffrey@freescale.com) * Srikanth Srinivasan (srikanth.srinivasan@freescale.com) */ @@ -9,7 +9,7 @@ #define EXC_OFF_SYS_RESET 0x0100 /* System reset offset */ -/*---------------------------------------------------------------- +/* * l2cr values. Look in config_.h for the actual setup */ #define l2cr 1017 @@ -23,7 +23,7 @@ #define L2CR_HWF 0x00000800 /* bit 20 - hardware flush */ #define L2CR_L2IP 0x00000001 /* global invalidate in progress */ -/*---------------------------------------------------------------- +/* * BAT settings. Look in config_.h for the actual setup */ -- cgit v1.2.3 From 9a655876e5995be80f49054e2509500e871e4d3a Mon Sep 17 00:00:00 2001 From: Jon Loeliger Date: Fri, 19 May 2006 13:26:34 -0500 Subject: Enable dual DDR controllers and interleaving. --- cpu/mpc86xx/spd_sdram.c | 615 +++++++++++++++++++++++++++++++++--------- include/configs/MPC8641HPCN.h | 12 +- 2 files changed, 505 insertions(+), 122 deletions(-) (limited to 'cpu/mpc86xx/spd_sdram.c') diff --git a/cpu/mpc86xx/spd_sdram.c b/cpu/mpc86xx/spd_sdram.c index 9ce31d7c6f..130c8fc396 100644 --- a/cpu/mpc86xx/spd_sdram.c +++ b/cpu/mpc86xx/spd_sdram.c @@ -41,6 +41,15 @@ extern int dma_xfer(void *dest, uint count, void *src); #define CFG_READ_SPD i2c_read #endif +/* + * Only one of the following three should be 1; others should be 0 + * By default the cache line interleaving is selected if + * the CONFIG_DDR_INTERLEAVE flag is defined in MPC8641HPCN.h + */ +#define CFG_PAGE_INTERLEAVING 0 +#define CFG_BANK_INTERLEAVING 0 +#define CFG_SUPER_BANK_INTERLEAVING 0 + /* * Convert picoseconds into clock cycles (rounding up if needed). */ @@ -144,10 +153,11 @@ convert_bcd_tenths_to_cycle_time_ps(unsigned int spd_val) long int -spd_sdram(void) +spd_init(unsigned char i2c_address, unsigned int ddr_num, + unsigned int dimm_num, unsigned int start_addr) { volatile immap_t *immap = (immap_t *)CFG_IMMR; - volatile ccsr_ddr_t *ddr1 = &immap->im_ddr1; + volatile ccsr_ddr_t *ddr; volatile ccsr_gur_t *gur = &immap->im_gur; spd_eeprom_t spd; unsigned int n_ranks; @@ -175,28 +185,41 @@ spd_sdram(void) unsigned int mode_caslat; unsigned char sdram_type; unsigned char d_init; + unsigned int law_size; + volatile ccsr_local_mcm_t *mcm = &immap->im_local_mcm; - - unsigned int law_size; - volatile ccsr_local_mcm_t *mcm = &immap->im_local_mcm; + if (ddr_num == 1) + ddr = &immap->im_ddr1; + else + ddr = &immap->im_ddr2; /* * Read SPD information. */ - CFG_READ_SPD(SPD_EEPROM_ADDRESS, 0, 1, (uchar *) &spd, sizeof(spd)); + debug("Performing SPD read at I2C address 0x%02lx\n",i2c_address); + memset((void *)&spd, 0, sizeof(spd)); + CFG_READ_SPD(i2c_address, 0, 1, (uchar *) &spd, sizeof(spd)); /* * Check for supported memory module types. */ if (spd.mem_type != SPD_MEMTYPE_DDR && spd.mem_type != SPD_MEMTYPE_DDR2) { - printf("Unable to locate DDR I or DDR II module.\n" - " Fundamental memory type is 0x%0x\n", - spd.mem_type); + debug("Warning: Unable to locate DDR I or DDR II module for DIMM %d of DDR controller %d.\n" + " Fundamental memory type is 0x%0x\n", + dimm_num, + ddr_num, + spd.mem_type); return 0; } + debug("\nFound memory of type 0x%02lx ", spd.mem_type); + if (spd.mem_type == SPD_MEMTYPE_DDR) + debug("DDR I\n"); + else + debug("DDR II\n"); + /* * These test gloss over DDR I and II differences in interpretation * of bytes 3 and 4, but irrelevantly. Multiple asymmetric banks @@ -253,11 +276,7 @@ spd_sdram(void) */ rank_density = compute_banksize(spd.mem_type, spd.row_dens); - - /* - * Eg: Bounds: 0x0000_0000 to 0x0f000_0000 first 256 Meg - */ - ddr1->cs0_bnds = (rank_density >> 24) - 1; + debug("Start address for this controller is 0x%08lx\n", start_addr); /* * ODT configuration recommendation from DDR Controller Chapter. @@ -268,30 +287,133 @@ spd_sdram(void) odt_wr_cfg = 1; /* Assert ODT on writes to CS0 */ } - ddr1->cs0_config = ( 1 << 31 - | (odt_rd_cfg << 20) - | (odt_wr_cfg << 16) - | (spd.nrow_addr - 12) << 8 - | (spd.ncol_addr - 8) ); - debug("\n"); - debug("DDR: cs0_bnds = 0x%08x\n", ddr1->cs0_bnds); - debug("DDR: cs0_config = 0x%08x\n", ddr1->cs0_config); +#ifdef CONFIG_DDR_INTERLEAVE +#ifdef CONFIG_MPC8641HPCN + if (dimm_num != 1) { + printf("For interleaving memory on HPCN, need to use DIMM 1 for DDR Controller %d !\n", ddr_num); + return 0; + } else { + /* + * Since interleaved memory only uses CS0, the + * memory sticks have to be identical in size and quantity + * of ranks. That essentially gives double the size on + * one rank, i.e on CS0 for both controllers put together. + * Confirm this??? + */ + rank_density *= 2; - if (n_ranks == 2) { /* - * Eg: Bounds: 0x0f00_0000 to 0x1e0000_0000, second 256 Meg + * Eg: Bounds: 0x0000_0000 to 0x0f000_0000 first 256 Meg + */ + start_addr = 0; + ddr->cs0_bnds = (start_addr >> 8) + | (((start_addr + rank_density - 1) >> 24)); + /* + * Default interleaving mode to cache-line interleaving. */ - ddr1->cs1_bnds = ( (rank_density >> 8) - | ((rank_density >> (24 - 1)) - 1) ); - ddr1->cs1_config = ( 1<<31 + ddr->cs0_config = ( 1 << 31 +#if (CFG_PAGE_INTERLEAVING == 1) + | (PAGE_INTERLEAVING) +#elif (CFG_BANK_INTERLEAVING == 1) + | (BANK_INTERLEAVING) +#elif (CFG_SUPER_BANK_INTERLEAVING == 1) + | (SUPER_BANK_INTERLEAVING) +#else + | (CACHE_LINE_INTERLEAVING) +#endif | (odt_rd_cfg << 20) | (odt_wr_cfg << 16) | (spd.nrow_addr - 12) << 8 | (spd.ncol_addr - 8) ); - debug("DDR: cs1_bnds = 0x%08x\n", ddr1->cs1_bnds); - debug("DDR: cs1_config = 0x%08x\n", ddr1->cs1_config); + + debug("DDR: cs0_bnds = 0x%08x\n", ddr->cs0_bnds); + debug("DDR: cs0_config = 0x%08x\n", ddr->cs0_config); + + /* + * Adjustment for dual rank memory to get correct memory + * size (return value of this function). + */ + if (n_ranks == 2) { + n_ranks = 1; + rank_density /= 2; + } else { + rank_density /= 2; + } } +#endif /* CONFIG_MPC8641HPCN */ +#else /* CONFIG_DDR_INTERLEAVE */ + + if (dimm_num == 1) { + /* + * Eg: Bounds: 0x0000_0000 to 0x0f000_0000 first 256 Meg + */ + ddr->cs0_bnds = (start_addr >> 8) + | (((start_addr + rank_density - 1) >> 24)); + + ddr->cs0_config = ( 1 << 31 + | (odt_rd_cfg << 20) + | (odt_wr_cfg << 16) + | (spd.nrow_addr - 12) << 8 + | (spd.ncol_addr - 8) ); + + debug("DDR: cs0_bnds = 0x%08x\n", ddr->cs0_bnds); + debug("DDR: cs0_config = 0x%08x\n", ddr->cs0_config); + + if (n_ranks == 2) { + /* + * Eg: Bounds: 0x1000_0000 to 0x1f00_0000, + * second 256 Meg + */ + ddr->cs1_bnds = (((start_addr + rank_density) >> 8) + | (( start_addr + 2*rank_density - 1) + >> 24)); + ddr->cs1_config = ( 1<<31 + | (odt_rd_cfg << 20) + | (odt_wr_cfg << 16) + | (spd.nrow_addr - 12) << 8 + | (spd.ncol_addr - 8) ); + debug("DDR: cs1_bnds = 0x%08x\n", ddr->cs1_bnds); + debug("DDR: cs1_config = 0x%08x\n", ddr->cs1_config); + } + + } else { + /* + * This is the 2nd DIMM slot for this controller + */ + /* + * Eg: Bounds: 0x0000_0000 to 0x0f000_0000 first 256 Meg + */ + ddr->cs2_bnds = (start_addr >> 8) + | (((start_addr + rank_density - 1) >> 24)); + + ddr->cs2_config = ( 1 << 31 + | (odt_rd_cfg << 20) + | (odt_wr_cfg << 16) + | (spd.nrow_addr - 12) << 8 + | (spd.ncol_addr - 8) ); + + debug("DDR: cs2_bnds = 0x%08x\n", ddr->cs2_bnds); + debug("DDR: cs2_config = 0x%08x\n", ddr->cs2_config); + + if (n_ranks == 2) { + /* + * Eg: Bounds: 0x1000_0000 to 0x1f00_0000, + * second 256 Meg + */ + ddr->cs3_bnds = (((start_addr + rank_density) >> 8) + | (( start_addr + 2*rank_density - 1) + >> 24)); + ddr->cs3_config = ( 1<<31 + | (odt_rd_cfg << 20) + | (odt_wr_cfg << 16) + | (spd.nrow_addr - 12) << 8 + | (spd.ncol_addr - 8) ); + debug("DDR: cs3_bnds = 0x%08x\n", ddr->cs3_bnds); + debug("DDR: cs3_config = 0x%08x\n", ddr->cs3_config); + } + } +#endif /* CONFIG_DDR_INTERLEAVE */ /* * Find the largest CAS by locating the highest 1 bit @@ -447,15 +569,14 @@ spd_sdram(void) unsigned char act_pd_exit = 2; /* Empirical? */ unsigned char pre_pd_exit = 6; /* Empirical? */ - ddr1->timing_cfg_0 = (0 + ddr->timing_cfg_0 = (0 | ((act_pd_exit & 0x7) << 20) /* ACT_PD_EXIT */ | ((pre_pd_exit & 0x7) << 16) /* PRE_PD_EXIT */ | ((taxpd_clk & 0xf) << 8) /* ODT_PD_EXIT */ | ((tmrd_clk & 0xf) << 0) /* MRS_CYC */ ); - debug("DDR: timing_cfg_0 = 0x%08x\n", ddr1->timing_cfg_0); + debug("DDR: timing_cfg_0 = 0x%08x\n", ddr->timing_cfg_0); - } else { } @@ -520,10 +641,10 @@ spd_sdram(void) /* * Sneak in some Extended Refresh Recovery. */ - ddr1->ext_refrec = (trfc_high << 16); - debug("DDR: ext_refrec = 0x%08x\n", ddr1->ext_refrec); + ddr->ext_refrec = (trfc_high << 16); + debug("DDR: ext_refrec = 0x%08x\n", ddr->ext_refrec); - ddr1->timing_cfg_1 = + ddr->timing_cfg_1 = (0 | ((picos_to_clk(spd.trp * 250) & 0x07) << 28) /* PRETOACT */ | ((picos_to_clk(spd.tras * 1000) & 0x0f ) << 24) /* ACTTOPRE */ @@ -535,7 +656,7 @@ spd_sdram(void) | ((twtr_clk & 0x07) << 0) /* WRTORD */ ); - debug("DDR: timing_cfg_1 = 0x%08x\n", ddr1->timing_cfg_1); + debug("DDR: timing_cfg_1 = 0x%08x\n", ddr->timing_cfg_1); /* @@ -612,7 +733,7 @@ spd_sdram(void) } } - ddr1->timing_cfg_2 = (0 + ddr->timing_cfg_2 = (0 | ((add_lat & 0x7) << 28) /* ADD_LAT */ | ((cpo & 0x1f) << 23) /* CPO */ | ((wr_lat & 0x7) << 19) /* WR_LAT */ @@ -622,7 +743,7 @@ spd_sdram(void) | ((four_act & 0x1f) << 0) /* FOUR_ACT */ ); - debug("DDR: timing_cfg_2 = 0x%08x\n", ddr1->timing_cfg_2); + debug("DDR: timing_cfg_2 = 0x%08x\n", ddr->timing_cfg_2); /* @@ -673,7 +794,7 @@ spd_sdram(void) } /* - * Encoded Burst Lenght of 4. + * Encoded Burst Length of 4. */ burst_len = 2; /* Fiat. */ @@ -706,7 +827,7 @@ spd_sdram(void) mode_odt_enable = 0x40; /* 150 Ohm */ } - ddr1->sdram_mode_1 = + ddr->sdram_mode_1 = (0 | (add_lat << (16 + 3)) /* Additive Latency in EMRS1 */ | (mode_odt_enable << 16) /* ODT Enable in EMRS1 */ @@ -715,14 +836,14 @@ spd_sdram(void) | (burst_len << 0) /* Burst length */ ); - debug("DDR: sdram_mode = 0x%08x\n", ddr1->sdram_mode_1); + debug("DDR: sdram_mode = 0x%08x\n", ddr->sdram_mode_1); /* * Clear EMRS2 and EMRS3. */ - ddr1->sdram_mode_2 = 0; - debug("DDR: sdram_mode_2 = 0x%08x\n", ddr1->sdram_mode_2); + ddr->sdram_mode_2 = 0; + debug("DDR: sdram_mode_2 = 0x%08x\n", ddr->sdram_mode_2); /* @@ -749,12 +870,12 @@ spd_sdram(void) * Set BSTOPRE to 0x100 for page mode * If auto-charge is used, set BSTOPRE = 0 */ - ddr1->sdram_interval = + ddr->sdram_interval = (0 | (refresh_clk & 0x3fff) << 16 | 0x100 ); - debug("DDR: sdram_interval = 0x%08x\n", ddr1->sdram_interval); + debug("DDR: sdram_interval = 0x%08x\n", ddr->sdram_interval); } /* @@ -763,11 +884,11 @@ spd_sdram(void) */ #if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER) if (spd.config == 0x02) { - ddr1->err_disable = 0x0000000d; - ddr1->err_sbe = 0x00ff0000; + ddr->err_disable = 0x0000000d; + ddr->err_sbe = 0x00ff0000; } - debug("DDR: err_disable = 0x%08x\n", ddr1->err_disable); - debug("DDR: err_sbe = 0x%08x\n", ddr1->err_sbe); + debug("DDR: err_disable = 0x%08x\n", ddr->err_disable); + debug("DDR: err_sbe = 0x%08x\n", ddr->err_sbe); #endif asm("sync;isync"); @@ -800,8 +921,8 @@ spd_sdram(void) * Use the DDR controller to auto initialize memory. */ d_init = 1; - ddr1->sdram_data_init = CONFIG_MEM_INIT_VALUE; - debug("DDR: ddr_data_init = 0x%08x\n", ddr1->sdram_data_init); + ddr->sdram_data_init = CONFIG_MEM_INIT_VALUE; + debug("DDR: ddr_data_init = 0x%08x\n", ddr->sdram_data_init); #else /* * Memory will be initialized via DMA, or not at all. @@ -809,13 +930,13 @@ spd_sdram(void) d_init = 0; #endif - ddr1->sdram_cfg_2 = (0 + ddr->sdram_cfg_2 = (0 | (dqs_cfg << 26) /* Differential DQS */ | (odt_cfg << 21) /* ODT */ | (d_init << 4) /* D_INIT auto init DDR */ ); - debug("DDR: sdram_cfg_2 = 0x%08x\n", ddr1->sdram_cfg_2); + debug("DDR: sdram_cfg_2 = 0x%08x\n", ddr->sdram_cfg_2); #ifdef MPC86xx_DDR_SDRAM_CLK_CNTL @@ -835,121 +956,373 @@ spd_sdram(void) clk_adjust = 0x7; } - ddr1->sdram_clk_cntl = (0 + ddr->sdram_clk_cntl = (0 | 0x80000000 | (clk_adjust << 23) ); - debug("DDR: sdram_clk_cntl = 0x%08x\n", ddr1->sdram_clk_cntl); + debug("DDR: sdram_clk_cntl = 0x%08x\n", ddr->sdram_clk_cntl); } #endif + /* - * Figure out the settings for the sdram_cfg register. - * Build up the entire register in 'sdram_cfg' before writing - * since the write into the register will actually enable the - * memory controller; all settings must be done before enabling. - * - * sdram_cfg[0] = 1 (ddr sdram logic enable) - * sdram_cfg[1] = 1 (self-refresh-enable) - * sdram_cfg[5:7] = (SDRAM type = DDR SDRAM) - * 010 DDR 1 SDRAM - * 011 DDR 2 SDRAM + * Figure out memory size in Megabytes. */ - sdram_type = (spd.mem_type == SPD_MEMTYPE_DDR) ? 2 : 3; - sdram_cfg_1 = (0 - | (1 << 31) /* Enable */ - | (1 << 30) /* Self refresh */ - | (sdram_type << 24) /* SDRAM type */ - ); + debug("# ranks = %d, rank_density = 0x%08lx\n", n_ranks, rank_density); + memsize = n_ranks * rank_density / 0x100000; + return memsize; +} + + +unsigned int enable_ddr(unsigned int ddr_num) +{ + volatile immap_t *immap = (immap_t *)CFG_IMMR; + spd_eeprom_t spd1,spd2; + volatile ccsr_ddr_t *ddr; + unsigned sdram_cfg_1; + unsigned char sdram_type, mem_type, config, mod_attr; + unsigned char d_init; + unsigned int no_dimm1=0, no_dimm2=0; + + /* Set up pointer to enable the current ddr controller */ + if (ddr_num == 1) + ddr = &immap->im_ddr1; + else + ddr = &immap->im_ddr2; /* - * sdram_cfg[3] = RD_EN - registered DIMM enable - * A value of 0x26 indicates micron registered DIMMS (micron.com) + * Read both dimm slots and decide whether + * or not to enable this controller. */ - if (spd.mem_type == SPD_MEMTYPE_DDR && spd.mod_attr == 0x26) { - sdram_cfg_1 |= 0x10000000; /* RD_EN */ + memset((void *)&spd1,0,sizeof(spd1)); + memset((void *)&spd2,0,sizeof(spd2)); + + if (ddr_num == 1) { + CFG_READ_SPD(SPD_EEPROM_ADDRESS1, + 0, 1, (uchar *) &spd1, sizeof(spd1)); + CFG_READ_SPD(SPD_EEPROM_ADDRESS2, + 0, 1, (uchar *) &spd2, sizeof(spd2)); + } else { + CFG_READ_SPD(SPD_EEPROM_ADDRESS3, + 0, 1, (uchar *) &spd1, sizeof(spd1)); + CFG_READ_SPD(SPD_EEPROM_ADDRESS4, + 0, 1, (uchar *) &spd2, sizeof(spd2)); } -#if defined(CONFIG_DDR_ECC) /* - * If the user wanted ECC (enabled via sdram_cfg[2]) + * Check for supported memory module types. */ - if (spd.config == 0x02) { - sdram_cfg_1 |= 0x20000000; /* ECC_EN */ + if (spd1.mem_type != SPD_MEMTYPE_DDR + && spd1.mem_type != SPD_MEMTYPE_DDR2) { + no_dimm1 = 1; + } else { + debug("\nFound memory of type 0x%02lx ",spd1.mem_type ); + if (spd1.mem_type == SPD_MEMTYPE_DDR) + debug("DDR I\n"); + else + debug("DDR II\n"); + } + + if (spd2.mem_type != SPD_MEMTYPE_DDR && + spd2.mem_type != SPD_MEMTYPE_DDR2) { + no_dimm2 = 1; + } else { + debug("\nFound memory of type 0x%02lx ",spd2.mem_type ); + if (spd2.mem_type == SPD_MEMTYPE_DDR) + debug("DDR I\n"); + else + debug("DDR II\n"); + } + +#ifdef CONFIG_DDR_INTERLEAVE + if (no_dimm1) { + printf("For interleaved operation memory modules need to be present in CS0 DIMM slots of both DDR controllers!\n"); + return 0; } #endif /* - * REV1 uses 1T timing. - * REV2 may use 1T or 2T as configured by the user. + * Memory is not present in DIMM1 and DIMM2 - so do not enable DDRn */ - { - uint pvr = get_pvr(); + if (no_dimm1 && no_dimm2) { + printf("No memory modules found for DDR controller %d!!\n", ddr_num); + return 0; + } else { + mem_type = no_dimm2 ? spd1.mem_type : spd2.mem_type; - if (pvr != PVR_85xx_REV1) { + /* + * Figure out the settings for the sdram_cfg register. + * Build up the entire register in 'sdram_cfg' before + * writing since the write into the register will + * actually enable the memory controller; all settings + * must be done before enabling. + * + * sdram_cfg[0] = 1 (ddr sdram logic enable) + * sdram_cfg[1] = 1 (self-refresh-enable) + * sdram_cfg[5:7] = (SDRAM type = DDR SDRAM) + * 010 DDR 1 SDRAM + * 011 DDR 2 SDRAM + */ + sdram_type = (mem_type == SPD_MEMTYPE_DDR) ? 2 : 3; + sdram_cfg_1 = (0 + | (1 << 31) /* Enable */ + | (1 << 30) /* Self refresh */ + | (sdram_type << 24) /* SDRAM type */ + ); + + /* + * sdram_cfg[3] = RD_EN - registered DIMM enable + * A value of 0x26 indicates micron registered + * DIMMS (micron.com) + */ + mod_attr = no_dimm2 ? spd1.mod_attr : spd2.mod_attr; + if (mem_type == SPD_MEMTYPE_DDR && mod_attr == 0x26) { + sdram_cfg_1 |= 0x10000000; /* RD_EN */ + } + +#if defined(CONFIG_DDR_ECC) + + config = no_dimm2 ? spd1.config : spd2.config; + + /* + * If the user wanted ECC (enabled via sdram_cfg[2]) + */ + if (config == 0x02) { + sdram_cfg_1 |= 0x20000000; /* ECC_EN */ + } +#endif + + /* + * REV1 uses 1T timing. + * REV2 may use 1T or 2T as configured by the user. + */ + { + uint pvr = get_pvr(); + + if (pvr != PVR_85xx_REV1) { #if defined(CONFIG_DDR_2T_TIMING) - /* - * Enable 2T timing by setting sdram_cfg[16]. - */ - sdram_cfg_1 |= 0x8000; /* 2T_EN */ + /* + * Enable 2T timing by setting sdram_cfg[16]. + */ + sdram_cfg_1 |= 0x8000; /* 2T_EN */ #endif + } } - } - /* - * 200 painful micro-seconds must elapse between - * the DDR clock setup and the DDR config enable. - */ - udelay(200); + /* + * 200 painful micro-seconds must elapse between + * the DDR clock setup and the DDR config enable. + */ + udelay(200); - /* - * Go! - */ - ddr1->sdram_cfg_1 = sdram_cfg_1; + /* + * Go! + */ + ddr->sdram_cfg_1 = sdram_cfg_1; - asm("sync;isync"); - udelay(500); + asm volatile("sync;isync"); + udelay(500); - debug("DDR: sdram_cfg = 0x%08x\n", ddr1->sdram_cfg_1); + debug("DDR: sdram_cfg = 0x%08x\n", ddr->sdram_cfg_1); #if defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER) - debug("DDR: memory initializing\n"); - /* - * Poll until memory is initialized. - * 512 Meg at 400 might hit this 200 times or so. - */ - while ((ddr1->sdram_cfg_2 & (d_init << 4)) != 0) { - udelay(1000); + d_init = 1; + debug("DDR: memory initializing\n"); + + /* + * Poll until memory is initialized. + * 512 Meg at 400 might hit this 200 times or so. + */ + while ((ddr->sdram_cfg_2 & (d_init << 4)) != 0) { + udelay(1000); + } + debug("DDR: memory initialized\n\n"); +#endif + + debug("Enabled DDR Controller %d\n", ddr_num); + return 1; + } +} + + +long int +spd_sdram(void) +{ + int memsize_ddr1_dimm1 = 0; + int memsize_ddr1_dimm2 = 0; + int memsize_ddr2_dimm1 = 0; + int memsize_ddr2_dimm2 = 0; + int memsize_total = 0; + int memsize_ddr1 = 0; + int memsize_ddr2 = 0; + unsigned int ddr1_enabled = 0; + unsigned int ddr2_enabled = 0; + unsigned int law_size_ddr1; + unsigned int law_size_ddr2; + volatile immap_t *immap = (immap_t *)CFG_IMMR; + volatile ccsr_ddr_t *ddr1 = &immap->im_ddr1; + volatile ccsr_ddr_t *ddr2 = &immap->im_ddr2; + volatile ccsr_local_mcm_t *mcm = &immap->im_local_mcm; + +#ifdef CONFIG_DDR_INTERLEAVE + unsigned int law_size_interleaved; + + memsize_ddr1_dimm1 = spd_init(SPD_EEPROM_ADDRESS1, + 1, 1, + (unsigned int)memsize_total * 1024*1024); + memsize_total += memsize_ddr1_dimm1; + + memsize_ddr2_dimm1 = spd_init(SPD_EEPROM_ADDRESS3, + 2, 1, + (unsigned int)memsize_total * 1024*1024); + memsize_total += memsize_ddr2_dimm1; + + if (memsize_ddr1_dimm1 != memsize_ddr2_dimm1) { + if (memsize_ddr1_dimm1 < memsize_ddr2_dimm1) + memsize_total -= memsize_ddr1_dimm1; + else + memsize_total -= memsize_ddr2_dimm1; + debug("Total memory available for interleaving 0x%08lx\n", + memsize_total * 1024 * 1024); + debug("Adjusting CS0_BNDS to account for unequal DIMM sizes in interleaved memory\n"); + ddr1->cs0_bnds = ((memsize_total * 1024 * 1024) - 1) >> 24; + ddr2->cs0_bnds = ((memsize_total * 1024 * 1024) - 1) >> 24; + debug("DDR1: cs0_bnds = 0x%08x\n", ddr1->cs0_bnds); + debug("DDR2: cs0_bnds = 0x%08x\n", ddr2->cs0_bnds); } - debug("DDR: memory initialized\n"); + + ddr1_enabled = enable_ddr(1); + ddr2_enabled = enable_ddr(2); + + /* + * Both controllers need to be enabled for interleaving. + */ + if (ddr1_enabled && ddr2_enabled) { + law_size_interleaved = 19 + __ilog2(memsize_total); + + /* + * Set up LAWBAR for DDR 1 space. + */ + mcm->lawbar1 = ((CFG_DDR_SDRAM_BASE >> 12) & 0xfffff); + mcm->lawar1 = (LAWAR_EN + | LAWAR_TRGT_IF_DDR_INTERLEAVED + | (LAWAR_SIZE & law_size_interleaved)); + debug("DDR: LAWBAR1=0x%08x\n", mcm->lawbar1); + debug("DDR: LAWAR1=0x%08x\n", mcm->lawar1); + debug("Interleaved memory size is 0x%08lx\n", memsize_total); + +#ifdef CONFIG_DDR_INTERLEAVE +#if (CFG_PAGE_INTERLEAVING == 1) + printf("Page "); +#elif (CFG_BANK_INTERLEAVING == 1) + printf("Bank "); +#elif (CFG_SUPER_BANK_INTERLEAVING == 1) + printf("Super-bank "); +#else + printf("Cache-line "); #endif +#endif + printf("Interleaved"); + return memsize_total * 1024 * 1024; + } else { + printf("Interleaved memory not enabled - check CS0 DIMM slots for both controllers.\n"); + return 0; + } + +#else + /* + * Call spd_sdram() routine to init ddr1 - pass I2c address, + * controller number, dimm number, and starting address. + */ + memsize_ddr1_dimm1 = spd_init(SPD_EEPROM_ADDRESS1, + 1, 1, + (unsigned int)memsize_total * 1024*1024); + memsize_total += memsize_ddr1_dimm1; + memsize_ddr1_dimm2 = spd_init(SPD_EEPROM_ADDRESS2, + 1, 2, + (unsigned int)memsize_total * 1024*1024); + memsize_total += memsize_ddr1_dimm2; /* - * Figure out memory size in Megabytes. + * Enable the DDR controller - pass ddr controller number. */ - memsize = n_ranks * rank_density / 0x100000; + ddr1_enabled = enable_ddr(1); + /* Keep track of memory to be addressed by DDR1 */ + memsize_ddr1 = memsize_ddr1_dimm1 + memsize_ddr1_dimm2; - /* + /* * First supported LAW size is 16M, at LAWAR_SIZE_16M == 23. Fnord. */ - law_size = 19 + __ilog2(memsize); + if (ddr1_enabled) { + law_size_ddr1 = 19 + __ilog2(memsize_ddr1); + + /* + * Set up LAWBAR for DDR 1 space. + */ + mcm->lawbar1 = ((CFG_DDR_SDRAM_BASE >> 12) & 0xfffff); + mcm->lawar1 = (LAWAR_EN + | LAWAR_TRGT_IF_DDR1 + | (LAWAR_SIZE & law_size_ddr1)); + debug("DDR: LAWBAR1=0x%08x\n", mcm->lawbar1); + debug("DDR: LAWAR1=0x%08x\n", mcm->lawar1); + } + +#if (CONFIG_NUM_DDR_CONTROLLERS > 1) + memsize_ddr2_dimm1 = spd_init(SPD_EEPROM_ADDRESS3, + 2, 1, + (unsigned int)memsize_total * 1024*1024); + memsize_total += memsize_ddr2_dimm1; + + memsize_ddr2_dimm2 = spd_init(SPD_EEPROM_ADDRESS4, + 2, 2, + (unsigned int)memsize_total * 1024*1024); + memsize_total += memsize_ddr2_dimm2; + + ddr2_enabled = enable_ddr(2); + + /* Keep track of memory to be addressed by DDR2 */ + memsize_ddr2 = memsize_ddr2_dimm1 + memsize_ddr2_dimm2; + + if (ddr2_enabled) { + law_size_ddr2 = 19 + __ilog2(memsize_ddr2); + + /* + * Set up LAWBAR for DDR 2 space. + */ + if (ddr1_enabled) + mcm->lawbar8 = (((memsize_ddr1 * 1024 * 1024) >> 12) + & 0xfffff); + else + mcm->lawbar8 = ((CFG_DDR_SDRAM_BASE >> 12) & 0xfffff); + + mcm->lawar8 = (LAWAR_EN + | LAWAR_TRGT_IF_DDR2 + | (LAWAR_SIZE & law_size_ddr2)); + debug("\nDDR: LAWBAR8=0x%08x\n", mcm->lawbar8); + debug("DDR: LAWAR8=0x%08x\n", mcm->lawar8); + } +#endif /* CONFIG_NUM_DDR_CONTROLLERS > 1 */ + + debug("\nMemory sizes are DDR1 = 0x%08lx, DDR2 = 0x%08lx\n", + memsize_ddr1, memsize_ddr2); /* - * Set up LAWBAR for all of DDR. + * If neither DDR controller is enabled return 0. */ - mcm->lawbar1 = ((CFG_DDR_SDRAM_BASE >> 12) & 0xfffff); - mcm->lawar1 = (LAWAR_EN - | LAWAR_TRGT_IF_DDR - | (LAWAR_SIZE & law_size)); - debug("DDR: LAWBAR1=0x%08x\n", mcm->lawbar1); - debug("DDR: LARAR1=0x%08x\n", mcm->lawar1); + if (!ddr1_enabled && !ddr2_enabled) + return 0; + else { + printf("Non-interleaved"); + return memsize_total * 1024 * 1024; + } - return memsize * 1024 * 1024; +#endif /* CONFIG_DDR_INTERLEAVE */ } + #endif /* CONFIG_SPD_EEPROM */ diff --git a/include/configs/MPC8641HPCN.h b/include/configs/MPC8641HPCN.h index aaf99c150f..2a197be294 100644 --- a/include/configs/MPC8641HPCN.h +++ b/include/configs/MPC8641HPCN.h @@ -57,6 +57,13 @@ #define CONFIG_DDR_ECC /* only for ECC DDR module */ #define CONFIG_ECC_INIT_VIA_DDRCONTROLLER /* DDR controller or DMA? */ #define CONFIG_MEM_INIT_VALUE 0xDeadBeef +#define CONFIG_NUM_DDR_CONTROLLERS 2 +/* #define CONFIG_DDR_INTERLEAVE 1 */ +#define CACHE_LINE_INTERLEAVING 0x20000000 +#define PAGE_INTERLEAVING 0x21000000 +#define BANK_INTERLEAVING 0x22000000 +#define SUPER_BANK_INTERLEAVING 0x23000000 + #define CONFIG_ALTIVEC 1 @@ -99,7 +106,10 @@ /* * Determine DDR configuration from I2C interface. */ - #define SPD_EEPROM_ADDRESS 0x51 /* DDR DIMM */ + #define SPD_EEPROM_ADDRESS1 0x51 /* DDR DIMM */ + #define SPD_EEPROM_ADDRESS2 0x52 /* DDR DIMM */ + #define SPD_EEPROM_ADDRESS3 0x53 /* DDR DIMM */ + #define SPD_EEPROM_ADDRESS4 0x54 /* DDR DIMM */ #else /* -- cgit v1.2.3 From 70205e5a6ddc8528b11db9eb4d3fa0209d9fce2a Mon Sep 17 00:00:00 2001 From: Haiying Wang Date: Tue, 30 May 2006 08:51:19 -0500 Subject: Fix two SDRAM setup bugs. Fix ECC setup bug. Enable 1T/2T based on number of DIMMs present. Signed-off-by: Haiying Wang --- cpu/mpc86xx/spd_sdram.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'cpu/mpc86xx/spd_sdram.c') diff --git a/cpu/mpc86xx/spd_sdram.c b/cpu/mpc86xx/spd_sdram.c index 130c8fc396..f30bbbd7e2 100644 --- a/cpu/mpc86xx/spd_sdram.c +++ b/cpu/mpc86xx/spd_sdram.c @@ -1088,24 +1088,24 @@ unsigned int enable_ddr(unsigned int ddr_num) * If the user wanted ECC (enabled via sdram_cfg[2]) */ if (config == 0x02) { + ddr->err_disable = 0x00000000; + asm("sync;isync;"); + ddr->err_sbe = 0x00ff0000; + ddr->err_int_en = 0x0000000d; sdram_cfg_1 |= 0x20000000; /* ECC_EN */ } #endif /* - * REV1 uses 1T timing. - * REV2 may use 1T or 2T as configured by the user. + * Set 1T or 2T timing based on 1 or 2 modules */ { - uint pvr = get_pvr(); - - if (pvr != PVR_85xx_REV1) { -#if defined(CONFIG_DDR_2T_TIMING) + if (!(no_dimm1 || no_dimm2)) { /* + * 2T timing,because both DIMMS are present. * Enable 2T timing by setting sdram_cfg[16]. */ sdram_cfg_1 |= 0x8000; /* 2T_EN */ -#endif } } -- cgit v1.2.3 From 91a414c7d1fb0eac912592cd995b30c9f23045c9 Mon Sep 17 00:00:00 2001 From: John Traill Date: Tue, 8 Aug 2006 11:32:43 +0100 Subject: Fix caslat calculation Signed-off-by: John Traill --- cpu/mpc86xx/spd_sdram.c | 135 ++++++++++++++---------------------------------- 1 file changed, 39 insertions(+), 96 deletions(-) (limited to 'cpu/mpc86xx/spd_sdram.c') diff --git a/cpu/mpc86xx/spd_sdram.c b/cpu/mpc86xx/spd_sdram.c index f30bbbd7e2..a4b9d54c7b 100644 --- a/cpu/mpc86xx/spd_sdram.c +++ b/cpu/mpc86xx/spd_sdram.c @@ -44,7 +44,7 @@ extern int dma_xfer(void *dest, uint count, void *src); /* * Only one of the following three should be 1; others should be 0 * By default the cache line interleaving is selected if - * the CONFIG_DDR_INTERLEAVE flag is defined in MPC8641HPCN.h + * the CONFIG_DDR_INTERLEAVE flag is defined */ #define CFG_PAGE_INTERLEAVING 0 #define CFG_BANK_INTERLEAVING 0 @@ -137,8 +137,8 @@ convert_bcd_tenths_to_cycle_time_ps(unsigned int spd_val) 800, 900, 250, - 330, /* FIXME: Is 333 better/valid? */ - 660, /* FIXME: Is 667 better/valid? */ + 330, + 660, 750, 0, /* undefined */ 0 /* undefined */ @@ -167,7 +167,7 @@ spd_init(unsigned char i2c_address, unsigned int ddr_num, unsigned int dqs_cfg; unsigned char twr_clk, twtr_clk, twr_auto_clk; unsigned int tCKmin_ps, tCKmax_ps; - unsigned int max_data_rate, effective_data_rate; + unsigned int max_data_rate; unsigned int busfreq; unsigned sdram_cfg_1; unsigned int memsize; @@ -187,6 +187,7 @@ spd_init(unsigned char i2c_address, unsigned int ddr_num, unsigned char d_init; unsigned int law_size; volatile ccsr_local_mcm_t *mcm = &immap->im_local_mcm; + unsigned int tCycle_ps, modfreq; if (ddr_num == 1) ddr = &immap->im_ddr1; @@ -288,7 +289,7 @@ spd_init(unsigned char i2c_address, unsigned int ddr_num, } #ifdef CONFIG_DDR_INTERLEAVE -#ifdef CONFIG_MPC8641HPCN + if (dimm_num != 1) { printf("For interleaving memory on HPCN, need to use DIMM 1 for DDR Controller %d !\n", ddr_num); return 0; @@ -340,8 +341,6 @@ spd_init(unsigned char i2c_address, unsigned int ddr_num, rank_density /= 2; } } -#endif /* CONFIG_MPC8641HPCN */ - #else /* CONFIG_DDR_INTERLEAVE */ if (dimm_num == 1) { @@ -468,81 +467,42 @@ spd_init(unsigned char i2c_address, unsigned int ddr_num, */ busfreq = get_bus_freq(0) / 1000000; /* MHz */ - effective_data_rate = max_data_rate; - if (busfreq < 90) { - /* DDR rate out-of-range */ - puts("DDR: platform frequency is not fit for DDR rate\n"); + if ((spd.mem_type == SPD_MEMTYPE_DDR2) && (busfreq < 266)) { + printf("DDR: platform frequency too low for correct DDR2 controller operation\n"); return 0; - - } else if (90 <= busfreq && busfreq < 230 && max_data_rate >= 230) { - /* - * busfreq 90~230 range, treated as DDR 200. - */ - effective_data_rate = 200; - if (spd.clk_cycle3 == 0xa0) /* 10 ns */ - caslat -= 2; - else if (spd.clk_cycle2 == 0xa0) - caslat--; - - } else if (230 <= busfreq && busfreq < 280 && max_data_rate >= 280) { - /* - * busfreq 230~280 range, treated as DDR 266. - */ - effective_data_rate = 266; - if (spd.clk_cycle3 == 0x75) /* 7.5 ns */ - caslat -= 2; - else if (spd.clk_cycle2 == 0x75) - caslat--; - - } else if (280 <= busfreq && busfreq < 350 && max_data_rate >= 350) { - /* - * busfreq 280~350 range, treated as DDR 333. - */ - effective_data_rate = 333; - if (spd.clk_cycle3 == 0x60) /* 6.0 ns */ - caslat -= 2; - else if (spd.clk_cycle2 == 0x60) - caslat--; - - } else if (350 <= busfreq && busfreq < 460 && max_data_rate >= 460) { - /* - * busfreq 350~460 range, treated as DDR 400. - */ - effective_data_rate = 400; - if (spd.clk_cycle3 == 0x50) /* 5.0 ns */ - caslat -= 2; - else if (spd.clk_cycle2 == 0x50) - caslat--; - - } else if (460 <= busfreq && busfreq < 560 && max_data_rate >= 560) { - /* - * busfreq 460~560 range, treated as DDR 533. - */ - effective_data_rate = 533; - if (spd.clk_cycle3 == 0x3D) /* 3.75 ns */ - caslat -= 2; - else if (spd.clk_cycle2 == 0x3D) - caslat--; - - } else if (560 <= busfreq && busfreq < 700 && max_data_rate >= 700) { - /* - * busfreq 560~700 range, treated as DDR 667. - */ - effective_data_rate = 667; - if (spd.clk_cycle3 == 0x30) /* 3.0 ns */ - caslat -= 2; - else if (spd.clk_cycle2 == 0x30) - caslat--; - - } else if (700 <= busfreq) { - /* - * DDR rate out-of-range - */ - printf("DDR: Bus freq %d MHz is not fit for DDR rate %d MHz\n", - busfreq, max_data_rate); + } else if (busfreq < 90) { + printf("DDR: platform frequency too low for correct DDR1 operation\n"); return 0; } + if ((busfreq <= modfreq) && (spd.cas_lat & (1 << (caslat - 2)))) { + caslat -= 2; + } else { + tCycle_ps = convert_bcd_tenths_to_cycle_time_ps(spd.clk_cycle2); + modfreq = 2 * 1000 * 1000 / tCycle_ps; + if ((busfreq <= modfreq) && (spd.cas_lat & (1 << (caslat - 1)))) + caslat -= 1; + else if (busfreq > max_data_rate) { + printf("DDR: Bus freq %d MHz is not fit for DDR rate %d MHz\n", + busfreq, max_data_rate); + return 0; + } + } + + /* + * Empirically set ~MCAS-to-preamble override for DDR 2. + * Your milage will vary. + */ + cpo = 0; + if (spd.mem_type == SPD_MEMTYPE_DDR2) { + if (busfreq <= 333) { + cpo = 0x7; + } else if (busfreq <= 400) { + cpo = 0x9; + } else { + cpo = 0xa; + } + } /* * Convert caslat clocks to DDR controller value. @@ -554,7 +514,6 @@ spd_init(unsigned char i2c_address, unsigned int ddr_num, caslat_ctrl = (2 * caslat - 1) & 0x0f; } - debug("DDR: effective data rate is %d MHz\n", effective_data_rate); debug("DDR: caslat SPD bit is %d, controller field is 0x%x\n", caslat, caslat_ctrl); @@ -676,7 +635,7 @@ spd_init(unsigned char i2c_address, unsigned int ddr_num, && (odt_wr_cfg || odt_rd_cfg) && (caslat < 4)) { add_lat = 4 - caslat; - if (add_lat > trcd_clk) { + if (add_lat >= trcd_clk) { add_lat = trcd_clk - 1; } } @@ -717,22 +676,6 @@ spd_init(unsigned char i2c_address, unsigned int ddr_num, four_act = picos_to_clk(37500); /* By the book. 1k pages? */ } - /* - * Empirically set ~MCAS-to-preamble override for DDR 2. - * Your milage will vary. - */ - cpo = 0; - if (spd.mem_type == SPD_MEMTYPE_DDR2) { - if (effective_data_rate == 266 || effective_data_rate == 333) { - cpo = 0x7; /* READ_LAT + 5/4 */ - } else if (effective_data_rate == 400) { - cpo = 0x9; /* READ_LAT + 7/4 */ - } else { - /* Pure speculation */ - cpo = 0xb; - } - } - ddr->timing_cfg_2 = (0 | ((add_lat & 0x7) << 28) /* ADD_LAT */ | ((cpo & 0x1f) << 23) /* CPO */ -- cgit v1.2.3 From cd6d73d5b895a5935ac4fde0a356288142a584e0 Mon Sep 17 00:00:00 2001 From: Jon Loeliger Date: Tue, 29 Aug 2006 09:48:49 -0500 Subject: Remove bogus msync and use volatile asm. --- cpu/mpc86xx/spd_sdram.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'cpu/mpc86xx/spd_sdram.c') diff --git a/cpu/mpc86xx/spd_sdram.c b/cpu/mpc86xx/spd_sdram.c index a4b9d54c7b..44b0d4133c 100644 --- a/cpu/mpc86xx/spd_sdram.c +++ b/cpu/mpc86xx/spd_sdram.c @@ -834,7 +834,7 @@ spd_init(unsigned char i2c_address, unsigned int ddr_num, debug("DDR: err_sbe = 0x%08x\n", ddr->err_sbe); #endif - asm("sync;isync"); + asm volatile("sync;isync"); udelay(500); /* @@ -1032,7 +1032,7 @@ unsigned int enable_ddr(unsigned int ddr_num) */ if (config == 0x02) { ddr->err_disable = 0x00000000; - asm("sync;isync;"); + asm volatile("sync;isync;"); ddr->err_sbe = 0x00ff0000; ddr->err_int_en = 0x0000000d; sdram_cfg_1 |= 0x20000000; /* ECC_EN */ @@ -1325,7 +1325,7 @@ ddr_enable_ecc(unsigned int dram_size) */ debug("DMA DDR: err_disable = 0x%08x\n", ddr1->err_disable); ddr1->err_disable = 0x00000000; - asm("sync;isync;msync"); + asm volatile("sync;isync"); debug("DMA DDR: err_disable = 0x%08x\n", ddr1->err_disable); } -- cgit v1.2.3 From f55df18187e7a45cb73fec4370d12135e6691ae1 Mon Sep 17 00:00:00 2001 From: John Traill Date: Fri, 29 Sep 2006 08:23:12 +0100 Subject: Fix missing tCycle/modfreq calculation. Signed-off-by: John Traill --- cpu/mpc86xx/spd_sdram.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'cpu/mpc86xx/spd_sdram.c') diff --git a/cpu/mpc86xx/spd_sdram.c b/cpu/mpc86xx/spd_sdram.c index 44b0d4133c..39da3cc535 100644 --- a/cpu/mpc86xx/spd_sdram.c +++ b/cpu/mpc86xx/spd_sdram.c @@ -466,6 +466,8 @@ spd_init(unsigned char i2c_address, unsigned int ddr_num, * are slower than the DDR module. */ busfreq = get_bus_freq(0) / 1000000; /* MHz */ + tCycle_ps = convert_bcd_tenths_to_cycle_time_ps(spd.clk_cycle3); + modfreq = 2 * 1000 * 1000 / tCycle_ps; if ((spd.mem_type == SPD_MEMTYPE_DDR2) && (busfreq < 266)) { printf("DDR: platform frequency too low for correct DDR2 controller operation\n"); -- cgit v1.2.3 From 1fd5699a4a24f5c1dab1b32f480bace1ebb9fc3e Mon Sep 17 00:00:00 2001 From: Jon Loeliger Date: Tue, 10 Oct 2006 17:19:03 -0500 Subject: Coding style changes to remove local varible blocks and reformat a bit nicer. --- cpu/mpc85xx/spd_sdram.c | 134 ++++++++++++++++++++++------------------------ cpu/mpc86xx/spd_sdram.c | 138 ++++++++++++++++++++++-------------------------- 2 files changed, 128 insertions(+), 144 deletions(-) (limited to 'cpu/mpc86xx/spd_sdram.c') diff --git a/cpu/mpc85xx/spd_sdram.c b/cpu/mpc85xx/spd_sdram.c index af99282dd9..7507801ee7 100644 --- a/cpu/mpc85xx/spd_sdram.c +++ b/cpu/mpc85xx/spd_sdram.c @@ -131,8 +131,8 @@ convert_bcd_tenths_to_cycle_time_ps(unsigned int spd_val) 800, 900, 250, - 330, /* FIXME: Is 333 better/valid? */ - 660, /* FIXME: Is 667 better/valid? */ + 330, + 660, 750, 0, /* undefined */ 0 /* undefined */ @@ -146,6 +146,28 @@ convert_bcd_tenths_to_cycle_time_ps(unsigned int spd_val) } +/* + * Determine Refresh Rate. Ignore self refresh bit on DDR I. + * Table from SPD Spec, Byte 12, converted to picoseconds and + * filled in with "default" normal values. + */ +unsigned int determine_refresh_rate(unsigned int spd_refresh) +{ + unsigned int refresh_time_ns[8] = { + 15625000, /* 0 Normal 1.00x */ + 3900000, /* 1 Reduced .25x */ + 7800000, /* 2 Extended .50x */ + 31300000, /* 3 Extended 2.00x */ + 62500000, /* 4 Extended 4.00x */ + 125000000, /* 5 Extended 8.00x */ + 15625000, /* 6 Normal 1.00x filler */ + 15625000, /* 7 Normal 1.00x filler */ + }; + + return picos_to_clk(refresh_time_ns[spd_refresh & 0x7]); +} + + long int spd_sdram(void) { @@ -157,6 +179,10 @@ spd_sdram(void) unsigned int rank_density; unsigned int odt_rd_cfg, odt_wr_cfg; unsigned int odt_cfg, mode_odt_enable; + unsigned int refresh_clk; +#ifdef MPC85xx_DDR_SDRAM_CLK_CNTL + unsigned char clk_adjust; +#endif unsigned int dqs_cfg; unsigned char twr_clk, twtr_clk, twr_auto_clk; unsigned int tCKmin_ps, tCKmax_ps; @@ -740,38 +766,21 @@ spd_sdram(void) ddr->sdram_mode_2 = 0; debug("DDR: sdram_mode_2 = 0x%08x\n", ddr->sdram_mode_2); - /* - * Determine Refresh Rate. Ignore self refresh bit on DDR I. - * Table from SPD Spec, Byte 12, converted to picoseconds and - * filled in with "default" normal values. + * Determine Refresh Rate. */ - { - unsigned int refresh_clk; - unsigned int refresh_time_ns[8] = { - 15625000, /* 0 Normal 1.00x */ - 3900000, /* 1 Reduced .25x */ - 7800000, /* 2 Extended .50x */ - 31300000, /* 3 Extended 2.00x */ - 62500000, /* 4 Extended 4.00x */ - 125000000, /* 5 Extended 8.00x */ - 15625000, /* 6 Normal 1.00x filler */ - 15625000, /* 7 Normal 1.00x filler */ - }; - - refresh_clk = picos_to_clk(refresh_time_ns[spd.refresh & 0x7]); - - /* - * Set BSTOPRE to 0x100 for page mode - * If auto-charge is used, set BSTOPRE = 0 - */ - ddr->sdram_interval = - (0 - | (refresh_clk & 0x3fff) << 16 - | 0x100 - ); - debug("DDR: sdram_interval = 0x%08x\n", ddr->sdram_interval); - } + refresh_clk = determine_refresh_rate(spd.refresh & 0x7); + + /* + * Set BSTOPRE to 0x100 for page mode + * If auto-charge is used, set BSTOPRE = 0 + */ + ddr->sdram_interval = + (0 + | (refresh_clk & 0x3fff) << 16 + | 0x100 + ); + debug("DDR: sdram_interval = 0x%08x\n", ddr->sdram_interval); /* * Is this an ECC DDR chip? @@ -835,28 +844,23 @@ spd_sdram(void) #ifdef MPC85xx_DDR_SDRAM_CLK_CNTL - { - unsigned char clk_adjust; - - /* - * Setup the clock control. - * SDRAM_CLK_CNTL[0] = Source synchronous enable == 1 - * SDRAM_CLK_CNTL[5-7] = Clock Adjust - * 0110 3/4 cycle late - * 0111 7/8 cycle late - */ - if (spd.mem_type == SPD_MEMTYPE_DDR) { - clk_adjust = 0x6; - } else { - clk_adjust = 0x7; - } + /* + * Setup the clock control. + * SDRAM_CLK_CNTL[0] = Source synchronous enable == 1 + * SDRAM_CLK_CNTL[5-7] = Clock Adjust + * 0110 3/4 cycle late + * 0111 7/8 cycle late + */ + if (spd.mem_type == SPD_MEMTYPE_DDR) + clk_adjust = 0x6; + else + clk_adjust = 0x7; - ddr->sdram_clk_cntl = (0 + ddr->sdram_clk_cntl = (0 | 0x80000000 | (clk_adjust << 23) ); - debug("DDR: sdram_clk_cntl = 0x%08x\n", ddr->sdram_clk_cntl); - } + debug("DDR: sdram_clk_cntl = 0x%08x\n", ddr->sdram_clk_cntl); #endif /* @@ -1081,26 +1085,16 @@ 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 *)0x002000, 0x002000, (uint *)0); /* 8K */ + dma_xfer((uint *)0x004000, 0x004000, (uint *)0); /* 16K */ + dma_xfer((uint *)0x008000, 0x008000, (uint *)0); /* 32K */ + dma_xfer((uint *)0x010000, 0x010000, (uint *)0); /* 64K */ + dma_xfer((uint *)0x020000, 0x020000, (uint *)0); /* 128k */ + dma_xfer((uint *)0x040000, 0x040000, (uint *)0); /* 256k */ + dma_xfer((uint *)0x080000, 0x080000, (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/mpc86xx/spd_sdram.c b/cpu/mpc86xx/spd_sdram.c index 39da3cc535..97bbf43868 100644 --- a/cpu/mpc86xx/spd_sdram.c +++ b/cpu/mpc86xx/spd_sdram.c @@ -152,6 +152,28 @@ convert_bcd_tenths_to_cycle_time_ps(unsigned int spd_val) } +/* + * Determine Refresh Rate. Ignore self refresh bit on DDR I. + * Table from SPD Spec, Byte 12, converted to picoseconds and + * filled in with "default" normal values. + */ +unsigned int determine_refresh_rate(unsigned int spd_refresh) +{ + unsigned int refresh_time_ns[8] = { + 15625000, /* 0 Normal 1.00x */ + 3900000, /* 1 Reduced .25x */ + 7800000, /* 2 Extended .50x */ + 31300000, /* 3 Extended 2.00x */ + 62500000, /* 4 Extended 4.00x */ + 125000000, /* 5 Extended 8.00x */ + 15625000, /* 6 Normal 1.00x filler */ + 15625000, /* 7 Normal 1.00x filler */ + }; + + return picos_to_clk(refresh_time_ns[spd_refresh & 0x7]); +} + + long int spd_init(unsigned char i2c_address, unsigned int ddr_num, unsigned int dimm_num, unsigned int start_addr) @@ -164,6 +186,10 @@ spd_init(unsigned char i2c_address, unsigned int ddr_num, unsigned int rank_density; unsigned int odt_rd_cfg, odt_wr_cfg; unsigned int odt_cfg, mode_odt_enable; + unsigned int refresh_clk; +#ifdef MPC86xx_DDR_SDRAM_CLK_CNTL + unsigned char clk_adjust; +#endif unsigned int dqs_cfg; unsigned char twr_clk, twtr_clk, twr_auto_clk; unsigned int tCKmin_ps, tCKmax_ps; @@ -197,7 +223,6 @@ spd_init(unsigned char i2c_address, unsigned int ddr_num, /* * Read SPD information. */ - debug("Performing SPD read at I2C address 0x%02lx\n",i2c_address); memset((void *)&spd, 0, sizeof(spd)); CFG_READ_SPD(i2c_address, 0, 1, (uchar *) &spd, sizeof(spd)); @@ -757,7 +782,6 @@ spd_init(unsigned char i2c_address, unsigned int ddr_num, twr_auto_clk = (spd.twr * 250 + tCKmax_ps - 1) / tCKmax_ps; } - /* * Mode Reg in bits 16 ~ 31, * Extended Mode Reg 1 in bits 0 ~ 15. @@ -783,45 +807,28 @@ spd_init(unsigned char i2c_address, unsigned int ddr_num, debug("DDR: sdram_mode = 0x%08x\n", ddr->sdram_mode_1); - /* * Clear EMRS2 and EMRS3. */ ddr->sdram_mode_2 = 0; debug("DDR: sdram_mode_2 = 0x%08x\n", ddr->sdram_mode_2); - /* - * Determine Refresh Rate. Ignore self refresh bit on DDR I. - * Table from SPD Spec, Byte 12, converted to picoseconds and - * filled in with "default" normal values. + * Determine Refresh Rate. */ - { - unsigned int refresh_clk; - unsigned int refresh_time_ns[8] = { - 15625000, /* 0 Normal 1.00x */ - 3900000, /* 1 Reduced .25x */ - 7800000, /* 2 Extended .50x */ - 31300000, /* 3 Extended 2.00x */ - 62500000, /* 4 Extended 4.00x */ - 125000000, /* 5 Extended 8.00x */ - 15625000, /* 6 Normal 1.00x filler */ - 15625000, /* 7 Normal 1.00x filler */ - }; + refresh_clk = determine_refresh_rate(spd.refresh & 0x7); - refresh_clk = picos_to_clk(refresh_time_ns[spd.refresh & 0x7]); + /* + * Set BSTOPRE to 0x100 for page mode + * If auto-charge is used, set BSTOPRE = 0 + */ + ddr->sdram_interval = + (0 + | (refresh_clk & 0x3fff) << 16 + | 0x100 + ); + debug("DDR: sdram_interval = 0x%08x\n", ddr->sdram_interval); - /* - * Set BSTOPRE to 0x100 for page mode - * If auto-charge is used, set BSTOPRE = 0 - */ - ddr->sdram_interval = - (0 - | (refresh_clk & 0x3fff) << 16 - | 0x100 - ); - debug("DDR: sdram_interval = 0x%08x\n", ddr->sdram_interval); - } /* * Is this an ECC DDR chip? @@ -885,31 +892,25 @@ spd_init(unsigned char i2c_address, unsigned int ddr_num, #ifdef MPC86xx_DDR_SDRAM_CLK_CNTL - { - unsigned char clk_adjust; - - /* - * Setup the clock control. - * SDRAM_CLK_CNTL[0] = Source synchronous enable == 1 - * SDRAM_CLK_CNTL[5-7] = Clock Adjust - * 0110 3/4 cycle late - * 0111 7/8 cycle late - */ - if (spd.mem_type == SPD_MEMTYPE_DDR) { - clk_adjust = 0x6; - } else { - clk_adjust = 0x7; - } + /* + * Setup the clock control. + * SDRAM_CLK_CNTL[0] = Source synchronous enable == 1 + * SDRAM_CLK_CNTL[5-7] = Clock Adjust + * 0110 3/4 cycle late + * 0111 7/8 cycle late + */ + if (spd.mem_type == SPD_MEMTYPE_DDR) + clk_adjust = 0x6; + else + clk_adjust = 0x7; - ddr->sdram_clk_cntl = (0 + ddr->sdram_clk_cntl = (0 | 0x80000000 | (clk_adjust << 23) ); - debug("DDR: sdram_clk_cntl = 0x%08x\n", ddr->sdram_clk_cntl); - } + debug("DDR: sdram_clk_cntl = 0x%08x\n", ddr->sdram_clk_cntl); #endif - /* * Figure out memory size in Megabytes. */ @@ -1259,10 +1260,9 @@ spd_sdram(void) */ if (!ddr1_enabled && !ddr2_enabled) return 0; - else { - printf("Non-interleaved"); - return memsize_total * 1024 * 1024; - } + + printf("Non-interleaved"); + return memsize_total * 1024 * 1024; #endif /* CONFIG_DDR_INTERLEAVE */ } @@ -1297,26 +1297,16 @@ 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 *)0x002000, 0x002000, (uint *)0); /* 8K */ + dma_xfer((uint *)0x004000, 0x004000, (uint *)0); /* 16K */ + dma_xfer((uint *)0x008000, 0x008000, (uint *)0); /* 32K */ + dma_xfer((uint *)0x010000, 0x010000, (uint *)0); /* 64K */ + dma_xfer((uint *)0x020000, 0x020000, (uint *)0); /* 128k */ + dma_xfer((uint *)0x040000, 0x040000, (uint *)0); /* 256k */ + dma_xfer((uint *)0x080000, 0x080000, (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); -- cgit v1.2.3 From ea08ff6e14f9ebb8c07cfa79c51ef540eb087393 Mon Sep 17 00:00:00 2001 From: Jon Loeliger Date: Fri, 27 Oct 2006 07:47:22 -0500 Subject: MPC86xx: Cleaned up unused and conditionally used local variables. Signed-off-by: Jon Loeliger --- cpu/mpc86xx/spd_sdram.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'cpu/mpc86xx/spd_sdram.c') diff --git a/cpu/mpc86xx/spd_sdram.c b/cpu/mpc86xx/spd_sdram.c index 97bbf43868..b18e8225de 100644 --- a/cpu/mpc86xx/spd_sdram.c +++ b/cpu/mpc86xx/spd_sdram.c @@ -195,7 +195,6 @@ spd_init(unsigned char i2c_address, unsigned int ddr_num, unsigned int tCKmin_ps, tCKmax_ps; unsigned int max_data_rate; unsigned int busfreq; - unsigned sdram_cfg_1; unsigned int memsize; unsigned char caslat, caslat_ctrl; unsigned int trfc, trfc_clk, trfc_low, trfc_high; @@ -209,10 +208,7 @@ spd_init(unsigned char i2c_address, unsigned int ddr_num, unsigned char cpo; unsigned char burst_len; unsigned int mode_caslat; - unsigned char sdram_type; unsigned char d_init; - unsigned int law_size; - volatile ccsr_local_mcm_t *mcm = &immap->im_local_mcm; unsigned int tCycle_ps, modfreq; if (ddr_num == 1) @@ -1107,12 +1103,12 @@ spd_sdram(void) unsigned int law_size_ddr1; unsigned int law_size_ddr2; volatile immap_t *immap = (immap_t *)CFG_IMMR; - volatile ccsr_ddr_t *ddr1 = &immap->im_ddr1; - volatile ccsr_ddr_t *ddr2 = &immap->im_ddr2; volatile ccsr_local_mcm_t *mcm = &immap->im_local_mcm; #ifdef CONFIG_DDR_INTERLEAVE unsigned int law_size_interleaved; + volatile ccsr_ddr_t *ddr1 = &immap->im_ddr1; + volatile ccsr_ddr_t *ddr2 = &immap->im_ddr2; memsize_ddr1_dimm1 = spd_init(SPD_EEPROM_ADDRESS1, 1, 1, -- cgit v1.2.3