]> git.kernelconcepts.de Git - karo-tx-uboot.git/blobdiff - arch/powerpc/cpu/mpc8xxx/ddr/ddr3_dimm_params.c
Merge branch 'u-boot-imx/master' into 'u-boot-arm/master'
[karo-tx-uboot.git] / arch / powerpc / cpu / mpc8xxx / ddr / ddr3_dimm_params.c
index d4199baa82c55c712141255faa3ff3ab646b407d..b67158c0ffae8284e0863513d345d02d4f612116 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2008-2009 Freescale Semiconductor, Inc.
+ * Copyright 2008-2012 Freescale Semiconductor, Inc.
  *     Dave Liu <daveliu@freescale.com>
  *
  * calculate the organization and timing parameter
@@ -71,7 +71,7 @@ compute_ranksize(const ddr3_spd_eeprom_t *spd)
        bsize = 1ULL << (nbit_sdram_cap_bsize - 3
                    + nbit_primary_bus_width - nbit_sdram_width);
 
-       debug("DDR: DDR III rank density = 0x%16lx\n", bsize);
+       debug("DDR: DDR III rank density = 0x%16llx\n", bsize);
 
        return bsize;
 }
@@ -90,6 +90,8 @@ 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) {
                if (spd->mem_type != SPD_MEMTYPE_DDR3) {
@@ -113,7 +115,8 @@ ddr_compute_dimm_parameters(const ddr3_spd_eeprom_t *spd,
         * and copying the part name in ASCII from the SPD onto it
         */
        memset(pdimm->mpart, 0, sizeof(pdimm->mpart));
-       memcpy(pdimm->mpart, spd->mpart, sizeof(pdimm->mpart) - 1);
+       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;
@@ -126,22 +129,41 @@ ddr_compute_dimm_parameters(const ddr3_spd_eeprom_t *spd,
                pdimm->ec_sdram_width = 0;
        pdimm->data_width = pdimm->primary_sdram_width
                          + pdimm->ec_sdram_width;
-
-       switch (spd->module_type & 0xf) {
-       case 0x01:      /* RDIMM */
-       case 0x05:      /* Mini-RDIMM */
-               pdimm->registered_dimm = 1; /* register buffered */
+       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:
+       case DDR3_SPD_MODULETYPE_MINI_RDIMM:
+       case DDR3_SPD_MODULETYPE_72B_SO_RDIMM:
+               /* Registered/buffered DIMMs */
+               pdimm->registered_dimm = 1;
+               for (i = 0; i < 16; i += 2) {
+                       u8 rcw = spd->mod_section.registered.rcw[i/2];
+                       pdimm->rcw[i]   = (rcw >> 0) & 0x0F;
+                       pdimm->rcw[i+1] = (rcw >> 4) & 0x0F;
+               }
                break;
 
-       case 0x02:      /* UDIMM */
-       case 0x03:      /* SO-DIMM */
-       case 0x04:      /* Micro-DIMM */
-       case 0x06:      /* Mini-UDIMM */
-               pdimm->registered_dimm = 0;     /* unbuffered */
+       case DDR3_SPD_MODULETYPE_UDIMM:
+       case DDR3_SPD_MODULETYPE_SO_DIMM:
+       case DDR3_SPD_MODULETYPE_MICRO_DIMM:
+       case DDR3_SPD_MODULETYPE_MINI_UDIMM:
+       case DDR3_SPD_MODULETYPE_MINI_CDIMM:
+       case DDR3_SPD_MODULETYPE_72B_SO_UDIMM:
+       case DDR3_SPD_MODULETYPE_72B_SO_CDIMM:
+       case DDR3_SPD_MODULETYPE_LRDIMM:
+       case DDR3_SPD_MODULETYPE_16B_SO_DIMM:
+       case DDR3_SPD_MODULETYPE_32B_SO_DIMM:
+               /* Unbuffered DIMMs */
+               if (spd->mod_section.unbuffered.addr_mapping & 0x1)
+                       pdimm->mirrored_dimm = 1;
                break;
 
        default:
-               printf("unknown dimm_type 0x%02X\n", spd->module_type);
+               printf("unknown module_type 0x%02X\n", spd->module_type);
                return 1;
        }
 
@@ -176,6 +198,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
@@ -184,7 +214,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
@@ -202,7 +233,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
@@ -219,7 +251,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
@@ -237,7 +270,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 =
@@ -257,7 +291,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 =
@@ -299,16 +333,5 @@ ddr_compute_dimm_parameters(const ddr3_spd_eeprom_t *spd,
        pdimm->tFAW_ps = (((spd->tFAW_msb & 0xf) << 8) | spd->tFAW_min)
                        * mtb_ps;
 
-       /*
-        * We need check the address mirror for unbuffered DIMM
-        * If SPD indicate the address map mirror, The DDR controller
-        * need care it.
-        */
-       if ((spd->module_type == SPD_MODULETYPE_UDIMM) ||
-           (spd->module_type == SPD_MODULETYPE_SODIMM) ||
-           (spd->module_type == SPD_MODULETYPE_MICRODIMM) ||
-           (spd->module_type == SPD_MODULETYPE_MINIUDIMM))
-               pdimm->mirrored_dimm = spd->mod_section.unbuffered.addr_mapping & 0x1;
-
        return 0;
 }