+// SPDX-License-Identifier: GPL-2.0+
/*
* (C) Copyright 2006-2007 Freescale Semiconductor, Inc.
*
* Copyright (C) 2004-2006 Freescale Semiconductor, Inc.
* (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
*/
+#ifndef CONFIG_MPC83XX_SDRAM
+
#include <common.h>
+#include <cpu_func.h>
+#include <log.h>
+#include <time.h>
+#include <vsprintf.h>
#include <asm/processor.h>
#include <asm/io.h>
#include <i2c.h>
#include <spd.h>
#include <asm/mmu.h>
#include <spd_sdram.h>
+#include <asm/bitops.h>
+#include <linux/delay.h>
DECLARE_GLOBAL_DATA_PTR;
printf(" (DDR%d", ((ddr->sdram_cfg & SDRAM_CFG_SDRAM_TYPE_MASK)
>> SDRAM_CFG_SDRAM_TYPE_SHIFT) - 1);
+#if defined(CONFIG_ARCH_MPC8308) || defined(CONFIG_ARCH_MPC831X)
+ if ((ddr->sdram_cfg & SDRAM_CFG_DBW_MASK) == SDRAM_CFG_DBW_16)
+ puts(", 16-bit");
+ else if ((ddr->sdram_cfg & SDRAM_CFG_DBW_MASK) == SDRAM_CFG_DBW_32)
+ puts(", 32-bit");
+ else
+ puts(", unknown width");
+#else
if (ddr->sdram_cfg & SDRAM_CFG_32_BE)
puts(", 32-bit");
else
puts(", 64-bit");
+#endif
if (ddr->sdram_cfg & SDRAM_CFG_ECC_EN)
puts(", ECC on");
#ifndef CONFIG_SYS_READ_SPD
#define CONFIG_SYS_READ_SPD i2c_read
#endif
+#ifndef SPD_EEPROM_OFFSET
+#define SPD_EEPROM_OFFSET 0
+#endif
+#ifndef SPD_EEPROM_ADDR_LEN
+#define SPD_EEPROM_ADDR_LEN 1
+#endif
/*
* Convert picoseconds into clock cycles (rounding up if needed).
unsigned int memsize;
unsigned int law_size;
unsigned char caslat, caslat_ctrl;
- unsigned int trfc, trfc_clk, trfc_low, trfc_high;
+ unsigned int trfc, trfc_clk, trfc_low;
unsigned int trcd_clk, trtp_clk;
unsigned char cke_min_clk;
unsigned char add_lat, wr_lat;
isync();
/* Read SPD parameters with I2C */
- CONFIG_SYS_READ_SPD(SPD_EEPROM_ADDRESS, 0, 1, (uchar *) & spd, sizeof (spd));
+ CONFIG_SYS_READ_SPD(SPD_EEPROM_ADDRESS, SPD_EEPROM_OFFSET,
+ SPD_EEPROM_ADDR_LEN, (uchar *) &spd, sizeof(spd));
#ifdef SPD_DEBUG
spd_debug(&spd);
#endif
/*
* Set up LAWBAR for all of DDR.
*/
- ecm->bar = CONFIG_SYS_DDR_SDRAM_BASE & 0xfffff000;
+ ecm->bar = CONFIG_SYS_SDRAM_BASE & 0xfffff000;
ecm->ar = (LAWAR_EN | LAWAR_TRGT_IF_DDR | (LAWAR_SIZE & law_size));
debug("DDR:bar=0x%08x\n", ecm->bar);
debug("DDR:ar=0x%08x\n", ecm->ar);
/*
* Errata DDR6 work around: input enable 2 cycles earlier.
- * including MPC834x Rev1.0/1.1 and MPC8360 Rev1.1/1.2.
+ * including MPC834X Rev1.0/1.1 and MPC8360 Rev1.1/1.2.
*/
if(PVR_MAJ(pvr) <= 1 && spd.mem_type == SPD_MEMTYPE_DDR){
if (caslat == 2)
else if (caslat == 4)
ddr->debug_reg = 0x202c0000; /* CL=3.0 */
- __asm__ __volatile__ ("sync");
+ sync();
debug("Errata DDR6 (debug_reg=0x%08x)\n", ddr->debug_reg);
}
* so preadjust it down 8 first before splitting it up.
*/
trfc_low = (trfc_clk - 8) & 0xf;
- trfc_high = ((trfc_clk - 8) >> 4) & 0x3;
ddr->timing_cfg_1 =
(((picos_to_clk(spd.trp * 250) & 0x07) << 28 ) | /* PRETOACT */
* Empirically, 0x3 == 6/8 clock delay is suggested for DDR I 266.
*/
wr_data_delay = 2;
+#ifdef CONFIG_SYS_DDR_WRITE_DATA_DELAY
+ wr_data_delay = CONFIG_SYS_DDR_WRITE_DATA_DELAY;
+#endif
/*
* Write Latency
/*
* Empirically set ~MCAS-to-preamble override for DDR 2.
- * Your milage will vary.
+ * Your mileage will vary.
*/
cpo = 0;
if (spd.mem_type == SPD_MEMTYPE_DDR2) {
+#ifdef CONFIG_SYS_DDR_CPO
+ cpo = CONFIG_SYS_DDR_CPO;
+#else
if (effective_data_rate == 266) {
cpo = 0x4; /* READ_LAT + 1/2 */
} else if (effective_data_rate == 333) {
/* Automatic calibration */
cpo = 0x1f;
}
+#endif
}
ddr->timing_cfg_2 = (0
ddr->sdram_mode =
(0
| (1 << (16 + 10)) /* DQS Differential disable */
+#ifdef CONFIG_SYS_DDR_MODE_WEAK
+ | (1 << (16 + 1)) /* weak driver (~60%) */
+#endif
| (add_lat << (16 + 3)) /* Additive Latency in EMRS1 */
| (mode_odt_enable << 16) /* ODT Enable in EMRS1 */
| ((twr_clk - 1) << 9) /* Write Recovery Autopre */
#endif
debug("DDR:sdram_clk_cntl=0x%08x\n", ddr->sdram_clk_cntl);
- asm("sync;isync");
+ sync();
+ isync();
udelay(600);
#endif
/* Enable controller, and GO! */
ddr->sdram_cfg = sdram_cfg;
- asm("sync;isync");
+ sync();
+ isync();
udelay(500);
debug("DDR:sdram_cfg=0x%08x\n", ddr->sdram_cfg);
#endif /* CONFIG_SPD_EEPROM */
#if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER)
+static inline u32 mftbu(void)
+{
+ u32 rval;
+
+ asm volatile("mftbu %0" : "=r" (rval));
+ return rval;
+}
+
+static inline u32 mftb(void)
+{
+ u32 rval;
+
+ asm volatile("mftb %0" : "=r" (rval));
+ return rval;
+}
+
/*
- * Use timebase counter, get_timer() is not availabe
+ * Use timebase counter, get_timer() is not available
* at this point of initialization yet.
*/
static __inline__ unsigned long get_tbms (void)
/* get the timebase ticks */
do {
- asm volatile ("mftbu %0":"=r" (tbu1):);
- asm volatile ("mftb %0":"=r" (tbl):);
- asm volatile ("mftbu %0":"=r" (tbu2):);
+ tbu1 = mftbu();
+ tbl = mftb();
+ tbu2 = mftbu();
} while (tbu1 != tbu2);
/* convert ticks to ms */
for (p = 0; p < (u64*)(size); p++) {
ppcDWstore((u32*)p, pattern);
}
- __asm__ __volatile__ ("sync");
+ sync();
#endif
t_end = get_tbms();
/* Enable errors for ECC */
ddr->err_disable &= ECC_ERROR_ENABLE;
- __asm__ __volatile__ ("sync");
- __asm__ __volatile__ ("isync");
+ sync();
+ isync();
}
#endif /* CONFIG_DDR_ECC */
+
+#endif /* !CONFIG_MPC83XX_SDRAM */