From 73b5396b25c52463aa71c782316e2d77a4b8d5ed Mon Sep 17 00:00:00 2001 From: York Sun Date: Fri, 17 Aug 2012 08:22:37 +0000 Subject: [PATCH] powerpc/mpc8xxx: Add fine timing support for DDR3 When the DDR3 speed goes higher, we need to utilize fine offset from SPD. Signed-off-by: York Sun Signed-off-by: Andy Fleming --- .../cpu/mpc8xxx/ddr/ddr3_dimm_params.c | 25 ++++++++++++++----- arch/powerpc/cpu/mpc8xxx/ddr/interactive.c | 18 ++++++++++--- .../powerpc/include/asm/fsl_ddr_dimm_params.h | 1 + include/ddr_spd.h | 7 +++++- 4 files changed, 40 insertions(+), 11 deletions(-) diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/ddr3_dimm_params.c b/arch/powerpc/cpu/mpc8xxx/ddr/ddr3_dimm_params.c index d0a546610e..3e7c269e40 100644 --- a/arch/powerpc/cpu/mpc8xxx/ddr/ddr3_dimm_params.c +++ b/arch/powerpc/cpu/mpc8xxx/ddr/ddr3_dimm_params.c @@ -1,5 +1,5 @@ /* - * Copyright 2008-2009 Freescale Semiconductor, Inc. + * Copyright 2008-2012 Freescale Semiconductor, Inc. * Dave Liu * * calculate the organization and timing parameter @@ -90,6 +90,7 @@ ddr_compute_dimm_parameters(const ddr3_spd_eeprom_t *spd, { unsigned int retval; unsigned int mtb_ps; + int ftb_10th_ps; int i; if (spd->mem_type) { @@ -196,6 +197,14 @@ ddr_compute_dimm_parameters(const ddr3_spd_eeprom_t *spd, mtb_ps = (spd->mtb_dividend * 1000) /spd->mtb_divisor; pdimm->mtb_ps = mtb_ps; + /* + * 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 + */ + ftb_10th_ps = + ((spd->ftb_div & 0xf0) >> 4) * 10 / (spd->ftb_div & 0x0f); + pdimm->ftb_10th_ps = ftb_10th_ps; /* * sdram minimum cycle time * we assume the MTB is 0.125ns @@ -204,7 +213,8 @@ ddr_compute_dimm_parameters(const ddr3_spd_eeprom_t *spd, * =12 MTB (1.5ns) ->DDR3-1333 * =10 MTB (1.25ns) ->DDR3-1600 */ - pdimm->tCKmin_X_ps = spd->tCK_min * mtb_ps; + pdimm->tCKmin_X_ps = spd->tCK_min * mtb_ps + + (spd->fine_tCK_min * ftb_10th_ps) / 10; /* * CAS latency supported @@ -222,7 +232,8 @@ ddr_compute_dimm_parameters(const ddr3_spd_eeprom_t *spd, * DDR3-1333H 108 MTB (13.5ns) * DDR3-1600H 90 MTB (11.25ns) */ - pdimm->tAA_ps = spd->tAA_min * mtb_ps; + pdimm->tAA_ps = spd->tAA_min * mtb_ps + + (spd->fine_tAA_min * ftb_10th_ps) / 10; /* * min write recovery time @@ -239,7 +250,8 @@ ddr_compute_dimm_parameters(const ddr3_spd_eeprom_t *spd, * DDR3-1333H 108 MTB (13.5ns) * DDR3-1600H 90 MTB (11.25) */ - pdimm->tRCD_ps = spd->tRCD_min * mtb_ps; + pdimm->tRCD_ps = spd->tRCD_min * mtb_ps + + (spd->fine_tRCD_min * ftb_10th_ps) / 10; /* * min row active to row active delay time @@ -257,7 +269,8 @@ ddr_compute_dimm_parameters(const ddr3_spd_eeprom_t *spd, * DDR3-1333H 108 MTB (13.5ns) * DDR3-1600H 90 MTB (11.25ns) */ - pdimm->tRP_ps = spd->tRP_min * mtb_ps; + pdimm->tRP_ps = spd->tRP_min * mtb_ps + + (spd->fine_tRP_min * ftb_10th_ps) / 10; /* min active to precharge delay time * eg: tRAS_min = @@ -277,7 +290,7 @@ ddr_compute_dimm_parameters(const ddr3_spd_eeprom_t *spd, * DDR3-1600H 370 MTB (46.25ns) */ pdimm->tRC_ps = (((spd->tRAS_tRC_ext & 0xf0) << 4) | spd->tRC_min_lsb) - * mtb_ps; + * mtb_ps + (spd->fine_tRC_min * ftb_10th_ps) / 10; /* * min refresh recovery delay time * eg: tRFC_min = diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/interactive.c b/arch/powerpc/cpu/mpc8xxx/ddr/interactive.c index 5b724371f6..738c8089f5 100644 --- a/arch/powerpc/cpu/mpc8xxx/ddr/interactive.c +++ b/arch/powerpc/cpu/mpc8xxx/ddr/interactive.c @@ -1,5 +1,5 @@ /* - * Copyright 2010-2011 Freescale Semiconductor, Inc. + * Copyright 2010-2012 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 @@ -1121,11 +1121,21 @@ void ddr3_spd_dump(const ddr3_spd_eeprom_t *spd) "therm_sensor SDRAM Thermal Sensor"); PRINT_NXS(33, spd->device_type, "device_type SDRAM Device Type"); + PRINT_NXS(34, spd->fine_tCK_min, + "fine_tCK_min Fine offset for tCKmin"); + PRINT_NXS(35, spd->fine_tAA_min, + "fine_tAA_min Fine offset for tAAmin"); + PRINT_NXS(36, spd->fine_tRCD_min, + "fine_tRCD_min Fine offset for tRCDmin"); + PRINT_NXS(37, spd->fine_tRP_min, + "fine_tRP_min Fine offset for tRPmin"); + PRINT_NXS(38, spd->fine_tRC_min, + "fine_tRC_min Fine offset for tRCmin"); - printf("%-3d-%3d: ", 34, 59); /* Reserved, General Section */ + printf("%-3d-%3d: ", 39, 59); /* Reserved, General Section */ - for (i = 34; i <= 59; i++) - printf("%02x ", spd->res_34_59[i - 34]); + for (i = 39; i <= 59; i++) + printf("%02x ", spd->res_39_59[i - 39]); puts("\n"); diff --git a/arch/powerpc/include/asm/fsl_ddr_dimm_params.h b/arch/powerpc/include/asm/fsl_ddr_dimm_params.h index 982b809462..ffe4db8b8a 100644 --- a/arch/powerpc/include/asm/fsl_ddr_dimm_params.h +++ b/arch/powerpc/include/asm/fsl_ddr_dimm_params.h @@ -43,6 +43,7 @@ typedef struct dimm_params_s { /* DIMM timing parameters */ unsigned int mtb_ps; /* medium timebase ps, only for ddr3 */ + unsigned int ftb_10th_ps; /* fine timebase, in 1/10 ps, only for ddr3 */ unsigned int tAA_ps; /* minimum CAS latency time, only for ddr3 */ unsigned int tFAW_ps; /* four active window delay, only for ddr3 */ diff --git a/include/ddr_spd.h b/include/ddr_spd.h index a9230b9108..9e74d8729e 100644 --- a/include/ddr_spd.h +++ b/include/ddr_spd.h @@ -221,7 +221,12 @@ typedef struct ddr3_spd_eeprom_s { unsigned char therm_ref_opt; /* 31 SDRAM Thermal and Refresh Opts */ unsigned char therm_sensor; /* 32 Module Thermal Sensor */ unsigned char device_type; /* 33 SDRAM device type */ - unsigned char res_34_59[26]; /* 34-59 Reserved, General Section */ + 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 */ + unsigned char res_39_59[21]; /* 39-59 Reserved, General Section */ /* Module-Specific Section: Bytes 60-116 */ union {