commit
080d897585
@ -1,63 +0,0 @@ |
||||
/* |
||||
* Copyright 2009 Freescale Semiconductor, Inc. |
||||
* |
||||
* Kumar Gala <kumar.gala@freescale.com>
|
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
*/ |
||||
|
||||
/* This file is intended to be included by other asm code since |
||||
* we will want to execute this on both the primary core when |
||||
* it does a bootm and the secondary core's that get released |
||||
* out of the spin table */ |
||||
|
||||
#define SET_IVOR(vector_number, vector_offset) \ |
||||
li r3,vector_offset@l; \
|
||||
mtspr SPRN_IVOR##vector_number,r3;
|
||||
|
||||
#define SET_GIVOR(vector_number, vector_offset) \ |
||||
li r3,vector_offset@l; \
|
||||
mtspr SPRN_GIVOR##vector_number,r3;
|
||||
|
||||
SET_IVOR(0, 0x020) /* Critical Input */ |
||||
SET_IVOR(1, 0x000) /* Machine Check */ |
||||
SET_IVOR(2, 0x060) /* Data Storage */ |
||||
SET_IVOR(3, 0x080) /* Instruction Storage */ |
||||
SET_IVOR(4, 0x0a0) /* External Input */ |
||||
SET_IVOR(5, 0x0c0) /* Alignment */ |
||||
SET_IVOR(6, 0x0e0) /* Program */ |
||||
SET_IVOR(7, 0x100) /* FP Unavailable */ |
||||
SET_IVOR(8, 0x120) /* System Call */ |
||||
SET_IVOR(9, 0x140) /* Auxiliary Processor Unavailable */ |
||||
SET_IVOR(10, 0x160) /* Decrementer */ |
||||
SET_IVOR(11, 0x180) /* Fixed Interval Timer */ |
||||
SET_IVOR(12, 0x1a0) /* Watchdog Timer */ |
||||
SET_IVOR(13, 0x1c0) /* Data TLB Error */ |
||||
SET_IVOR(14, 0x1e0) /* Instruction TLB Error */ |
||||
SET_IVOR(15, 0x040) /* Debug */ |
||||
|
||||
/* e500v1 & e500v2 only */ |
||||
#ifndef CONFIG_E500MC |
||||
SET_IVOR(32, 0x200) /* SPE Unavailable */ |
||||
SET_IVOR(33, 0x220) /* Embedded FP Data */ |
||||
SET_IVOR(34, 0x240) /* Embedded FP Round */ |
||||
#endif |
||||
|
||||
SET_IVOR(35, 0x260) /* Performance monitor */ |
||||
|
||||
/* e500mc only */ |
||||
#ifdef CONFIG_E500MC |
||||
SET_IVOR(36, 0x280) /* Processor doorbell */ |
||||
SET_IVOR(37, 0x2a0) /* Processor doorbell critical */ |
||||
SET_IVOR(38, 0x2c0) /* Guest Processor doorbell */ |
||||
SET_IVOR(39, 0x2e0) /* Guest Processor critical & machine check */ |
||||
SET_IVOR(40, 0x300) /* Hypervisor system call */ |
||||
SET_IVOR(41, 0x320) /* Hypervisor Priviledge */ |
||||
|
||||
SET_GIVOR(2, 0x060) /* Guest Data Storage */ |
||||
SET_GIVOR(3, 0x080) /* Guest Instruction Storage */ |
||||
SET_GIVOR(4, 0x0a0) /* Guest External Input */ |
||||
SET_GIVOR(8, 0x120) /* Guest System Call */ |
||||
SET_GIVOR(13, 0x1c0) /* Guest Data TLB Error */ |
||||
SET_GIVOR(14, 0x1e0) /* Guest Instruction TLB Error */ |
||||
#endif |
@ -0,0 +1,114 @@ |
||||
/* Copyright 2013 Freescale Semiconductor, Inc.
|
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
*/ |
||||
|
||||
#include <common.h> |
||||
#include <asm/spl.h> |
||||
#include <malloc.h> |
||||
#include <ns16550.h> |
||||
#include <nand.h> |
||||
#include <i2c.h> |
||||
#include "../common/qixis.h" |
||||
#include "b4860qds_qixis.h" |
||||
|
||||
DECLARE_GLOBAL_DATA_PTR; |
||||
|
||||
phys_size_t get_effective_memsize(void) |
||||
{ |
||||
return CONFIG_SYS_L3_SIZE; |
||||
} |
||||
|
||||
unsigned long get_board_sys_clk(void) |
||||
{ |
||||
u8 sysclk_conf = QIXIS_READ(brdcfg[1]); |
||||
|
||||
switch ((sysclk_conf & 0x0C) >> 2) { |
||||
case QIXIS_CLK_100: |
||||
return 100000000; |
||||
case QIXIS_CLK_125: |
||||
return 125000000; |
||||
case QIXIS_CLK_133: |
||||
return 133333333; |
||||
} |
||||
return 66666666; |
||||
} |
||||
|
||||
unsigned long get_board_ddr_clk(void) |
||||
{ |
||||
u8 ddrclk_conf = QIXIS_READ(brdcfg[1]); |
||||
|
||||
switch (ddrclk_conf & 0x03) { |
||||
case QIXIS_CLK_100: |
||||
return 100000000; |
||||
case QIXIS_CLK_125: |
||||
return 125000000; |
||||
case QIXIS_CLK_133: |
||||
return 133333333; |
||||
} |
||||
return 66666666; |
||||
} |
||||
|
||||
void board_init_f(ulong bootflag) |
||||
{ |
||||
u32 plat_ratio, sys_clk, uart_clk; |
||||
ccsr_gur_t *gur = (void *)CONFIG_SYS_MPC85xx_GUTS_ADDR; |
||||
|
||||
/* Memcpy existing GD at CONFIG_SPL_GD_ADDR */ |
||||
memcpy((void *)CONFIG_SPL_GD_ADDR, (void *)gd, sizeof(gd_t)); |
||||
|
||||
/* Update GD pointer */ |
||||
gd = (gd_t *)(CONFIG_SPL_GD_ADDR); |
||||
|
||||
/* compiler optimization barrier needed for GCC >= 3.4 */ |
||||
__asm__ __volatile__("" : : : "memory"); |
||||
|
||||
console_init_f(); |
||||
|
||||
/* initialize selected port with appropriate baud rate */ |
||||
sys_clk = get_board_sys_clk(); |
||||
plat_ratio = (in_be32(&gur->rcwsr[0]) >> 25) & 0x1f; |
||||
uart_clk = sys_clk * plat_ratio / 2; |
||||
|
||||
NS16550_init((NS16550_t)CONFIG_SYS_NS16550_COM1, |
||||
uart_clk / 16 / CONFIG_BAUDRATE); |
||||
|
||||
relocate_code(CONFIG_SPL_RELOC_STACK, (gd_t *)CONFIG_SPL_GD_ADDR, 0x0); |
||||
} |
||||
|
||||
void board_init_r(gd_t *gd, ulong dest_addr) |
||||
{ |
||||
bd_t *bd; |
||||
|
||||
bd = (bd_t *)(gd + sizeof(gd_t)); |
||||
memset(bd, 0, sizeof(bd_t)); |
||||
gd->bd = bd; |
||||
bd->bi_memstart = CONFIG_SYS_INIT_L3_ADDR; |
||||
bd->bi_memsize = CONFIG_SYS_L3_SIZE; |
||||
|
||||
probecpu(); |
||||
get_clocks(); |
||||
mem_malloc_init(CONFIG_SPL_RELOC_MALLOC_ADDR, |
||||
CONFIG_SPL_RELOC_MALLOC_SIZE); |
||||
|
||||
#ifndef CONFIG_SPL_NAND_BOOT |
||||
env_init(); |
||||
env_relocate(); |
||||
#else |
||||
/* relocate environment function pointers etc. */ |
||||
nand_spl_load_image(CONFIG_ENV_OFFSET, CONFIG_ENV_SIZE, |
||||
(uchar *)CONFIG_ENV_ADDR); |
||||
gd->env_addr = (ulong)(CONFIG_ENV_ADDR); |
||||
gd->env_valid = 1; |
||||
#endif |
||||
|
||||
i2c_init_all(); |
||||
|
||||
puts("\n\n"); |
||||
|
||||
gd->ram_size = initdram(0); |
||||
|
||||
#ifdef CONFIG_SPL_NAND_BOOT |
||||
nand_boot(); |
||||
#endif |
||||
} |
@ -0,0 +1,9 @@ |
||||
#
|
||||
# Copyright 2007 Freescale Semiconductor, Inc.
|
||||
# (C) Copyright 2001-2006
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
|
||||
obj-y += qemu-ppce500.o
|
@ -0,0 +1,348 @@ |
||||
/*
|
||||
* Copyright 2007,2009-2014 Freescale Semiconductor, Inc. |
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
*/ |
||||
|
||||
#include <common.h> |
||||
#include <command.h> |
||||
#include <pci.h> |
||||
#include <asm/processor.h> |
||||
#include <asm/mmu.h> |
||||
#include <asm/fsl_pci.h> |
||||
#include <asm/io.h> |
||||
#include <libfdt.h> |
||||
#include <fdt_support.h> |
||||
#include <netdev.h> |
||||
#include <fdtdec.h> |
||||
#include <errno.h> |
||||
#include <malloc.h> |
||||
|
||||
DECLARE_GLOBAL_DATA_PTR; |
||||
|
||||
static void *get_fdt_virt(void) |
||||
{ |
||||
return (void *)CONFIG_SYS_TMPVIRT; |
||||
} |
||||
|
||||
static uint64_t get_fdt_phys(void) |
||||
{ |
||||
return (uint64_t)(uintptr_t)gd->fdt_blob; |
||||
} |
||||
|
||||
static void map_fdt_as(int esel) |
||||
{ |
||||
u32 mas0, mas1, mas2, mas3, mas7; |
||||
uint64_t fdt_phys = get_fdt_phys(); |
||||
unsigned long fdt_phys_tlb = fdt_phys & ~0xffffful; |
||||
unsigned long fdt_virt_tlb = (ulong)get_fdt_virt() & ~0xffffful; |
||||
|
||||
mas0 = MAS0_TLBSEL(1) | MAS0_ESEL(esel); |
||||
mas1 = MAS1_VALID | MAS1_TID(0) | MAS1_TS | MAS1_TSIZE(BOOKE_PAGESZ_1M); |
||||
mas2 = FSL_BOOKE_MAS2(fdt_virt_tlb, 0); |
||||
mas3 = FSL_BOOKE_MAS3(fdt_phys_tlb, 0, MAS3_SW|MAS3_SR); |
||||
mas7 = FSL_BOOKE_MAS7(fdt_phys_tlb); |
||||
|
||||
write_tlb(mas0, mas1, mas2, mas3, mas7); |
||||
} |
||||
|
||||
uint64_t get_phys_ccsrbar_addr_early(void) |
||||
{ |
||||
void *fdt = get_fdt_virt(); |
||||
uint64_t r; |
||||
|
||||
/*
|
||||
* To be able to read the FDT we need to create a temporary TLB |
||||
* map for it. |
||||
*/ |
||||
map_fdt_as(10); |
||||
r = fdt_get_base_address(fdt, fdt_path_offset(fdt, "/soc")); |
||||
disable_tlb(10); |
||||
|
||||
return r; |
||||
} |
||||
|
||||
int board_early_init_f(void) |
||||
{ |
||||
return 0; |
||||
} |
||||
|
||||
int checkboard(void) |
||||
{ |
||||
return 0; |
||||
} |
||||
|
||||
static int pci_map_region(void *fdt, int pci_node, int range_id, |
||||
phys_size_t *ppaddr, pci_addr_t *pvaddr, |
||||
pci_size_t *psize, ulong *pmap_addr) |
||||
{ |
||||
uint64_t addr; |
||||
uint64_t size; |
||||
ulong map_addr; |
||||
int r; |
||||
|
||||
r = fdt_read_range(fdt, pci_node, 0, NULL, &addr, &size); |
||||
if (r) |
||||
return r; |
||||
|
||||
if (ppaddr) |
||||
*ppaddr = addr; |
||||
if (psize) |
||||
*psize = size; |
||||
|
||||
if (!pmap_addr) |
||||
return 0; |
||||
|
||||
map_addr = *pmap_addr; |
||||
|
||||
/* Align map_addr */ |
||||
map_addr += size - 1; |
||||
map_addr &= ~(size - 1); |
||||
|
||||
if (map_addr + size >= CONFIG_SYS_PCI_MAP_END) |
||||
return -1; |
||||
|
||||
/* Map virtual memory for range */ |
||||
assert(!tlb_map_range(map_addr, addr, size, TLB_MAP_IO)); |
||||
*pmap_addr = map_addr + size; |
||||
|
||||
if (pvaddr) |
||||
*pvaddr = map_addr; |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
void pci_init_board(void) |
||||
{ |
||||
struct pci_controller *pci_hoses; |
||||
void *fdt = get_fdt_virt(); |
||||
int pci_node = -1; |
||||
int pci_num = 0; |
||||
int pci_count = 0; |
||||
ulong map_addr; |
||||
|
||||
puts("\n"); |
||||
|
||||
/* Start MMIO and PIO range maps above RAM */ |
||||
map_addr = CONFIG_SYS_PCI_MAP_START; |
||||
|
||||
/* Count and allocate PCI buses */ |
||||
pci_node = fdt_node_offset_by_prop_value(fdt, pci_node, |
||||
"device_type", "pci", 4); |
||||
while (pci_node != -FDT_ERR_NOTFOUND) { |
||||
pci_node = fdt_node_offset_by_prop_value(fdt, pci_node, |
||||
"device_type", "pci", 4); |
||||
pci_count++; |
||||
} |
||||
|
||||
if (pci_count) { |
||||
pci_hoses = malloc(sizeof(struct pci_controller) * pci_count); |
||||
} else { |
||||
printf("PCI: disabled\n\n"); |
||||
return; |
||||
} |
||||
|
||||
/* Spawn PCI buses based on device tree */ |
||||
pci_node = fdt_node_offset_by_prop_value(fdt, pci_node, |
||||
"device_type", "pci", 4); |
||||
while (pci_node != -FDT_ERR_NOTFOUND) { |
||||
struct fsl_pci_info pci_info = { }; |
||||
const fdt32_t *reg; |
||||
int r; |
||||
|
||||
reg = fdt_getprop(fdt, pci_node, "reg", NULL); |
||||
pci_info.regs = fdt_translate_address(fdt, pci_node, reg); |
||||
|
||||
/* Map MMIO range */ |
||||
r = pci_map_region(fdt, pci_node, 0, &pci_info.mem_phys, NULL, |
||||
&pci_info.mem_size, &map_addr); |
||||
if (r) |
||||
break; |
||||
|
||||
/* Map PIO range */ |
||||
r = pci_map_region(fdt, pci_node, 1, &pci_info.io_phys, NULL, |
||||
&pci_info.io_size, &map_addr); |
||||
if (r) |
||||
break; |
||||
|
||||
/*
|
||||
* The PCI framework finds virtual addresses for the buses |
||||
* through our address map, so tell it the physical addresses. |
||||
*/ |
||||
pci_info.mem_bus = pci_info.mem_phys; |
||||
pci_info.io_bus = pci_info.io_phys; |
||||
|
||||
/* Instantiate */ |
||||
pci_info.pci_num = pci_num + 1; |
||||
|
||||
fsl_setup_hose(&pci_hoses[pci_num], pci_info.regs); |
||||
printf("PCI: base address %lx\n", pci_info.regs); |
||||
|
||||
fsl_pci_init_port(&pci_info, &pci_hoses[pci_num], pci_num); |
||||
|
||||
/* Jump to next PCI node */ |
||||
pci_node = fdt_node_offset_by_prop_value(fdt, pci_node, |
||||
"device_type", "pci", 4); |
||||
pci_num++; |
||||
} |
||||
|
||||
puts("\n"); |
||||
} |
||||
|
||||
int last_stage_init(void) |
||||
{ |
||||
void *fdt = get_fdt_virt(); |
||||
int len = 0; |
||||
const uint64_t *prop; |
||||
int chosen; |
||||
|
||||
chosen = fdt_path_offset(fdt, "/chosen"); |
||||
if (chosen < 0) { |
||||
printf("Couldn't find /chosen node in fdt\n"); |
||||
return -EIO; |
||||
} |
||||
|
||||
/* -kernel boot */ |
||||
prop = fdt_getprop(fdt, chosen, "qemu,boot-kernel", &len); |
||||
if (prop && (len >= 8)) |
||||
setenv_hex("qemu_kernel_addr", *prop); |
||||
|
||||
/* Give the user a variable for the host fdt */ |
||||
setenv_hex("fdt_addr_r", (ulong)fdt); |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
static uint64_t get_linear_ram_size(void) |
||||
{ |
||||
void *fdt = get_fdt_virt(); |
||||
const void *prop; |
||||
int memory; |
||||
int len; |
||||
|
||||
memory = fdt_path_offset(fdt, "/memory"); |
||||
prop = fdt_getprop(fdt, memory, "reg", &len); |
||||
|
||||
if (prop && len >= 16) |
||||
return *(uint64_t *)(prop+8); |
||||
|
||||
panic("Couldn't determine RAM size"); |
||||
} |
||||
|
||||
int board_eth_init(bd_t *bis) |
||||
{ |
||||
return pci_eth_init(bis); |
||||
} |
||||
|
||||
#if defined(CONFIG_OF_BOARD_SETUP) |
||||
void ft_board_setup(void *blob, bd_t *bd) |
||||
{ |
||||
FT_FSL_PCI_SETUP; |
||||
} |
||||
#endif |
||||
|
||||
void print_laws(void) |
||||
{ |
||||
/* We don't emulate LAWs yet */ |
||||
} |
||||
|
||||
phys_size_t fixed_sdram(void) |
||||
{ |
||||
return get_linear_ram_size(); |
||||
} |
||||
|
||||
phys_size_t fsl_ddr_sdram_size(void) |
||||
{ |
||||
return get_linear_ram_size(); |
||||
} |
||||
|
||||
void init_tlbs(void) |
||||
{ |
||||
phys_size_t ram_size; |
||||
|
||||
/*
|
||||
* Create a temporary AS=1 map for the fdt |
||||
* |
||||
* We use ESEL=0 here to overwrite the previous AS=0 map for ourselves |
||||
* which was only 4k big. This way we don't have to clear any other maps. |
||||
*/ |
||||
map_fdt_as(0); |
||||
|
||||
/* Fetch RAM size from the fdt */ |
||||
ram_size = get_linear_ram_size(); |
||||
|
||||
/* And remove our fdt map again */ |
||||
disable_tlb(0); |
||||
|
||||
/* Create an internal map of manually created TLB maps */ |
||||
init_used_tlb_cams(); |
||||
|
||||
/* Create a dynamic AS=0 CCSRBAR mapping */ |
||||
assert(!tlb_map_range(CONFIG_SYS_CCSRBAR, CONFIG_SYS_CCSRBAR_PHYS, |
||||
1024 * 1024, TLB_MAP_IO)); |
||||
|
||||
/* Create a RAM map that spans all accessible RAM */ |
||||
setup_ddr_tlbs(ram_size >> 20); |
||||
|
||||
/* Create a map for the TLB */ |
||||
assert(!tlb_map_range((ulong)get_fdt_virt(), get_fdt_phys(), |
||||
1024 * 1024, TLB_MAP_RAM)); |
||||
} |
||||
|
||||
void init_laws(void) |
||||
{ |
||||
/* We don't emulate LAWs yet */ |
||||
} |
||||
|
||||
static uint32_t get_cpu_freq(void) |
||||
{ |
||||
void *fdt = get_fdt_virt(); |
||||
int cpus_node = fdt_path_offset(fdt, "/cpus"); |
||||
int cpu_node = fdt_first_subnode(fdt, cpus_node); |
||||
const char *prop = "clock-frequency"; |
||||
return fdt_getprop_u32_default_node(fdt, cpu_node, 0, prop, 0); |
||||
} |
||||
|
||||
void get_sys_info(sys_info_t *sys_info) |
||||
{ |
||||
int freq = get_cpu_freq(); |
||||
|
||||
memset(sys_info, 0, sizeof(sys_info_t)); |
||||
sys_info->freq_systembus = freq; |
||||
sys_info->freq_ddrbus = freq; |
||||
sys_info->freq_processor[0] = freq; |
||||
} |
||||
|
||||
int get_clocks (void) |
||||
{ |
||||
sys_info_t sys_info; |
||||
|
||||
get_sys_info(&sys_info); |
||||
|
||||
gd->cpu_clk = sys_info.freq_processor[0]; |
||||
gd->bus_clk = sys_info.freq_systembus; |
||||
gd->mem_clk = sys_info.freq_ddrbus; |
||||
gd->arch.lbc_clk = sys_info.freq_ddrbus; |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
unsigned long get_tbclk (void) |
||||
{ |
||||
void *fdt = get_fdt_virt(); |
||||
int cpus_node = fdt_path_offset(fdt, "/cpus"); |
||||
int cpu_node = fdt_first_subnode(fdt, cpus_node); |
||||
const char *prop = "timebase-frequency"; |
||||
return fdt_getprop_u32_default_node(fdt, cpu_node, 0, prop, 0); |
||||
} |
||||
|
||||
/********************************************
|
||||
* get_bus_freq |
||||
* return system bus freq in Hz |
||||
*********************************************/ |
||||
ulong get_bus_freq (ulong dummy) |
||||
{ |
||||
sys_info_t sys_info; |
||||
get_sys_info(&sys_info); |
||||
return sys_info.freq_systembus; |
||||
} |
@ -0,0 +1,112 @@ |
||||
/**
|
||||
* Copyright 2014 Freescale Semiconductor |
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
* |
||||
* This file provides support for the board-specific CPLD used on some Freescale |
||||
* reference boards. |
||||
* |
||||
* The following macros need to be defined: |
||||
* |
||||
* CONFIG_SYS_CPLD_BASE-The virtual address of the base of the CPLD register map |
||||
*/ |
||||
|
||||
#include <common.h> |
||||
#include <command.h> |
||||
#include <asm/io.h> |
||||
|
||||
#include "cpld.h" |
||||
|
||||
u8 cpld_read(unsigned int reg) |
||||
{ |
||||
void *p = (void *)CONFIG_SYS_CPLD_BASE; |
||||
|
||||
return in_8(p + reg); |
||||
} |
||||
|
||||
void cpld_write(unsigned int reg, u8 value) |
||||
{ |
||||
void *p = (void *)CONFIG_SYS_CPLD_BASE; |
||||
|
||||
out_8(p + reg, value); |
||||
} |
||||
|
||||
/**
|
||||
* Set the boot bank to the alternate bank |
||||
*/ |
||||
void cpld_set_altbank(void) |
||||
{ |
||||
u8 reg = CPLD_READ(flash_ctl_status); |
||||
|
||||
reg = (reg & ~CPLD_BANK_SEL_MASK) | CPLD_LBMAP_ALTBANK; |
||||
|
||||
CPLD_WRITE(flash_ctl_status, reg); |
||||
CPLD_WRITE(reset_ctl1, CPLD_LBMAP_RESET); |
||||
} |
||||
|
||||
/**
|
||||
* Set the boot bank to the default bank |
||||
*/ |
||||
void cpld_set_defbank(void) |
||||
{ |
||||
u8 reg = CPLD_READ(flash_ctl_status); |
||||
|
||||
reg = (reg & ~CPLD_BANK_SEL_MASK) | CPLD_LBMAP_DFLTBANK; |
||||
|
||||
CPLD_WRITE(flash_ctl_status, reg); |
||||
CPLD_WRITE(reset_ctl1, CPLD_LBMAP_RESET); |
||||
} |
||||
|
||||
#ifdef DEBUG |
||||
static void cpld_dump_regs(void) |
||||
{ |
||||
printf("cpld_ver = 0x%02x\n", CPLD_READ(cpld_ver)); |
||||
printf("cpld_ver_sub = 0x%02x\n", CPLD_READ(cpld_ver_sub)); |
||||
printf("hw_ver = 0x%02x\n", CPLD_READ(hw_ver)); |
||||
printf("sw_ver = 0x%02x\n", CPLD_READ(sw_ver)); |
||||
printf("reset_ctl1 = 0x%02x\n", CPLD_READ(reset_ctl1)); |
||||
printf("reset_ctl2 = 0x%02x\n", CPLD_READ(reset_ctl2)); |
||||
printf("int_status = 0x%02x\n", CPLD_READ(int_status)); |
||||
printf("flash_ctl_status = 0x%02x\n", CPLD_READ(flash_ctl_status)); |
||||
printf("fan_ctl_status = 0x%02x\n", CPLD_READ(fan_ctl_status)); |
||||
printf("led_ctl_status = 0x%02x\n", CPLD_READ(led_ctl_status)); |
||||
printf("sfp_ctl_status = 0x%02x\n", CPLD_READ(sfp_ctl_status)); |
||||
printf("misc_ctl_status = 0x%02x\n", CPLD_READ(misc_ctl_status)); |
||||
printf("boot_override = 0x%02x\n", CPLD_READ(boot_override)); |
||||
printf("boot_config1 = 0x%02x\n", CPLD_READ(boot_config1)); |
||||
printf("boot_config2 = 0x%02x\n", CPLD_READ(boot_config2)); |
||||
putc('\n'); |
||||
} |
||||
#endif |
||||
|
||||
int do_cpld(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) |
||||
{ |
||||
int rc = 0; |
||||
|
||||
if (argc <= 1) |
||||
return cmd_usage(cmdtp); |
||||
|
||||
if (strcmp(argv[1], "reset") == 0) { |
||||
if (strcmp(argv[2], "altbank") == 0) |
||||
cpld_set_altbank(); |
||||
else |
||||
cpld_set_defbank(); |
||||
#ifdef DEBUG |
||||
} else if (strcmp(argv[1], "dump") == 0) { |
||||
cpld_dump_regs(); |
||||
#endif |
||||
} else |
||||
rc = cmd_usage(cmdtp); |
||||
|
||||
return rc; |
||||
} |
||||
|
||||
U_BOOT_CMD( |
||||
cpld, CONFIG_SYS_MAXARGS, 1, do_cpld, |
||||
"Reset the board or alternate bank", |
||||
"reset - hard reset to default bank\n" |
||||
"cpld reset altbank - reset to alternate bank\n" |
||||
#ifdef DEBUG |
||||
"cpld dump - display the CPLD registers\n" |
||||
#endif |
||||
); |
@ -0,0 +1,40 @@ |
||||
/**
|
||||
* Copyright 2013 Freescale Semiconductor |
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
* |
||||
* This file provides support for the ngPIXIS, a board-specific FPGA used on |
||||
* some Freescale reference boards. |
||||
*/ |
||||
|
||||
/*
|
||||
* CPLD register set. Feel free to add board-specific #ifdefs where necessary. |
||||
*/ |
||||
struct cpld_data { |
||||
u8 cpld_ver; /* 0x00 - CPLD Major Revision Register */ |
||||
u8 cpld_ver_sub; /* 0x01 - CPLD Minor Revision Register */ |
||||
u8 hw_ver; /* 0x02 - Hardware Revision Register */ |
||||
u8 sw_ver; /* 0x03 - Software Revision register */ |
||||
u8 res0[12]; /* 0x04 - 0x0F - not used */ |
||||
u8 reset_ctl1; /* 0x10 - Reset control Register1 */ |
||||
u8 reset_ctl2; /* 0x11 - Reset control Register2 */ |
||||
u8 int_status; /* 0x12 - Interrupt status Register */ |
||||
u8 flash_ctl_status; /* 0x13 - Flash control and status register */ |
||||
u8 fan_ctl_status; /* 0x14 - Fan control and status register */ |
||||
u8 led_ctl_status; /* 0x15 - LED control and status register */ |
||||
u8 sfp_ctl_status; /* 0x16 - SFP control and status register */ |
||||
u8 misc_ctl_status; /* 0x17 - Miscellanies ctrl & status register*/ |
||||
u8 boot_override; /* 0x18 - Boot override register */ |
||||
u8 boot_config1; /* 0x19 - Boot config override register*/ |
||||
u8 boot_config2; /* 0x1A - Boot config override register*/ |
||||
} cpld_data_t; |
||||
|
||||
|
||||
/* Pointer to the CPLD register set */ |
||||
|
||||
u8 cpld_read(unsigned int reg); |
||||
void cpld_write(unsigned int reg, u8 value); |
||||
|
||||
#define CPLD_READ(reg) cpld_read(offsetof(struct cpld_data, reg)) |
||||
#define CPLD_WRITE(reg, value)\ |
||||
cpld_write(offsetof(struct cpld_data, reg), value) |
@ -0,0 +1,122 @@ |
||||
/* Copyright 2013 Freescale Semiconductor, Inc.
|
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
*/ |
||||
|
||||
#include <common.h> |
||||
#include <malloc.h> |
||||
#include <ns16550.h> |
||||
#include <nand.h> |
||||
#include <i2c.h> |
||||
#include <mmc.h> |
||||
#include <fsl_esdhc.h> |
||||
#include <spi_flash.h> |
||||
|
||||
DECLARE_GLOBAL_DATA_PTR; |
||||
|
||||
phys_size_t get_effective_memsize(void) |
||||
{ |
||||
return CONFIG_SYS_L3_SIZE; |
||||
} |
||||
|
||||
unsigned long get_board_sys_clk(void) |
||||
{ |
||||
return CONFIG_SYS_CLK_FREQ; |
||||
} |
||||
|
||||
unsigned long get_board_ddr_clk(void) |
||||
{ |
||||
return CONFIG_DDR_CLK_FREQ; |
||||
} |
||||
|
||||
#define FSL_CORENET_CCSR_PORSR1_RCW_MASK 0xFF800000 |
||||
void board_init_f(ulong bootflag) |
||||
{ |
||||
u32 plat_ratio, sys_clk, uart_clk; |
||||
#ifdef CONFIG_SPL_NAND_BOOT |
||||
u32 porsr1, pinctl; |
||||
#endif |
||||
ccsr_gur_t *gur = (void *)CONFIG_SYS_MPC85xx_GUTS_ADDR; |
||||
|
||||
#ifdef CONFIG_SPL_NAND_BOOT |
||||
/*
|
||||
* There is T1040 SoC issue where NOR, FPGA are inaccessible during |
||||
* NAND boot because IFC signals > IFC_AD7 are not enabled. |
||||
* This workaround changes RCW source to make all signals enabled. |
||||
*/ |
||||
porsr1 = in_be32(&gur->porsr1); |
||||
pinctl = ((porsr1 & ~(FSL_CORENET_CCSR_PORSR1_RCW_MASK)) | 0x24800000); |
||||
out_be32((unsigned int *)(CONFIG_SYS_DCSRBAR + 0x20000), pinctl); |
||||
#endif |
||||
|
||||
/* Memcpy existing GD at CONFIG_SPL_GD_ADDR */ |
||||
memcpy((void *)CONFIG_SPL_GD_ADDR, (void *)gd, sizeof(gd_t)); |
||||
|
||||
/* Update GD pointer */ |
||||
gd = (gd_t *)(CONFIG_SPL_GD_ADDR); |
||||
|
||||
/* compiler optimization barrier needed for GCC >= 3.4 */ |
||||
__asm__ __volatile__("" : : : "memory"); |
||||
|
||||
console_init_f(); |
||||
|
||||
/* initialize selected port with appropriate baud rate */ |
||||
sys_clk = get_board_sys_clk(); |
||||
plat_ratio = (in_be32(&gur->rcwsr[0]) >> 25) & 0x1f; |
||||
uart_clk = sys_clk * plat_ratio / 2; |
||||
|
||||
NS16550_init((NS16550_t)CONFIG_SYS_NS16550_COM1, |
||||
uart_clk / 16 / CONFIG_BAUDRATE); |
||||
|
||||
relocate_code(CONFIG_SPL_RELOC_STACK, (gd_t *)CONFIG_SPL_GD_ADDR, 0x0); |
||||
} |
||||
|
||||
void board_init_r(gd_t *gd, ulong dest_addr) |
||||
{ |
||||
bd_t *bd; |
||||
|
||||
bd = (bd_t *)(gd + sizeof(gd_t)); |
||||
memset(bd, 0, sizeof(bd_t)); |
||||
gd->bd = bd; |
||||
bd->bi_memstart = CONFIG_SYS_INIT_L3_ADDR; |
||||
bd->bi_memsize = CONFIG_SYS_L3_SIZE; |
||||
|
||||
probecpu(); |
||||
get_clocks(); |
||||
mem_malloc_init(CONFIG_SPL_RELOC_MALLOC_ADDR, |
||||
CONFIG_SPL_RELOC_MALLOC_SIZE); |
||||
|
||||
#ifdef CONFIG_SPL_MMC_BOOT |
||||
mmc_initialize(bd); |
||||
#endif |
||||
|
||||
/* relocate environment function pointers etc. */ |
||||
#ifdef CONFIG_SPL_NAND_BOOT |
||||
nand_spl_load_image(CONFIG_ENV_OFFSET, CONFIG_ENV_SIZE, |
||||
(uchar *)CONFIG_ENV_ADDR); |
||||
#endif |
||||
#ifdef CONFIG_SPL_MMC_BOOT |
||||
mmc_spl_load_image(CONFIG_ENV_OFFSET, CONFIG_ENV_SIZE, |
||||
(uchar *)CONFIG_ENV_ADDR); |
||||
#endif |
||||
#ifdef CONFIG_SPL_SPI_BOOT |
||||
spi_spl_load_image(CONFIG_ENV_OFFSET, CONFIG_ENV_SIZE, |
||||
(uchar *)CONFIG_ENV_ADDR); |
||||
#endif |
||||
gd->env_addr = (ulong)(CONFIG_ENV_ADDR); |
||||
gd->env_valid = 1; |
||||
|
||||
i2c_init_all(); |
||||
|
||||
puts("\n\n"); |
||||
|
||||
gd->ram_size = initdram(0); |
||||
|
||||
#ifdef CONFIG_SPL_MMC_BOOT |
||||
mmc_boot(); |
||||
#elif defined(CONFIG_SPL_SPI_BOOT) |
||||
spi_boot(); |
||||
#elif defined(CONFIG_SPL_NAND_BOOT) |
||||
nand_boot(); |
||||
#endif |
||||
} |
@ -0,0 +1,7 @@ |
||||
#PBL preamble and RCW header |
||||
aa55aa55 010e0100 |
||||
# serdes protocol 0x66 |
||||
0c18000e 0e000000 00000000 00000000 |
||||
66000002 80000002 e8106000 01000000 |
||||
00000000 00000000 00000000 00032810 |
||||
00000000 0342500f 00000000 00000000 |
@ -0,0 +1,7 @@ |
||||
#PBL preamble and RCW header |
||||
aa55aa55 010e0100 |
||||
# serdes protocol 0x66 |
||||
0c18000e 0e000000 00000000 00000000 |
||||
06000002 00400002 e8106000 01000000 |
||||
00000000 00000000 00000000 00030810 |
||||
00000000 01fe0a06 00000000 00000000 |
@ -0,0 +1,26 @@ |
||||
#PBI commands |
||||
#Initialize CPC1 |
||||
09010000 00200400 |
||||
09138000 00000000 |
||||
091380c0 00000100 |
||||
#Configure CPC1 as 256KB SRAM |
||||
09010100 00000000 |
||||
09010104 fffc0007 |
||||
09010f00 08000000 |
||||
09010000 80000000 |
||||
#Configure LAW for CPC1 |
||||
09000cd0 00000000 |
||||
09000cd4 fffc0000 |
||||
09000cd8 81000011 |
||||
#Configure alternate space |
||||
09000010 00000000 |
||||
09000014 ff000000 |
||||
09000018 81000000 |
||||
#Configure SPI controller |
||||
09110000 80000403 |
||||
09110020 2d170008 |
||||
09110024 00100008 |
||||
09110028 00100008 |
||||
0911002c 00100008 |
||||
#Flush PBL data |
||||
091380c0 000FFFFF |
@ -0,0 +1,137 @@ |
||||
/* Copyright 2013 Freescale Semiconductor, Inc.
|
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
*/ |
||||
|
||||
#include <common.h> |
||||
#include <malloc.h> |
||||
#include <ns16550.h> |
||||
#include <nand.h> |
||||
#include <i2c.h> |
||||
#include <mmc.h> |
||||
#include <fsl_esdhc.h> |
||||
#include <spi_flash.h> |
||||
#include "../common/qixis.h" |
||||
#include "t208xqds_qixis.h" |
||||
|
||||
DECLARE_GLOBAL_DATA_PTR; |
||||
|
||||
phys_size_t get_effective_memsize(void) |
||||
{ |
||||
return CONFIG_SYS_L3_SIZE; |
||||
} |
||||
|
||||
unsigned long get_board_sys_clk(void) |
||||
{ |
||||
u8 sysclk_conf = QIXIS_READ(brdcfg[1]); |
||||
|
||||
switch (sysclk_conf & 0x0F) { |
||||
case QIXIS_SYSCLK_83: |
||||
return 83333333; |
||||
case QIXIS_SYSCLK_100: |
||||
return 100000000; |
||||
case QIXIS_SYSCLK_125: |
||||
return 125000000; |
||||
case QIXIS_SYSCLK_133: |
||||
return 133333333; |
||||
case QIXIS_SYSCLK_150: |
||||
return 150000000; |
||||
case QIXIS_SYSCLK_160: |
||||
return 160000000; |
||||
case QIXIS_SYSCLK_166: |
||||
return 166666666; |
||||
} |
||||
return 66666666; |
||||
} |
||||
|
||||
unsigned long get_board_ddr_clk(void) |
||||
{ |
||||
u8 ddrclk_conf = QIXIS_READ(brdcfg[1]); |
||||
|
||||
switch ((ddrclk_conf & 0x30) >> 4) { |
||||
case QIXIS_DDRCLK_100: |
||||
return 100000000; |
||||
case QIXIS_DDRCLK_125: |
||||
return 125000000; |
||||
case QIXIS_DDRCLK_133: |
||||
return 133333333; |
||||
} |
||||
return 66666666; |
||||
} |
||||
|
||||
void board_init_f(ulong bootflag) |
||||
{ |
||||
u32 plat_ratio, sys_clk, ccb_clk; |
||||
ccsr_gur_t *gur = (void *)CONFIG_SYS_MPC85xx_GUTS_ADDR; |
||||
|
||||
/* Memcpy existing GD at CONFIG_SPL_GD_ADDR */ |
||||
memcpy((void *)CONFIG_SPL_GD_ADDR, (void *)gd, sizeof(gd_t)); |
||||
|
||||
/* Update GD pointer */ |
||||
gd = (gd_t *)(CONFIG_SPL_GD_ADDR); |
||||
|
||||
console_init_f(); |
||||
|
||||
/* initialize selected port with appropriate baud rate */ |
||||
sys_clk = get_board_sys_clk(); |
||||
plat_ratio = (in_be32(&gur->rcwsr[0]) >> 25) & 0x1f; |
||||
ccb_clk = sys_clk * plat_ratio / 2; |
||||
|
||||
NS16550_init((NS16550_t)CONFIG_SYS_NS16550_COM1, |
||||
ccb_clk / 16 / CONFIG_BAUDRATE); |
||||
|
||||
#if defined(CONFIG_SPL_MMC_BOOT) |
||||
puts("\nSD boot...\n"); |
||||
#elif defined(CONFIG_SPL_SPI_BOOT) |
||||
puts("\nSPI boot...\n"); |
||||
#elif defined(CONFIG_SPL_NAND_BOOT) |
||||
puts("\nNAND boot...\n"); |
||||
#endif |
||||
|
||||
relocate_code(CONFIG_SPL_RELOC_STACK, (gd_t *)CONFIG_SPL_GD_ADDR, 0x0); |
||||
} |
||||
|
||||
void board_init_r(gd_t *gd, ulong dest_addr) |
||||
{ |
||||
bd_t *bd; |
||||
|
||||
bd = (bd_t *)(gd + sizeof(gd_t)); |
||||
memset(bd, 0, sizeof(bd_t)); |
||||
gd->bd = bd; |
||||
bd->bi_memstart = CONFIG_SYS_INIT_L3_ADDR; |
||||
bd->bi_memsize = CONFIG_SYS_L3_SIZE; |
||||
|
||||
probecpu(); |
||||
get_clocks(); |
||||
mem_malloc_init(CONFIG_SPL_RELOC_MALLOC_ADDR, |
||||
CONFIG_SPL_RELOC_MALLOC_SIZE); |
||||
|
||||
#ifdef CONFIG_SPL_NAND_BOOT |
||||
nand_spl_load_image(CONFIG_ENV_OFFSET, CONFIG_ENV_SIZE, |
||||
(uchar *)CONFIG_ENV_ADDR); |
||||
#endif |
||||
#ifdef CONFIG_SPL_MMC_BOOT |
||||
mmc_initialize(bd); |
||||
mmc_spl_load_image(CONFIG_ENV_OFFSET, CONFIG_ENV_SIZE, |
||||
(uchar *)CONFIG_ENV_ADDR); |
||||
#endif |
||||
#ifdef CONFIG_SPL_SPI_BOOT |
||||
spi_spl_load_image(CONFIG_ENV_OFFSET, CONFIG_ENV_SIZE, |
||||
(uchar *)CONFIG_ENV_ADDR); |
||||
#endif |
||||
|
||||
gd->env_addr = (ulong)(CONFIG_ENV_ADDR); |
||||
gd->env_valid = 1; |
||||
|
||||
i2c_init_all(); |
||||
|
||||
gd->ram_size = initdram(0); |
||||
|
||||
#ifdef CONFIG_SPL_MMC_BOOT |
||||
mmc_boot(); |
||||
#elif defined(CONFIG_SPL_SPI_BOOT) |
||||
spi_boot(); |
||||
#elif defined(CONFIG_SPL_NAND_BOOT) |
||||
nand_boot(); |
||||
#endif |
||||
} |
@ -0,0 +1,107 @@ |
||||
/* Copyright 2013 Freescale Semiconductor, Inc.
|
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
*/ |
||||
|
||||
#include <common.h> |
||||
#include <malloc.h> |
||||
#include <ns16550.h> |
||||
#include <nand.h> |
||||
#include <i2c.h> |
||||
#include <mmc.h> |
||||
#include <fsl_esdhc.h> |
||||
#include <spi_flash.h> |
||||
|
||||
DECLARE_GLOBAL_DATA_PTR; |
||||
|
||||
phys_size_t get_effective_memsize(void) |
||||
{ |
||||
return CONFIG_SYS_L3_SIZE; |
||||
} |
||||
|
||||
unsigned long get_board_sys_clk(void) |
||||
{ |
||||
return CONFIG_SYS_CLK_FREQ; |
||||
} |
||||
|
||||
unsigned long get_board_ddr_clk(void) |
||||
{ |
||||
return CONFIG_DDR_CLK_FREQ; |
||||
} |
||||
|
||||
void board_init_f(ulong bootflag) |
||||
{ |
||||
u32 plat_ratio, sys_clk, ccb_clk; |
||||
ccsr_gur_t *gur = (void *)CONFIG_SYS_MPC85xx_GUTS_ADDR; |
||||
|
||||
/* Memcpy existing GD at CONFIG_SPL_GD_ADDR */ |
||||
memcpy((void *)CONFIG_SPL_GD_ADDR, (void *)gd, sizeof(gd_t)); |
||||
|
||||
/* Update GD pointer */ |
||||
gd = (gd_t *)(CONFIG_SPL_GD_ADDR); |
||||
|
||||
console_init_f(); |
||||
|
||||
/* initialize selected port with appropriate baud rate */ |
||||
sys_clk = get_board_sys_clk(); |
||||
plat_ratio = (in_be32(&gur->rcwsr[0]) >> 25) & 0x1f; |
||||
ccb_clk = sys_clk * plat_ratio / 2; |
||||
|
||||
NS16550_init((NS16550_t)CONFIG_SYS_NS16550_COM1, |
||||
ccb_clk / 16 / CONFIG_BAUDRATE); |
||||
|
||||
#if defined(CONFIG_SPL_MMC_BOOT) |
||||
puts("\nSD boot...\n"); |
||||
#elif defined(CONFIG_SPL_SPI_BOOT) |
||||
puts("\nSPI boot...\n"); |
||||
#elif defined(CONFIG_SPL_NAND_BOOT) |
||||
puts("\nNAND boot...\n"); |
||||
#endif |
||||
|
||||
relocate_code(CONFIG_SPL_RELOC_STACK, (gd_t *)CONFIG_SPL_GD_ADDR, 0x0); |
||||
} |
||||
|
||||
void board_init_r(gd_t *gd, ulong dest_addr) |
||||
{ |
||||
bd_t *bd; |
||||
|
||||
bd = (bd_t *)(gd + sizeof(gd_t)); |
||||
memset(bd, 0, sizeof(bd_t)); |
||||
gd->bd = bd; |
||||
bd->bi_memstart = CONFIG_SYS_INIT_L3_ADDR; |
||||
bd->bi_memsize = CONFIG_SYS_L3_SIZE; |
||||
|
||||
probecpu(); |
||||
get_clocks(); |
||||
mem_malloc_init(CONFIG_SPL_RELOC_MALLOC_ADDR, |
||||
CONFIG_SPL_RELOC_MALLOC_SIZE); |
||||
|
||||
#ifdef CONFIG_SPL_NAND_BOOT |
||||
nand_spl_load_image(CONFIG_ENV_OFFSET, CONFIG_ENV_SIZE, |
||||
(uchar *)CONFIG_ENV_ADDR); |
||||
#endif |
||||
#ifdef CONFIG_SPL_MMC_BOOT |
||||
mmc_initialize(bd); |
||||
mmc_spl_load_image(CONFIG_ENV_OFFSET, CONFIG_ENV_SIZE, |
||||
(uchar *)CONFIG_ENV_ADDR); |
||||
#endif |
||||
#ifdef CONFIG_SPL_SPI_BOOT |
||||
spi_spl_load_image(CONFIG_ENV_OFFSET, CONFIG_ENV_SIZE, |
||||
(uchar *)CONFIG_ENV_ADDR); |
||||
#endif |
||||
|
||||
gd->env_addr = (ulong)(CONFIG_ENV_ADDR); |
||||
gd->env_valid = 1; |
||||
|
||||
i2c_init_all(); |
||||
|
||||
gd->ram_size = initdram(0); |
||||
|
||||
#ifdef CONFIG_SPL_MMC_BOOT |
||||
mmc_boot(); |
||||
#elif defined(CONFIG_SPL_SPI_BOOT) |
||||
spi_boot(); |
||||
#elif defined(CONFIG_SPL_NAND_BOOT) |
||||
nand_boot(); |
||||
#endif |
||||
} |
@ -0,0 +1,141 @@ |
||||
/* Copyright 2014 Freescale Semiconductor, Inc.
|
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
*/ |
||||
|
||||
#include <common.h> |
||||
#include <asm/spl.h> |
||||
#include <malloc.h> |
||||
#include <ns16550.h> |
||||
#include <nand.h> |
||||
#include <mmc.h> |
||||
#include <fsl_esdhc.h> |
||||
#include <i2c.h> |
||||
#include "../common/qixis.h" |
||||
#include "t4240qds_qixis.h" |
||||
|
||||
#define FSL_CORENET_CCSR_PORSR1_RCW_MASK 0xFF800000 |
||||
|
||||
DECLARE_GLOBAL_DATA_PTR; |
||||
|
||||
phys_size_t get_effective_memsize(void) |
||||
{ |
||||
return CONFIG_SYS_L3_SIZE; |
||||
} |
||||
|
||||
unsigned long get_board_sys_clk(void) |
||||
{ |
||||
u8 sysclk_conf = QIXIS_READ(brdcfg[1]); |
||||
|
||||
switch (sysclk_conf & 0x0F) { |
||||
case QIXIS_SYSCLK_83: |
||||
return 83333333; |
||||
case QIXIS_SYSCLK_100: |
||||
return 100000000; |
||||
case QIXIS_SYSCLK_125: |
||||
return 125000000; |
||||
case QIXIS_SYSCLK_133: |
||||
return 133333333; |
||||
case QIXIS_SYSCLK_150: |
||||
return 150000000; |
||||
case QIXIS_SYSCLK_160: |
||||
return 160000000; |
||||
case QIXIS_SYSCLK_166: |
||||
return 166666666; |
||||
} |
||||
return 66666666; |
||||
} |
||||
|
||||
unsigned long get_board_ddr_clk(void) |
||||
{ |
||||
u8 ddrclk_conf = QIXIS_READ(brdcfg[1]); |
||||
|
||||
switch ((ddrclk_conf & 0x30) >> 4) { |
||||
case QIXIS_DDRCLK_100: |
||||
return 100000000; |
||||
case QIXIS_DDRCLK_125: |
||||
return 125000000; |
||||
case QIXIS_DDRCLK_133: |
||||
return 133333333; |
||||
} |
||||
return 66666666; |
||||
} |
||||
|
||||
void board_init_f(ulong bootflag) |
||||
{ |
||||
u32 plat_ratio, sys_clk, ccb_clk; |
||||
ccsr_gur_t *gur = (void *)CONFIG_SYS_MPC85xx_GUTS_ADDR; |
||||
#ifdef CONFIG_SPL_NAND_BOOT |
||||
u32 porsr1, pinctl; |
||||
#endif |
||||
|
||||
#ifdef CONFIG_SPL_NAND_BOOT |
||||
porsr1 = in_be32(&gur->porsr1); |
||||
pinctl = ((porsr1 & ~(FSL_CORENET_CCSR_PORSR1_RCW_MASK)) | 0x24800000); |
||||
out_be32((unsigned int *)(CONFIG_SYS_DCSRBAR + 0x20000), pinctl); |
||||
#endif |
||||
/* Memcpy existing GD at CONFIG_SPL_GD_ADDR */ |
||||
memcpy((void *)CONFIG_SPL_GD_ADDR, (void *)gd, sizeof(gd_t)); |
||||
|
||||
/* Update GD pointer */ |
||||
gd = (gd_t *)(CONFIG_SPL_GD_ADDR); |
||||
|
||||
/* compiler optimization barrier needed for GCC >= 3.4 */ |
||||
__asm__ __volatile__("" : : : "memory"); |
||||
|
||||
console_init_f(); |
||||
|
||||
/* initialize selected port with appropriate baud rate */ |
||||
sys_clk = get_board_sys_clk(); |
||||
plat_ratio = (in_be32(&gur->rcwsr[0]) >> 25) & 0x1f; |
||||
ccb_clk = sys_clk * plat_ratio / 2; |
||||
|
||||
NS16550_init((NS16550_t)CONFIG_SYS_NS16550_COM1, |
||||
ccb_clk / 16 / CONFIG_BAUDRATE); |
||||
|
||||
#ifdef CONFIG_SPL_MMC_BOOT |
||||
puts("\nSD boot...\n"); |
||||
#elif defined(CONFIG_SPL_NAND_BOOT) |
||||
puts("\nNAND boot...\n"); |
||||
#endif |
||||
relocate_code(CONFIG_SPL_RELOC_STACK, (gd_t *)CONFIG_SPL_GD_ADDR, 0x0); |
||||
} |
||||
|
||||
void board_init_r(gd_t *gd, ulong dest_addr) |
||||
{ |
||||
bd_t *bd; |
||||
|
||||
bd = (bd_t *)(gd + sizeof(gd_t)); |
||||
memset(bd, 0, sizeof(bd_t)); |
||||
gd->bd = bd; |
||||
bd->bi_memstart = CONFIG_SYS_INIT_L3_ADDR; |
||||
bd->bi_memsize = CONFIG_SYS_L3_SIZE; |
||||
|
||||
probecpu(); |
||||
get_clocks(); |
||||
mem_malloc_init(CONFIG_SPL_RELOC_MALLOC_ADDR, |
||||
CONFIG_SPL_RELOC_MALLOC_SIZE); |
||||
|
||||
#ifdef CONFIG_SPL_NAND_BOOT |
||||
nand_spl_load_image(CONFIG_ENV_OFFSET, CONFIG_ENV_SIZE, |
||||
(uchar *)CONFIG_ENV_ADDR); |
||||
#endif |
||||
#ifdef CONFIG_SPL_MMC_BOOT |
||||
mmc_initialize(bd); |
||||
mmc_spl_load_image(CONFIG_ENV_OFFSET, CONFIG_ENV_SIZE, |
||||
(uchar *)CONFIG_ENV_ADDR); |
||||
#endif |
||||
|
||||
gd->env_addr = (ulong)(CONFIG_ENV_ADDR); |
||||
gd->env_valid = 1; |
||||
|
||||
i2c_init_all(); |
||||
|
||||
gd->ram_size = initdram(0); |
||||
|
||||
#ifdef CONFIG_SPL_MMC_BOOT |
||||
mmc_boot(); |
||||
#elif defined(CONFIG_SPL_NAND_BOOT) |
||||
nand_boot(); |
||||
#endif |
||||
} |
@ -1,7 +1,7 @@ |
||||
#PBL preamble and RCW header |
||||
aa55aa55 010e0100 |
||||
#serdes protocol 1_28_6_12 |
||||
120c0019 0c101915 00000000 00000000 |
||||
04383063 30548c00 6c020000 1d000000 |
||||
16070019 18101916 00000000 00000000 |
||||
04383060 30548c00 ec020000 f5000000 |
||||
00000000 ee0000ee 00000000 000307fc |
||||
00000000 00000000 00000000 00000020 |
||||
00000000 00000000 00000000 00000028 |
||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,300 @@ |
||||
/*
|
||||
* Copyright 2014 Freescale Semiconductor, Inc. |
||||
* |
||||
* calculate the organization and timing parameter |
||||
* from ddr3 spd, please refer to the spec |
||||
* JEDEC standard No.21-C 4_01_02_12R23A.pdf |
||||
* |
||||
* |
||||
*/ |
||||
|
||||
#include <common.h> |
||||
#include <fsl_ddr_sdram.h> |
||||
|
||||
#include <fsl_ddr.h> |
||||
|
||||
/*
|
||||
* Calculate the Density of each Physical Rank. |
||||
* Returned size is in bytes. |
||||
* |
||||
* Total DIMM size = |
||||
* sdram capacity(bit) / 8 * primary bus width / sdram width |
||||
* * Logical Ranks per DIMM |
||||
* |
||||
* where: sdram capacity = spd byte4[3:0] |
||||
* primary bus width = spd byte13[2:0] |
||||
* sdram width = spd byte12[2:0] |
||||
* Logical Ranks per DIMM = spd byte12[5:3] for SDP, DDP, QDP |
||||
* spd byte12{5:3] * spd byte6[6:4] for 3DS |
||||
* |
||||
* To simplify each rank size = total DIMM size / Number of Package Ranks |
||||
* where Number of Package Ranks = spd byte12[5:3] |
||||
* |
||||
* 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 |
||||
* 0111 32Gb 4GB |
||||
* |
||||
* SPD byte13 - module memory bus width |
||||
* bit[2:0] primary bus width |
||||
* 000 8bits |
||||
* 001 16bits |
||||
* 010 32bits |
||||
* 011 64bits |
||||
* |
||||
* SPD byte12 - module organization |
||||
* bit[2:0] sdram device width |
||||
* 000 4bits |
||||
* 001 8bits |
||||
* 010 16bits |
||||
* 011 32bits |
||||
* |
||||
* SPD byte12 - module organization |
||||
* bit[5:3] number of package ranks per DIMM |
||||
* 000 1 |
||||
* 001 2 |
||||
* 010 3 |
||||
* 011 4 |
||||
* |
||||
* SPD byte6 - SDRAM package type |
||||
* bit[6:4] Die count |
||||
* 000 1 |
||||
* 001 2 |
||||
* 010 3 |
||||
* 011 4 |
||||
* 100 5 |
||||
* 101 6 |
||||
* 110 7 |
||||
* 111 8 |
||||
* |
||||
* SPD byte6 - SRAM package type |
||||
* bit[1:0] Signal loading |
||||
* 00 Not specified |
||||
* 01 Multi load stack |
||||
* 10 Sigle load stack (3DS) |
||||
* 11 Reserved |
||||
*/ |
||||
static unsigned long long |
||||
compute_ranksize(const struct ddr4_spd_eeprom_s *spd) |
||||
{ |
||||
unsigned long long bsize; |
||||
|
||||
int nbit_sdram_cap_bsize = 0; |
||||
int nbit_primary_bus_width = 0; |
||||
int nbit_sdram_width = 0; |
||||
int die_count = 0; |
||||
bool package_3ds; |
||||
|
||||
if ((spd->density_banks & 0xf) <= 7) |
||||
nbit_sdram_cap_bsize = (spd->density_banks & 0xf) + 28; |
||||
if ((spd->bus_width & 0x7) < 4) |
||||
nbit_primary_bus_width = (spd->bus_width & 0x7) + 3; |
||||
if ((spd->organization & 0x7) < 4) |
||||
nbit_sdram_width = (spd->organization & 0x7) + 2; |
||||
package_3ds = (spd->package_type & 0x3) == 0x2; |
||||
if (package_3ds) |
||||
die_count = (spd->package_type >> 4) & 0x7; |
||||
|
||||
bsize = 1ULL << (nbit_sdram_cap_bsize - 3 + |
||||
nbit_primary_bus_width - nbit_sdram_width + |
||||
die_count); |
||||
|
||||
debug("DDR: DDR III rank density = 0x%16llx\n", bsize); |
||||
|
||||
return bsize; |
||||
} |
||||
|
||||
#define spd_to_ps(mtb, ftb) \ |
||||
(mtb * pdimm->mtb_ps + (ftb * pdimm->ftb_10th_ps) / 10) |
||||
/*
|
||||
* ddr_compute_dimm_parameters for DDR3 SPD |
||||
* |
||||
* Compute DIMM parameters based upon the SPD information in spd. |
||||
* Writes the results to the dimm_params_t structure pointed by pdimm. |
||||
* |
||||
*/ |
||||
unsigned int |
||||
ddr_compute_dimm_parameters(const generic_spd_eeprom_t *spd, |
||||
dimm_params_t *pdimm, |
||||
unsigned int dimm_number) |
||||
{ |
||||
unsigned int retval; |
||||
int i; |
||||
|
||||
if (spd->mem_type) { |
||||
if (spd->mem_type != SPD_MEMTYPE_DDR4) { |
||||
printf("DIMM %u: is not a DDR4 SPD.\n", dimm_number); |
||||
return 1; |
||||
} |
||||
} else { |
||||
memset(pdimm, 0, sizeof(dimm_params_t)); |
||||
return 1; |
||||
} |
||||
|
||||
retval = ddr4_spd_check(spd); |
||||
if (retval) { |
||||
printf("DIMM %u: failed checksum\n", dimm_number); |
||||
return 2; |
||||
} |
||||
|
||||
/*
|
||||
* The part name in ASCII in the SPD EEPROM is not null terminated. |
||||
* Guarantee null termination here by presetting all bytes to 0 |
||||
* and copying the part name in ASCII from the SPD onto it |
||||
*/ |
||||
memset(pdimm->mpart, 0, sizeof(pdimm->mpart)); |
||||
if ((spd->info_size_crc & 0xF) > 2) |
||||
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->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->data_width = pdimm->primary_sdram_width |
||||
+ pdimm->ec_sdram_width; |
||||
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_RDIMM: |
||||
/* Registered/buffered DIMMs */ |
||||
pdimm->registered_dimm = 1; |
||||
break; |
||||
|
||||
case DDR3_SPD_MODULETYPE_UDIMM: |
||||
case DDR3_SPD_MODULETYPE_SO_DIMM: |
||||
/* Unbuffered DIMMs */ |
||||
if (spd->mod_section.unbuffered.addr_mapping & 0x1) |
||||
pdimm->mirrored_dimm = 1; |
||||
break; |
||||
|
||||
default: |
||||
printf("unknown module_type 0x%02X\n", spd->module_type); |
||||
return 1; |
||||
} |
||||
|
||||
/* SDRAM device parameters */ |
||||
pdimm->n_row_addr = ((spd->addressing >> 3) & 0x7) + 12; |
||||
pdimm->n_col_addr = (spd->addressing & 0x7) + 9; |
||||
pdimm->bank_addr_bits = (spd->density_banks >> 4) & 0x3; |
||||
pdimm->bank_group_bits = (spd->density_banks >> 6) & 0x3; |
||||
|
||||
/*
|
||||
* The SPD spec has not the ECC bit, |
||||
* We consider the DIMM as ECC capability |
||||
* when the extension bus exist |
||||
*/ |
||||
if (pdimm->ec_sdram_width) |
||||
pdimm->edc_config = 0x02; |
||||
else |
||||
pdimm->edc_config = 0x00; |
||||
|
||||
/*
|
||||
* The SPD spec has not the burst length byte |
||||
* but DDR4 spec has nature BL8 and BC4, |
||||
* BL8 -bit3, BC4 -bit2 |
||||
*/ |
||||
pdimm->burst_lengths_bitmask = 0x0c; |
||||
pdimm->row_density = __ilog2(pdimm->rank_density); |
||||
|
||||
/* MTB - medium timebase
|
||||
* The MTB in the SPD spec is 125ps, |
||||
* |
||||
* FTB - fine timebase |
||||
* use 1/10th of ps as our unit to avoid floating point |
||||
* eg, 10 for 1ps, 25 for 2.5ps, 50 for 5ps |
||||
*/ |
||||
if ((spd->timebases & 0xf) == 0x0) { |
||||
pdimm->mtb_ps = 125; |
||||
pdimm->ftb_10th_ps = 10; |
||||
|
||||
} else { |
||||
printf("Unknown Timebases\n"); |
||||
} |
||||
|
||||
/* sdram minimum cycle time */ |
||||
pdimm->tckmin_x_ps = spd_to_ps(spd->tck_min, spd->fine_tck_min); |
||||
|
||||
/* sdram max cycle time */ |
||||
pdimm->tckmax_ps = spd_to_ps(spd->tck_max, spd->fine_tck_max); |
||||
|
||||
/*
|
||||
* CAS latency supported |
||||
* bit0 - CL7 |
||||
* bit4 - CL11 |
||||
* bit8 - CL15 |
||||
* bit12- CL19 |
||||
* bit16- CL23 |
||||
*/ |
||||
pdimm->caslat_x = (spd->caslat_b1 << 7) | |
||||
(spd->caslat_b2 << 15) | |
||||
(spd->caslat_b3 << 23); |
||||
|
||||
BUG_ON(spd->caslat_b4 != 0); |
||||
|
||||
/*
|
||||
* min CAS latency time |
||||
*/ |
||||
pdimm->taa_ps = spd_to_ps(spd->taa_min, spd->fine_taa_min); |
||||
|
||||
/*
|
||||
* min RAS to CAS delay time |
||||
*/ |
||||
pdimm->trcd_ps = spd_to_ps(spd->trcd_min, spd->fine_trcd_min); |
||||
|
||||
/*
|
||||
* Min Row Precharge Delay Time |
||||
*/ |
||||
pdimm->trp_ps = spd_to_ps(spd->trp_min, spd->fine_trp_min); |
||||
|
||||
/* min active to precharge delay time */ |
||||
pdimm->tras_ps = (((spd->tras_trc_ext & 0xf) << 8) + |
||||
spd->tras_min_lsb) * pdimm->mtb_ps; |
||||
|
||||
/* min active to actice/refresh delay time */ |
||||
pdimm->trc_ps = spd_to_ps((((spd->tras_trc_ext & 0xf0) << 4) + |
||||
spd->trc_min_lsb), spd->fine_trc_min); |
||||
/* Min Refresh Recovery Delay Time */ |
||||
pdimm->trfc1_ps = ((spd->trfc1_min_msb << 8) | (spd->trfc1_min_lsb)) * |
||||
pdimm->mtb_ps; |
||||
pdimm->trfc2_ps = ((spd->trfc2_min_msb << 8) | (spd->trfc2_min_lsb)) * |
||||
pdimm->mtb_ps; |
||||
pdimm->trfc4_ps = ((spd->trfc4_min_msb << 8) | (spd->trfc4_min_lsb)) * |
||||
pdimm->mtb_ps; |
||||
/* min four active window delay time */ |
||||
pdimm->tfaw_ps = (((spd->tfaw_msb & 0xf) << 8) | spd->tfaw_min) * |
||||
pdimm->mtb_ps; |
||||
|
||||
/* min row active to row active delay time, different bank group */ |
||||
pdimm->trrds_ps = spd_to_ps(spd->trrds_min, spd->fine_trrds_min); |
||||
/* min row active to row active delay time, same bank group */ |
||||
pdimm->trrdl_ps = spd_to_ps(spd->trrdl_min, spd->fine_trrdl_min); |
||||
/* min CAS to CAS Delay Time (tCCD_Lmin), same bank group */ |
||||
pdimm->tccdl_ps = spd_to_ps(spd->tccdl_min, spd->fine_tccdl_min); |
||||
|
||||
/*
|
||||
* Average periodic refresh interval |
||||
* tREFI = 7.8 us at normal temperature range |
||||
*/ |
||||
pdimm->refresh_rate_ps = 7800000; |
||||
|
||||
for (i = 0; i < 18; i++) |
||||
pdimm->dq_mapping[i] = spd->mapping[i]; |
||||
|
||||
pdimm->dq_mapping_ors = ((spd->mapping[0] >> 6) & 0x3) == 0 ? 1 : 0; |
||||
|
||||
return 0; |
||||
} |
@ -0,0 +1,234 @@ |
||||
/*
|
||||
* Copyright 2014 Freescale Semiconductor, Inc. |
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
*/ |
||||
|
||||
#include <common.h> |
||||
#include <asm/io.h> |
||||
#include <fsl_ddr_sdram.h> |
||||
#include <asm/processor.h> |
||||
#include <fsl_ddr.h> |
||||
|
||||
#if (CONFIG_CHIP_SELECTS_PER_CTRL > 4) |
||||
#error Invalid setting for CONFIG_CHIP_SELECTS_PER_CTRL |
||||
#endif |
||||
|
||||
/*
|
||||
* regs has the to-be-set values for DDR controller registers |
||||
* ctrl_num is the DDR controller number |
||||
* step: 0 goes through the initialization in one pass |
||||
* 1 sets registers and returns before enabling controller |
||||
* 2 resumes from step 1 and continues to initialize |
||||
* Dividing the initialization to two steps to deassert DDR reset signal |
||||
* to comply with JEDEC specs for RDIMMs. |
||||
*/ |
||||
void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs, |
||||
unsigned int ctrl_num, int step) |
||||
{ |
||||
unsigned int i, bus_width; |
||||
struct ccsr_ddr __iomem *ddr; |
||||
u32 temp_sdram_cfg; |
||||
u32 total_gb_size_per_controller; |
||||
int timeout; |
||||
|
||||
switch (ctrl_num) { |
||||
case 0: |
||||
ddr = (void *)CONFIG_SYS_FSL_DDR_ADDR; |
||||
break; |
||||
#if defined(CONFIG_SYS_FSL_DDR2_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 1) |
||||
case 1: |
||||
ddr = (void *)CONFIG_SYS_FSL_DDR2_ADDR; |
||||
break; |
||||
#endif |
||||
#if defined(CONFIG_SYS_FSL_DDR3_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 2) |
||||
case 2: |
||||
ddr = (void *)CONFIG_SYS_FSL_DDR3_ADDR; |
||||
break; |
||||
#endif |
||||
#if defined(CONFIG_SYS_FSL_DDR4_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 3) |
||||
case 3: |
||||
ddr = (void *)CONFIG_SYS_FSL_DDR4_ADDR; |
||||
break; |
||||
#endif |
||||
default: |
||||
printf("%s unexpected ctrl_num = %u\n", __func__, ctrl_num); |
||||
return; |
||||
} |
||||
|
||||
if (step == 2) |
||||
goto step2; |
||||
|
||||
if (regs->ddr_eor) |
||||
ddr_out32(&ddr->eor, regs->ddr_eor); |
||||
|
||||
ddr_out32(&ddr->sdram_clk_cntl, regs->ddr_sdram_clk_cntl); |
||||
|
||||
for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) { |
||||
if (i == 0) { |
||||
ddr_out32(&ddr->cs0_bnds, regs->cs[i].bnds); |
||||
ddr_out32(&ddr->cs0_config, regs->cs[i].config); |
||||
ddr_out32(&ddr->cs0_config_2, regs->cs[i].config_2); |
||||
|
||||
} else if (i == 1) { |
||||
ddr_out32(&ddr->cs1_bnds, regs->cs[i].bnds); |
||||
ddr_out32(&ddr->cs1_config, regs->cs[i].config); |
||||
ddr_out32(&ddr->cs1_config_2, regs->cs[i].config_2); |
||||
|
||||
} else if (i == 2) { |
||||
ddr_out32(&ddr->cs2_bnds, regs->cs[i].bnds); |
||||
ddr_out32(&ddr->cs2_config, regs->cs[i].config); |
||||
ddr_out32(&ddr->cs2_config_2, regs->cs[i].config_2); |
||||
|
||||
} else if (i == 3) { |
||||
ddr_out32(&ddr->cs3_bnds, regs->cs[i].bnds); |
||||
ddr_out32(&ddr->cs3_config, regs->cs[i].config); |
||||
ddr_out32(&ddr->cs3_config_2, regs->cs[i].config_2); |
||||
} |
||||
} |
||||
|
||||
ddr_out32(&ddr->timing_cfg_3, regs->timing_cfg_3); |
||||
ddr_out32(&ddr->timing_cfg_0, regs->timing_cfg_0); |
||||
ddr_out32(&ddr->timing_cfg_1, regs->timing_cfg_1); |
||||
ddr_out32(&ddr->timing_cfg_2, regs->timing_cfg_2); |
||||
ddr_out32(&ddr->timing_cfg_4, regs->timing_cfg_4); |
||||
ddr_out32(&ddr->timing_cfg_5, regs->timing_cfg_5); |
||||
ddr_out32(&ddr->timing_cfg_6, regs->timing_cfg_6); |
||||
ddr_out32(&ddr->timing_cfg_7, regs->timing_cfg_7); |
||||
ddr_out32(&ddr->timing_cfg_8, regs->timing_cfg_8); |
||||
ddr_out32(&ddr->timing_cfg_9, regs->timing_cfg_9); |
||||
ddr_out32(&ddr->ddr_zq_cntl, regs->ddr_zq_cntl); |
||||
ddr_out32(&ddr->dq_map_0, regs->dq_map_0); |
||||
ddr_out32(&ddr->dq_map_1, regs->dq_map_1); |
||||
ddr_out32(&ddr->dq_map_2, regs->dq_map_2); |
||||
ddr_out32(&ddr->dq_map_3, regs->dq_map_3); |
||||
ddr_out32(&ddr->sdram_cfg_2, regs->ddr_sdram_cfg_2); |
||||
ddr_out32(&ddr->sdram_cfg_3, regs->ddr_sdram_cfg_3); |
||||
ddr_out32(&ddr->sdram_mode, regs->ddr_sdram_mode); |
||||
ddr_out32(&ddr->sdram_mode_2, regs->ddr_sdram_mode_2); |
||||
ddr_out32(&ddr->sdram_mode_3, regs->ddr_sdram_mode_3); |
||||
ddr_out32(&ddr->sdram_mode_4, regs->ddr_sdram_mode_4); |
||||
ddr_out32(&ddr->sdram_mode_5, regs->ddr_sdram_mode_5); |
||||
ddr_out32(&ddr->sdram_mode_6, regs->ddr_sdram_mode_6); |
||||
ddr_out32(&ddr->sdram_mode_7, regs->ddr_sdram_mode_7); |
||||
ddr_out32(&ddr->sdram_mode_8, regs->ddr_sdram_mode_8); |
||||
ddr_out32(&ddr->sdram_mode_9, regs->ddr_sdram_mode_9); |
||||
ddr_out32(&ddr->sdram_mode_10, regs->ddr_sdram_mode_10); |
||||
ddr_out32(&ddr->sdram_mode_11, regs->ddr_sdram_mode_11); |
||||
ddr_out32(&ddr->sdram_mode_12, regs->ddr_sdram_mode_12); |
||||
ddr_out32(&ddr->sdram_mode_13, regs->ddr_sdram_mode_13); |
||||
ddr_out32(&ddr->sdram_mode_14, regs->ddr_sdram_mode_14); |
||||
ddr_out32(&ddr->sdram_mode_15, regs->ddr_sdram_mode_15); |
||||
ddr_out32(&ddr->sdram_mode_16, regs->ddr_sdram_mode_16); |
||||
ddr_out32(&ddr->sdram_md_cntl, regs->ddr_sdram_md_cntl); |
||||
ddr_out32(&ddr->sdram_interval, regs->ddr_sdram_interval); |
||||
ddr_out32(&ddr->sdram_data_init, regs->ddr_data_init); |
||||
ddr_out32(&ddr->init_addr, regs->ddr_init_addr); |
||||
ddr_out32(&ddr->init_ext_addr, regs->ddr_init_ext_addr); |
||||
ddr_out32(&ddr->ddr_wrlvl_cntl, regs->ddr_wrlvl_cntl); |
||||
#ifndef CONFIG_SYS_FSL_DDR_EMU |
||||
/*
|
||||
* Skip these two registers if running on emulator |
||||
* because emulator doesn't have skew between bytes. |
||||
*/ |
||||
|
||||
if (regs->ddr_wrlvl_cntl_2) |
||||
ddr_out32(&ddr->ddr_wrlvl_cntl_2, regs->ddr_wrlvl_cntl_2); |
||||
if (regs->ddr_wrlvl_cntl_3) |
||||
ddr_out32(&ddr->ddr_wrlvl_cntl_3, regs->ddr_wrlvl_cntl_3); |
||||
#endif |
||||
|
||||
ddr_out32(&ddr->ddr_sr_cntr, regs->ddr_sr_cntr); |
||||
ddr_out32(&ddr->ddr_sdram_rcw_1, regs->ddr_sdram_rcw_1); |
||||
ddr_out32(&ddr->ddr_sdram_rcw_2, regs->ddr_sdram_rcw_2); |
||||
ddr_out32(&ddr->ddr_sdram_rcw_3, regs->ddr_sdram_rcw_3); |
||||
ddr_out32(&ddr->ddr_sdram_rcw_4, regs->ddr_sdram_rcw_4); |
||||
ddr_out32(&ddr->ddr_sdram_rcw_5, regs->ddr_sdram_rcw_5); |
||||
ddr_out32(&ddr->ddr_sdram_rcw_6, regs->ddr_sdram_rcw_6); |
||||
ddr_out32(&ddr->ddr_cdr1, regs->ddr_cdr1); |
||||
ddr_out32(&ddr->ddr_cdr2, regs->ddr_cdr2); |
||||
ddr_out32(&ddr->err_disable, regs->err_disable); |
||||
ddr_out32(&ddr->err_int_en, regs->err_int_en); |
||||
for (i = 0; i < 32; i++) { |
||||
if (regs->debug[i]) { |
||||
debug("Write to debug_%d as %08x\n", |
||||
i+1, regs->debug[i]); |
||||
ddr_out32(&ddr->debug[i], regs->debug[i]); |
||||
} |
||||
} |
||||
|
||||
/*
|
||||
* For RDIMMs, JEDEC spec requires clocks to be stable before reset is |
||||
* deasserted. Clocks start when any chip select is enabled and clock |
||||
* control register is set. Because all DDR components are connected to |
||||
* one reset signal, this needs to be done in two steps. Step 1 is to |
||||
* get the clocks started. Step 2 resumes after reset signal is |
||||
* deasserted. |
||||
*/ |
||||
if (step == 1) { |
||||
udelay(200); |
||||
return; |
||||
} |
||||
|
||||
step2: |
||||
/* Set, but do not enable the memory */ |
||||
temp_sdram_cfg = regs->ddr_sdram_cfg; |
||||
temp_sdram_cfg &= ~(SDRAM_CFG_MEM_EN); |
||||
ddr_out32(&ddr->sdram_cfg, temp_sdram_cfg); |
||||
|
||||
/*
|
||||
* 500 painful micro-seconds must elapse between |
||||
* the DDR clock setup and the DDR config enable. |
||||
* DDR2 need 200 us, and DDR3 need 500 us from spec, |
||||
* we choose the max, that is 500 us for all of case. |
||||
*/ |
||||
udelay(500); |
||||
asm volatile("sync;isync"); |
||||
|
||||
/* Let the controller go */ |
||||
temp_sdram_cfg = ddr_in32(&ddr->sdram_cfg) & ~SDRAM_CFG_BI; |
||||
ddr_out32(&ddr->sdram_cfg, temp_sdram_cfg | SDRAM_CFG_MEM_EN); |
||||
asm volatile("sync;isync"); |
||||
|
||||
total_gb_size_per_controller = 0; |
||||
for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) { |
||||
if (!(regs->cs[i].config & 0x80000000)) |
||||
continue; |
||||
total_gb_size_per_controller += 1 << ( |
||||
((regs->cs[i].config >> 14) & 0x3) + 2 + |
||||
((regs->cs[i].config >> 8) & 0x7) + 12 + |
||||
((regs->cs[i].config >> 4) & 0x3) + 0 + |
||||
((regs->cs[i].config >> 0) & 0x7) + 8 + |
||||
3 - ((regs->ddr_sdram_cfg >> 19) & 0x3) - |
||||
26); /* minus 26 (count of 64M) */ |
||||
} |
||||
if (fsl_ddr_get_intl3r() & 0x80000000) /* 3-way interleaving */ |
||||
total_gb_size_per_controller *= 3; |
||||
else if (regs->cs[0].config & 0x20000000) /* 2-way interleaving */ |
||||
total_gb_size_per_controller <<= 1; |
||||
/*
|
||||
* total memory / bus width = transactions needed |
||||
* transactions needed / data rate = seconds |
||||
* to add plenty of buffer, double the time |
||||
* For example, 2GB on 666MT/s 64-bit bus takes about 402ms |
||||
* Let's wait for 800ms |
||||
*/ |
||||
bus_width = 3 - ((ddr->sdram_cfg & SDRAM_CFG_DBW_MASK) |
||||
>> SDRAM_CFG_DBW_SHIFT); |
||||
timeout = ((total_gb_size_per_controller << (6 - bus_width)) * 100 / |
||||
(get_ddr_freq(0) >> 20)) << 2; |
||||
total_gb_size_per_controller >>= 4; /* shift down to gb size */ |
||||
debug("total %d GB\n", total_gb_size_per_controller); |
||||
debug("Need to wait up to %d * 10ms\n", timeout); |
||||
|
||||
/* Poll DDR_SDRAM_CFG_2[D_INIT] bit until auto-data init is done. */ |
||||
while ((ddr_in32(&ddr->sdram_cfg_2) & SDRAM_CFG2_D_INIT) && |
||||
(timeout >= 0)) { |
||||
udelay(10000); /* throttle polling rate */ |
||||
timeout--; |
||||
} |
||||
|
||||
if (timeout <= 0) |
||||
printf("Waiting for D_INIT timeout. Memory may not work.\n"); |
||||
|
||||
} |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue