From c7497b0fff4f086bccd13b8d408800d2f27419ee Mon Sep 17 00:00:00 2001 From: Stefan Agner Date: Fri, 24 Oct 2014 17:06:07 +0200 Subject: arm: vf610: extract leveling parameter in a struct DDR leveling parameters are board specific, hence we should be able to set them differently per board. Extract the leveling parameters in a seperate struct to be able to set them per board. --- arch/arm/imx-common/ddr-vf610.c | 48 +++++++++++++++++++++-------- arch/arm/include/asm/arch-vf610/ddr-vf610.h | 15 ++++++++- arch/arm/include/asm/arch-vf610/imx-regs.h | 6 ++-- board/freescale/vf610twr/vf610twr.c | 14 ++++++++- board/toradex/colibri_vf/colibri_vf.c | 2 +- 5 files changed, 65 insertions(+), 20 deletions(-) diff --git a/arch/arm/imx-common/ddr-vf610.c b/arch/arm/imx-common/ddr-vf610.c index ffcc3d2dd8..1987f06773 100644 --- a/arch/arm/imx-common/ddr-vf610.c +++ b/arch/arm/imx-common/ddr-vf610.c @@ -10,6 +10,7 @@ #include #include #include +#include void setup_iomux_ddr(void) { @@ -100,7 +101,37 @@ void ddr_phy_init(void) writel(DDRMC_PHY_PROC_PAD_ODT, &ddrmr->phy[52]); } -void ddr_ctrl_init(int tref, int trfc, int col_diff, int row_diff) +static void ddr_ctrl_lvl_init(struct ddr_lvl_info *lvl) +{ + struct ddrmr_regs *ddrmr = (struct ddrmr_regs *)DDR_BASE_ADDR; + u32 cr102 = 0, cr105 = 0, cr106 = 0, cr110 = 0; + + if (lvl->wrlvl_reg_en) { + writel(DDRMC_CR97_WRLVL_EN, &ddrmr->cr[97]); + writel(DDRMC_CR98_WRLVL_DL_0(lvl->wrlvl_dl_0), &ddrmr->cr[98]); + writel(DDRMC_CR99_WRLVL_DL_1(lvl->wrlvl_dl_1), &ddrmr->cr[99]); + } + + if (lvl->rdlvl_reg_en) { + cr102 |= DDRMC_CR102_RDLVL_REG_EN; + cr105 |= DDRMC_CR105_RDLVL_DL_0(lvl->rdlvl_dl_0); + cr110 |= DDRMC_CR110_RDLVL_DL_1(lvl->rdlvl_dl_1); + } + + if (lvl->rdlvl_gt_reg_en ) { + cr102 |= DDRMC_CR102_RDLVL_GT_REGEN; + cr106 |= DDRMC_CR106_RDLVL_GTDL_0(lvl->rdlvl_gt_dl_0); + cr110 |= DDRMC_CR110_RDLVL_GTDL_1(lvl->rdlvl_gt_dl_1); + } + + writel(cr102, &ddrmr->cr[102]); + writel(cr105, &ddrmr->cr[105]); + writel(cr106, &ddrmr->cr[106]); + writel(cr110, &ddrmr->cr[110]); +} + +void ddr_ctrl_init(int tref, int trfc, int col_diff, int row_diff, + struct ddr_lvl_info *lvl) { struct ddrmr_regs *ddrmr = (struct ddrmr_regs *)DDR_BASE_ADDR; @@ -174,18 +205,9 @@ void ddr_ctrl_init(int tref, int trfc, int col_diff, int row_diff) writel(DDRMC_CR91_R2W_SMCSDL(2), &ddrmr->cr[91]); writel(DDRMC_CR96_WLMRD(40) | DDRMC_CR96_WLDQSEN(25), &ddrmr->cr[96]); - writel(DDRMC_CR97_WRLVL_EN, &ddrmr->cr[97]); - writel(DDRMC_CR98_WRLVL_DL_0, &ddrmr->cr[98]); - writel(DDRMC_CR99_WRLVL_DL_1, &ddrmr->cr[99]); - - writel(DDRMC_CR102_RDLVL_GT_REGEN | DDRMC_CR102_RDLVL_REG_EN, - &ddrmr->cr[102]); - - writel(DDRMC_CR105_RDLVL_DL_0(0), &ddrmr->cr[105]); - writel(DDRMC_CR106_RDLVL_GTDL_0(4), &ddrmr->cr[106]); - writel(DDRMC_CR110_RDLVL_GTDL_1(4), &ddrmr->cr[110]); - writel(DDRMC_CR114_RDLVL_GTDL_2(0), &ddrmr->cr[114]); - writel(DDRMC_CR115_RDLVL_GTDL_2(0), &ddrmr->cr[115]); + + if (lvl != NULL) + ddr_ctrl_lvl_init(lvl); writel(DDRMC_CR117_AXI0_W_PRI(0) | DDRMC_CR117_AXI0_R_PRI(0), &ddrmr->cr[117]); diff --git a/arch/arm/include/asm/arch-vf610/ddr-vf610.h b/arch/arm/include/asm/arch-vf610/ddr-vf610.h index 6c1cf6adce..e56d94dc75 100644 --- a/arch/arm/include/asm/arch-vf610/ddr-vf610.h +++ b/arch/arm/include/asm/arch-vf610/ddr-vf610.h @@ -8,8 +8,21 @@ #ifndef __ASM_ARCH_VF610_DDR_H #define __ASM_ARCH_VF610_DDR_H +struct ddr_lvl_info { + u16 wrlvl_reg_en; + u16 wrlvl_dl_0; + u16 wrlvl_dl_1; + u16 rdlvl_gt_reg_en; + u16 rdlvl_gt_dl_0; + u16 rdlvl_gt_dl_1; + u16 rdlvl_reg_en; + u16 rdlvl_dl_0; + u16 rdlvl_dl_1; +}; + void setup_iomux_ddr(void); void ddr_phy_init(void); -void ddr_ctrl_init(int tref, int trfc, int col_diff, int row_diff); +void ddr_ctrl_init(int tref, int trfc, int col_diff, int row_diff, + struct ddr_lvl_info *lvl); #endif diff --git a/arch/arm/include/asm/arch-vf610/imx-regs.h b/arch/arm/include/asm/arch-vf610/imx-regs.h index 2341e9d342..c510842b9c 100644 --- a/arch/arm/include/asm/arch-vf610/imx-regs.h +++ b/arch/arm/include/asm/arch-vf610/imx-regs.h @@ -198,16 +198,14 @@ #define DDRMC_CR96_WLMRD(v) (((v) & 0x3f) << 8) #define DDRMC_CR96_WLDQSEN(v) ((v) & 0x3f) #define DDRMC_CR97_WRLVL_EN (1 << 24) -#define DDRMC_CR98_WRLVL_DL_0 (0) -#define DDRMC_CR99_WRLVL_DL_1 (0) +#define DDRMC_CR98_WRLVL_DL_0(v) ((v) & 0xffff) +#define DDRMC_CR99_WRLVL_DL_1(v) ((v) & 0xffff) #define DDRMC_CR102_RDLVL_GT_REGEN (1 << 16) #define DDRMC_CR102_RDLVL_REG_EN (1 << 8) #define DDRMC_CR105_RDLVL_DL_0(v) (((v) & 0xff) << 8) #define DDRMC_CR106_RDLVL_GTDL_0(v) ((v) & 0xff) #define DDRMC_CR110_RDLVL_DL_1(v) ((v) & 0xff) #define DDRMC_CR110_RDLVL_GTDL_1(v) (((v) & 0xff) << 16) -#define DDRMC_CR114_RDLVL_GTDL_2(v) (((v) & 0xffff) << 8) -#define DDRMC_CR115_RDLVL_GTDL_2(v) ((v) & 0xff) #define DDRMC_CR117_AXI0_W_PRI(v) (((v) & 0x3) << 8) #define DDRMC_CR117_AXI0_R_PRI(v) ((v) & 0x3) #define DDRMC_CR118_AXI1_W_PRI(v) (((v) & 0x3) << 24) diff --git a/board/freescale/vf610twr/vf610twr.c b/board/freescale/vf610twr/vf610twr.c index 085c2ee790..91dc343c7c 100644 --- a/board/freescale/vf610twr/vf610twr.c +++ b/board/freescale/vf610twr/vf610twr.c @@ -30,9 +30,21 @@ DECLARE_GLOBAL_DATA_PTR; int dram_init(void) { + struct ddr_lvl_info lvl = { + .wrlvl_reg_en = 1, + .wrlvl_dl_0 = 0, + .wrlvl_dl_1 = 0, + .rdlvl_gt_reg_en = 1, + .rdlvl_gt_dl_0 = 4, + .rdlvl_gt_dl_1 = 4, + .rdlvl_reg_en = 1, + .rdlvl_dl_0 = 0, + .rdlvl_dl_1 = 0, + }; + setup_iomux_ddr(); - ddr_ctrl_init(3120, 44, 1, 3); + ddr_ctrl_init(3120, 44, 1, 3, &lvl); gd->ram_size = get_ram_size((void *)PHYS_SDRAM, PHYS_SDRAM_SIZE); return 0; diff --git a/board/toradex/colibri_vf/colibri_vf.c b/board/toradex/colibri_vf/colibri_vf.c index cef2e50f24..4149e0b7d3 100644 --- a/board/toradex/colibri_vf/colibri_vf.c +++ b/board/toradex/colibri_vf/colibri_vf.c @@ -37,7 +37,7 @@ int dram_init(void) { setup_iomux_ddr(); - ddr_ctrl_init(3120, 64, 1, 2); + ddr_ctrl_init(3120, 64, 1, 2, NULL); gd->ram_size = get_ram_size((void *)PHYS_SDRAM, PHYS_SDRAM_SIZE); return 0; -- cgit v1.2.3