Merge branch 'for-next/ppc'
This commit is contained in:
commit
0a5529d0ed
|
@ -13,6 +13,7 @@ endif
|
||||||
|
|
||||||
board-$(CONFIG_MACH_PHYCORE_MPC5200B_TINY) := pcm030
|
board-$(CONFIG_MACH_PHYCORE_MPC5200B_TINY) := pcm030
|
||||||
board-$(CONFIG_P2020RDB) := freescale-p2020rdb
|
board-$(CONFIG_P2020RDB) := freescale-p2020rdb
|
||||||
|
board-$(CONFIG_P1022DS) := freescale-p1022ds
|
||||||
board-$(CONFIG_DA923RC) := geip-da923rc
|
board-$(CONFIG_DA923RC) := geip-da923rc
|
||||||
|
|
||||||
machine-$(CONFIG_ARCH_MPC5200) := mpc5xxx
|
machine-$(CONFIG_ARCH_MPC5200) := mpc5xxx
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
obj-y += p1022ds.o
|
||||||
|
obj-y += law.o
|
||||||
|
obj-y += tlb.o
|
||||||
|
obj-y += ddr.o
|
||||||
|
obj-y += ics307_clk.o
|
|
@ -0,0 +1,55 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2009-2011 Freescale Semiconductor, Inc.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __CONFIG_H
|
||||||
|
#define __CONFIG_H
|
||||||
|
|
||||||
|
#ifndef __ASSEMBLY__
|
||||||
|
extern unsigned long ics307_clk_freq(unsigned int reg);
|
||||||
|
#endif
|
||||||
|
#define CFG_SYS_CLK_FREQ ics307_clk_freq(25)
|
||||||
|
#define CFG_DDR_CLK_FREQ ics307_clk_freq(28)
|
||||||
|
|
||||||
|
#define CFG_CHIP_SELECTS_PER_CTRL 2
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Memory map
|
||||||
|
*
|
||||||
|
* 0x0000_0000 0x7fff_ffff DDR 2G cacheable
|
||||||
|
*
|
||||||
|
* Localbus non-cacheable
|
||||||
|
* 0xe800_0000 0xefff_ffff FLASH 128M non-cacheable
|
||||||
|
* 0xffdf_0000 0xffdf_0fff PIXIS 4K Cacheable
|
||||||
|
* 0xffd0_0000 0xffd0_3fff L1 for stack 16K Cacheable TLB0
|
||||||
|
*/
|
||||||
|
#define CFG_SDRAM_BASE 0x00000000
|
||||||
|
|
||||||
|
#define CFG_CCSRBAR_DEFAULT 0xff700000
|
||||||
|
#define CFG_CCSRBAR 0xffe00000
|
||||||
|
#define CFG_CCSRBAR_PHYS CFG_CCSRBAR
|
||||||
|
#define CFG_IMMR CFG_CCSRBAR
|
||||||
|
|
||||||
|
#define CFG_INIT_RAM_ADDR 0xffd00000
|
||||||
|
#define CFG_INIT_RAM_SIZE 0x00004000
|
||||||
|
#define CFG_INIT_BI_SIZE 0x00000100
|
||||||
|
#define CFG_INIT_SP_OFFSET (CFG_INIT_RAM_SIZE - CFG_INIT_BI_SIZE)
|
||||||
|
|
||||||
|
#define CFG_BOOT_BLOCK 0xe0000000
|
||||||
|
#define CFG_BOOT_BLOCK_PHYS CFG_BOOT_BLOCK
|
||||||
|
#define CFG_FLASH_BASE 0xe8000000
|
||||||
|
#define CFG_FLASH_BASE_PHYS CFG_FLASH_BASE
|
||||||
|
#define CFG_PIXIS_BASE 0xffdf0000
|
||||||
|
#define CFG_PIXIS_BASE_PHYS CFG_PIXIS_BASE
|
||||||
|
|
||||||
|
#endif /* __CONFIG_H */
|
|
@ -0,0 +1,126 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2010 Freescale Semiconductor, Inc.
|
||||||
|
* Authors: Srikanth Srinivasan <srikanth.srinivasan@freescale.com>
|
||||||
|
* Timur Tabi <timur@freescale.com>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-2.0+
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <common.h>
|
||||||
|
#include <init.h>
|
||||||
|
#include <mach/fsl_i2c.h>
|
||||||
|
#include <mach/immap_85xx.h>
|
||||||
|
#include <mach/clock.h>
|
||||||
|
#include <asm/io.h>
|
||||||
|
#include <asm/fsl_lbc.h>
|
||||||
|
#include <asm/fsl_ddr_sdram.h>
|
||||||
|
#include <asm/fsl_ddr_dimm_params.h>
|
||||||
|
#include "p1022ds.h"
|
||||||
|
|
||||||
|
static const u8 spd_addr = 0x51;
|
||||||
|
|
||||||
|
int fsl_ddr_board_info(struct ddr_board_info_s *info)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Early mapping is needed to access the clock
|
||||||
|
* parameters in the FPGA.
|
||||||
|
*/
|
||||||
|
p1022ds_lbc_early_init();
|
||||||
|
|
||||||
|
info->fsl_ddr_ver = 0;
|
||||||
|
info->ddr_base = IOMEM(MPC85xx_DDR_ADDR);
|
||||||
|
/* Actual number of chip select used */
|
||||||
|
info->cs_per_ctrl = CFG_CHIP_SELECTS_PER_CTRL;
|
||||||
|
info->dimm_slots_per_ctrl = 1;
|
||||||
|
info->i2c_bus = 1;
|
||||||
|
info->i2c_slave = 0x7f;
|
||||||
|
info->i2c_speed = 400000;
|
||||||
|
info->i2c_base = IOMEM(I2C2_BASE_ADDR);
|
||||||
|
info->spd_i2c_addr = &spd_addr;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct board_specific_parameters {
|
||||||
|
u32 n_ranks;
|
||||||
|
u32 datarate_mhz_high;
|
||||||
|
u32 clk_adjust; /* Range: 0-8 */
|
||||||
|
u32 cpo; /* Range: 2-31 */
|
||||||
|
u32 write_data_delay; /* Range: 0-6 */
|
||||||
|
u32 force_2t;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This table contains all valid speeds we want to override with board
|
||||||
|
* specific parameters. datarate_mhz_high values need to be in ascending order
|
||||||
|
* for each n_ranks group.
|
||||||
|
*/
|
||||||
|
static const struct board_specific_parameters dimm0[] = {
|
||||||
|
/*
|
||||||
|
* memory controller 0
|
||||||
|
* num| hi| clk| cpo|wrdata|2T
|
||||||
|
* ranks| mhz|adjst| | delay|
|
||||||
|
*/
|
||||||
|
{ 1, 549, 5, 31, 3, 0 },
|
||||||
|
{ 1, 850, 5, 31, 5, 0 },
|
||||||
|
{ 2, 549, 5, 31, 3, 0 },
|
||||||
|
{ 2, 850, 5, 31, 5, 0 },
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
|
||||||
|
void fsl_ddr_board_options(struct memctl_options_s *popts,
|
||||||
|
struct dimm_params_s *pdimm)
|
||||||
|
{
|
||||||
|
const struct board_specific_parameters *pbsp, *pbsp_highest = NULL;
|
||||||
|
unsigned long ddr_freq;
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
|
for (i = 0; i < popts->board_info->cs_per_ctrl; i++) {
|
||||||
|
popts->cs_local_opts[i].odt_rd_cfg = 0;
|
||||||
|
popts->cs_local_opts[i].odt_wr_cfg = 1;
|
||||||
|
popts->cs_local_opts[i].odt_rtt_wr = DDR3_RTT_OFF;
|
||||||
|
}
|
||||||
|
popts->cs_local_opts[0].odt_rtt_norm = DDR3_RTT_40_OHM;
|
||||||
|
popts->cs_local_opts[1].odt_rtt_norm = DDR3_RTT_OFF;
|
||||||
|
|
||||||
|
pbsp = dimm0;
|
||||||
|
|
||||||
|
ddr_freq = fsl_get_ddr_freq(0) / 1000000;
|
||||||
|
/*
|
||||||
|
* To have optimal parameters specific to the board, do a fine
|
||||||
|
* adjustment of DDR parameters depending on the DDR data rate.
|
||||||
|
*/
|
||||||
|
while (pbsp->datarate_mhz_high) {
|
||||||
|
if (pbsp->n_ranks == pdimm->n_ranks) {
|
||||||
|
if (ddr_freq <= pbsp->datarate_mhz_high) {
|
||||||
|
popts->clk_adjust = pbsp->clk_adjust;
|
||||||
|
popts->cpo_override = pbsp->cpo;
|
||||||
|
popts->write_data_delay =
|
||||||
|
pbsp->write_data_delay;
|
||||||
|
popts->twoT_en = pbsp->force_2t;
|
||||||
|
goto found;
|
||||||
|
}
|
||||||
|
pbsp_highest = pbsp;
|
||||||
|
}
|
||||||
|
pbsp++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Use highest parameters if none were found */
|
||||||
|
if (pbsp_highest) {
|
||||||
|
popts->clk_adjust = pbsp->clk_adjust;
|
||||||
|
popts->cpo_override = pbsp->cpo;
|
||||||
|
popts->write_data_delay = pbsp->write_data_delay;
|
||||||
|
popts->twoT_en = pbsp->force_2t;
|
||||||
|
}
|
||||||
|
|
||||||
|
found:
|
||||||
|
popts->half_strength_driver_enable = 1;
|
||||||
|
|
||||||
|
/* Per AN4039, enable ZQ calibration. */
|
||||||
|
popts->zq_en = 1;
|
||||||
|
|
||||||
|
popts->auto_self_refresh_en = 1;
|
||||||
|
popts->sr_it = 0xb;
|
||||||
|
|
||||||
|
popts->dll_rst_dis = 1;
|
||||||
|
}
|
|
@ -0,0 +1,2 @@
|
||||||
|
#!/bin/sh
|
||||||
|
source /env/config
|
|
@ -0,0 +1,2 @@
|
||||||
|
#!/bin/sh
|
||||||
|
export bootargs="root=/dev/nfs rw ip=bootp console=ttyS0,115200"
|
|
@ -0,0 +1,46 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2010-2011 Freescale Semiconductor, Inc.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-2.0+
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <common.h>
|
||||||
|
#include <asm/io.h>
|
||||||
|
|
||||||
|
/* decode S[0-2] to Output Divider (OD) */
|
||||||
|
static u8 ics307_s_to_od[] = {
|
||||||
|
10, 2, 8, 4, 5, 7, 3, 6
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Calculate frequency being generated by ICS307-02 clock chip. */
|
||||||
|
unsigned long ics307_clk_freq(unsigned int reg)
|
||||||
|
{
|
||||||
|
const unsigned long input_freq = 33333000;
|
||||||
|
void __iomem *fpga_base = IOMEM(CFG_PIXIS_BASE);
|
||||||
|
unsigned char cw0, cw1, cw2;
|
||||||
|
unsigned long vdw, rdw, od, freq;
|
||||||
|
|
||||||
|
cw0 = in_8(fpga_base + reg);
|
||||||
|
cw1 = in_8(fpga_base + reg + 1);
|
||||||
|
cw2 = in_8(fpga_base + reg + 2);
|
||||||
|
vdw = ((cw1 << 1) & 0x1fe) + ((cw2 >> 7) & 1);
|
||||||
|
rdw = cw2 & 0x7f;
|
||||||
|
od = ics307_s_to_od[cw0 & 0x7];
|
||||||
|
/*
|
||||||
|
* CLK1 Freq = Input Frequency * 2 * (VDW + 8) / ((RDW + 2) * OD)
|
||||||
|
*
|
||||||
|
* cw0: C1 C0 TTL F1 F0 S2 S1 S0
|
||||||
|
* cw1: V8 V7 V6 V5 V4 V3 V2 V1
|
||||||
|
* cw2: V0 R6 R5 R4 R3 R2 R1 R0
|
||||||
|
*
|
||||||
|
* R6:R0 = Reference Divider Word (RDW)
|
||||||
|
* V8:V0 = VCO Divider Word (VDW)
|
||||||
|
* S2:S0 = Output Divider Select (OD)
|
||||||
|
* F1:F0 = Function of CLK2 Output
|
||||||
|
* TTL = duty cycle
|
||||||
|
* C1:C0 = internal load capacitance for crystal
|
||||||
|
*/
|
||||||
|
freq = input_freq * 2 * (vdw + 8) / ((rdw + 2) * od);
|
||||||
|
|
||||||
|
return freq;
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2009-2010 Freescale Semiconductor, Inc.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <common.h>
|
||||||
|
#include <asm/fsl_law.h>
|
||||||
|
|
||||||
|
struct law_entry law_table[] = {
|
||||||
|
FSL_SET_LAW(CFG_BOOT_BLOCK_PHYS, LAW_SIZE_256M, LAW_TRGT_IF_LBC),
|
||||||
|
FSL_SET_LAW(CFG_PIXIS_BASE_PHYS, LAW_SIZE_4K, LAW_TRGT_IF_LBC),
|
||||||
|
};
|
||||||
|
|
||||||
|
int num_law_entries = ARRAY_SIZE(law_table);
|
|
@ -0,0 +1,181 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2014 GE Intelligent Platforms, Inc.
|
||||||
|
* Copyright 2009-2011 Freescale Semiconductor, Inc.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <common.h>
|
||||||
|
#include <init.h>
|
||||||
|
#include <driver.h>
|
||||||
|
#include <ns16550.h>
|
||||||
|
#include <net.h>
|
||||||
|
#include <types.h>
|
||||||
|
#include <i2c/i2c.h>
|
||||||
|
#include <partition.h>
|
||||||
|
#include <memory.h>
|
||||||
|
#include <asm/cache.h>
|
||||||
|
#include <asm/fsl_ddr_sdram.h>
|
||||||
|
#include <asm/fsl_law.h>
|
||||||
|
#include <mach/mpc85xx.h>
|
||||||
|
#include <mach/mmu.h>
|
||||||
|
#include <mach/immap_85xx.h>
|
||||||
|
#include <mach/gianfar.h>
|
||||||
|
#include <mach/clock.h>
|
||||||
|
#include <mach/early_udelay.h>
|
||||||
|
|
||||||
|
/* Define attributes for eTSEC1 and eTSEC2 */
|
||||||
|
static struct gfar_info_struct gfar_info[] = {
|
||||||
|
{
|
||||||
|
.phyaddr = 1,
|
||||||
|
.tbiana = 0,
|
||||||
|
.tbicr = 0,
|
||||||
|
.mdiobus_tbi = 0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.phyaddr = 2,
|
||||||
|
.tbiana = 0,
|
||||||
|
.tbicr = 0,
|
||||||
|
.mdiobus_tbi = 0,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
struct i2c_platform_data i2cplat[] = {
|
||||||
|
{ .bitrate = 400000, },
|
||||||
|
{ .bitrate = 400000, },
|
||||||
|
};
|
||||||
|
|
||||||
|
void p1022ds_lbc_early_init(void)
|
||||||
|
{
|
||||||
|
void __iomem *gur = IOMEM(MPC85xx_GUTS_ADDR);
|
||||||
|
void __iomem *lbc = LBC_BASE_ADDR;
|
||||||
|
|
||||||
|
/* Set the local bus monitor timeout value to the maximum */
|
||||||
|
clrsetbits_be32(lbc + FSL_LBC_LBCR_OFFSET, 0xff0f, 0xf);
|
||||||
|
/* Set the pin muxing to enable ETSEC2. */
|
||||||
|
clrbits_be32(gur + MPC85xx_GUTS_PMUXCR2_OFFSET, 0x001f8000);
|
||||||
|
/* Set pmuxcr to allow both i2c1 and i2c2 */
|
||||||
|
setbits_be32(gur + MPC85xx_GUTS_PMUXCR_OFFSET, 0x1000);
|
||||||
|
|
||||||
|
/* Map the boot flash and FPGA */
|
||||||
|
fsl_set_lbc_br(0, BR_PHYS_ADDR(CFG_FLASH_BASE_PHYS) | BR_PS_16 | BR_V);
|
||||||
|
fsl_set_lbc_or(0, 0xf8000ff7);
|
||||||
|
fsl_set_lbc_br(2, BR_PHYS_ADDR(CFG_PIXIS_BASE_PHYS) | BR_PS_8 | BR_V);
|
||||||
|
fsl_set_lbc_or(2, 0xffff8ff7);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void board_eth_init(void)
|
||||||
|
{
|
||||||
|
struct i2c_adapter *adapter;
|
||||||
|
struct i2c_client client;
|
||||||
|
char mac[6];
|
||||||
|
int ret, ix;
|
||||||
|
|
||||||
|
adapter = i2c_get_adapter(1);
|
||||||
|
client.addr = 0x57;
|
||||||
|
client.adapter = adapter;
|
||||||
|
|
||||||
|
for (ix = 0; ix < 2; ix++) {
|
||||||
|
int mac_offset;
|
||||||
|
|
||||||
|
mac_offset = 0x42 + (sizeof(mac) * ix);
|
||||||
|
ret = i2c_read_reg(&client, mac_offset, mac, sizeof(mac));
|
||||||
|
if (ret != sizeof(mac))
|
||||||
|
pr_err("Fail to retrieve MAC address\n");
|
||||||
|
else
|
||||||
|
eth_register_ethaddr(ix, mac);
|
||||||
|
}
|
||||||
|
|
||||||
|
fsl_eth_init(1, &gfar_info[0]);
|
||||||
|
fsl_eth_init(2, &gfar_info[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int p1022ds_devices_init(void)
|
||||||
|
{
|
||||||
|
add_cfi_flash_device(DEVICE_ID_DYNAMIC, CFG_FLASH_BASE, 128 << 20, 0);
|
||||||
|
devfs_add_partition("nor0", 0x7f80000, 0x80000, DEVFS_PARTITION_FIXED,
|
||||||
|
"self0");
|
||||||
|
devfs_add_partition("nor0", 0x7f00000, 0x10000, DEVFS_PARTITION_FIXED,
|
||||||
|
"env0");
|
||||||
|
add_generic_device("i2c-fsl", 0, NULL, I2C1_BASE_ADDR, 0x100,
|
||||||
|
IORESOURCE_MEM, &i2cplat[0]);
|
||||||
|
add_generic_device("i2c-fsl", 1, NULL, I2C2_BASE_ADDR, 0x100,
|
||||||
|
IORESOURCE_MEM, &i2cplat[1]);
|
||||||
|
|
||||||
|
board_eth_init();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
device_initcall(p1022ds_devices_init);
|
||||||
|
|
||||||
|
static struct NS16550_plat serial_plat = {
|
||||||
|
.clock = 0,
|
||||||
|
.shift = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int p1022ds_console_init(void)
|
||||||
|
{
|
||||||
|
barebox_set_model("Freescale P1022DS");
|
||||||
|
barebox_set_hostname("p1022ds");
|
||||||
|
|
||||||
|
serial_plat.clock = fsl_get_bus_freq(0);
|
||||||
|
add_ns16550_device(DEVICE_ID_DYNAMIC, CFG_IMMR + 0x4500, 16,
|
||||||
|
IORESOURCE_MEM_8BIT, &serial_plat);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
console_initcall(p1022ds_console_init);
|
||||||
|
|
||||||
|
static int p1022ds_mem_init(void)
|
||||||
|
{
|
||||||
|
barebox_add_memory_bank("ram0", 0x0, fsl_get_effective_memsize());
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
mem_initcall(p1022ds_mem_init);
|
||||||
|
|
||||||
|
static int p1022ds_board_init_r(void)
|
||||||
|
{
|
||||||
|
void __iomem *fpga = IOMEM(CFG_PIXIS_BASE);
|
||||||
|
const uint32_t flashbase = CFG_BOOT_BLOCK;
|
||||||
|
const u8 flash_esel = e500_find_tlb_idx((void *)flashbase, 1);
|
||||||
|
|
||||||
|
/* Enable SPI */
|
||||||
|
out_8(fpga + 8, (in_8(fpga + 8) & ~(0xc0)) | (0x80));
|
||||||
|
|
||||||
|
/* Map the NAND flash */
|
||||||
|
fsl_set_lbc_br(1, BR_PHYS_ADDR(0xff800000) | BR_PS_8 |
|
||||||
|
(2 << BR_DECC_SHIFT) | BR_MS_FCM | BR_V);
|
||||||
|
fsl_set_lbc_or(1, 0xffff8796);
|
||||||
|
|
||||||
|
/* Flush d-cache and invalidate i-cache of any FLASH data */
|
||||||
|
flush_dcache();
|
||||||
|
invalidate_icache();
|
||||||
|
|
||||||
|
/* invalidate existing TLB entry for flash */
|
||||||
|
e500_disable_tlb(flash_esel);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Remap Boot flash region to caching-inhibited
|
||||||
|
* so that flash can be erased properly.
|
||||||
|
*/
|
||||||
|
e500_set_tlb(1, flashbase, CFG_BOOT_BLOCK_PHYS,
|
||||||
|
MAS3_SX | MAS3_SW | MAS3_SR, MAS2_I | MAS2_G,
|
||||||
|
0, flash_esel, BOOKE_PAGESZ_256M, 1);
|
||||||
|
|
||||||
|
fsl_l2_cache_init();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
core_initcall(p1022ds_board_init_r);
|
|
@ -0,0 +1,14 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2014 GE Intelligent Platforms, Inc.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
void p1022ds_lbc_early_init(void);
|
|
@ -0,0 +1,59 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2011 Freescale Semiconductor, Inc.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <common.h>
|
||||||
|
#include <mach/mmu.h>
|
||||||
|
|
||||||
|
struct fsl_e_tlb_entry tlb_table[] = {
|
||||||
|
/* TLB 0 - for temp stack in cache */
|
||||||
|
FSL_SET_TLB_ENTRY(0, CFG_INIT_RAM_ADDR, CFG_INIT_RAM_ADDR,
|
||||||
|
MAS3_SX | MAS3_SW | MAS3_SR, 0,
|
||||||
|
0, 0, BOOKE_PAGESZ_4K, 0),
|
||||||
|
FSL_SET_TLB_ENTRY(0, CFG_INIT_RAM_ADDR + (4 * 1024),
|
||||||
|
CFG_INIT_RAM_ADDR + (4 * 1024),
|
||||||
|
MAS3_SX | MAS3_SW | MAS3_SR, 0,
|
||||||
|
0, 0, BOOKE_PAGESZ_4K, 0),
|
||||||
|
FSL_SET_TLB_ENTRY(0, CFG_INIT_RAM_ADDR + (8 * 1024),
|
||||||
|
CFG_INIT_RAM_ADDR + (8 * 1024),
|
||||||
|
MAS3_SX | MAS3_SW | MAS3_SR, 0,
|
||||||
|
0, 0, BOOKE_PAGESZ_4K, 0),
|
||||||
|
FSL_SET_TLB_ENTRY(0, CFG_INIT_RAM_ADDR + (12 * 1024),
|
||||||
|
CFG_INIT_RAM_ADDR + (12 * 1024),
|
||||||
|
MAS3_SX | MAS3_SW | MAS3_SR, 0,
|
||||||
|
0, 0, BOOKE_PAGESZ_4K, 0),
|
||||||
|
|
||||||
|
/* TLB 1 */
|
||||||
|
/* *I*** - Covers boot page */
|
||||||
|
FSL_SET_TLB_ENTRY(1, 0xfffff000, 0xfffff000,
|
||||||
|
MAS3_SX | MAS3_SW | MAS3_SR, MAS2_I | MAS2_G,
|
||||||
|
0, 0, BOOKE_PAGESZ_4K, 1),
|
||||||
|
|
||||||
|
/* *I*G* - CCSRBAR */
|
||||||
|
FSL_SET_TLB_ENTRY(1, CFG_CCSRBAR, CFG_CCSRBAR_PHYS,
|
||||||
|
MAS3_SX | MAS3_SW | MAS3_SR, MAS2_I | MAS2_G,
|
||||||
|
0, 1, BOOKE_PAGESZ_1M, 1),
|
||||||
|
|
||||||
|
/* W**G* - Flash/promjet, localbus */
|
||||||
|
/* This will be changed to *I*G* after relocation to RAM. */
|
||||||
|
FSL_SET_TLB_ENTRY(1, CFG_BOOT_BLOCK, CFG_BOOT_BLOCK_PHYS,
|
||||||
|
MAS3_SX | MAS3_SR, MAS2_M | MAS2_W | MAS2_G,
|
||||||
|
0, 2, BOOKE_PAGESZ_256M, 1),
|
||||||
|
|
||||||
|
FSL_SET_TLB_ENTRY(1, CFG_PIXIS_BASE, CFG_PIXIS_BASE_PHYS,
|
||||||
|
MAS3_SX | MAS3_SW | MAS3_SR, MAS2_I | MAS2_G,
|
||||||
|
0, 7, BOOKE_PAGESZ_4K, 1),
|
||||||
|
};
|
||||||
|
|
||||||
|
int num_tlb_entries = ARRAY_SIZE(tlb_table);
|
|
@ -30,8 +30,6 @@ extern unsigned long get_board_sys_clk(unsigned long dummy);
|
||||||
#define CFG_SYS_CLK_FREQ get_board_sys_clk(0)
|
#define CFG_SYS_CLK_FREQ get_board_sys_clk(0)
|
||||||
#define CFG_DDR_CLK_FREQ 66666666
|
#define CFG_DDR_CLK_FREQ 66666666
|
||||||
|
|
||||||
#define CFG_BTB /* toggle branch predition */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Base addresses -- Note these are effective addresses where the
|
* Base addresses -- Note these are effective addresses where the
|
||||||
* actual resources get mapped (not physical addresses)
|
* actual resources get mapped (not physical addresses)
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
#!/bin/sh
|
||||||
|
source /env/config
|
|
@ -0,0 +1,2 @@
|
||||||
|
#!/bin/sh
|
||||||
|
export bootargs="root=/dev/nfs rw ip=bootp"
|
|
@ -83,7 +83,10 @@ struct i2c_platform_data i2cplat = {
|
||||||
static int devices_init(void)
|
static int devices_init(void)
|
||||||
{
|
{
|
||||||
add_cfi_flash_device(DEVICE_ID_DYNAMIC, CFG_FLASH_BASE, 16 << 20, 0);
|
add_cfi_flash_device(DEVICE_ID_DYNAMIC, CFG_FLASH_BASE, 16 << 20, 0);
|
||||||
|
devfs_add_partition("nor0", 0xf60000, 0x8000, DEVFS_PARTITION_FIXED,
|
||||||
|
"env0");
|
||||||
|
devfs_add_partition("nor0", 0xf80000, 0x80000, DEVFS_PARTITION_FIXED,
|
||||||
|
"self0");
|
||||||
add_generic_device("i2c-fsl", 0, NULL, I2C1_BASE_ADDR,
|
add_generic_device("i2c-fsl", 0, NULL, I2C1_BASE_ADDR,
|
||||||
0x100, IORESOURCE_MEM, &i2cplat);
|
0x100, IORESOURCE_MEM, &i2cplat);
|
||||||
add_generic_device("i2c-fsl", 1, NULL, I2C2_BASE_ADDR,
|
add_generic_device("i2c-fsl", 1, NULL, I2C2_BASE_ADDR,
|
||||||
|
@ -92,8 +95,6 @@ static int devices_init(void)
|
||||||
fsl_eth_init(2, &gfar_info[0]);
|
fsl_eth_init(2, &gfar_info[0]);
|
||||||
fsl_eth_init(3, &gfar_info[1]);
|
fsl_eth_init(3, &gfar_info[1]);
|
||||||
|
|
||||||
devfs_add_partition("nor0", 0xf80000, 0x80000, DEVFS_PARTITION_FIXED,
|
|
||||||
"self0");
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,7 +107,7 @@ static struct NS16550_plat serial_plat = {
|
||||||
|
|
||||||
static int p2020_console_init(void)
|
static int p2020_console_init(void)
|
||||||
{
|
{
|
||||||
barebox_set_model("Freescale P2020 RDB");
|
barebox_set_model("Freescale P2020RDB");
|
||||||
barebox_set_hostname("p2020rdb");
|
barebox_set_hostname("p2020rdb");
|
||||||
|
|
||||||
serial_plat.clock = fsl_get_bus_freq(0);
|
serial_plat.clock = fsl_get_bus_freq(0);
|
||||||
|
|
|
@ -18,7 +18,6 @@
|
||||||
#define __CONFIG_H
|
#define __CONFIG_H
|
||||||
|
|
||||||
#define CFG_SYS_CLK_FREQ 66666666
|
#define CFG_SYS_CLK_FREQ 66666666
|
||||||
#define CFG_BTB /* toggle branch prediction */
|
|
||||||
|
|
||||||
#define CFG_FLASH_CFI_WIDTH FLASH_CFI_16BIT
|
#define CFG_FLASH_CFI_WIDTH FLASH_CFI_16BIT
|
||||||
#define CFG_CHIP_SELECTS_PER_CTRL 1
|
#define CFG_CHIP_SELECTS_PER_CTRL 1
|
||||||
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
CONFIG_ARCH_MPC85XX=y
|
||||||
|
CONFIG_P1022DS=y
|
||||||
|
CONFIG_P1022=y
|
||||||
|
CONFIG_LONGHELP=y
|
||||||
|
CONFIG_GLOB=y
|
||||||
|
CONFIG_CMDLINE_EDITING=y
|
||||||
|
CONFIG_AUTO_COMPLETE=y
|
||||||
|
CONFIG_CMD_BOOTM_ZLIB=y
|
||||||
|
CONFIG_CMD_BOOTM_BZLIB=y
|
||||||
|
CONFIG_CMD_BOOTM_VERBOSE=y
|
||||||
|
CONFIG_ZLIB=y
|
||||||
|
CONFIG_BZLIB=y
|
||||||
|
CONFIG_CMD_EDIT=y
|
||||||
|
CONFIG_CMD_SLEEP=y
|
||||||
|
CONFIG_CMD_FLASH=y
|
||||||
|
CONFIG_CMD_RESET=y
|
||||||
|
CONFIG_CMD_GO=y
|
||||||
|
CONFIG_DEFAULT_ENVIRONMENT_GENERIC=n
|
||||||
|
CONFIG_DEFAULT_ENVIRONMENT_PATH="arch/ppc/boards/freescale-p1022ds/env/"
|
||||||
|
CONFIG_CMD_LOADENV=y
|
||||||
|
CONFIG_CMD_PRINTENV=y
|
||||||
|
CONFIG_CMD_SAVEENV=y
|
||||||
|
CONFIG_FSL_ELBC=y
|
||||||
|
CONFIG_DRIVER_CFI=y
|
||||||
|
CONFIG_DRIVER_CFI_AMD=y
|
||||||
|
CONFIG_DRIVER_CFI_INTEL=n
|
||||||
|
CONFIG_DRIVER_CFI_BANK_WIDTH_1=n
|
||||||
|
CONFIG_DRIVER_CFI_BANK_WIDTH_2=y
|
||||||
|
CONFIG_DRIVER_CFI_BANK_WIDTH_4=n
|
||||||
|
CONFIG_MTD=y
|
||||||
|
CONFIG_MTD_WRITE=y
|
||||||
|
CONFIG_MALLOC_SIZE=0x4000000
|
||||||
|
CONFIG_BAUDRATE=115200
|
||||||
|
CONFIG_DRIVER_SERIAL_NS16550=y
|
||||||
|
CONFIG_RELOCATABLE=y
|
||||||
|
CONFIG_DRIVER_NET_GIANFAR=y
|
||||||
|
CONFIG_NET=y
|
||||||
|
CONFIG_NET_PING=y
|
||||||
|
CONFIG_FS_TFTP=y
|
||||||
|
CONFIG_NET_TFTP=y
|
||||||
|
CONFIG_CMD_TFTP=y
|
||||||
|
CONFIG_PING=y
|
||||||
|
CONFIG_I2C=y
|
||||||
|
CONFIG_I2C_IMX=y
|
||||||
|
CONFIG_CMD_I2C=y
|
||||||
|
CONFIG_CMD_MIITOOL=y
|
||||||
|
CONFIG_CMD_EXPORT=y
|
||||||
|
CONFIG_OFTREE=y
|
||||||
|
CONFIG_CMD_OFTREE_PROBE=y
|
||||||
|
CONFIG_CMD_OFTREE=y
|
||||||
|
CONFIG_CMD_BAREBOX_UPDATE=y
|
||||||
|
CONFIG_CMD_IOMEM=y
|
||||||
|
CONFIG_CMD_MEMTEST=y
|
|
@ -6,10 +6,25 @@ CONFIG_GLOB=y
|
||||||
CONFIG_CMDLINE_EDITING=y
|
CONFIG_CMDLINE_EDITING=y
|
||||||
CONFIG_AUTO_COMPLETE=y
|
CONFIG_AUTO_COMPLETE=y
|
||||||
CONFIG_CMD_SLEEP=y
|
CONFIG_CMD_SLEEP=y
|
||||||
|
CONFIG_CMD_PARTITION=y
|
||||||
|
CONFIG_CMD_BOOTM_ZLIB=y
|
||||||
|
CONFIG_CMD_BOOTM_BZLIB=y
|
||||||
|
CONFIG_ZLIB=y
|
||||||
|
CONFIG_BZLIB=y
|
||||||
|
CONFIG_CMD_EDIT=y
|
||||||
|
CONFIG_CMD_EXPORT=y
|
||||||
CONFIG_CMD_FLASH=y
|
CONFIG_CMD_FLASH=y
|
||||||
CONFIG_CMD_RESET=y
|
CONFIG_CMD_RESET=y
|
||||||
CONFIG_CMD_GO=y
|
CONFIG_CMD_GO=y
|
||||||
|
CONFIG_DEFAULT_ENVIRONMENT_GENERIC=n
|
||||||
|
CONFIG_DEFAULT_ENVIRONMENT_PATH="arch/ppc/boards/freescale-p2020rdb/env/"
|
||||||
|
CONFIG_CMD_LOADENV=y
|
||||||
|
CONFIG_CMD_PRINTENV=y
|
||||||
|
CONFIG_CMD_SAVEENV=y
|
||||||
|
CONFIG_CMD_READLINK=y
|
||||||
CONFIG_FSL_ELBC=y
|
CONFIG_FSL_ELBC=y
|
||||||
|
CONFIG_CMD_TIMEOUT=y
|
||||||
|
CONFIG_CMD_UNCOMPRESS=y
|
||||||
CONFIG_DRIVER_CFI=y
|
CONFIG_DRIVER_CFI=y
|
||||||
CONFIG_DRIVER_CFI_AMD=y
|
CONFIG_DRIVER_CFI_AMD=y
|
||||||
CONFIG_DRIVER_CFI_INTEL=n
|
CONFIG_DRIVER_CFI_INTEL=n
|
||||||
|
@ -17,7 +32,7 @@ CONFIG_DRIVER_CFI_BANK_WIDTH_1=n
|
||||||
CONFIG_DRIVER_CFI_BANK_WIDTH_2=y
|
CONFIG_DRIVER_CFI_BANK_WIDTH_2=y
|
||||||
CONFIG_DRIVER_CFI_BANK_WIDTH_4=n
|
CONFIG_DRIVER_CFI_BANK_WIDTH_4=n
|
||||||
CONFIG_MTD=y
|
CONFIG_MTD=y
|
||||||
CONFIG_MALLOC_SIZE=0x200000
|
CONFIG_MALLOC_SIZE=0x2800000
|
||||||
CONFIG_BAUDRATE=115200
|
CONFIG_BAUDRATE=115200
|
||||||
CONFIG_DRIVER_SERIAL_NS16550=y
|
CONFIG_DRIVER_SERIAL_NS16550=y
|
||||||
CONFIG_RELOCATABLE=y
|
CONFIG_RELOCATABLE=y
|
||||||
|
@ -34,3 +49,7 @@ CONFIG_CMD_I2C=y
|
||||||
CONFIG_CMD_MIITOOL=y
|
CONFIG_CMD_MIITOOL=y
|
||||||
CONFIG_CMD_MEMTEST=y
|
CONFIG_CMD_MEMTEST=y
|
||||||
CONFIG_CMD_IOMEM=y
|
CONFIG_CMD_IOMEM=y
|
||||||
|
CONFIG_CMD_VERSION=n
|
||||||
|
CONFIG_OFTREE=y
|
||||||
|
CONFIG_CMD_OFTREE_PROBE=y
|
||||||
|
CONFIG_CMD_OFTREE=y
|
|
@ -172,7 +172,7 @@ _start_e500:
|
||||||
mtspr HID1,r0
|
mtspr HID1,r0
|
||||||
|
|
||||||
/* Enable Branch Prediction */
|
/* Enable Branch Prediction */
|
||||||
#if defined(CFG_BTB)
|
#if defined(CONFIG_BTB)
|
||||||
lis r0,BUCSR_ENABLE@h
|
lis r0,BUCSR_ENABLE@h
|
||||||
ori r0,r0,BUCSR_ENABLE@l
|
ori r0,r0,BUCSR_ENABLE@l
|
||||||
mtspr SPRN_BUCSR,r0
|
mtspr SPRN_BUCSR,r0
|
||||||
|
|
|
@ -1,2 +1,4 @@
|
||||||
obj-y += main.o util.o ctrl_regs.o options.o lc_common_dimm_params.o
|
obj-y += main.o util.o ctrl_regs.o options.o lc_common_dimm_params.o
|
||||||
obj-$(CONFIG_FSL_DDR2) += ddr2_dimm_params.o ddr2_setctrl.o
|
obj-y += ddr_setctrl.o
|
||||||
|
obj-$(CONFIG_FSL_DDR2) += ddr2_dimm_params.o
|
||||||
|
obj-$(CONFIG_FSL_DDR3) += ddr3_dimm_params.o
|
||||||
|
|
|
@ -23,6 +23,7 @@ struct common_timing_params_s {
|
||||||
uint32_t tRRD_ps; /* maximum = 63750 ps */
|
uint32_t tRRD_ps; /* maximum = 63750 ps */
|
||||||
uint32_t tRC_ps; /* maximum = 254 ns + .75 ns = 254750 ps */
|
uint32_t tRC_ps; /* maximum = 254 ns + .75 ns = 254750 ps */
|
||||||
uint32_t refresh_rate_ps;
|
uint32_t refresh_rate_ps;
|
||||||
|
uint32_t extended_op_srt;
|
||||||
uint32_t tIS_ps; /* byte 32, spd->ca_setup */
|
uint32_t tIS_ps; /* byte 32, spd->ca_setup */
|
||||||
uint32_t tIH_ps; /* byte 33, spd->ca_hold */
|
uint32_t tIH_ps; /* byte 33, spd->ca_hold */
|
||||||
uint32_t tDS_ps; /* byte 34, spd->data_setup */
|
uint32_t tDS_ps; /* byte 34, spd->data_setup */
|
||||||
|
@ -36,6 +37,7 @@ struct common_timing_params_s {
|
||||||
uint32_t additive_latency;
|
uint32_t additive_latency;
|
||||||
uint32_t all_DIMMs_burst_lengths_bitmask;
|
uint32_t all_DIMMs_burst_lengths_bitmask;
|
||||||
uint32_t all_DIMMs_registered;
|
uint32_t all_DIMMs_registered;
|
||||||
|
uint32_t all_DIMMs_unbuffered;
|
||||||
uint32_t all_DIMMs_ECC_capable;
|
uint32_t all_DIMMs_ECC_capable;
|
||||||
uint64_t total_mem;
|
uint64_t total_mem;
|
||||||
uint64_t base_address;
|
uint64_t base_address;
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Generic driver for Freescale DDR2 memory controller.
|
* Generic driver for Freescale DDR2/DDR3 memory controller.
|
||||||
* Based on code from spd_sdram.c
|
* Based on code from spd_sdram.c
|
||||||
* Author: James Yang [at freescale.com]
|
* Author: James Yang [at freescale.com]
|
||||||
*/
|
*/
|
||||||
|
@ -17,6 +17,33 @@
|
||||||
#include <asm/fsl_ddr_sdram.h>
|
#include <asm/fsl_ddr_sdram.h>
|
||||||
#include "ddr.h"
|
#include "ddr.h"
|
||||||
|
|
||||||
|
static uint32_t compute_cas_write_latency(void)
|
||||||
|
{
|
||||||
|
uint32_t cwl;
|
||||||
|
const uint32_t mclk_ps = get_memory_clk_period_ps();
|
||||||
|
|
||||||
|
if (mclk_ps >= 2500)
|
||||||
|
cwl = 5;
|
||||||
|
else if (mclk_ps >= 1875)
|
||||||
|
cwl = 6;
|
||||||
|
else if (mclk_ps >= 1500)
|
||||||
|
cwl = 7;
|
||||||
|
else if (mclk_ps >= 1250)
|
||||||
|
cwl = 8;
|
||||||
|
else if (mclk_ps >= 1070)
|
||||||
|
cwl = 9;
|
||||||
|
else if (mclk_ps >= 935)
|
||||||
|
cwl = 10;
|
||||||
|
else if (mclk_ps >= 833)
|
||||||
|
cwl = 11;
|
||||||
|
else if (mclk_ps >= 750)
|
||||||
|
cwl = 12;
|
||||||
|
else
|
||||||
|
cwl = 12;
|
||||||
|
|
||||||
|
return cwl;
|
||||||
|
}
|
||||||
|
|
||||||
static void set_csn_config(int dimm_number, int i,
|
static void set_csn_config(int dimm_number, int i,
|
||||||
struct fsl_ddr_cfg_regs_s *ddr,
|
struct fsl_ddr_cfg_regs_s *ddr,
|
||||||
const struct memctl_options_s *popts,
|
const struct memctl_options_s *popts,
|
||||||
|
@ -81,40 +108,91 @@ static void set_csn_config(int dimm_number, int i,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void set_timing_cfg_0(struct fsl_ddr_cfg_regs_s *ddr,
|
static void set_timing_cfg_0(struct fsl_ddr_cfg_regs_s *ddr,
|
||||||
const struct memctl_options_s *popts)
|
const struct memctl_options_s *popts,
|
||||||
|
const struct dimm_params_s *dimm)
|
||||||
{
|
{
|
||||||
uint32_t trwt_mclk = 0;
|
uint32_t trwt_mclk = 0, twrt_mclk = 0, act_pd_exit_mclk,
|
||||||
|
pre_pd_exit_mclk, taxpd_mclk, tmrd_mclk, txp,
|
||||||
|
data_rate = fsl_get_ddr_freq(0);
|
||||||
|
|
||||||
if (popts->trwt_override)
|
if (popts->sdram_type == SDRAM_TYPE_DDR2) {
|
||||||
trwt_mclk = popts->trwt;
|
act_pd_exit_mclk = popts->txard;
|
||||||
|
pre_pd_exit_mclk = popts->txp;
|
||||||
|
taxpd_mclk = popts->taxpd;
|
||||||
|
tmrd_mclk = popts->tmrd;
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* tXARD is not part of the DDR3 specification, use the
|
||||||
|
* parameter txp instead of it. That is:
|
||||||
|
* txp=max(3nCK, 7.5ns). As well, use tAXPD=1.
|
||||||
|
*/
|
||||||
|
txp = max_t(uint32_t, (get_memory_clk_period_ps() * 3), 7500);
|
||||||
|
data_rate = fsl_get_ddr_freq(0);
|
||||||
|
tmrd_mclk = 4;
|
||||||
|
|
||||||
|
/* for faster clock, need more time for data setup */
|
||||||
|
if (popts->trwt_override)
|
||||||
|
trwt_mclk = popts->trwt;
|
||||||
|
else if (data_rate / 1000000 > 1800)
|
||||||
|
trwt_mclk = 2;
|
||||||
|
else
|
||||||
|
trwt_mclk = 0;
|
||||||
|
|
||||||
|
if (data_rate / 1000000 > 1150)
|
||||||
|
twrt_mclk = 1;
|
||||||
|
else
|
||||||
|
twrt_mclk = 0;
|
||||||
|
|
||||||
|
taxpd_mclk = 1;
|
||||||
|
if (popts->dynamic_power == 0) {
|
||||||
|
act_pd_exit_mclk = 1;
|
||||||
|
pre_pd_exit_mclk = 1;
|
||||||
|
} else {
|
||||||
|
/* act_pd_exit_mclk = tXARD, see above */
|
||||||
|
act_pd_exit_mclk = picos_to_mclk(txp);
|
||||||
|
/* Mode register MR0[A12] is '1' - fast exit */
|
||||||
|
pre_pd_exit_mclk = act_pd_exit_mclk;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ddr->timing_cfg_0 = (((trwt_mclk & 0x3) << 30)
|
ddr->timing_cfg_0 = (((trwt_mclk & 0x3) << 30)
|
||||||
| ((popts->txard & 0x7) << 20)
|
| ((twrt_mclk & 0x3) << 28)
|
||||||
| ((popts->txp & 0xF) << 16)
|
| ((act_pd_exit_mclk & 0xf) << 20)
|
||||||
| ((popts->taxpd & 0xf) << 8)
|
| ((pre_pd_exit_mclk & 0xf) << 16)
|
||||||
| ((popts->tmrd & 0xf) << 0));
|
| ((taxpd_mclk & 0xf) << 8)
|
||||||
|
| ((tmrd_mclk & 0x1f) << 0)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void set_timing_cfg_3(struct fsl_ddr_cfg_regs_s *ddr,
|
static void set_timing_cfg_3(struct fsl_ddr_cfg_regs_s *ddr,
|
||||||
|
const struct memctl_options_s *popts,
|
||||||
const struct common_timing_params_s *dimm,
|
const struct common_timing_params_s *dimm,
|
||||||
uint32_t cas_latency)
|
uint32_t cas_latency, uint32_t additive_latency)
|
||||||
{
|
{
|
||||||
uint32_t ext_pretoact, ext_acttopre, ext_acttorw, ext_refrec;
|
uint32_t ext_pretoact, ext_acttopre, ext_acttorw, ext_refrec, ext_wrrec;
|
||||||
|
|
||||||
ext_pretoact = picos_to_mclk(dimm->tRP_ps) >> 4;
|
ext_pretoact = picos_to_mclk(dimm->tRP_ps) >> 4;
|
||||||
ext_acttopre = picos_to_mclk(dimm->tRAS_ps) >> 4;
|
ext_acttopre = picos_to_mclk(dimm->tRAS_ps) >> 4;
|
||||||
ext_acttorw = picos_to_mclk(dimm->tRCD_ps) >> 4;
|
ext_acttorw = picos_to_mclk(dimm->tRCD_ps) >> 4;
|
||||||
cas_latency = ((cas_latency << 1) - 1) >> 4;
|
cas_latency = ((cas_latency << 1) - 1) >> 4;
|
||||||
|
additive_latency = additive_latency >> 4;
|
||||||
ext_refrec = (picos_to_mclk(dimm->tRFC_ps) - 8) >> 4;
|
ext_refrec = (picos_to_mclk(dimm->tRFC_ps) - 8) >> 4;
|
||||||
|
/* ext_wrrec only deals with 16 clock and above, or 14 with OTF */
|
||||||
|
ext_wrrec = (picos_to_mclk(dimm->tWR_ps) +
|
||||||
|
(popts->otf_burst_chop_en ? 2 : 0)) >> 4;
|
||||||
|
|
||||||
ddr->timing_cfg_3 = (((ext_pretoact & 0x1) << 28)
|
ddr->timing_cfg_3 = (((ext_pretoact & 0x1) << 28)
|
||||||
| ((ext_acttopre & 0x2) << 24)
|
| ((ext_acttopre & 0x3) << 24)
|
||||||
| ((ext_acttorw & 0x1) << 22)
|
| ((ext_acttorw & 0x1) << 22)
|
||||||
| ((ext_refrec & 0x1F) << 16)
|
| ((ext_refrec & 0x1F) << 16)
|
||||||
| ((cas_latency & 0x3) << 12));
|
| ((cas_latency & 0x3) << 12)
|
||||||
|
| ((additive_latency & 0x1) << 10)
|
||||||
|
| ((ext_wrrec & 0x1) << 8)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void set_timing_cfg_1(struct fsl_ddr_cfg_regs_s *ddr,
|
static void set_timing_cfg_1(struct fsl_ddr_cfg_regs_s *ddr,
|
||||||
|
const struct memctl_options_s *popts,
|
||||||
const struct common_timing_params_s *dimm,
|
const struct common_timing_params_s *dimm,
|
||||||
uint32_t cas_latency)
|
uint32_t cas_latency)
|
||||||
{
|
{
|
||||||
|
@ -152,10 +230,19 @@ static void set_timing_cfg_1(struct fsl_ddr_cfg_regs_s *ddr,
|
||||||
wrrec_mclk = picos_to_mclk(dimm->tWR_ps);
|
wrrec_mclk = picos_to_mclk(dimm->tWR_ps);
|
||||||
if (wrrec_mclk <= 16)
|
if (wrrec_mclk <= 16)
|
||||||
wrrec_mclk = wrrec_table[wrrec_mclk - 1];
|
wrrec_mclk = wrrec_table[wrrec_mclk - 1];
|
||||||
|
if (popts->otf_burst_chop_en)
|
||||||
|
wrrec_mclk += 2;
|
||||||
|
|
||||||
wrtord_mclk = picos_to_mclk(dimm->tWTR_ps);
|
wrtord_mclk = picos_to_mclk(dimm->tWTR_ps);
|
||||||
if (wrtord_mclk < 2)
|
if (popts->sdram_type == SDRAM_TYPE_DDR2) {
|
||||||
wrtord_mclk = 2;
|
wrtord_mclk = max_t(uint32_t, wrtord_mclk, 2);
|
||||||
|
} else {
|
||||||
|
wrtord_mclk = max_t(uint32_t, wrtord_mclk, 4);
|
||||||
|
acttoact_mclk = max_t(uint32_t, acttoact_mclk, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (popts->otf_burst_chop_en)
|
||||||
|
wrtord_mclk += 2;
|
||||||
|
|
||||||
ddr->timing_cfg_1 = (((pretoact_mclk & 0x0F) << 28)
|
ddr->timing_cfg_1 = (((pretoact_mclk & 0x0F) << 28)
|
||||||
| ((acttopre_mclk & 0x0F) << 24)
|
| ((acttopre_mclk & 0x0F) << 24)
|
||||||
|
@ -176,11 +263,16 @@ static void set_timing_cfg_2(struct fsl_ddr_cfg_regs_s *ddr,
|
||||||
|
|
||||||
cpo = popts->cpo_override;
|
cpo = popts->cpo_override;
|
||||||
rd_to_pre = picos_to_mclk(dimm->tRTP_ps);
|
rd_to_pre = picos_to_mclk(dimm->tRTP_ps);
|
||||||
if (rd_to_pre < 2)
|
if (popts->sdram_type == SDRAM_TYPE_DDR2) {
|
||||||
rd_to_pre = 2;
|
cas_latency = cas_latency - 1;
|
||||||
|
rd_to_pre = max_t(uint32_t, rd_to_pre, 2);
|
||||||
|
} else {
|
||||||
|
cas_latency = compute_cas_write_latency();
|
||||||
|
rd_to_pre = max_t(uint32_t, rd_to_pre, 4);
|
||||||
|
}
|
||||||
|
|
||||||
if (additive_latency)
|
if (popts->otf_burst_chop_en)
|
||||||
rd_to_pre += additive_latency;
|
rd_to_pre += 2;
|
||||||
|
|
||||||
wr_data_delay = popts->write_data_delay;
|
wr_data_delay = popts->write_data_delay;
|
||||||
cke_pls = picos_to_mclk(popts->tCKE_clock_pulse_width_ps);
|
cke_pls = picos_to_mclk(popts->tCKE_clock_pulse_width_ps);
|
||||||
|
@ -188,7 +280,7 @@ static void set_timing_cfg_2(struct fsl_ddr_cfg_regs_s *ddr,
|
||||||
|
|
||||||
ddr->timing_cfg_2 = (((additive_latency & 0xf) << 28)
|
ddr->timing_cfg_2 = (((additive_latency & 0xf) << 28)
|
||||||
| ((cpo & 0x1f) << 23)
|
| ((cpo & 0x1f) << 23)
|
||||||
| (((cas_latency - 1) & 0xf) << 19)
|
| ((cas_latency & 0xf) << 19)
|
||||||
| ((rd_to_pre & 7) << 13)
|
| ((rd_to_pre & 7) << 13)
|
||||||
| ((wr_data_delay & 7) << 10)
|
| ((wr_data_delay & 7) << 10)
|
||||||
| ((cke_pls & 0x7) << 6)
|
| ((cke_pls & 0x7) << 6)
|
||||||
|
@ -199,7 +291,8 @@ static void set_ddr_sdram_cfg(struct fsl_ddr_cfg_regs_s *ddr,
|
||||||
const struct memctl_options_s *popts,
|
const struct memctl_options_s *popts,
|
||||||
const struct common_timing_params_s *dimm)
|
const struct common_timing_params_s *dimm)
|
||||||
{
|
{
|
||||||
uint32_t mem_en, sren, ecc_en, sdram_type, dyn_pwr, dbw, twoT_en, hse;
|
uint32_t mem_en, sren, ecc_en, sdram_type, dyn_pwr, dbw, twoT_en, hse,
|
||||||
|
threet_en, eight_be = 0;
|
||||||
|
|
||||||
mem_en = 1;
|
mem_en = 1;
|
||||||
sren = popts->self_refresh_in_sleep;
|
sren = popts->self_refresh_in_sleep;
|
||||||
|
@ -208,15 +301,16 @@ static void set_ddr_sdram_cfg(struct fsl_ddr_cfg_regs_s *ddr,
|
||||||
else
|
else
|
||||||
ecc_en = 0;
|
ecc_en = 0;
|
||||||
|
|
||||||
if (popts->sdram_type)
|
sdram_type = popts->sdram_type;
|
||||||
sdram_type = popts->sdram_type;
|
|
||||||
else
|
|
||||||
sdram_type = FSL_SDRAM_TYPE;
|
|
||||||
|
|
||||||
twoT_en = popts->twoT_en;
|
twoT_en = popts->twoT_en;
|
||||||
dyn_pwr = popts->dynamic_power;
|
dyn_pwr = popts->dynamic_power;
|
||||||
dbw = popts->data_bus_width;
|
dbw = popts->data_bus_width;
|
||||||
hse = popts->half_strength_driver_enable;
|
hse = popts->half_strength_driver_enable;
|
||||||
|
threet_en = popts->threet_en;
|
||||||
|
|
||||||
|
if (sdram_type == SDRAM_TYPE_DDR3)
|
||||||
|
if ((popts->burst_length == DDR_BL8) || (dbw == 1))
|
||||||
|
eight_be = 1;
|
||||||
|
|
||||||
ddr->ddr_sdram_cfg = (((mem_en & 0x1) << 31)
|
ddr->ddr_sdram_cfg = (((mem_en & 0x1) << 31)
|
||||||
| ((sren & 0x1) << 30)
|
| ((sren & 0x1) << 30)
|
||||||
|
@ -224,6 +318,8 @@ static void set_ddr_sdram_cfg(struct fsl_ddr_cfg_regs_s *ddr,
|
||||||
| ((sdram_type & 0x7) << 24)
|
| ((sdram_type & 0x7) << 24)
|
||||||
| ((dyn_pwr & 0x1) << 21)
|
| ((dyn_pwr & 0x1) << 21)
|
||||||
| ((dbw & 0x3) << 19)
|
| ((dbw & 0x3) << 19)
|
||||||
|
| ((eight_be & 0x1) << 18)
|
||||||
|
| ((threet_en & 0x1) << 16)
|
||||||
| ((twoT_en & 0x1) << 15)
|
| ((twoT_en & 0x1) << 15)
|
||||||
| ((hse & 0x1) << 3));
|
| ((hse & 0x1) << 3));
|
||||||
}
|
}
|
||||||
|
@ -232,7 +328,8 @@ static void set_ddr_sdram_cfg_2(struct fsl_ddr_cfg_regs_s *ddr,
|
||||||
const struct memctl_options_s *popts)
|
const struct memctl_options_s *popts)
|
||||||
{
|
{
|
||||||
struct ddr_board_info_s *bi = popts->board_info;
|
struct ddr_board_info_s *bi = popts->board_info;
|
||||||
uint32_t i, dll_rst_dis, dqs_cfg, odt_cfg = 0, num_pr, d_init = 0;
|
uint32_t i, dll_rst_dis, dqs_cfg, odt_cfg = 0, num_pr, d_init = 0,
|
||||||
|
obc_cfg = 0, x4_en, md_en = 0, rcw_en = 0;
|
||||||
|
|
||||||
dll_rst_dis = popts->dll_rst_dis;
|
dll_rst_dis = popts->dll_rst_dis;
|
||||||
dqs_cfg = popts->DQS_config;
|
dqs_cfg = popts->DQS_config;
|
||||||
|
@ -256,11 +353,48 @@ static void set_ddr_sdram_cfg_2(struct fsl_ddr_cfg_regs_s *ddr,
|
||||||
ddr->ddr_data_init = popts->data_init;
|
ddr->ddr_data_init = popts->data_init;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (popts->sdram_type == SDRAM_TYPE_DDR3) {
|
||||||
|
obc_cfg = popts->otf_burst_chop_en;
|
||||||
|
md_en = popts->mirrored_dimm;
|
||||||
|
}
|
||||||
|
|
||||||
|
x4_en = popts->x4_en ? 1 : 0;
|
||||||
|
|
||||||
ddr->ddr_sdram_cfg_2 = (((dll_rst_dis & 0x1) << 29)
|
ddr->ddr_sdram_cfg_2 = (((dll_rst_dis & 0x1) << 29)
|
||||||
| ((dqs_cfg & 0x3) << 26)
|
| ((dqs_cfg & 0x3) << 26)
|
||||||
| ((odt_cfg & 0x3) << 21)
|
| ((odt_cfg & 0x3) << 21)
|
||||||
| ((num_pr & 0xf) << 12)
|
| ((num_pr & 0xf) << 12)
|
||||||
| ((d_init & 0x1) << 4));
|
| (x4_en << 10)
|
||||||
|
| ((obc_cfg & 0x1) << 6)
|
||||||
|
| ((d_init & 0x1) << 4)
|
||||||
|
| ((rcw_en & 0x1) << 2)
|
||||||
|
| ((md_en & 0x1) << 0)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void set_ddr_sdram_mode_2(struct fsl_ddr_cfg_regs_s *ddr,
|
||||||
|
const struct memctl_options_s *popts,
|
||||||
|
const struct common_timing_params_s *dimm)
|
||||||
|
{
|
||||||
|
uint16_t esdmode2;
|
||||||
|
uint32_t rtt_wr, srt = 0, cwl;
|
||||||
|
|
||||||
|
cwl = compute_cas_write_latency() - 5;
|
||||||
|
|
||||||
|
if (popts->rtt_override)
|
||||||
|
rtt_wr = popts->rtt_wr_override_value;
|
||||||
|
else
|
||||||
|
rtt_wr = popts->cs_local_opts[0].odt_rtt_wr;
|
||||||
|
|
||||||
|
if (dimm->extended_op_srt)
|
||||||
|
srt = dimm->extended_op_srt;
|
||||||
|
|
||||||
|
esdmode2 = (((rtt_wr & 0x3) << 9)
|
||||||
|
| ((srt & 0x1) << 7)
|
||||||
|
| ((cwl & 0x7) << 3)
|
||||||
|
);
|
||||||
|
|
||||||
|
ddr->ddr_sdram_mode_2 = (esdmode2 & 0xffff) << 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -277,12 +411,107 @@ set_ddr_sdram_interval(struct fsl_ddr_cfg_regs_s *ddr,
|
||||||
ddr->ddr_sdram_interval = (((refint & 0xFFFF) << 16)
|
ddr->ddr_sdram_interval = (((refint & 0xFFFF) << 16)
|
||||||
| ((bstopre & 0x3FFF) << 0));
|
| ((bstopre & 0x3FFF) << 0));
|
||||||
}
|
}
|
||||||
|
void set_ddr3_sdram_mode(struct fsl_ddr_cfg_regs_s *ddr,
|
||||||
static void set_ddr_sdram_mode(struct fsl_ddr_cfg_regs_s *ddr,
|
|
||||||
const struct memctl_options_s *popts,
|
const struct memctl_options_s *popts,
|
||||||
const struct common_timing_params_s *dimm,
|
const struct common_timing_params_s *dimm,
|
||||||
uint32_t cas_latency,
|
uint32_t cas_latency, uint32_t additive_latency)
|
||||||
uint32_t additive_latency)
|
{
|
||||||
|
uint16_t esdmode, sdmode;
|
||||||
|
/* Mode Register - MR1 */
|
||||||
|
uint32_t rtt, al;
|
||||||
|
/* Mode Register - MR0 */
|
||||||
|
uint32_t dll_on, wr = 0, dll_rst, mode, caslat = 4, bt, bl, wr_mclk;
|
||||||
|
/*
|
||||||
|
* DDR_SDRAM_MODE doesn't support 9,11,13,15
|
||||||
|
* Please refer JEDEC Standard No. 79-3E for Mode Register MR0
|
||||||
|
* for this table
|
||||||
|
*/
|
||||||
|
static const u8 wr_table[] = {1, 2, 3, 4, 5, 5, 6, 6, 7, 7, 0, 0};
|
||||||
|
uint8_t cas_latency_table[] = { /* From 5 to 16 clocks */
|
||||||
|
0x2, 0x4, 0x6, 0x8, 0xa, 0xc, 0xe, 0x1, 0x3, 0x5, 0x7, 0x9,
|
||||||
|
};
|
||||||
|
const unsigned int mclk_ps = get_memory_clk_period_ps();
|
||||||
|
|
||||||
|
if (popts->rtt_override)
|
||||||
|
rtt = popts->rtt_override_value;
|
||||||
|
else
|
||||||
|
rtt = popts->cs_local_opts[0].odt_rtt_norm;
|
||||||
|
|
||||||
|
if (additive_latency == (cas_latency - 1))
|
||||||
|
al = 1;
|
||||||
|
else if (additive_latency == (cas_latency - 2))
|
||||||
|
al = 2;
|
||||||
|
else
|
||||||
|
al = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The esdmode value will also be used for writing
|
||||||
|
* MR1 during write leveling for DDR3, although the
|
||||||
|
* bits specifically related to the write leveling
|
||||||
|
* scheme will be handled automatically by the DDR
|
||||||
|
* controller. So wrlvl_en is set to 0 here.
|
||||||
|
*/
|
||||||
|
esdmode = (((rtt & 0x4) << 7)
|
||||||
|
| ((rtt & 0x2) << 5)
|
||||||
|
| ((al & 0x3) << 3)
|
||||||
|
| ((rtt & 0x1) << 2)
|
||||||
|
);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* DLL control for precharge PD
|
||||||
|
* 0=slow exit DLL off (tXPDLL)
|
||||||
|
* 1=fast exit DLL on (tXP)
|
||||||
|
*/
|
||||||
|
dll_on = 1;
|
||||||
|
|
||||||
|
wr_mclk = (dimm->tWR_ps + mclk_ps - 1) / mclk_ps;
|
||||||
|
if (wr_mclk <= 16)
|
||||||
|
wr = wr_table[wr_mclk - 5];
|
||||||
|
|
||||||
|
dll_rst = 0; /* dll no reset */
|
||||||
|
mode = 0; /* normal mode */
|
||||||
|
|
||||||
|
/* look up table to get the cas latency bits */
|
||||||
|
if (cas_latency >= 5 && cas_latency <= 16)
|
||||||
|
caslat = cas_latency_table[cas_latency - 5];
|
||||||
|
|
||||||
|
/* BT: Burst Type (0=Nibble Sequential, 1=Interleaved) */
|
||||||
|
bt = 0;
|
||||||
|
|
||||||
|
switch (popts->burst_length) {
|
||||||
|
case DDR_BL8:
|
||||||
|
bl = 0;
|
||||||
|
break;
|
||||||
|
case DDR_OTF:
|
||||||
|
bl = 1;
|
||||||
|
break;
|
||||||
|
case DDR_BC4:
|
||||||
|
bl = 2;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
bl = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
sdmode = (((dll_on & 0x1) << 12)
|
||||||
|
| ((wr & 0x7) << 9)
|
||||||
|
| ((dll_rst & 0x1) << 8)
|
||||||
|
| ((mode & 0x1) << 7)
|
||||||
|
| (((caslat >> 1) & 0x7) << 4)
|
||||||
|
| ((bt & 0x1) << 3)
|
||||||
|
| ((caslat & 1) << 2)
|
||||||
|
| ((bl & 0x3) << 0)
|
||||||
|
);
|
||||||
|
|
||||||
|
ddr->ddr_sdram_mode = (((esdmode & 0xffff) << 16)
|
||||||
|
| ((sdmode & 0xffff) << 0)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_ddr2_sdram_mode(struct fsl_ddr_cfg_regs_s *ddr,
|
||||||
|
const struct memctl_options_s *popts,
|
||||||
|
const struct common_timing_params_s *dimm,
|
||||||
|
uint32_t cas_latency, uint32_t additive_latency)
|
||||||
{
|
{
|
||||||
uint16_t esdmode, sdmode;
|
uint16_t esdmode, sdmode;
|
||||||
uint32_t dqs_en, rtt, al, wr, bl;
|
uint32_t dqs_en, rtt, al, wr, bl;
|
||||||
|
@ -342,6 +571,19 @@ static void set_ddr_sdram_mode(struct fsl_ddr_cfg_regs_s *ddr,
|
||||||
| ((sdmode & 0xFFFF) << 0));
|
| ((sdmode & 0xFFFF) << 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void set_ddrx_sdram_mode(struct fsl_ddr_cfg_regs_s *ddr,
|
||||||
|
const struct memctl_options_s *popts,
|
||||||
|
const struct common_timing_params_s *dimm,
|
||||||
|
uint32_t cas_latency, uint32_t additive_latency)
|
||||||
|
{
|
||||||
|
if (popts->sdram_type == SDRAM_TYPE_DDR2)
|
||||||
|
set_ddr2_sdram_mode(ddr, popts, dimm, cas_latency,
|
||||||
|
additive_latency);
|
||||||
|
else
|
||||||
|
set_ddr3_sdram_mode(ddr, popts, dimm, cas_latency,
|
||||||
|
additive_latency);
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t check_fsl_memctl_config_regs(const struct fsl_ddr_cfg_regs_s *ddr)
|
uint32_t check_fsl_memctl_config_regs(const struct fsl_ddr_cfg_regs_s *ddr)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
@ -355,6 +597,98 @@ uint32_t check_fsl_memctl_config_regs(const struct fsl_ddr_cfg_regs_s *ddr)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void set_timing_cfg_4(struct fsl_ddr_cfg_regs_s *ddr,
|
||||||
|
const struct memctl_options_s *popts)
|
||||||
|
{
|
||||||
|
uint32_t rrt = 0, wwt = 0, dll_lock = 1;
|
||||||
|
|
||||||
|
if (popts->burst_length != DDR_BL8)
|
||||||
|
rrt = wwt = 2;
|
||||||
|
|
||||||
|
ddr->timing_cfg_4 = (((rrt & 0xf) << 20)
|
||||||
|
| ((wwt & 0xf) << 16)
|
||||||
|
| (dll_lock & 0x3)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void set_timing_cfg_5(struct fsl_ddr_cfg_regs_s *ddr,
|
||||||
|
const struct memctl_options_s *popts,
|
||||||
|
uint32_t cas_latency)
|
||||||
|
{
|
||||||
|
uint32_t rodt_on, rodt_off = 4, wodt_on = 1, wodt_off = 4;
|
||||||
|
|
||||||
|
/* rodt_on = timing_cfg_1[caslat] - timing_cfg_2[wrlat] + 1 */
|
||||||
|
rodt_on = cas_latency - ((ddr->timing_cfg_2 & 0x00780000) >> 19) + 1;
|
||||||
|
|
||||||
|
ddr->timing_cfg_5 = (((rodt_on & 0x1f) << 24)
|
||||||
|
| ((rodt_off & 0x7) << 20)
|
||||||
|
| ((wodt_on & 0x1f) << 12)
|
||||||
|
| ((wodt_off & 0x7) << 8)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void set_ddr_zq_cntl(struct fsl_ddr_cfg_regs_s *ddr, uint32_t zq_en)
|
||||||
|
{
|
||||||
|
uint32_t zqinit = 0, zqoper = 0, zqcs = 0;
|
||||||
|
|
||||||
|
if (zq_en) {
|
||||||
|
zqinit = 9;
|
||||||
|
zqoper = 8;
|
||||||
|
zqcs = 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
ddr->ddr_zq_cntl = (((zq_en & 0x1) << 31)
|
||||||
|
| ((zqinit & 0xf) << 24)
|
||||||
|
| ((zqoper & 0xf) << 16)
|
||||||
|
| ((zqcs & 0xf) << 8)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void set_ddr_wrlvl_cntl(struct fsl_ddr_cfg_regs_s *ddr,
|
||||||
|
uint32_t wrlvl_en, const struct memctl_options_s *popts)
|
||||||
|
{
|
||||||
|
uint32_t wrlvl_mrd = 0, wrlvl_odten = 0, wrlvl_dqsen = 0,
|
||||||
|
wrlvl_wlr = 0, wrlvl_start = 0, wrlvl_smpl = 0;
|
||||||
|
|
||||||
|
/* Enable write leveling for DDR3 due to fly-by topology */
|
||||||
|
if (wrlvl_en) {
|
||||||
|
wrlvl_mrd = 0x6;
|
||||||
|
wrlvl_odten = 0x7;
|
||||||
|
wrlvl_dqsen = 0x5;
|
||||||
|
/*
|
||||||
|
* Write leveling sample time at least need 6 clocks
|
||||||
|
* higher than tWLO to allow enough time for progagation
|
||||||
|
* delay and sampling the prime data bits.
|
||||||
|
*/
|
||||||
|
wrlvl_smpl = 0xf;
|
||||||
|
/*
|
||||||
|
* Write leveling repetition time. At least tWLO + 6 clocks
|
||||||
|
* Set it to 64
|
||||||
|
*/
|
||||||
|
wrlvl_wlr = 0x6;
|
||||||
|
/*
|
||||||
|
* Write leveling start time
|
||||||
|
* The value use for the DQS_ADJUST for the first sample
|
||||||
|
* when write leveling is enabled. It probably needs to be
|
||||||
|
* overriden per platform.
|
||||||
|
*/
|
||||||
|
wrlvl_start = 0x8;
|
||||||
|
if (popts->wrlvl_override) {
|
||||||
|
wrlvl_smpl = popts->wrlvl_sample;
|
||||||
|
wrlvl_start = popts->wrlvl_start;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ddr->ddr_wrlvl_cntl = (((wrlvl_en & 0x1) << 31)
|
||||||
|
| ((wrlvl_mrd & 0x7) << 24)
|
||||||
|
| ((wrlvl_odten & 0x7) << 20)
|
||||||
|
| ((wrlvl_dqsen & 0x7) << 16)
|
||||||
|
| ((wrlvl_smpl & 0xf) << 12)
|
||||||
|
| ((wrlvl_wlr & 0x7) << 8)
|
||||||
|
| ((wrlvl_start & 0x1f) << 0)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t
|
uint32_t
|
||||||
compute_fsl_memctl_config_regs(const struct memctl_options_s *popts,
|
compute_fsl_memctl_config_regs(const struct memctl_options_s *popts,
|
||||||
struct fsl_ddr_cfg_regs_s *ddr,
|
struct fsl_ddr_cfg_regs_s *ddr,
|
||||||
|
@ -364,7 +698,7 @@ compute_fsl_memctl_config_regs(const struct memctl_options_s *popts,
|
||||||
{
|
{
|
||||||
struct ddr_board_info_s *binfo = popts->board_info;
|
struct ddr_board_info_s *binfo = popts->board_info;
|
||||||
uint32_t cas_latency, additive_latency, i, cs_per_dimm,
|
uint32_t cas_latency, additive_latency, i, cs_per_dimm,
|
||||||
dimm_number;
|
dimm_number, zq_en, wrlvl_en, sr_it = 0;
|
||||||
uint64_t ea, sa, rank_density;
|
uint64_t ea, sa, rank_density;
|
||||||
|
|
||||||
if (dimm == NULL)
|
if (dimm == NULL)
|
||||||
|
@ -383,6 +717,9 @@ compute_fsl_memctl_config_regs(const struct memctl_options_s *popts,
|
||||||
else
|
else
|
||||||
additive_latency = dimm->additive_latency;
|
additive_latency = dimm->additive_latency;
|
||||||
|
|
||||||
|
if (popts->auto_self_refresh_en)
|
||||||
|
sr_it = popts->sr_it;
|
||||||
|
|
||||||
/* Chip Select Memory Bounds (CSn_BNDS) */
|
/* Chip Select Memory Bounds (CSn_BNDS) */
|
||||||
for (i = 0; i < binfo->cs_per_ctrl; i++) {
|
for (i = 0; i < binfo->cs_per_ctrl; i++) {
|
||||||
cs_per_dimm = binfo->cs_per_ctrl / binfo->dimm_slots_per_ctrl;
|
cs_per_dimm = binfo->cs_per_ctrl / binfo->dimm_slots_per_ctrl;
|
||||||
|
@ -405,21 +742,37 @@ compute_fsl_memctl_config_regs(const struct memctl_options_s *popts,
|
||||||
sa >>= 24;
|
sa >>= 24;
|
||||||
ea >>= 24;
|
ea >>= 24;
|
||||||
|
|
||||||
ddr->cs[i].bnds = (((sa & 0xFFF) << 16) | ((ea & 0xFFF) << 0));
|
ddr->cs[i].bnds =
|
||||||
|
(((sa & 0xffff) << 16) | ((ea & 0xffff) << 0));
|
||||||
set_csn_config(dimm_number, i, ddr, popts, dimmp);
|
set_csn_config(dimm_number, i, ddr, popts, dimmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
set_timing_cfg_0(ddr, popts);
|
set_timing_cfg_0(ddr, popts, dimmp);
|
||||||
set_timing_cfg_3(ddr, dimm, cas_latency);
|
set_timing_cfg_3(ddr, popts, dimm, cas_latency, additive_latency);
|
||||||
set_timing_cfg_1(ddr, dimm, cas_latency);
|
set_timing_cfg_1(ddr, popts, dimm, cas_latency);
|
||||||
set_timing_cfg_2(ddr, popts, dimm, cas_latency, additive_latency);
|
set_timing_cfg_2(ddr, popts, dimm, cas_latency, additive_latency);
|
||||||
|
|
||||||
|
ddr->ddr_cdr1 = popts->ddr_cdr1;
|
||||||
|
ddr->ddr_cdr1 = popts->ddr_cdr2;
|
||||||
|
|
||||||
set_ddr_sdram_cfg(ddr, popts, dimm);
|
set_ddr_sdram_cfg(ddr, popts, dimm);
|
||||||
set_ddr_sdram_cfg_2(ddr, popts);
|
set_ddr_sdram_cfg_2(ddr, popts);
|
||||||
set_ddr_sdram_mode(ddr, popts, dimm, cas_latency, additive_latency);
|
set_ddrx_sdram_mode(ddr, popts, dimm, cas_latency, additive_latency);
|
||||||
|
if (popts->sdram_type == SDRAM_TYPE_DDR3) {
|
||||||
|
set_ddr_sdram_mode_2(ddr, popts, dimm);
|
||||||
|
set_timing_cfg_4(ddr, popts);
|
||||||
|
set_timing_cfg_5(ddr, popts, cas_latency);
|
||||||
|
zq_en = (popts->zq_en) ? 1 : 0;
|
||||||
|
set_ddr_zq_cntl(ddr, zq_en);
|
||||||
|
wrlvl_en = (popts->wrlvl_en) ? 1 : 0;
|
||||||
|
set_ddr_wrlvl_cntl(ddr, wrlvl_en, popts);
|
||||||
|
}
|
||||||
set_ddr_sdram_interval(ddr, popts, dimm);
|
set_ddr_sdram_interval(ddr, popts, dimm);
|
||||||
|
|
||||||
ddr->ddr_data_init = popts->data_init;
|
ddr->ddr_data_init = popts->data_init;
|
||||||
ddr->ddr_sdram_clk_cntl = (popts->clk_adjust & 0xF) << 23;
|
ddr->ddr_sdram_clk_cntl = (popts->clk_adjust & 0xF) << 23;
|
||||||
|
|
||||||
|
ddr->ddr_sr_cntr = (sr_it & 0xf) << 16;
|
||||||
|
|
||||||
return check_fsl_memctl_config_regs(ddr);
|
return check_fsl_memctl_config_regs(ddr);
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,6 +47,17 @@ struct fsl_ddr_cfg_regs_s {
|
||||||
uint32_t ddr_sdram_clk_cntl;
|
uint32_t ddr_sdram_clk_cntl;
|
||||||
uint32_t ddr_init_addr;
|
uint32_t ddr_init_addr;
|
||||||
uint32_t ddr_init_ext_addr;
|
uint32_t ddr_init_ext_addr;
|
||||||
|
uint32_t timing_cfg_4;
|
||||||
|
uint32_t timing_cfg_5;
|
||||||
|
uint32_t ddr_zq_cntl;
|
||||||
|
uint32_t ddr_wrlvl_cntl;
|
||||||
|
uint32_t ddr_wrlvl_cntl_2;
|
||||||
|
uint32_t ddr_wrlvl_cntl_3;
|
||||||
|
uint32_t ddr_sr_cntr;
|
||||||
|
uint32_t ddr_sdram_rcw_1;
|
||||||
|
uint32_t ddr_sdram_rcw_2;
|
||||||
|
uint32_t ddr_cdr1;
|
||||||
|
uint32_t ddr_cdr2;
|
||||||
uint32_t err_disable;
|
uint32_t err_disable;
|
||||||
uint32_t err_int_en;
|
uint32_t err_int_en;
|
||||||
uint32_t debug[32];
|
uint32_t debug[32];
|
||||||
|
@ -82,8 +93,8 @@ uint32_t compute_fsl_memctl_config_regs(
|
||||||
uint32_t compute_dimm_parameters(
|
uint32_t compute_dimm_parameters(
|
||||||
const generic_spd_eeprom_t *spdin,
|
const generic_spd_eeprom_t *spdin,
|
||||||
struct dimm_params_s *pdimm);
|
struct dimm_params_s *pdimm);
|
||||||
uint32_t compute_lowest_common_dimm_parameters(
|
void compute_lowest_common_dimm_parameters(
|
||||||
const struct dimm_params_s *dimm_params,
|
const struct fsl_ddr_info_s *pinfo,
|
||||||
struct common_timing_params_s *outpdimm,
|
struct common_timing_params_s *outpdimm,
|
||||||
uint32_t number_of_dimms);
|
uint32_t number_of_dimms);
|
||||||
uint32_t populate_memctl_options(
|
uint32_t populate_memctl_options(
|
||||||
|
|
|
@ -193,17 +193,12 @@ compute_dimm_parameters(const generic_spd_eeprom_t *spdin,
|
||||||
const struct ddr2_spd_eeprom_s *spd = spdin;
|
const struct ddr2_spd_eeprom_s *spd = spdin;
|
||||||
uint32_t retval;
|
uint32_t retval;
|
||||||
|
|
||||||
if (!spd->mem_type) {
|
|
||||||
memset(pdimm, 0, sizeof(struct dimm_params_s));
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (spd->mem_type != SPD_MEMTYPE_DDR2)
|
if (spd->mem_type != SPD_MEMTYPE_DDR2)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
retval = ddr2_spd_checksum_pass(spd);
|
retval = ddr2_spd_checksum_pass(spd);
|
||||||
if (retval)
|
if (retval)
|
||||||
goto spd_err;
|
goto error;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The part name in ASCII in the SPD EEPROM is not null terminated.
|
* The part name in ASCII in the SPD EEPROM is not null terminated.
|
||||||
|
@ -298,6 +293,4 @@ compute_dimm_parameters(const generic_spd_eeprom_t *spdin,
|
||||||
return 0;
|
return 0;
|
||||||
error:
|
error:
|
||||||
return 1;
|
return 1;
|
||||||
spd_err:
|
|
||||||
return 2;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,193 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2008-2012 Freescale Semiconductor, Inc.
|
||||||
|
* Dave Liu <daveliu@freescale.com>
|
||||||
|
*
|
||||||
|
* calculate the organization and timing parameter
|
||||||
|
* from ddr3 spd, please refer to the spec
|
||||||
|
* JEDEC standard No.21-C 4_01_02_11R18.pdf
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* Version 2 as published by the Free Software Foundation.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <common.h>
|
||||||
|
#include <asm/fsl_ddr_sdram.h>
|
||||||
|
#include "ddr.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Calculate the Density of each Physical Rank.
|
||||||
|
* Returned size is in bytes.
|
||||||
|
*
|
||||||
|
* each rank size =
|
||||||
|
* sdram capacity(bit) / 8 * primary bus width / sdram width
|
||||||
|
*
|
||||||
|
* where: sdram capacity = spd byte4[3:0]
|
||||||
|
* primary bus width = spd byte8[2:0]
|
||||||
|
* sdram width = spd byte7[2:0]
|
||||||
|
*
|
||||||
|
* SPD byte4 - sdram density and banks
|
||||||
|
* bit[3:0] size(bit) size(byte)
|
||||||
|
* 0000 256Mb 32MB
|
||||||
|
* 0001 512Mb 64MB
|
||||||
|
* 0010 1Gb 128MB
|
||||||
|
* 0011 2Gb 256MB
|
||||||
|
* 0100 4Gb 512MB
|
||||||
|
* 0101 8Gb 1GB
|
||||||
|
* 0110 16Gb 2GB
|
||||||
|
*
|
||||||
|
* SPD byte8 - module memory bus width
|
||||||
|
* bit[2:0] primary bus width
|
||||||
|
* 000 8bits
|
||||||
|
* 001 16bits
|
||||||
|
* 010 32bits
|
||||||
|
* 011 64bits
|
||||||
|
*
|
||||||
|
* SPD byte7 - module organiztion
|
||||||
|
* bit[2:0] sdram device width
|
||||||
|
* 000 4bits
|
||||||
|
* 001 8bits
|
||||||
|
* 010 16bits
|
||||||
|
* 011 32bits
|
||||||
|
*/
|
||||||
|
static uint64_t compute_ranksize(const struct ddr3_spd_eeprom_s *spd)
|
||||||
|
{
|
||||||
|
uint64_t bsize;
|
||||||
|
int sdram_cap_bsize = 0, prim_bus_width = 0, sdram_width = 0;
|
||||||
|
|
||||||
|
if ((spd->density_banks & 0xf) < 7)
|
||||||
|
sdram_cap_bsize = (spd->density_banks & 0xf) + 28;
|
||||||
|
if ((spd->bus_width & 0x7) < 4)
|
||||||
|
prim_bus_width = (spd->bus_width & 0x7) + 3;
|
||||||
|
if ((spd->organization & 0x7) < 4)
|
||||||
|
sdram_width = (spd->organization & 0x7) + 2;
|
||||||
|
|
||||||
|
bsize = 1ULL << (sdram_cap_bsize - 3 + prim_bus_width - sdram_width);
|
||||||
|
|
||||||
|
return bsize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* compute_dimm_parameters for DDR3 SPD
|
||||||
|
*
|
||||||
|
* Compute DIMM parameters based upon the SPD information in spd.
|
||||||
|
* Writes the results to the dimm_params_s structure pointed by pdimm.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
uint32_t
|
||||||
|
compute_dimm_parameters(const generic_spd_eeprom_t *spdin,
|
||||||
|
struct dimm_params_s *pdimm)
|
||||||
|
{
|
||||||
|
const struct ddr3_spd_eeprom_s *spd = spdin;
|
||||||
|
uint32_t retval, mtb_ps;
|
||||||
|
int ftb_tmp;
|
||||||
|
|
||||||
|
if (spd->mem_type != SPD_MEMTYPE_DDR3)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
retval = ddr3_spd_checksum_pass(spd);
|
||||||
|
if (retval)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
memset(pdimm->mpart, 0, sizeof(pdimm->mpart));
|
||||||
|
if ((spd->info_size_crc & 0xf) > 1)
|
||||||
|
memcpy(pdimm->mpart, spd->mpart, sizeof(pdimm->mpart) - 1);
|
||||||
|
|
||||||
|
/* DIMM organization parameters */
|
||||||
|
pdimm->n_ranks = ((spd->organization >> 3) & 0x7) + 1;
|
||||||
|
pdimm->rank_density = compute_ranksize(spd);
|
||||||
|
pdimm->capacity = pdimm->n_ranks * pdimm->rank_density;
|
||||||
|
pdimm->data_width = pdimm->primary_sdram_width + pdimm->ec_sdram_width;
|
||||||
|
pdimm->primary_sdram_width = 1 << (3 + (spd->bus_width & 0x7));
|
||||||
|
if ((spd->bus_width >> 3) & 0x3)
|
||||||
|
pdimm->ec_sdram_width = 8;
|
||||||
|
else
|
||||||
|
pdimm->ec_sdram_width = 0;
|
||||||
|
pdimm->device_width = 1 << ((spd->organization & 0x7) + 2);
|
||||||
|
|
||||||
|
/* These are the types defined by the JEDEC DDR3 SPD spec */
|
||||||
|
pdimm->mirrored_dimm = 0;
|
||||||
|
pdimm->registered_dimm = 0;
|
||||||
|
switch (spd->module_type & DDR3_SPD_MODULETYPE_MASK) {
|
||||||
|
case DDR3_SPD_MODULETYPE_UDIMM:
|
||||||
|
/* Unbuffered DIMMs */
|
||||||
|
if (spd->mod_section.unbuffered.addr_mapping & 0x1)
|
||||||
|
pdimm->mirrored_dimm = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* SDRAM device parameters */
|
||||||
|
pdimm->n_row_addr = ((spd->addressing >> 3) & 0x7) + 12;
|
||||||
|
pdimm->n_col_addr = (spd->addressing & 0x7) + 9;
|
||||||
|
pdimm->n_banks_per_sdram_device =
|
||||||
|
8 << ((spd->density_banks >> 4) & 0x7);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The SPD spec does not define an ECC bit. The DIMM is considered
|
||||||
|
* to have ECC capability if the extension bus exists.
|
||||||
|
*/
|
||||||
|
if (pdimm->ec_sdram_width)
|
||||||
|
pdimm->edc_config = 0x02;
|
||||||
|
else
|
||||||
|
pdimm->edc_config = 0x00;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The SPD spec does not define the burst length byte.
|
||||||
|
* but the DDR3 spec defines BL8 and BC4, on bit 3 and
|
||||||
|
* bit 2.
|
||||||
|
*/
|
||||||
|
pdimm->burst_lengths_bitmask = 0x0c;
|
||||||
|
pdimm->row_density = __ilog2(pdimm->rank_density);
|
||||||
|
|
||||||
|
mtb_ps = (spd->mtb_dividend * 1000) / spd->mtb_divisor;
|
||||||
|
pdimm->mtb_ps = mtb_ps;
|
||||||
|
|
||||||
|
ftb_tmp = spd->ftb_div & 0xf0;
|
||||||
|
pdimm->ftb_10th_ps = ((ftb_tmp >> 4) * 10) / ftb_tmp;
|
||||||
|
|
||||||
|
pdimm->tCKmin_X_ps = spd->tck_min * mtb_ps +
|
||||||
|
(spd->fine_tck_min * ftb_tmp) / 10;
|
||||||
|
pdimm->caslat_X = ((spd->caslat_msb << 8) | spd->caslat_lsb) << 4;
|
||||||
|
|
||||||
|
pdimm->taa_ps = spd->taa_min * mtb_ps +
|
||||||
|
(spd->fine_taa_min * ftb_tmp) / 10;
|
||||||
|
|
||||||
|
pdimm->tRCD_ps = spd->trcd_min * mtb_ps +
|
||||||
|
(spd->fine_trcd_min * ftb_tmp) / 10;
|
||||||
|
|
||||||
|
pdimm->tRP_ps = spd->trp_min * mtb_ps +
|
||||||
|
(spd->fine_trp_min * ftb_tmp) / 10;
|
||||||
|
pdimm->tRAS_ps = (((spd->tras_trc_ext & 0xf) << 8) | spd->tras_min_lsb)
|
||||||
|
* mtb_ps;
|
||||||
|
pdimm->tWR_ps = spd->twr_min * mtb_ps;
|
||||||
|
pdimm->tWTR_ps = spd->twtr_min * mtb_ps;
|
||||||
|
pdimm->tRFC_ps = ((spd->trfc_min_msb << 8) | spd->trfc_min_lsb)
|
||||||
|
* mtb_ps;
|
||||||
|
pdimm->tRRD_ps = spd->trrd_min * mtb_ps;
|
||||||
|
pdimm->tRC_ps = (((spd->tras_trc_ext & 0xf0) << 4) | spd->trc_min_lsb);
|
||||||
|
pdimm->tRC_ps *= mtb_ps;
|
||||||
|
pdimm->tRC_ps += (spd->fine_trc_min * ftb_tmp) / 10;
|
||||||
|
|
||||||
|
pdimm->tRTP_ps = spd->trtp_min * mtb_ps;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Average periodic refresh interval
|
||||||
|
* tREFI = 7.8 us at normal temperature range
|
||||||
|
* = 3.9 us at ext temperature range
|
||||||
|
*/
|
||||||
|
pdimm->refresh_rate_ps = 7800000;
|
||||||
|
if ((spd->therm_ref_opt & 0x1) && !(spd->therm_ref_opt & 0x2)) {
|
||||||
|
pdimm->refresh_rate_ps = 3900000;
|
||||||
|
pdimm->extended_op_srt = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
pdimm->tfaw_ps = (((spd->tfaw_msb & 0xf) << 8) | spd->tfaw_min)
|
||||||
|
* mtb_ps;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
error:
|
||||||
|
return 1;
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2008 Freescale Semiconductor, Inc.
|
* Copyright 2008-2011 Freescale Semiconductor, Inc.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
@ -10,12 +10,13 @@
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
#include <asm/fsl_ddr_sdram.h>
|
#include <asm/fsl_ddr_sdram.h>
|
||||||
|
#include <asm/processor.h>
|
||||||
#include <mach/early_udelay.h>
|
#include <mach/early_udelay.h>
|
||||||
#include "ddr.h"
|
#include "ddr.h"
|
||||||
|
|
||||||
int fsl_ddr_set_memctl_regs(const struct fsl_ddr_info_s *info)
|
int fsl_ddr_set_memctl_regs(const struct fsl_ddr_info_s *info)
|
||||||
{
|
{
|
||||||
uint32_t i;
|
uint32_t i, temp_sdram_cfg;
|
||||||
void __iomem *ddr;
|
void __iomem *ddr;
|
||||||
const struct fsl_ddr_cfg_regs_s *regs;
|
const struct fsl_ddr_cfg_regs_s *regs;
|
||||||
|
|
||||||
|
@ -29,6 +30,9 @@ int fsl_ddr_set_memctl_regs(const struct fsl_ddr_info_s *info)
|
||||||
out_be32(ddr + DDR_OFF(CS0_BNDS) + (i << 3), regs->cs[i].bnds);
|
out_be32(ddr + DDR_OFF(CS0_BNDS) + (i << 3), regs->cs[i].bnds);
|
||||||
out_be32(ddr + DDR_OFF(CS0_CONFIG) + (i << 2),
|
out_be32(ddr + DDR_OFF(CS0_CONFIG) + (i << 2),
|
||||||
regs->cs[i].config);
|
regs->cs[i].config);
|
||||||
|
if (info->memctl_opts.sdram_type == SDRAM_TYPE_DDR3)
|
||||||
|
out_be32(ddr + DDR_OFF(CS0_CONFIG_2) + (i << 2),
|
||||||
|
regs->cs[i].config_2);
|
||||||
}
|
}
|
||||||
|
|
||||||
out_be32(ddr + DDR_OFF(TIMING_CFG_3), regs->timing_cfg_3);
|
out_be32(ddr + DDR_OFF(TIMING_CFG_3), regs->timing_cfg_3);
|
||||||
|
@ -45,12 +49,40 @@ int fsl_ddr_set_memctl_regs(const struct fsl_ddr_info_s *info)
|
||||||
out_be32(ddr + DDR_OFF(SDRAM_INIT_ADDR), regs->ddr_init_addr);
|
out_be32(ddr + DDR_OFF(SDRAM_INIT_ADDR), regs->ddr_init_addr);
|
||||||
out_be32(ddr + DDR_OFF(SDRAM_INIT_ADDR_EXT), regs->ddr_init_ext_addr);
|
out_be32(ddr + DDR_OFF(SDRAM_INIT_ADDR_EXT), regs->ddr_init_ext_addr);
|
||||||
|
|
||||||
early_udelay(200);
|
if (info->memctl_opts.sdram_type == SDRAM_TYPE_DDR3) {
|
||||||
|
out_be32(ddr + DDR_OFF(TIMING_CFG_4), regs->timing_cfg_4);
|
||||||
|
out_be32(ddr + DDR_OFF(TIMING_CFG_5), regs->timing_cfg_5);
|
||||||
|
out_be32(ddr + DDR_OFF(ZQ_CNTL), regs->ddr_zq_cntl);
|
||||||
|
out_be32(ddr + DDR_OFF(WRLVL_CNTL), regs->ddr_wrlvl_cntl);
|
||||||
|
|
||||||
|
if (regs->ddr_wrlvl_cntl_2)
|
||||||
|
out_be32(ddr + DDR_OFF(WRLVL_CNTL_2),
|
||||||
|
regs->ddr_wrlvl_cntl_2);
|
||||||
|
if (regs->ddr_wrlvl_cntl_3)
|
||||||
|
out_be32(ddr + DDR_OFF(WRLVL_CNTL_3),
|
||||||
|
regs->ddr_wrlvl_cntl_3);
|
||||||
|
|
||||||
|
out_be32(ddr + DDR_OFF(SR_CNTL), regs->ddr_sr_cntr);
|
||||||
|
out_be32(ddr + DDR_OFF(SDRAM_RCW_1), regs->ddr_sdram_rcw_1);
|
||||||
|
out_be32(ddr + DDR_OFF(SDRAM_RCW_2), regs->ddr_sdram_rcw_2);
|
||||||
|
out_be32(ddr + DDR_OFF(DDRCDR1), regs->ddr_cdr1);
|
||||||
|
out_be32(ddr + DDR_OFF(DDRCDR2), regs->ddr_cdr2);
|
||||||
|
}
|
||||||
|
|
||||||
|
out_be32(ddr + DDR_OFF(ERR_DISABLE), regs->err_disable);
|
||||||
|
out_be32(ddr + DDR_OFF(ERR_INT_EN), regs->err_int_en);
|
||||||
|
|
||||||
|
temp_sdram_cfg = regs->ddr_sdram_cfg;
|
||||||
|
temp_sdram_cfg &= ~(SDRAM_CFG_MEM_EN);
|
||||||
|
out_be32(ddr + DDR_OFF(SDRAM_CFG), temp_sdram_cfg);
|
||||||
|
|
||||||
|
early_udelay(500);
|
||||||
|
/* Make sure all instructions are completed before enabling memory.*/
|
||||||
|
asm volatile("sync;isync");
|
||||||
|
temp_sdram_cfg = in_be32(ddr + DDR_OFF(SDRAM_CFG)) & ~SDRAM_CFG_BI;
|
||||||
|
out_be32(ddr + DDR_OFF(SDRAM_CFG), temp_sdram_cfg | SDRAM_CFG_MEM_EN);
|
||||||
asm volatile("sync;isync");
|
asm volatile("sync;isync");
|
||||||
|
|
||||||
out_be32(ddr + DDR_OFF(SDRAM_CFG), regs->ddr_sdram_cfg);
|
|
||||||
|
|
||||||
/* Poll DDR_SDRAM_CFG_2[D_INIT] bit until auto-data init is done. */
|
|
||||||
while (in_be32(ddr + DDR_OFF(SDRAM_CFG_2)) & SDRAM_CFG2_D_INIT)
|
while (in_be32(ddr + DDR_OFF(SDRAM_CFG_2)) & SDRAM_CFG2_D_INIT)
|
||||||
early_udelay(10000);
|
early_udelay(10000);
|
||||||
|
|
|
@ -12,6 +12,36 @@
|
||||||
|
|
||||||
#include "ddr.h"
|
#include "ddr.h"
|
||||||
|
|
||||||
|
static uint32_t
|
||||||
|
compute_cas_latency_ddr3(const struct dimm_params_s *dimm_params,
|
||||||
|
uint32_t number_of_dimms)
|
||||||
|
{
|
||||||
|
uint32_t i, taamin_ps = 0, tckmin_x_ps = 0, common_caslat,
|
||||||
|
caslat_actual, retry = 16;
|
||||||
|
const uint32_t mclk_ps = get_memory_clk_period_ps();
|
||||||
|
|
||||||
|
/* compute the common CAS latency supported between slots */
|
||||||
|
common_caslat = dimm_params[0].caslat_X;
|
||||||
|
for (i = 1; i < number_of_dimms; i++) {
|
||||||
|
if (dimm_params[i].n_ranks)
|
||||||
|
common_caslat &= dimm_params[i].caslat_X;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < number_of_dimms; i++) {
|
||||||
|
taamin_ps = max(taamin_ps, dimm_params[i].taa_ps);
|
||||||
|
tckmin_x_ps = max(tckmin_x_ps, dimm_params[i].tCKmin_X_ps);
|
||||||
|
}
|
||||||
|
|
||||||
|
caslat_actual = (taamin_ps + mclk_ps - 1) / mclk_ps;
|
||||||
|
/* check if the dimms support the CAS latency */
|
||||||
|
while (!(common_caslat & (1 << caslat_actual)) && retry > 0) {
|
||||||
|
caslat_actual++;
|
||||||
|
retry--;
|
||||||
|
}
|
||||||
|
|
||||||
|
return caslat_actual;
|
||||||
|
}
|
||||||
|
|
||||||
static unsigned int common_burst_length(
|
static unsigned int common_burst_length(
|
||||||
const struct dimm_params_s *dimm_params,
|
const struct dimm_params_s *dimm_params,
|
||||||
const unsigned int number_of_dimms)
|
const unsigned int number_of_dimms)
|
||||||
|
@ -22,7 +52,6 @@ static unsigned int common_burst_length(
|
||||||
for (i = 0; i < number_of_dimms; i++)
|
for (i = 0; i < number_of_dimms; i++)
|
||||||
if (dimm_params[i].n_ranks)
|
if (dimm_params[i].n_ranks)
|
||||||
temp &= dimm_params[i].burst_lengths_bitmask;
|
temp &= dimm_params[i].burst_lengths_bitmask;
|
||||||
|
|
||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,16 +144,17 @@ static unsigned int compute_lowest_caslat(
|
||||||
* whose parameters have been computed into the array pointed to
|
* whose parameters have been computed into the array pointed to
|
||||||
* by dimm_params.
|
* by dimm_params.
|
||||||
*/
|
*/
|
||||||
unsigned int
|
void compute_lowest_common_dimm_parameters(const struct fsl_ddr_info_s *pinfo,
|
||||||
compute_lowest_common_dimm_parameters(const struct dimm_params_s *dimm,
|
|
||||||
struct common_timing_params_s *out,
|
struct common_timing_params_s *out,
|
||||||
const unsigned int number_of_dimms)
|
const unsigned int number_of_dimms)
|
||||||
{
|
{
|
||||||
const uint32_t mclk_ps = get_memory_clk_period_ps();
|
|
||||||
uint32_t temp1, i;
|
uint32_t temp1, i;
|
||||||
struct common_timing_params_s tmp = {0};
|
struct common_timing_params_s tmp = {0};
|
||||||
|
const struct dimm_params_s *dimm = pinfo->dimm_params;
|
||||||
|
const struct memctl_options_s *popts = &pinfo->memctl_opts;
|
||||||
|
|
||||||
tmp.tCKmax_ps = 0xFFFFFFFF;
|
tmp.tCKmax_ps = 0xFFFFFFFF;
|
||||||
|
tmp.extended_op_srt = 1;
|
||||||
temp1 = 0;
|
temp1 = 0;
|
||||||
for (i = 0; i < number_of_dimms; i++) {
|
for (i = 0; i < number_of_dimms; i++) {
|
||||||
if (dimm[i].n_ranks == 0) {
|
if (dimm[i].n_ranks == 0) {
|
||||||
|
@ -157,58 +187,69 @@ compute_lowest_common_dimm_parameters(const struct dimm_params_s *dimm,
|
||||||
tmp.tQHS_ps = max(tmp.tQHS_ps, dimm[i].tQHS_ps);
|
tmp.tQHS_ps = max(tmp.tQHS_ps, dimm[i].tQHS_ps);
|
||||||
tmp.refresh_rate_ps = max(tmp.refresh_rate_ps,
|
tmp.refresh_rate_ps = max(tmp.refresh_rate_ps,
|
||||||
dimm[i].refresh_rate_ps);
|
dimm[i].refresh_rate_ps);
|
||||||
|
tmp.extended_op_srt = min(tmp.extended_op_srt,
|
||||||
|
dimm[i].extended_op_srt);
|
||||||
/* Find maximum tDQSQ_max_ps to find slowest timing. */
|
/* Find maximum tDQSQ_max_ps to find slowest timing. */
|
||||||
tmp.tDQSQ_max_ps = max(tmp.tDQSQ_max_ps, dimm[i].tDQSQ_max_ps);
|
tmp.tDQSQ_max_ps = max(tmp.tDQSQ_max_ps, dimm[i].tDQSQ_max_ps);
|
||||||
}
|
}
|
||||||
tmp.ndimms_present = number_of_dimms - temp1;
|
tmp.ndimms_present = number_of_dimms - temp1;
|
||||||
|
|
||||||
if (temp1 == number_of_dimms)
|
if (temp1 == number_of_dimms)
|
||||||
return 0;
|
return;
|
||||||
|
|
||||||
temp1 = common_burst_length(dimm, number_of_dimms);
|
temp1 = common_burst_length(dimm, number_of_dimms);
|
||||||
tmp.all_DIMMs_burst_lengths_bitmask = temp1;
|
tmp.all_DIMMs_burst_lengths_bitmask = temp1;
|
||||||
tmp.all_DIMMs_registered = 0;
|
|
||||||
|
|
||||||
tmp.lowest_common_SPD_caslat = compute_lowest_caslat(dimm,
|
/* Support only unbuffered DIMMs */
|
||||||
number_of_dimms);
|
tmp.all_DIMMs_registered = 0;
|
||||||
/*
|
tmp.all_DIMMs_unbuffered = 1;
|
||||||
* Compute a common 'de-rated' CAS latency.
|
|
||||||
*
|
if (popts->sdram_type == SDRAM_TYPE_DDR3) {
|
||||||
* The strategy here is to find the *highest* de-rated cas latency
|
tmp.lowest_common_SPD_caslat = compute_cas_latency_ddr3(dimm,
|
||||||
* with the assumption that all of the DIMMs will support a de-rated
|
number_of_dimms);
|
||||||
* CAS latency higher than or equal to their lowest de-rated value.
|
} else {
|
||||||
*/
|
tmp.lowest_common_SPD_caslat = compute_lowest_caslat(dimm,
|
||||||
temp1 = 0;
|
number_of_dimms);
|
||||||
for (i = 0; i < number_of_dimms; i++)
|
/*
|
||||||
temp1 = max(temp1, dimm[i].caslat_lowest_derated);
|
* Compute a common 'de-rated' CAS latency.
|
||||||
tmp.highest_common_derated_caslat = temp1;
|
*
|
||||||
|
* The strategy here is to find the *highest* de-rated cas
|
||||||
|
* latency with the assumption that all of the DIMMs will
|
||||||
|
* support a de-rated CAS latency higher than or equal to
|
||||||
|
* their lowest de-rated value.
|
||||||
|
*/
|
||||||
|
temp1 = 0;
|
||||||
|
for (i = 0; i < number_of_dimms; i++)
|
||||||
|
temp1 = max(temp1, dimm[i].caslat_lowest_derated);
|
||||||
|
tmp.highest_common_derated_caslat = temp1;
|
||||||
|
}
|
||||||
|
|
||||||
temp1 = 1;
|
temp1 = 1;
|
||||||
for (i = 0; i < number_of_dimms; i++)
|
for (i = 0; i < number_of_dimms; i++)
|
||||||
if (dimm[i].n_ranks &&
|
if (dimm[i].n_ranks && !(dimm[i].edc_config & EDC_ECC)) {
|
||||||
!(dimm[i].edc_config & EDC_ECC)) {
|
|
||||||
temp1 = 0;
|
temp1 = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
tmp.all_DIMMs_ECC_capable = temp1;
|
tmp.all_DIMMs_ECC_capable = temp1;
|
||||||
|
|
||||||
if (mclk_ps > tmp.tCKmax_max_ps)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* AL must be less or equal to tRCD. Typically, AL would
|
* AL must be less or equal to tRCD. Typically, AL would
|
||||||
* be AL = tRCD - 1;
|
* be AL = tRCD - 1;
|
||||||
*
|
*
|
||||||
* When ODT read or write is enabled the sum of CAS latency +
|
* When ODT read or write is enabled the sum of CAS latency +
|
||||||
* additive latency must be at least 3 cycles.
|
* additive latency must be at least 3 cycles.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
if ((tmp.lowest_common_SPD_caslat < 4) && (picos_to_mclk(tmp.tRCD_ps) >
|
tmp.additive_latency = 0;
|
||||||
tmp.lowest_common_SPD_caslat))
|
if (popts->sdram_type == SDRAM_TYPE_DDR2) {
|
||||||
tmp.additive_latency = picos_to_mclk(tmp.tRCD_ps) -
|
if ((tmp.lowest_common_SPD_caslat < 4) &&
|
||||||
tmp.lowest_common_SPD_caslat;
|
(picos_to_mclk(tmp.tRCD_ps) >
|
||||||
|
tmp.lowest_common_SPD_caslat))
|
||||||
|
tmp.additive_latency = picos_to_mclk(tmp.tRCD_ps) -
|
||||||
|
tmp.lowest_common_SPD_caslat;
|
||||||
|
|
||||||
|
if (mclk_to_picos(tmp.additive_latency) > tmp.tRCD_ps)
|
||||||
|
tmp.additive_latency = picos_to_mclk(tmp.tRCD_ps);
|
||||||
|
}
|
||||||
|
|
||||||
memcpy(out, &tmp, sizeof(struct common_timing_params_s));
|
memcpy(out, &tmp, sizeof(struct common_timing_params_s));
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#include <asm/fsl_law.h>
|
#include <asm/fsl_law.h>
|
||||||
|
#include <asm/fsl_ddr_sdram.h>
|
||||||
#include "ddr.h"
|
#include "ddr.h"
|
||||||
|
|
||||||
static int get_spd(generic_spd_eeprom_t *spd,
|
static int get_spd(generic_spd_eeprom_t *spd,
|
||||||
|
@ -143,6 +144,14 @@ static uint32_t compute_dimm_param(struct fsl_ddr_info_s *pinfo, uint32_t ndimm)
|
||||||
generic_spd_eeprom_t *spd;
|
generic_spd_eeprom_t *spd;
|
||||||
uint32_t i, retval;
|
uint32_t i, retval;
|
||||||
|
|
||||||
|
spd = &(pinfo->spd_installed_dimms[0]);
|
||||||
|
if (spd->mem_type == SPD_MEMTYPE_DDR3)
|
||||||
|
pinfo->memctl_opts.sdram_type = SDRAM_TYPE_DDR3;
|
||||||
|
else if (spd->mem_type == SPD_MEMTYPE_DDR2)
|
||||||
|
pinfo->memctl_opts.sdram_type = SDRAM_TYPE_DDR2;
|
||||||
|
else
|
||||||
|
return 1;
|
||||||
|
|
||||||
for (i = 0; i < ndimm; i++) {
|
for (i = 0; i < ndimm; i++) {
|
||||||
spd = &(pinfo->spd_installed_dimms[i]);
|
spd = &(pinfo->spd_installed_dimms[i]);
|
||||||
pdimm = &(pinfo->dimm_params[i]);
|
pdimm = &(pinfo->dimm_params[i]);
|
||||||
|
@ -185,8 +194,7 @@ uint64_t fsl_ddr_compute(struct fsl_ddr_info_s *pinfo)
|
||||||
* STEP 3: Compute a common set of timing parameters
|
* STEP 3: Compute a common set of timing parameters
|
||||||
* suitable for all of the DIMMs on each memory controller
|
* suitable for all of the DIMMs on each memory controller
|
||||||
*/
|
*/
|
||||||
compute_lowest_common_dimm_parameters(pinfo->dimm_params,
|
compute_lowest_common_dimm_parameters(pinfo, timing_params, ndimm);
|
||||||
timing_params, ndimm);
|
|
||||||
|
|
||||||
/* STEP 4: Gather configuration requirements from user */
|
/* STEP 4: Gather configuration requirements from user */
|
||||||
populate_memctl_options(timing_params->all_DIMMs_registered,
|
populate_memctl_options(timing_params->all_DIMMs_registered,
|
||||||
|
|
|
@ -46,18 +46,42 @@ uint32_t populate_memctl_options(int all_DIMMs_registered,
|
||||||
* 0 = 64-bit, 1 = 32-bit, 2 = 16-bit
|
* 0 = 64-bit, 1 = 32-bit, 2 = 16-bit
|
||||||
*/
|
*/
|
||||||
if (pdimm->n_ranks != 0) {
|
if (pdimm->n_ranks != 0) {
|
||||||
if ((pdimm->data_width >= 64) && (pdimm->data_width <= 72))
|
if (popts->sdram_type == SDRAM_TYPE_DDR3) {
|
||||||
popts->data_bus_width = 0;
|
if (pdimm[0].primary_sdram_width == 64)
|
||||||
else if ((pdimm->data_width >= 32) &&
|
popts->data_bus_width = 0;
|
||||||
(pdimm->data_width <= 40))
|
else if (pdimm[0].primary_sdram_width == 32)
|
||||||
popts->data_bus_width = 1;
|
popts->data_bus_width = 1;
|
||||||
else
|
else if (pdimm[0].primary_sdram_width == 16)
|
||||||
panic("data width %u is invalid!\n",
|
popts->data_bus_width = 2;
|
||||||
pdimm->data_width);
|
else
|
||||||
|
hang();
|
||||||
|
} else {
|
||||||
|
if ((pdimm->data_width >= 64) &&
|
||||||
|
(pdimm->data_width <= 72))
|
||||||
|
popts->data_bus_width = 0;
|
||||||
|
else if ((pdimm->data_width >= 32) &&
|
||||||
|
(pdimm->data_width <= 40))
|
||||||
|
popts->data_bus_width = 1;
|
||||||
|
else
|
||||||
|
hang();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (popts->sdram_type == SDRAM_TYPE_DDR3) {
|
||||||
|
if (popts->data_bus_width == 0) {
|
||||||
|
popts->otf_burst_chop_en = 1;
|
||||||
|
popts->burst_length = DDR_OTF;
|
||||||
|
} else {
|
||||||
|
/* 32-bit or 16-bit bus */
|
||||||
|
popts->otf_burst_chop_en = 0;
|
||||||
|
popts->burst_length = DDR_BL8;
|
||||||
|
}
|
||||||
|
popts->mirrored_dimm = pdimm[0].mirrored_dimm;
|
||||||
|
} else {
|
||||||
|
/* Must be a burst length of 4 for DDR2 */
|
||||||
|
popts->burst_length = DDR_BL4;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Must be a burst length of 4 for DD2 */
|
|
||||||
popts->burst_length = DDR_BL4;
|
|
||||||
/* Decide whether to use the computed de-rated latency */
|
/* Decide whether to use the computed de-rated latency */
|
||||||
popts->use_derated_caslat = 0;
|
popts->use_derated_caslat = 0;
|
||||||
|
|
||||||
|
@ -70,6 +94,7 @@ uint32_t populate_memctl_options(int all_DIMMs_registered,
|
||||||
* - how much time you want to spend playing around
|
* - how much time you want to spend playing around
|
||||||
*/
|
*/
|
||||||
popts->twoT_en = 0;
|
popts->twoT_en = 0;
|
||||||
|
popts->threet_en = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Default BSTTOPRE precharge interval
|
* Default BSTTOPRE precharge interval
|
||||||
|
@ -90,7 +115,18 @@ uint32_t populate_memctl_options(int all_DIMMs_registered,
|
||||||
* The default value below would work for x4/x8 wide memory.
|
* The default value below would work for x4/x8 wide memory.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
popts->tFAW_window_four_activates_ps = 37500;
|
if (popts->sdram_type == SDRAM_TYPE_DDR2) {
|
||||||
|
popts->tFAW_window_four_activates_ps = 37500;
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* Due to ddr3 dimm fly-by topology, enable write leveling
|
||||||
|
* to meet the tQDSS under different loading.
|
||||||
|
*/
|
||||||
|
popts->tFAW_window_four_activates_ps = pdimm[0].tfaw_ps;
|
||||||
|
popts->wrlvl_en = 1;
|
||||||
|
popts->zq_en = 1;
|
||||||
|
popts->wrlvl_override = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Default powerdown exit timings.
|
* Default powerdown exit timings.
|
||||||
|
|
|
@ -21,6 +21,8 @@ struct dimm_params_s {
|
||||||
uint32_t primary_sdram_width;
|
uint32_t primary_sdram_width;
|
||||||
uint32_t ec_sdram_width;
|
uint32_t ec_sdram_width;
|
||||||
uint32_t registered_dimm;
|
uint32_t registered_dimm;
|
||||||
|
uint32_t device_width;
|
||||||
|
/* SDRAM device parameters */
|
||||||
uint32_t n_row_addr;
|
uint32_t n_row_addr;
|
||||||
uint32_t n_col_addr;
|
uint32_t n_col_addr;
|
||||||
uint32_t edc_config; /* 0 = none, 1 = parity, 2 = ECC */
|
uint32_t edc_config; /* 0 = none, 1 = parity, 2 = ECC */
|
||||||
|
@ -28,6 +30,11 @@ struct dimm_params_s {
|
||||||
uint32_t burst_lengths_bitmask; /* BL=4 bit 2, BL=8 = bit 3 */
|
uint32_t burst_lengths_bitmask; /* BL=4 bit 2, BL=8 = bit 3 */
|
||||||
uint32_t row_density;
|
uint32_t row_density;
|
||||||
uint64_t base_address;
|
uint64_t base_address;
|
||||||
|
uint32_t mirrored_dimm;
|
||||||
|
uint32_t mtb_ps;
|
||||||
|
uint32_t ftb_10th_ps;
|
||||||
|
uint32_t taa_ps;
|
||||||
|
uint32_t tfaw_ps;
|
||||||
/* SDRAM clock periods */
|
/* SDRAM clock periods */
|
||||||
uint32_t tCKmin_X_ps;
|
uint32_t tCKmin_X_ps;
|
||||||
uint32_t tCKmin_X_minus_1_ps;
|
uint32_t tCKmin_X_minus_1_ps;
|
||||||
|
@ -48,6 +55,7 @@ struct dimm_params_s {
|
||||||
uint32_t tRRD_ps; /* maximum = 63750 ps */
|
uint32_t tRRD_ps; /* maximum = 63750 ps */
|
||||||
uint32_t tRC_ps; /* maximum = 254 ns + .75 ns = 254750 ps */
|
uint32_t tRC_ps; /* maximum = 254 ns + .75 ns = 254750 ps */
|
||||||
uint32_t refresh_rate_ps;
|
uint32_t refresh_rate_ps;
|
||||||
|
uint32_t extended_op_srt;
|
||||||
uint32_t tIS_ps; /* byte 32, spd->ca_setup */
|
uint32_t tIS_ps; /* byte 32, spd->ca_setup */
|
||||||
uint32_t tIH_ps; /* byte 33, spd->ca_hold */
|
uint32_t tIH_ps; /* byte 33, spd->ca_hold */
|
||||||
uint32_t tDS_ps; /* byte 34, spd->data_setup */
|
uint32_t tDS_ps; /* byte 34, spd->data_setup */
|
||||||
|
@ -55,6 +63,7 @@ struct dimm_params_s {
|
||||||
uint32_t tRTP_ps; /* byte 38, spd->trtp */
|
uint32_t tRTP_ps; /* byte 38, spd->trtp */
|
||||||
uint32_t tDQSQ_max_ps; /* byte 44, spd->tdqsq */
|
uint32_t tDQSQ_max_ps; /* byte 44, spd->tdqsq */
|
||||||
uint32_t tQHS_ps; /* byte 45, spd->tqhs */
|
uint32_t tQHS_ps; /* byte 45, spd->tqhs */
|
||||||
|
uint32_t rcw[16];
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -19,17 +19,24 @@
|
||||||
#define SDRAM_TYPE_DDR3 7
|
#define SDRAM_TYPE_DDR3 7
|
||||||
|
|
||||||
#define DDR_BL4 4
|
#define DDR_BL4 4
|
||||||
|
#define DDR_BC4 DDR_BL4
|
||||||
|
#define DDR_OTF 6
|
||||||
#define DDR_BL8 8
|
#define DDR_BL8 8
|
||||||
|
|
||||||
#define DDR2_RTT_OFF 0
|
#define DDR2_RTT_OFF 0
|
||||||
#define DDR2_RTT_75_OHM 1
|
#define DDR2_RTT_75_OHM 1
|
||||||
#define DDR2_RTT_150_OHM 2
|
#define DDR2_RTT_150_OHM 2
|
||||||
#define DDR2_RTT_50_OHM 3
|
#define DDR2_RTT_50_OHM 3
|
||||||
|
#define DDR3_RTT_OFF 0
|
||||||
|
#define DDR3_RTT_40_OHM 3
|
||||||
|
|
||||||
#if defined(CONFIG_FSL_DDR2)
|
|
||||||
#define FSL_DDR_MIN_TCKE_PULSE_WIDTH_DDR (3)
|
#define FSL_DDR_MIN_TCKE_PULSE_WIDTH_DDR (3)
|
||||||
|
#if defined(CONFIG_FSL_DDR2)
|
||||||
typedef struct ddr2_spd_eeprom_s generic_spd_eeprom_t;
|
typedef struct ddr2_spd_eeprom_s generic_spd_eeprom_t;
|
||||||
#define FSL_SDRAM_TYPE SDRAM_TYPE_DDR2
|
#define FSL_SDRAM_TYPE SDRAM_TYPE_DDR2
|
||||||
|
#elif defined(CONFIG_FSL_DDR3)
|
||||||
|
typedef struct ddr3_spd_eeprom_s generic_spd_eeprom_t;
|
||||||
|
#define FSL_SDRAM_TYPE SDRAM_TYPE_DDR3
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define FSL_DDR_ODT_NEVER 0x0
|
#define FSL_DDR_ODT_NEVER 0x0
|
||||||
|
@ -121,6 +128,10 @@ struct memctl_options_s {
|
||||||
uint32_t dynamic_power;
|
uint32_t dynamic_power;
|
||||||
uint32_t data_bus_width;
|
uint32_t data_bus_width;
|
||||||
uint32_t burst_length;
|
uint32_t burst_length;
|
||||||
|
uint32_t otf_burst_chop_en;
|
||||||
|
uint32_t mirrored_dimm;
|
||||||
|
uint32_t ap_en;
|
||||||
|
uint32_t x4_en;
|
||||||
/* Global Timing Parameters */
|
/* Global Timing Parameters */
|
||||||
uint32_t cas_latency_override;
|
uint32_t cas_latency_override;
|
||||||
uint32_t cas_latency_override_value;
|
uint32_t cas_latency_override_value;
|
||||||
|
@ -130,16 +141,36 @@ struct memctl_options_s {
|
||||||
uint32_t clk_adjust;
|
uint32_t clk_adjust;
|
||||||
uint32_t cpo_override;
|
uint32_t cpo_override;
|
||||||
uint32_t write_data_delay;
|
uint32_t write_data_delay;
|
||||||
|
/* Write leveling */
|
||||||
|
uint32_t wrlvl_override;
|
||||||
|
uint32_t wrlvl_sample;
|
||||||
|
uint32_t wrlvl_start;
|
||||||
|
uint32_t wrlvl_ctl_2;
|
||||||
|
uint32_t wrlvl_ctl_3;
|
||||||
uint32_t half_strength_driver_enable;
|
uint32_t half_strength_driver_enable;
|
||||||
uint32_t twoT_en;
|
uint32_t twoT_en;
|
||||||
|
uint32_t threet_en;
|
||||||
uint32_t bstopre;
|
uint32_t bstopre;
|
||||||
uint32_t tCKE_clock_pulse_width_ps;
|
uint32_t tCKE_clock_pulse_width_ps;
|
||||||
uint32_t tFAW_window_four_activates_ps;
|
uint32_t tFAW_window_four_activates_ps;
|
||||||
/* Rtt impedance */
|
/* Rtt impedance */
|
||||||
uint32_t rtt_override;
|
uint32_t rtt_override;
|
||||||
uint32_t rtt_override_value;
|
uint32_t rtt_override_value;
|
||||||
|
uint32_t rtt_wr_override_value;
|
||||||
/* Automatic self refresh */
|
/* Automatic self refresh */
|
||||||
uint32_t auto_self_refresh_en;
|
uint32_t auto_self_refresh_en;
|
||||||
|
uint32_t sr_it;
|
||||||
|
/* ZQ calibration */
|
||||||
|
uint32_t zq_en;
|
||||||
|
/* Write leveling */
|
||||||
|
uint32_t wrlvl_en;
|
||||||
|
/* RCW override for RDIMM */
|
||||||
|
uint32_t rcw_override;
|
||||||
|
uint32_t rcw_1;
|
||||||
|
uint32_t rcw_2;
|
||||||
|
/* control register 1 */
|
||||||
|
uint32_t ddr_cdr1;
|
||||||
|
uint32_t ddr_cdr2;
|
||||||
/* read-to-write turnaround */
|
/* read-to-write turnaround */
|
||||||
uint32_t trwt_override;
|
uint32_t trwt_override;
|
||||||
uint32_t trwt;
|
uint32_t trwt;
|
||||||
|
|
|
@ -25,8 +25,10 @@
|
||||||
#define BR_PS_8 0x00000800 /* Port Size 8 bit */
|
#define BR_PS_8 0x00000800 /* Port Size 8 bit */
|
||||||
#define BR_PS_16 0x00001000 /* Port Size 16 bit */
|
#define BR_PS_16 0x00001000 /* Port Size 16 bit */
|
||||||
#define BR_PS_32 0x00001800 /* Port Size 32 bit */
|
#define BR_PS_32 0x00001800 /* Port Size 32 bit */
|
||||||
|
#define BR_DECC_SHIFT 9
|
||||||
#define BR_V 0x00000001
|
#define BR_V 0x00000001
|
||||||
#define BR_V_SHIFT 0
|
#define BR_V_SHIFT 0
|
||||||
|
#define BR_MS_FCM 0x00000020
|
||||||
#define BR_MS_UPMA 0x00000080
|
#define BR_MS_UPMA 0x00000080
|
||||||
|
|
||||||
/* Convert an address into the right format for the BR registers */
|
/* Convert an address into the right format for the BR registers */
|
||||||
|
@ -61,6 +63,7 @@
|
||||||
#define FSL_LBC_MDR_OFFSET 0x88
|
#define FSL_LBC_MDR_OFFSET 0x88
|
||||||
#define FSL_LBC_LTESR_OFFSET 0xB0
|
#define FSL_LBC_LTESR_OFFSET 0xB0
|
||||||
#define FSL_LBC_LTEIR_OFFSET 0xB8
|
#define FSL_LBC_LTEIR_OFFSET 0xB8
|
||||||
|
#define FSL_LBC_LBCR_OFFSET 0xD0
|
||||||
|
|
||||||
#define MxMR_MAD_MSK 0x0000003f /* Machine Address Mask */
|
#define MxMR_MAD_MSK 0x0000003f /* Machine Address Mask */
|
||||||
#define MxMR_GPL_x4DIS 0x00040000 /* GPL_A4 Ouput Line Disable */
|
#define MxMR_GPL_x4DIS 0x00040000 /* GPL_A4 Ouput Line Disable */
|
||||||
|
|
|
@ -867,6 +867,7 @@
|
||||||
#define SVR_8641 0x8090
|
#define SVR_8641 0x8090
|
||||||
#define SVR_8544 0x803401
|
#define SVR_8544 0x803401
|
||||||
#define SVR_8544_E 0x803C01
|
#define SVR_8544_E 0x803C01
|
||||||
|
#define SVR_P1022 0x80E600
|
||||||
#define SVR_P2020 0x80E200
|
#define SVR_P2020 0x80E200
|
||||||
#define SVR_P2020_E 0x80EA00
|
#define SVR_P2020_E 0x80EA00
|
||||||
|
|
||||||
|
|
|
@ -1,17 +1,21 @@
|
||||||
if ARCH_MPC85XX
|
if ARCH_MPC85XX
|
||||||
|
|
||||||
config MMU
|
config MMU
|
||||||
default y if CMD_MEMTEST
|
default y
|
||||||
|
|
||||||
|
config BTB
|
||||||
|
bool
|
||||||
|
default y if P2020RDB || P1022DS || DA923RC
|
||||||
|
|
||||||
config TEXT_BASE
|
config TEXT_BASE
|
||||||
hex
|
hex
|
||||||
default 0xeff80000 if P2020RDB
|
default 0xeff80000 if P2020RDB || P1022DS
|
||||||
default 0xfff80000 if DA923RC
|
default 0xfff80000 if DA923RC
|
||||||
|
|
||||||
config RESET_VECTOR_ADDRESS
|
config RESET_VECTOR_ADDRESS
|
||||||
hex
|
hex
|
||||||
default 0xfffffffc if DA923RC
|
default 0xfffffffc if DA923RC
|
||||||
default 0xeffffffc if P2020RDB
|
default 0xeffffffc if P2020RDB || P1022DS
|
||||||
|
|
||||||
config MPC85xx
|
config MPC85xx
|
||||||
bool
|
bool
|
||||||
|
@ -33,6 +37,11 @@ config P2020RDB
|
||||||
help
|
help
|
||||||
Say Y here if you are using the Freescale P2020RDB
|
Say Y here if you are using the Freescale P2020RDB
|
||||||
|
|
||||||
|
config P1022DS
|
||||||
|
bool "P1022DS"
|
||||||
|
help
|
||||||
|
Say Y here if you are using the Freescale P1022DS
|
||||||
|
|
||||||
config DA923RC
|
config DA923RC
|
||||||
bool "DA923RC"
|
bool "DA923RC"
|
||||||
help
|
help
|
||||||
|
@ -40,12 +49,27 @@ config DA923RC
|
||||||
endchoice
|
endchoice
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
config FSL_ELBC
|
||||||
|
bool
|
||||||
|
default y if P2020RDB || P1022DS
|
||||||
|
|
||||||
|
config DDR_SPD
|
||||||
|
bool
|
||||||
|
select CRC16
|
||||||
|
default y if DA923RC || P1022DS
|
||||||
|
|
||||||
if P2020RDB
|
if P2020RDB
|
||||||
config P2020
|
config P2020
|
||||||
bool
|
bool
|
||||||
default y
|
default y
|
||||||
|
endif
|
||||||
|
|
||||||
config FSL_ELBC
|
if P1022DS
|
||||||
|
config P1022
|
||||||
|
bool
|
||||||
|
default y
|
||||||
|
|
||||||
|
config FSL_DDR3
|
||||||
bool
|
bool
|
||||||
default y
|
default y
|
||||||
endif
|
endif
|
||||||
|
@ -55,10 +79,6 @@ config MPC8544
|
||||||
bool
|
bool
|
||||||
default y
|
default y
|
||||||
|
|
||||||
config DDR_SPD
|
|
||||||
bool
|
|
||||||
default y
|
|
||||||
|
|
||||||
config FSL_DDR2
|
config FSL_DDR2
|
||||||
bool
|
bool
|
||||||
default y
|
default y
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
struct cpu_type cpu_type_list[] = {
|
struct cpu_type cpu_type_list[] = {
|
||||||
CPU_TYPE_ENTRY(8544, 8544, 1),
|
CPU_TYPE_ENTRY(8544, 8544, 1),
|
||||||
CPU_TYPE_ENTRY(8544, 8544_E, 1),
|
CPU_TYPE_ENTRY(8544, 8544_E, 1),
|
||||||
|
CPU_TYPE_ENTRY(P1022, P1022, 2),
|
||||||
CPU_TYPE_ENTRY(P2020, P2020, 2),
|
CPU_TYPE_ENTRY(P2020, P2020, 2),
|
||||||
CPU_TYPE_ENTRY(P2020, P2020_E, 2),
|
CPU_TYPE_ENTRY(P2020, P2020_E, 2),
|
||||||
};
|
};
|
||||||
|
|
|
@ -54,6 +54,14 @@ static void fdt_add_enet_stashing(void *fdt)
|
||||||
of_property_write_u32(node, "rx-stash-idx", 0);
|
of_property_write_u32(node, "rx-stash-idx", 0);
|
||||||
node = of_find_compatible_node(node, NULL, "gianfar");
|
node = of_find_compatible_node(node, NULL, "gianfar");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
node = of_find_compatible_node(fdt, NULL, "fsl,etsec2");
|
||||||
|
while (node) {
|
||||||
|
of_set_property(node, "bd-stash", NULL, 0, 1);
|
||||||
|
of_property_write_u32(node, "rx-stash-len", 96);
|
||||||
|
of_property_write_u32(node, "rx-stash-idx", 0);
|
||||||
|
node = of_find_compatible_node(node, NULL, "fsl,etsec2");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int fdt_stdout_setup(struct device_node *blob)
|
static int fdt_stdout_setup(struct device_node *blob)
|
||||||
|
|
|
@ -39,6 +39,15 @@
|
||||||
#define FSL_ERRATUM_A005125
|
#define FSL_ERRATUM_A005125
|
||||||
#define PPC_E500_DEBUG_TLB 0
|
#define PPC_E500_DEBUG_TLB 0
|
||||||
|
|
||||||
|
#elif defined(CONFIG_P1022)
|
||||||
|
#define MAX_CPUS 2
|
||||||
|
#define FSL_NUM_LAWS 12
|
||||||
|
#define FSL_NUM_TSEC 2
|
||||||
|
#define FSL_SEC_COMPAT 2
|
||||||
|
#define PPC_E500_DEBUG_TLB 2
|
||||||
|
#define FSL_TSECV2
|
||||||
|
#define FSL_ERRATUM_A005125
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#error Processor type not defined for this platform
|
#error Processor type not defined for this platform
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -36,7 +36,7 @@
|
||||||
|
|
||||||
#define MPC85xx_GPIO_OFFSET 0xf000
|
#define MPC85xx_GPIO_OFFSET 0xf000
|
||||||
#define MPC85xx_L2_OFFSET 0x20000
|
#define MPC85xx_L2_OFFSET 0x20000
|
||||||
#ifdef CONFIG_TSECV2
|
#ifdef FSL_TSECV2
|
||||||
#define TSEC1_OFFSET 0xB0000
|
#define TSEC1_OFFSET 0xB0000
|
||||||
#else
|
#else
|
||||||
#define TSEC1_OFFSET 0x24000
|
#define TSEC1_OFFSET 0x24000
|
||||||
|
@ -75,6 +75,11 @@
|
||||||
#define MPC85xx_DDR_CS1_CONFIG_OFFSET 0x084
|
#define MPC85xx_DDR_CS1_CONFIG_OFFSET 0x084
|
||||||
#define MPC85xx_DDR_CS2_CONFIG_OFFSET 0x088
|
#define MPC85xx_DDR_CS2_CONFIG_OFFSET 0x088
|
||||||
#define MPC85xx_DDR_CS3_CONFIG_OFFSET 0x08c
|
#define MPC85xx_DDR_CS3_CONFIG_OFFSET 0x08c
|
||||||
|
/* Chip Select 0, 1, 2, 3 Configuration 2 */
|
||||||
|
#define MPC85xx_DDR_CS0_CONFIG_2_OFFSET 0x0c0
|
||||||
|
#define MPC85xx_DDR_CS1_CONFIG_2_OFFSET 0x0c4
|
||||||
|
#define MPC85xx_DDR_CS2_CONFIG_2_OFFSET 0x0c8
|
||||||
|
#define MPC85xx_DDR_CS3_CONFIG_2_OFFSET 0x0cc
|
||||||
/* SDRAM Timing Configuration 0, 1, 2, 3 */
|
/* SDRAM Timing Configuration 0, 1, 2, 3 */
|
||||||
#define MPC85xx_DDR_TIMING_CFG_3_OFFSET 0x100
|
#define MPC85xx_DDR_TIMING_CFG_3_OFFSET 0x100
|
||||||
#define MPC85xx_DDR_TIMING_CFG_0_OFFSET 0x104
|
#define MPC85xx_DDR_TIMING_CFG_0_OFFSET 0x104
|
||||||
|
@ -97,9 +102,30 @@
|
||||||
/* training init and extended addr */
|
/* training init and extended addr */
|
||||||
#define MPC85xx_DDR_SDRAM_INIT_ADDR_OFFSET 0x148
|
#define MPC85xx_DDR_SDRAM_INIT_ADDR_OFFSET 0x148
|
||||||
#define MPC85xx_DDR_SDRAM_INIT_ADDR_EXT_OFFSET 0x14c
|
#define MPC85xx_DDR_SDRAM_INIT_ADDR_EXT_OFFSET 0x14c
|
||||||
|
/* SDRAM Timing Configuration 4,5 */
|
||||||
|
#define MPC85xx_DDR_TIMING_CFG_4_OFFSET 0x160
|
||||||
|
#define MPC85xx_DDR_TIMING_CFG_5_OFFSET 0x164
|
||||||
|
/* DDR ZQ calibration control */
|
||||||
|
#define MPC85xx_DDR_ZQ_CNTL_OFFSET 0x170
|
||||||
|
/* DDR write leveling control */
|
||||||
|
#define MPC85xx_DDR_WRLVL_CNTL_OFFSET 0x174
|
||||||
|
/* Self Refresh Counter */
|
||||||
|
#define MPC85xx_DDR_SR_CNTL_OFFSET 0x17c
|
||||||
|
/* DDR SDRAM Register Control Word */
|
||||||
|
#define MPC85xx_DDR_SDRAM_RCW_1_OFFSET 0x180
|
||||||
|
#define MPC85xx_DDR_SDRAM_RCW_2_OFFSET 0x184
|
||||||
|
/* DDR write leveling control */
|
||||||
|
#define MPC85xx_DDR_WRLVL_CNTL_2_OFFSET 0x190
|
||||||
|
#define MPC85xx_DDR_WRLVL_CNTL_3_OFFSET 0x194
|
||||||
|
/* DDR Control Driver */
|
||||||
|
#define MPC85xx_DDR_DDRCDR1_OFFSET 0xb28
|
||||||
|
#define MPC85xx_DDR_DDRCDR2_OFFSET 0xb2c
|
||||||
/* DDR IP block revision */
|
/* DDR IP block revision */
|
||||||
#define MPC85xx_DDR_IP_REV1_OFFSET 0xbf8
|
#define MPC85xx_DDR_IP_REV1_OFFSET 0xbf8
|
||||||
#define MPC85xx_DDR_IP_REV2_OFFSET 0xbfc
|
#define MPC85xx_DDR_IP_REV2_OFFSET 0xbfc
|
||||||
|
/* Memory Error Disable */
|
||||||
|
#define MPC85xx_DDR_ERR_DISABLE_OFFSET 0xe44
|
||||||
|
#define MPC85xx_DDR_ERR_INT_EN_OFFSET 0xe48
|
||||||
|
|
||||||
#define DDR_OFF(REGNAME) (MPC85xx_DDR_##REGNAME##_OFFSET)
|
#define DDR_OFF(REGNAME) (MPC85xx_DDR_##REGNAME##_OFFSET)
|
||||||
|
|
||||||
|
@ -147,6 +173,8 @@
|
||||||
#define MPC85xx_PORPLLSR_DDR_RATIO_SHIFT 9
|
#define MPC85xx_PORPLLSR_DDR_RATIO_SHIFT 9
|
||||||
#define MPC85xx_GUTS_PORDEVSR2_OFFSET 0x14
|
#define MPC85xx_GUTS_PORDEVSR2_OFFSET 0x14
|
||||||
#define MPC85xx_PORDEVSR2_SEC_CFG 0x00000080
|
#define MPC85xx_PORDEVSR2_SEC_CFG 0x00000080
|
||||||
|
#define MPC85xx_GUTS_PMUXCR_OFFSET 0x60
|
||||||
|
#define MPC85xx_GUTS_PMUXCR2_OFFSET 0x64
|
||||||
#define MPC85xx_GUTS_DEVDISR_OFFSET 0x70
|
#define MPC85xx_GUTS_DEVDISR_OFFSET 0x70
|
||||||
#define MPC85xx_DEVDISR_TB0 0x00004000
|
#define MPC85xx_DEVDISR_TB0 0x00004000
|
||||||
#define MPC85xx_DEVDISR_TB1 0x00001000
|
#define MPC85xx_DEVDISR_TB1 0x00001000
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
|
#include <crc.h>
|
||||||
#include <ddr_spd.h>
|
#include <ddr_spd.h>
|
||||||
|
|
||||||
uint32_t ddr2_spd_checksum_pass(const struct ddr2_spd_eeprom_s *spd)
|
uint32_t ddr2_spd_checksum_pass(const struct ddr2_spd_eeprom_s *spd)
|
||||||
|
@ -37,3 +38,26 @@ uint32_t ddr2_spd_checksum_pass(const struct ddr2_spd_eeprom_s *spd)
|
||||||
error:
|
error:
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t ddr3_spd_checksum_pass(const struct ddr3_spd_eeprom_s *spd)
|
||||||
|
{
|
||||||
|
char crc_lsb, crc_msb;
|
||||||
|
int csum16, len;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SPD byte0[7] - CRC coverage
|
||||||
|
* 0 = CRC covers bytes 0~125
|
||||||
|
* 1 = CRC covers bytes 0~116
|
||||||
|
*/
|
||||||
|
|
||||||
|
len = !(spd->info_size_crc & 0x80) ? 126 : 117;
|
||||||
|
csum16 = cyg_crc16((char *)spd, len);
|
||||||
|
|
||||||
|
crc_lsb = (char) (csum16 & 0xff);
|
||||||
|
crc_msb = (char) (csum16 >> 8);
|
||||||
|
|
||||||
|
if (spd->crc[0] != crc_lsb || spd->crc[1] != crc_msb)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -114,13 +114,126 @@ struct ddr2_spd_eeprom_s {
|
||||||
uint8_t mdate[2]; /* 93 Manufacturing Date */
|
uint8_t mdate[2]; /* 93 Manufacturing Date */
|
||||||
uint8_t sernum[4]; /* 95 Assembly Serial Number */
|
uint8_t sernum[4]; /* 95 Assembly Serial Number */
|
||||||
uint8_t mspec[27]; /* 99-127 Manufacturer Specific Data */
|
uint8_t mspec[27]; /* 99-127 Manufacturer Specific Data */
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ddr3_spd_eeprom_s {
|
||||||
|
/* General Section: Bytes 0-59 */
|
||||||
|
uint8_t info_size_crc; /* 0 # bytes written into serial memory,
|
||||||
|
CRC coverage */
|
||||||
|
uint8_t spd_rev; /* 1 Total # bytes of SPD mem device */
|
||||||
|
uint8_t mem_type; /* 2 Key Byte / Fundamental mem type */
|
||||||
|
uint8_t module_type; /* 3 Key Byte / Module Type */
|
||||||
|
uint8_t density_banks; /* 4 SDRAM Density and Banks */
|
||||||
|
uint8_t addressing; /* 5 SDRAM Addressing */
|
||||||
|
uint8_t module_vdd; /* 6 Module nominal voltage, VDD */
|
||||||
|
uint8_t organization; /* 7 Module Organization */
|
||||||
|
uint8_t bus_width; /* 8 Module Memory Bus Width */
|
||||||
|
uint8_t ftb_div; /* 9 Fine Timebase (FTB)
|
||||||
|
Dividend / Divisor */
|
||||||
|
uint8_t mtb_dividend; /* 10 Medium Timebase (MTB) Dividend */
|
||||||
|
uint8_t mtb_divisor; /* 11 Medium Timebase (MTB) Divisor */
|
||||||
|
uint8_t tck_min; /* 12 SDRAM Minimum Cycle Time */
|
||||||
|
uint8_t res_13; /* 13 Reserved */
|
||||||
|
uint8_t caslat_lsb; /* 14 CAS Latencies Supported,
|
||||||
|
Least Significant Byte */
|
||||||
|
uint8_t caslat_msb; /* 15 CAS Latencies Supported,
|
||||||
|
Most Significant Byte */
|
||||||
|
uint8_t taa_min; /* 16 Min CAS Latency Time */
|
||||||
|
uint8_t twr_min; /* 17 Min Write REcovery Time */
|
||||||
|
uint8_t trcd_min; /* 18 Min RAS# to CAS# Delay Time */
|
||||||
|
uint8_t trrd_min; /* 19 Min Row Active to
|
||||||
|
Row Active Delay Time */
|
||||||
|
uint8_t trp_min; /* 20 Min Row Precharge Delay Time */
|
||||||
|
uint8_t tras_trc_ext; /* 21 Upper Nibbles for tRAS and tRC */
|
||||||
|
uint8_t tras_min_lsb; /* 22 Min Active to Precharge
|
||||||
|
Delay Time */
|
||||||
|
uint8_t trc_min_lsb; /* 23 Min Active to Active/Refresh
|
||||||
|
Delay Time, LSB */
|
||||||
|
uint8_t trfc_min_lsb; /* 24 Min Refresh Recovery Delay Time */
|
||||||
|
uint8_t trfc_min_msb; /* 25 Min Refresh Recovery Delay Time */
|
||||||
|
uint8_t twtr_min; /* 26 Min Internal Write to
|
||||||
|
Read Command Delay Time */
|
||||||
|
uint8_t trtp_min; /* 27 Min Internal Read to Precharge
|
||||||
|
Command Delay Time */
|
||||||
|
uint8_t tfaw_msb; /* 28 Upper Nibble for tFAW */
|
||||||
|
uint8_t tfaw_min; /* 29 Min Four Activate Window
|
||||||
|
Delay Time*/
|
||||||
|
uint8_t opt_features; /* 30 SDRAM Optional Features */
|
||||||
|
uint8_t therm_ref_opt; /* 31 SDRAM Thermal and Refresh Opts */
|
||||||
|
uint8_t therm_sensor; /* 32 Module Thermal Sensor */
|
||||||
|
uint8_t device_type; /* 33 SDRAM device type */
|
||||||
|
int8_t fine_tck_min; /* 34 Fine offset for tCKmin */
|
||||||
|
int8_t fine_taa_min; /* 35 Fine offset for tAAmin */
|
||||||
|
int8_t fine_trcd_min; /* 36 Fine offset for tRCDmin */
|
||||||
|
int8_t fine_trp_min; /* 37 Fine offset for tRPmin */
|
||||||
|
int8_t fine_trc_min; /* 38 Fine offset for tRCmin */
|
||||||
|
uint8_t res_39_59[21]; /* 39-59 Reserved, General Section */
|
||||||
|
|
||||||
|
/* Module-Specific Section: Bytes 60-116 */
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
/* 60 (Unbuffered) Module Nominal Height */
|
||||||
|
uint8_t mod_height;
|
||||||
|
/* 61 (Unbuffered) Module Maximum Thickness */
|
||||||
|
uint8_t mod_thickness;
|
||||||
|
/* 62 (Unbuffered) Reference Raw Card Used */
|
||||||
|
uint8_t ref_raw_card;
|
||||||
|
/* 63 (Unbuffered) Address Mapping from
|
||||||
|
Edge Connector to DRAM */
|
||||||
|
uint8_t addr_mapping;
|
||||||
|
/* 64-116 (Unbuffered) Reserved */
|
||||||
|
uint8_t res_64_116[53];
|
||||||
|
} unbuffered;
|
||||||
|
struct {
|
||||||
|
/* 60 (Registered) Module Nominal Height */
|
||||||
|
uint8_t mod_height;
|
||||||
|
/* 61 (Registered) Module Maximum Thickness */
|
||||||
|
uint8_t mod_thickness;
|
||||||
|
/* 62 (Registered) Reference Raw Card Used */
|
||||||
|
uint8_t ref_raw_card;
|
||||||
|
/* 63 DIMM Module Attributes */
|
||||||
|
uint8_t modu_attr;
|
||||||
|
/* 64 RDIMM Thermal Heat Spreader Solution */
|
||||||
|
uint8_t thermal;
|
||||||
|
/* 65 Register Manufacturer ID Code, LSB */
|
||||||
|
uint8_t reg_id_lo;
|
||||||
|
/* 66 Register Manufacturer ID Code, MSB */
|
||||||
|
uint8_t reg_id_hi;
|
||||||
|
/* 67 Register Revision Number */
|
||||||
|
uint8_t reg_rev;
|
||||||
|
/* 68 Register Type */
|
||||||
|
uint8_t reg_type;
|
||||||
|
/* 69-76 RC1,3,5..15 (MS Nib.)/RC0,2,4..14 (LS Nib.) */
|
||||||
|
uint8_t rcw[8];
|
||||||
|
} registered;
|
||||||
|
uint8_t uc[57]; /* 60-116 Module-Specific Section */
|
||||||
|
} mod_section;
|
||||||
|
|
||||||
|
/* Unique Module ID: Bytes 117-125 */
|
||||||
|
uint8_t mmid_lsb; /* 117 Module MfgID Code LSB - JEP-106 */
|
||||||
|
uint8_t mmid_msb; /* 118 Module MfgID Code MSB - JEP-106 */
|
||||||
|
uint8_t mloc; /* 119 Mfg Location */
|
||||||
|
uint8_t mdate[2]; /* 120-121 Mfg Date */
|
||||||
|
uint8_t sernum[4]; /* 122-125 Module Serial Number */
|
||||||
|
|
||||||
|
/* CRC: Bytes 126-127 */
|
||||||
|
uint8_t crc[2]; /* 126-127 SPD CRC */
|
||||||
|
|
||||||
|
/* Other Manufacturer Fields and User Space: Bytes 128-255 */
|
||||||
|
uint8_t mpart[18]; /* 128-145 Mfg's Module Part Number */
|
||||||
|
uint8_t mrev[2]; /* 146-147 Module Revision Code */
|
||||||
|
uint8_t dmid_lsb; /* 148 DRAM MfgID Code LSB - JEP-106 */
|
||||||
|
uint8_t dmid_msb; /* 149 DRAM MfgID Code MSB - JEP-106 */
|
||||||
|
uint8_t msd[26]; /* 150-175 Mfg's Specific Data */
|
||||||
|
uint8_t cust[80]; /* 176-255 Open for Customer Use */
|
||||||
|
};
|
||||||
|
|
||||||
|
extern uint32_t ddr3_spd_checksum_pass(const struct ddr3_spd_eeprom_s *spd);
|
||||||
extern uint32_t ddr2_spd_checksum_pass(const struct ddr2_spd_eeprom_s *spd);
|
extern uint32_t ddr2_spd_checksum_pass(const struct ddr2_spd_eeprom_s *spd);
|
||||||
|
|
||||||
/* * Byte 2 Fundamental Memory Types. */
|
/* * Byte 2 Fundamental Memory Types. */
|
||||||
#define SPD_MEMTYPE_DDR2 (0x08)
|
#define SPD_MEMTYPE_DDR2 (0x08)
|
||||||
|
#define SPD_MEMTYPE_DDR3 (0x0B)
|
||||||
|
|
||||||
/* DIMM Type for DDR2 SPD (according to v1.3) */
|
/* DIMM Type for DDR2 SPD (according to v1.3) */
|
||||||
#define DDR2_SPD_DIMMTYPE_RDIMM (0x01)
|
#define DDR2_SPD_DIMMTYPE_RDIMM (0x01)
|
||||||
|
@ -132,4 +245,7 @@ extern uint32_t ddr2_spd_checksum_pass(const struct ddr2_spd_eeprom_s *spd);
|
||||||
#define DDR2_SPD_DIMMTYPE_MINI_RDIMM (0x10)
|
#define DDR2_SPD_DIMMTYPE_MINI_RDIMM (0x10)
|
||||||
#define DDR2_SPD_DIMMTYPE_MINI_UDIMM (0x20)
|
#define DDR2_SPD_DIMMTYPE_MINI_UDIMM (0x20)
|
||||||
|
|
||||||
|
/* Byte 3 Key Byte / Module Type for DDR3 SPD */
|
||||||
|
#define DDR3_SPD_MODULETYPE_MASK (0x0F)
|
||||||
|
#define DDR3_SPD_MODULETYPE_UDIMM (0x02)
|
||||||
#endif /* _DDR_SPD_H_ */
|
#endif /* _DDR_SPD_H_ */
|
||||||
|
|
Loading…
Reference in New Issue