FSL DDR rework
Subsystems (2)
v5 cover FSL DDR rework
01 - Add proper SPD definitions for DDR1/2/3
02 - FSL DDR: Provide a generic set_ddr_laws()
03 - FSL DDR: Rewrite the FSL mpc8xxx DDR controller setup code. 04 - FSL DDR: Add DDR1 DIMM paramter support
05 - FSL DDR: Add DDR2 DIMM paramter support
06 - FSL DDR: Add 86xx specific register setting
07 - FSL DDR: Convert MPC8641HPCN to new DDR code.
08 - FSL DDR: Convert MPC8610HPCD to new DDR code.
09 - FSL DDR: Convert SBC8641D to new DDR code.
10 - FSL DDR: Remove old SPD support from cpu/mpc86xx
This is the latest spin of the DDR work and hopefully address some of the comments we discussioned on IRC.
I've converted ALL 86xx platforms and if these patches are acceptable I'll go ahead and do the 85xx platforms as a followup.
I've dropped the interactive change at this point.
Patches 03..05 are the core of the DDR support. These patches are split up so they can be
Here is some size data for building the MPC8641HPCN_config:
text data bss dec hex filename
315244 29044 98960 443248 6c370 u-boot (baseline) 320356 29096 98960 448412 6d79c u-boot (w/o DDR changes)
------------------------------------------------
5122 52 5164 delta
I think an increase of 5k is worth is for the improvements we get.
- k
PATCH v5 1/10 Add proper SPD definitions for DDR1/2/3
From: James Yang <[email protected]>
Also adds helper functions for DDR1/2 to verify the checksum.
--- common/Makefile | 1 + common/ddr_spd.c | 61 +++++++++++ include/ddr_spd.h | 292 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 354 insertions(+), 0 deletions(-) create mode 100644 common/ddr_spd.c create mode 100644 include/ddr_spd.h
common/Makefile +1 -0
@@ -151,6 +151,7 @@ COBJS-y += cmd_mac.o COBJS-$(CONFIG_CMD_MFSL) += cmd_mfsl.o COBJS-$(CONFIG_MP) += cmd_mp.o COBJS-$(CONFIG_CMD_SF) += cmd_sf.o +COBJS-$(CONFIG_DDR_SPD) += ddr_spd.o COBJS := $(COBJS-y) SRCS := $(AOBJS:.o=.S) $(COBJS:.o=.c)
common/ddr_spd.c new file +61 -0
61 lines not on this page · raw message
include/ddr_spd.h new file +292 -0
292 lines not on this page · raw message
Signature · 1 line
1.5.5.1
PATCH v5 2/10 FSL DDR: Provide a generic set_ddr_laws()
Provide a helper function that will setup the last available LAWs (upto 2) for DDR. Useful for SPD/dyanmic DDR setting code.
--- drivers/misc/fsl_law.c | 39 +++++++++++++++++++++++++++++++++++++++ include/asm-ppc/fsl_law.h | 1 + 2 files changed, 40 insertions(+), 0 deletions(-)
drivers/misc/fsl_law.c +39 -0
@@ -121,6 +121,45 @@ void print_laws(void)return ; } +/* use up to 2 LAWs for DDR, used the last available LAWs */ +int set_ddr_laws (u64 start,u64 sz,enum law_trgt_if id) +{ +u64 start_align, law_sz; +int law_sz_enc; + +if (start ==0 ) + start_align =1ull << (LAW_SIZE_32G +1 ); +else + start_align =1ull << (ffs64 (start) -1 ); + law_sz =min (start_align, sz); + law_sz_enc =__ilog2_u64 (law_sz) -1 ; + +if (set_last_law (start, law_sz_enc, id) <0 ) +return -1 ; + +/* do we still have anything to map */ + sz = sz - law_sz; +if (sz) { + start += law_sz; + + start_align =1ull << (ffs64 (start) -1 ); + law_sz =min (start_align, sz); + law_sz_enc =__ilog2_u64 (law_sz) -1 ; + +if (set_last_law (start, law_sz_enc, id) <0 ) +return -1 ; + }else { +return 0 ; + } + +/* do we still have anything to map */ + sz = sz - law_sz; +if (sz) +return 1 ; + +return 0 ; +} +void init_laws (void ) {int i;
include/asm-ppc/fsl_law.h +1 -0
@@ -75,6 +75,7 @@ struct law_entry {extern void set_law (u8 idx,phys_addr_t addr,enum law_size sz,enum law_trgt_if id);extern int set_next_law (phys_addr_t addr,enum law_size sz,enum law_trgt_if id);extern int set_last_law (phys_addr_t addr,enum law_size sz,enum law_trgt_if id); +extern int set_ddr_laws (u64 start,u64 sz,enum law_trgt_if id);extern void disable_law (u8 idx);extern void init_laws (void );extern void print_laws (void );
Signature · 1 line
1.5.5.1
PATCH v5 3/10 FSL DDR: Rewrite the FSL mpc8xxx DDR controller setup code.
The main purpose of this rewrite it to be able to share the same initialization code on all FSL PowerPC products that have DDR controllers. (83xx, 85xx, 86xx).
The code is broken up into the following steps:
GET_SPD
COMPUTE_DIMM_PARMS
COMPUTE_COMMON_PARMS
GATHER_OPTS
ASSIGN_ADDRESSES
COMPUTE_REGS
PROGRAM_REGS
This allows us to share more code an easily allow for board specific code overrides.
Additionally this code base adds support for >4G of DDR and provides a foundation for supporting interleaving on processors with more than one controller.
--- Makefile | 4 + cpu/mpc85xx/Makefile | 11 +- cpu/mpc86xx/Makefile | 5 +- cpu/mpc8xxx/ddr/Makefile | 31 + cpu/mpc8xxx/ddr/common_timing_params.h | 53 ++ cpu/mpc8xxx/ddr/ctrl_regs.c | 993 +++++++++++++++++++++++++++++++ cpu/mpc8xxx/ddr/ddr.h | 80 +++ cpu/mpc8xxx/ddr/ddr1_2_dimm_params.h | 84 +++ cpu/mpc8xxx/ddr/lc_common_dimm_params.c | 404 +++++++++++++ cpu/mpc8xxx/ddr/main.c | 473 +++++++++++++++ cpu/mpc8xxx/ddr/options.c | 197 ++++++ cpu/mpc8xxx/ddr/util.c | 103 ++++ include/asm-ppc/fsl_ddr_sdram.h | 137 +++++ 13 files changed, 2573 insertions(+), 2 deletions(-) create mode 100644 cpu/mpc8xxx/ddr/Makefile create mode 100644 cpu/mpc8xxx/ddr/common_timing_params.h create mode 100644 cpu/mpc8xxx/ddr/ctrl_regs.c create mode 100644 cpu/mpc8xxx/ddr/ddr.h create mode 100644 cpu/mpc8xxx/ddr/ddr1_2_dimm_params.h create mode 100644 cpu/mpc8xxx/ddr/lc_common_dimm_params.c create mode 100644 cpu/mpc8xxx/ddr/main.c create mode 100644 cpu/mpc8xxx/ddr/options.c create mode 100644 cpu/mpc8xxx/ddr/util.c create mode 100644 include/asm-ppc/fsl_ddr_sdram.h
Makefile +4 -0
@@ -236,6 +236,10 @@ LIBS += drivers/qe/qe.a endif ifeq ($(CPU),mpc85xx) LIBS += drivers/qe/qe.a +LIBS += cpu/mpc8xxx/ddr/libddr.a +endif +ifeq ($(CPU),mpc86xx) +LIBS += cpu/mpc8xxx/ddr/libddr.a endif LIBS += drivers/rtc/librtc.a LIBS += drivers/serial/libserial.a
cpu/mpc85xx/Makefile +10 -1
@@ -33,8 +33,17 @@ SOBJS-$(CONFIG_MP) += release.o SOBJS = $(SOBJS-y) COBJS-$(CONFIG_MP) += mp.o COBJS-$(CONFIG_OF_LIBFDT) += fdt.o + +ifneq ($(CONFIG_FSL_DDR3),y) +ifneq ($(CONFIG_FSL_DDR2),y) +ifneq ($(CONFIG_FSL_DDR1),y) +COBJS-y += spd_sdram.o +endif +endif +endif + COBJS = traps.o cpu.o cpu_init.o speed.o interrupts.o tlb.o \ - pci.o serial_scc.o commproc.o ether_fcc.o spd_sdram.o qe_io.o \ + pci.o serial_scc.o commproc.o ether_fcc.o qe_io.o \ $(COBJS-y) SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
cpu/mpc86xx/Makefile +4 -1
@@ -36,10 +36,13 @@ COBJS-y += cpu.o COBJS-y += cpu_init.o COBJS-y += speed.o COBJS-y += interrupts.o -COBJS-y += spd_sdram.o COBJS-$(CONFIG_OF_LIBFDT) += fdt.o +ifneq ($(CONFIG_FSL_DDR2),y) +COBJS-y += spd_sdram.o +endif + SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS-y:.o=.c) OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS-y)) START := $(addprefix $(obj),$(START))
cpu/mpc8xxx/ddr/Makefile new file +31 -0
@@ -0,0 +1,31 @@ +# +# Copyright 2008 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 +# Version 2 as published by the Free Software Foundation. +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)libddr.a + +COBJS-$(CONFIG_FSL_DDR1) += main.o util.o ctrl_regs.o options.o \ + lc_common_dimm_params.o +COBJS-$(CONFIG_FSL_DDR1) += ddr1_dimm_params.o + +COBJS-$(CONFIG_FSL_DDR2) += main.o util.o ctrl_regs.o options.o \ + lc_common_dimm_params.o +COBJS-$(CONFIG_FSL_DDR2) += ddr2_dimm_params.o + +SRCS := $(START:.o=.S) $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c) +OBJS := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y)) + +all: $(obj).depend $(LIB) + +$(LIB): $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend
cpu/mpc8xxx/ddr/common_timing_params.h new file +53 -0
53 lines not on this page · raw message
cpu/mpc8xxx/ddr/ctrl_regs.c new file +993 -0
993 lines not on this page · raw message
cpu/mpc8xxx/ddr/ddr.h new file +80 -0
80 lines not on this page · raw message
cpu/mpc8xxx/ddr/ddr1_2_dimm_params.h new file +84 -0
84 lines not on this page · raw message
cpu/mpc8xxx/ddr/lc_common_dimm_params.c new file +404 -0
404 lines not on this page · raw message
cpu/mpc8xxx/ddr/main.c new file +473 -0
473 lines not on this page · raw message
cpu/mpc8xxx/ddr/options.c new file +197 -0
197 lines not on this page · raw message
cpu/mpc8xxx/ddr/util.c new file +103 -0
103 lines not on this page · raw message
include/asm-ppc/fsl_ddr_sdram.h new file +137 -0
137 lines not on this page · raw message
Signature · 1 line
1.5.5.1
PATCH v5 4/10 FSL DDR: Add DDR1 DIMM paramter support
Compute DIMM parameters based upon the SPD information in spd.
--- cpu/mpc8xxx/ddr/ddr1_dimm_params.c | 343 ++++++++++++++++++++++++++++++++++++ 1 files changed, 343 insertions(+), 0 deletions(-) create mode 100644 cpu/mpc8xxx/ddr/ddr1_dimm_params.c
cpu/mpc8xxx/ddr/ddr1_dimm_params.c new file +343 -0
@@ -0,0 +1,343 @@ +/* +* Copyright 2008 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 +* 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. +* +* Study these table from Byte 31 of JEDEC SPD Spec. +* +* DDR I DDR II +* Bit Size Size +* --- ----- ------ +* 7 high 512MB 512MB +* 6 256MB 256MB +* 5 128MB 128MB +* 4 64MB 16GB +* 3 32MB 8GB +* 2 16MB 4GB +* 1 2GB 2GB +* 0 low 1GB 1GB +* +* Reorder Table to be linear by stripping the bottom +* 2 or 5 bits off and shifting them up to the top. +*/ + +static phys_size_t +compute_ranksize (unsigned int mem_type,unsigned char row_dens) +{ +phys_size_t bsize; + +/* Bottom 2 bits up to the top. */ + bsize = ((row_dens >>2 ) | ((row_dens &3 ) <<6 )); + bsize <<=24ULL ; +debug ("DDR: DDR I rank density = 0x%08x\n" , bsize); + +return bsize; +} + +/* +* Convert a two-nibble BCD value into a cycle time. +* While the spec calls for nano-seconds, picos are returned. +* +* This implements the tables for bytes 9, 23 and 25 for both +* DDR I and II. No allowance for distinguishing the invalid +* fields absent for DDR I yet present in DDR II is made. +* (That is, cycle times of .25, .33, .66 and .75 ns are +* allowed for both DDR II and I.) +*/ +static unsigned int +convert_bcd_tenths_to_cycle_time_ps (unsigned int spd_val) +{ +/* Table look up the lower nibble, allow DDR I & II. */ +unsigned int tenths_ps[16 ] = { +0 , +100 , +200 , +300 , +400 , +500 , +600 , +700 , +800 , +900 , +250 ,/* This and the next 3 entries valid ... */ +330 ,/* ... only for tCK calculations. */ +660 , +750 , +0 ,/* undefined */ +0 /* undefined */ + }; + +unsigned int whole_ns = (spd_val &0xF0 ) >>4 ; +unsigned int tenth_ns = spd_val &0x0F ; +unsigned int ps = whole_ns *1000 + tenths_ps[tenth_ns]; + +return ps; +} + +static unsigned int +convert_bcd_hundredths_to_cycle_time_ps (unsigned int spd_val) +{ +unsigned int tenth_ns = (spd_val &0xF0 ) >>4 ; +unsigned int hundredth_ns = spd_val &0x0F ; +unsigned int ps = tenth_ns *100 + hundredth_ns *10 ; + +return ps; +} + +static unsigned int byte40_table_ps[8 ] = { +0 , +250 , +330 , +500 , +660 , +750 , +0 ,/* supposed to be RFC, but not sure what that means */ +0 /* Undefined */ +}; + +static unsigned int +compute_trfc_ps_from_spd (unsigned char trctrfc_ext,unsigned char trfc) +{ +unsigned int trfc_ps; + + trfc_ps = (((trctrfc_ext &0x1 ) *256 ) + trfc) *1000 + + byte40_table_ps[(trctrfc_ext >>1 ) &0x7 ]; + +return trfc_ps; +} + +static unsigned int +compute_trc_ps_from_spd (unsigned char trctrfc_ext,unsigned char trc) +{ +unsigned int trc_ps; + + trc_ps = trc *1000 + byte40_table_ps[(trctrfc_ext >>4 ) &0x7 ]; + +return trc_ps; +} + +/* +* tCKmax from DDR I SPD Byte 43 +* +* Bits 7:2 == whole ns +* Bits 1:0 == quarter ns +* 00 == 0.00 ns +* 01 == 0.25 ns +* 10 == 0.50 ns +* 11 == 0.75 ns +* +* Returns picoseconds. +*/ +static unsigned int +compute_tckmax_from_spd_ps (unsigned int byte43) +{ +return (byte43 >>2 ) *1000 + (byte43 &0x3 ) *250 ; +} + +/* +* Determine Refresh Rate. Ignore self refresh bit on DDR I. +* Table from SPD Spec, Byte 12, converted to picoseconds and +* filled in with "default" normal values. +*/ +static unsigned int +determine_refresh_rate_ps (const unsigned int spd_refresh) +{ +unsigned int refresh_time_ps[8 ] = { +15625000 ,/* 0 Normal 1.00x */ +3900000 ,/* 1 Reduced .25x */ +7800000 ,/* 2 Extended .50x */ +31300000 ,/* 3 Extended 2.00x */ +62500000 ,/* 4 Extended 4.00x */ +125000000 ,/* 5 Extended 8.00x */ +15625000 ,/* 6 Normal 1.00x filler */ +15625000 ,/* 7 Normal 1.00x filler */ + }; + +return refresh_time_ps[spd_refresh &0x7 ]; +} + +/* +* The purpose of this function is to compute a suitable +* CAS latency given the DRAM clock period. The SPD only +* defines at most 3 CAS latencies. Typically the slower in +* frequency the DIMM runs at, the shorter its CAS latency can be. +* If the DIMM is operating at a sufficiently low frequency, +* it may be able to run at a CAS latency shorter than the +* shortest SPD-defined CAS latency. +* +* If a CAS latency is not found, 0 is returned. +* +* Do this by finding in the standard speed bin table the longest +* tCKmin that doesn't exceed the value of mclk_ps (tCK). +* +* An assumption made is that the SDRAM device allows the +* CL to be programmed for a value that is lower than those +* advertised by the SPD. This is not always the case, +* as those modes not defined in the SPD are optional. +* +* CAS latency de-rating based upon values JEDEC Standard No. 79-E +* Table 11. +* +* ordinal 2, ddr1_speed_bins[1] contains tCK for CL=2 +*/ +/* CL2.0 CL2.5 CL3.0 */ +unsigned short ddr1_speed_bins[] = {0 ,7500 ,6000 ,5000 }; + +unsigned int +compute_derated_DDR1_CAS_latency (unsigned int mclk_ps) +{ +const unsigned int num_speed_bins =ARRAY_SIZE (ddr1_speed_bins); +unsigned int lowest_tCKmin_found =0 ; +unsigned int lowest_tCKmin_CL =0 ; +unsigned int i; + +debug ("mclk_ps = %u\n" , mclk_ps); + +for (i =0 ; i < num_speed_bins; i++) { +unsigned int x = ddr1_speed_bins[i]; +debug ("i=%u, x = %u, lowest_tCKmin_found = %u\n" , + i, x, lowest_tCKmin_found); +if (x && lowest_tCKmin_found <= x && x <= mclk_ps) { + lowest_tCKmin_found = x; + lowest_tCKmin_CL = i +1 ; + } + } + +debug ("lowest_tCKmin_CL = %u\n" , lowest_tCKmin_CL); + +return lowest_tCKmin_CL; +} + +/* +* ddr_compute_dimm_parameters for DDR1 SPD +* +* Compute DIMM parameters based upon the SPD information in spd. +* Writes the results to the dimm_params_t structure pointed by pdimm. +* +* FIXME: use #define for the retvals +*/ +unsigned int +ddr_compute_dimm_parameters (const ddr1_spd_eeprom_t *spd, +dimm_params_t *pdimm, +unsigned int dimm_number) +{ +unsigned int retval; + +if (spd->mem_type) { +if (spd->mem_type !=SPD_MEMTYPE_DDR ) { +printf ("DIMM %u: is not a DDR1 SPD.\n" , dimm_number); +return 1 ; + } + }else { +memset (pdimm,0 ,sizeof (dimm_params_t)); +return 1 ; + } + + retval =ddr1_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)); +memcpy (pdimm->mpart, spd->mpart,sizeof (pdimm->mpart) -1 ); + +/* DIMM organization parameters */ + pdimm->n_ranks = spd->nrows; + pdimm->rank_density =compute_ranksize (spd->mem_type, spd->bank_dens); + pdimm->capacity = pdimm->n_ranks * pdimm->rank_density; + pdimm->data_width = spd->dataw_lsb; + pdimm->primary_sdram_width = spd->primw; + pdimm->ec_sdram_width = spd->ecw; + +/* +* FIXME: Need to determine registered_dimm status. +* 1 == register buffered +* 0 == unbuffered +*/ + pdimm->registered_dimm =0 ;/* unbuffered */ + +/* SDRAM device parameters */ + pdimm->n_row_addr = spd->nrow_addr; + pdimm->n_col_addr = spd->ncol_addr; + pdimm->n_banks_per_sdram_device = spd->nbanks; + pdimm->edc_config = spd->config; + pdimm->burst_lengths_bitmask = spd->burstl; + pdimm->row_density = spd->bank_dens; + +/* +* Calculate the Maximum Data Rate based on the Minimum Cycle time. +* The SPD clk_cycle field (tCKmin) is measured in tenths of +* nanoseconds and represented as BCD. +*/ + pdimm->tCKmin_X_ps + =convert_bcd_tenths_to_cycle_time_ps (spd->clk_cycle); + pdimm->tCKmin_X_minus_1_ps + =convert_bcd_tenths_to_cycle_time_ps (spd->clk_cycle2); + pdimm->tCKmin_X_minus_2_ps + =convert_bcd_tenths_to_cycle_time_ps (spd->clk_cycle3); + + pdimm->tCKmax_ps =compute_tckmax_from_spd_ps (spd->tckmax); + +/* +* Compute CAS latencies defined by SPD +* The SPD caslat_X should have at least 1 and at most 3 bits set. +* +* If cas_lat after masking is 0, the __ilog2 function returns +* 255 into the variable. This behavior is abused once. +*/ + pdimm->caslat_X =__ilog2 (spd->cas_lat); + pdimm->caslat_X_minus_1 =__ilog2 (spd->cas_lat + & ~(1 << pdimm->caslat_X)); + pdimm->caslat_X_minus_2 =__ilog2 (spd->cas_lat + & ~(1 << pdimm->caslat_X) + & ~(1 << pdimm->caslat_X_minus_1)); + +/* Compute CAS latencies below that defined by SPD */ + pdimm->caslat_lowest_derated + =compute_derated_DDR1_CAS_latency (get_memory_clk_period_ps ()); + +/* Compute timing parameters */ + pdimm->tRCD_ps = spd->trcd *250 ; + pdimm->tRP_ps = spd->trp *250 ; + pdimm->tRAS_ps = spd->tras *1000 ; + + pdimm->tWR_ps =mclk_to_picos (3 ); + pdimm->tWTR_ps =mclk_to_picos (1 ); + pdimm->tRFC_ps =compute_trfc_ps_from_spd (0 , spd->trfc); + + pdimm->tRRD_ps = spd->trrd *250 ; + pdimm->tRC_ps =compute_trc_ps_from_spd (0 , spd->trc); + + pdimm->refresh_rate_ps =determine_refresh_rate_ps (spd->refresh); + + pdimm->tIS_ps =convert_bcd_hundredths_to_cycle_time_ps (spd->ca_setup); + pdimm->tIH_ps =convert_bcd_hundredths_to_cycle_time_ps (spd->ca_hold); + pdimm->tDS_ps + =convert_bcd_hundredths_to_cycle_time_ps (spd->data_setup); + pdimm->tDH_ps + =convert_bcd_hundredths_to_cycle_time_ps (spd->data_hold); + + pdimm->tRTP_ps =mclk_to_picos (2 );/* By the book. */ + pdimm->tDQSQ_max_ps = spd->tdqsq *10 ; + pdimm->tQHS_ps = spd->tqhs *10 ; + +return 0 ; +}
Signature · 1 line
1.5.5.1
PATCH v5 4/10 FSL DDR: Add DDR1 support
--- cpu/mpc8xxx/ddr/ddr1_dimm_params.c | 343 ++++++++++++++++++++++++++++++++++++ 1 files changed, 343 insertions(+), 0 deletions(-) create mode 100644 cpu/mpc8xxx/ddr/ddr1_dimm_params.c
cpu/mpc8xxx/ddr/ddr1_dimm_params.c new file +343 -0
@@ -0,0 +1,343 @@ +/* +* Copyright 2008 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 +* 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. +* +* Study these table from Byte 31 of JEDEC SPD Spec. +* +* DDR I DDR II +* Bit Size Size +* --- ----- ------ +* 7 high 512MB 512MB +* 6 256MB 256MB +* 5 128MB 128MB +* 4 64MB 16GB +* 3 32MB 8GB +* 2 16MB 4GB +* 1 2GB 2GB +* 0 low 1GB 1GB +* +* Reorder Table to be linear by stripping the bottom +* 2 or 5 bits off and shifting them up to the top. +*/ + +static phys_size_t +compute_ranksize (unsigned int mem_type,unsigned char row_dens) +{ +phys_size_t bsize; + +/* Bottom 2 bits up to the top. */ + bsize = ((row_dens >>2 ) | ((row_dens &3 ) <<6 )); + bsize <<=24ULL ; +debug ("DDR: DDR I rank density = 0x%08x\n" , bsize); + +return bsize; +} + +/* +* Convert a two-nibble BCD value into a cycle time. +* While the spec calls for nano-seconds, picos are returned. +* +* This implements the tables for bytes 9, 23 and 25 for both +* DDR I and II. No allowance for distinguishing the invalid +* fields absent for DDR I yet present in DDR II is made. +* (That is, cycle times of .25, .33, .66 and .75 ns are +* allowed for both DDR II and I.) +*/ +static unsigned int +convert_bcd_tenths_to_cycle_time_ps (unsigned int spd_val) +{ +/* Table look up the lower nibble, allow DDR I & II. */ +unsigned int tenths_ps[16 ] = { +0 , +100 , +200 , +300 , +400 , +500 , +600 , +700 , +800 , +900 , +250 ,/* This and the next 3 entries valid ... */ +330 ,/* ... only for tCK calculations. */ +660 , +750 , +0 ,/* undefined */ +0 /* undefined */ + }; + +unsigned int whole_ns = (spd_val &0xF0 ) >>4 ; +unsigned int tenth_ns = spd_val &0x0F ; +unsigned int ps = whole_ns *1000 + tenths_ps[tenth_ns]; + +return ps; +} + +static unsigned int +convert_bcd_hundredths_to_cycle_time_ps (unsigned int spd_val) +{ +unsigned int tenth_ns = (spd_val &0xF0 ) >>4 ; +unsigned int hundredth_ns = spd_val &0x0F ; +unsigned int ps = tenth_ns *100 + hundredth_ns *10 ; + +return ps; +} + +static unsigned int byte40_table_ps[8 ] = { +0 , +250 , +330 , +500 , +660 , +750 , +0 ,/* supposed to be RFC, but not sure what that means */ +0 /* Undefined */ +}; + +static unsigned int +compute_trfc_ps_from_spd (unsigned char trctrfc_ext,unsigned char trfc) +{ +unsigned int trfc_ps; + + trfc_ps = (((trctrfc_ext &0x1 ) *256 ) + trfc) *1000 + + byte40_table_ps[(trctrfc_ext >>1 ) &0x7 ]; + +return trfc_ps; +} + +static unsigned int +compute_trc_ps_from_spd (unsigned char trctrfc_ext,unsigned char trc) +{ +unsigned int trc_ps; + + trc_ps = trc *1000 + byte40_table_ps[(trctrfc_ext >>4 ) &0x7 ]; + +return trc_ps; +} + +/* +* tCKmax from DDR I SPD Byte 43 +* +* Bits 7:2 == whole ns +* Bits 1:0 == quarter ns +* 00 == 0.00 ns +* 01 == 0.25 ns +* 10 == 0.50 ns +* 11 == 0.75 ns +* +* Returns picoseconds. +*/ +static unsigned int +compute_tckmax_from_spd_ps (unsigned int byte43) +{ +return (byte43 >>2 ) *1000 + (byte43 &0x3 ) *250 ; +} + +/* +* Determine Refresh Rate. Ignore self refresh bit on DDR I. +* Table from SPD Spec, Byte 12, converted to picoseconds and +* filled in with "default" normal values. +*/ +static unsigned int +determine_refresh_rate_ps (const unsigned int spd_refresh) +{ +unsigned int refresh_time_ps[8 ] = { +15625000 ,/* 0 Normal 1.00x */ +3900000 ,/* 1 Reduced .25x */ +7800000 ,/* 2 Extended .50x */ +31300000 ,/* 3 Extended 2.00x */ +62500000 ,/* 4 Extended 4.00x */ +125000000 ,/* 5 Extended 8.00x */ +15625000 ,/* 6 Normal 1.00x filler */ +15625000 ,/* 7 Normal 1.00x filler */ + }; + +return refresh_time_ps[spd_refresh &0x7 ]; +} + +/* +* The purpose of this function is to compute a suitable +* CAS latency given the DRAM clock period. The SPD only +* defines at most 3 CAS latencies. Typically the slower in +* frequency the DIMM runs at, the shorter its CAS latency can be. +* If the DIMM is operating at a sufficiently low frequency, +* it may be able to run at a CAS latency shorter than the +* shortest SPD-defined CAS latency. +* +* If a CAS latency is not found, 0 is returned. +* +* Do this by finding in the standard speed bin table the longest +* tCKmin that doesn't exceed the value of mclk_ps (tCK). +* +* An assumption made is that the SDRAM device allows the +* CL to be programmed for a value that is lower than those +* advertised by the SPD. This is not always the case, +* as those modes not defined in the SPD are optional. +* +* CAS latency de-rating based upon values JEDEC Standard No. 79-E +* Table 11. +* +* ordinal 2, ddr1_speed_bins[1] contains tCK for CL=2 +*/ +/* CL2.0 CL2.5 CL3.0 */ +unsigned short ddr1_speed_bins[] = {0 ,7500 ,6000 ,5000 }; + +unsigned int +compute_derated_DDR1_CAS_latency (unsigned int mclk_ps) +{ +const unsigned int num_speed_bins =ARRAY_SIZE (ddr1_speed_bins); +unsigned int lowest_tCKmin_found =0 ; +unsigned int lowest_tCKmin_CL =0 ; +unsigned int i; + +debug ("mclk_ps = %u\n" , mclk_ps); + +for (i =0 ; i < num_speed_bins; i++) { +unsigned int x = ddr1_speed_bins[i]; +debug ("i=%u, x = %u, lowest_tCKmin_found = %u\n" , + i, x, lowest_tCKmin_found); +if (x && lowest_tCKmin_found <= x && x <= mclk_ps) { + lowest_tCKmin_found = x; + lowest_tCKmin_CL = i +1 ; + } + } + +debug ("lowest_tCKmin_CL = %u\n" , lowest_tCKmin_CL); + +return lowest_tCKmin_CL; +} + +/* +* ddr_compute_dimm_parameters for DDR1 SPD +* +* Compute DIMM parameters based upon the SPD information in spd. +* Writes the results to the dimm_params_t structure pointed by pdimm. +* +* FIXME: use #define for the retvals +*/ +unsigned int +ddr_compute_dimm_parameters (const ddr1_spd_eeprom_t *spd, +dimm_params_t *pdimm, +unsigned int dimm_number) +{ +unsigned int retval; + +if (spd->mem_type) { +if (spd->mem_type !=SPD_MEMTYPE_DDR ) { +printf ("DIMM %u: is not a DDR1 SPD.\n" , dimm_number); +return 1 ; + } + }else { +memset (pdimm,0 ,sizeof (dimm_params_t)); +return 1 ; + } + + retval =ddr1_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)); +memcpy (pdimm->mpart, spd->mpart,sizeof (pdimm->mpart) -1 ); + +/* DIMM organization parameters */ + pdimm->n_ranks = spd->nrows; + pdimm->rank_density =compute_ranksize (spd->mem_type, spd->bank_dens); + pdimm->capacity = pdimm->n_ranks * pdimm->rank_density; + pdimm->data_width = spd->dataw_lsb; + pdimm->primary_sdram_width = spd->primw; + pdimm->ec_sdram_width = spd->ecw; + +/* +* FIXME: Need to determine registered_dimm status. +* 1 == register buffered +* 0 == unbuffered +*/ + pdimm->registered_dimm =0 ;/* unbuffered */ + +/* SDRAM device parameters */ + pdimm->n_row_addr = spd->nrow_addr; + pdimm->n_col_addr = spd->ncol_addr; + pdimm->n_banks_per_sdram_device = spd->nbanks; + pdimm->edc_config = spd->config; + pdimm->burst_lengths_bitmask = spd->burstl; + pdimm->row_density = spd->bank_dens; + +/* +* Calculate the Maximum Data Rate based on the Minimum Cycle time. +* The SPD clk_cycle field (tCKmin) is measured in tenths of +* nanoseconds and represented as BCD. +*/ + pdimm->tCKmin_X_ps + =convert_bcd_tenths_to_cycle_time_ps (spd->clk_cycle); + pdimm->tCKmin_X_minus_1_ps + =convert_bcd_tenths_to_cycle_time_ps (spd->clk_cycle2); + pdimm->tCKmin_X_minus_2_ps + =convert_bcd_tenths_to_cycle_time_ps (spd->clk_cycle3); + + pdimm->tCKmax_ps =compute_tckmax_from_spd_ps (spd->tckmax); + +/* +* Compute CAS latencies defined by SPD +* The SPD caslat_X should have at least 1 and at most 3 bits set. +* +* If cas_lat after masking is 0, the __ilog2 function returns +* 255 into the variable. This behavior is abused once. +*/ + pdimm->caslat_X =__ilog2 (spd->cas_lat); + pdimm->caslat_X_minus_1 =__ilog2 (spd->cas_lat + & ~(1 << pdimm->caslat_X)); + pdimm->caslat_X_minus_2 =__ilog2 (spd->cas_lat + & ~(1 << pdimm->caslat_X) + & ~(1 << pdimm->caslat_X_minus_1)); + +/* Compute CAS latencies below that defined by SPD */ + pdimm->caslat_lowest_derated + =compute_derated_DDR1_CAS_latency (get_memory_clk_period_ps ()); + +/* Compute timing parameters */ + pdimm->tRCD_ps = spd->trcd *250 ; + pdimm->tRP_ps = spd->trp *250 ; + pdimm->tRAS_ps = spd->tras *1000 ; + + pdimm->tWR_ps =mclk_to_picos (3 ); + pdimm->tWTR_ps =mclk_to_picos (1 ); + pdimm->tRFC_ps =compute_trfc_ps_from_spd (0 , spd->trfc); + + pdimm->tRRD_ps = spd->trrd *250 ; + pdimm->tRC_ps =compute_trc_ps_from_spd (0 , spd->trc); + + pdimm->refresh_rate_ps =determine_refresh_rate_ps (spd->refresh); + + pdimm->tIS_ps =convert_bcd_hundredths_to_cycle_time_ps (spd->ca_setup); + pdimm->tIH_ps =convert_bcd_hundredths_to_cycle_time_ps (spd->ca_hold); + pdimm->tDS_ps + =convert_bcd_hundredths_to_cycle_time_ps (spd->data_setup); + pdimm->tDH_ps + =convert_bcd_hundredths_to_cycle_time_ps (spd->data_hold); + + pdimm->tRTP_ps =mclk_to_picos (2 );/* By the book. */ + pdimm->tDQSQ_max_ps = spd->tdqsq *10 ; + pdimm->tQHS_ps = spd->tqhs *10 ; + +return 0 ; +}
Signature · 1 line
1.5.5.1
PATCH v5 4/10 FSL DDR: Add DDR1 support
Quoted 8 lines · Kumar Gala
Signed-off-by James Yang <[email protected]>Signed-off-by Jon Loeliger <[email protected]>Signed-off-by Kumar Gala <[email protected]>---
cpu/mpc8xxx/ddr/ddr1_dimm_params.c| 343 +++++++++++++++++++++++++++
+++++++++1 files changed, 343 insertions(+), 0 deletions(-)create mode 100644
cpu/mpc8xxx/ddr/ddr1_dimm_params.c
oops, this is an old version (changed to commit message on the real one, you should take:
'FSL DDR: Add DDR1 DIMM paramter support'
- k
PATCH v5 4/10 FSL DDR: Add DDR1 support
Dear Kumar Gala,
Quoted 12 lines · In message <[email protected]> you wrote:
Quoted 8 lines · Kumar Gala
Signed-off-by James Yang <[email protected]>Signed-off-by Jon Loeliger <[email protected]>Signed-off-by Kumar Gala <[email protected]>---
cpu/mpc8xxx/ddr/ddr1_dimm_params.c| 343 +++++++++++++++++++++++++++
+++++++++1 files changed, 343 insertions(+), 0 deletions(-)create mode 100644
cpu/mpc8xxx/ddr/ddr1_dimm_params.c
Quoted 4 lines
oops, this is an old version (changed to commit message on the real one, you should take:
'FSL DDR: Add DDR1 DIMM paramter support'
What's a paramter ? ;-)
Best regards,
Wolfgang Denk
Signature · 5 lines
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de The human mind ordinarily operates at only ten percent of its capacity. The rest is overhead for the operating system.
PATCH v5 5/10 FSL DDR: Add DDR2 DIMM paramter support
In reply to Kumar GalaCompute DIMM parameters based upon the SPD information.
--- cpu/mpc8xxx/ddr/ddr2_dimm_params.c | 339 ++++++++++++++++++++++++++++++++++++ 1 files changed, 339 insertions(+), 0 deletions(-) create mode 100644 cpu/mpc8xxx/ddr/ddr2_dimm_params.c
cpu/mpc8xxx/ddr/ddr2_dimm_params.c new file +339 -0
@@ -0,0 +1,339 @@ +/* +* Copyright 2008 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 +* 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. +* +* Study these table from Byte 31 of JEDEC SPD Spec. +* +* DDR I DDR II +* Bit Size Size +* --- ----- ------ +* 7 high 512MB 512MB +* 6 256MB 256MB +* 5 128MB 128MB +* 4 64MB 16GB +* 3 32MB 8GB +* 2 16MB 4GB +* 1 2GB 2GB +* 0 low 1GB 1GB +* +* Reorder Table to be linear by stripping the bottom +* 2 or 5 bits off and shifting them up to the top. +* +*/ +static phys_size_t +compute_ranksize (unsigned int mem_type,unsigned char row_dens) +{ +phys_size_t bsize; + +/* Bottom 5 bits up to the top. */ + bsize = ((row_dens >>5 ) | ((row_dens &31 ) <<3 )); + bsize <<=27ULL ; +debug ("DDR: DDR II rank density = 0x%08x\n" , bsize); + +return bsize; +} + +/* +* Convert a two-nibble BCD value into a cycle time. +* While the spec calls for nano-seconds, picos are returned. +* +* This implements the tables for bytes 9, 23 and 25 for both +* DDR I and II. No allowance for distinguishing the invalid +* fields absent for DDR I yet present in DDR II is made. +* (That is, cycle times of .25, .33, .66 and .75 ns are +* allowed for both DDR II and I.) +*/ +static unsigned int +convert_bcd_tenths_to_cycle_time_ps (unsigned int spd_val) +{ +/* Table look up the lower nibble, allow DDR I & II. */ +unsigned int tenths_ps[16 ] = { +0 , +100 , +200 , +300 , +400 , +500 , +600 , +700 , +800 , +900 , +250 ,/* This and the next 3 entries valid ... */ +330 ,/* ... only for tCK calculations. */ +660 , +750 , +0 ,/* undefined */ +0 /* undefined */ + }; + +unsigned int whole_ns = (spd_val &0xF0 ) >>4 ; +unsigned int tenth_ns = spd_val &0x0F ; +unsigned int ps = whole_ns *1000 + tenths_ps[tenth_ns]; + +return ps; +} + +static unsigned int +convert_bcd_hundredths_to_cycle_time_ps (unsigned int spd_val) +{ +unsigned int tenth_ns = (spd_val &0xF0 ) >>4 ; +unsigned int hundredth_ns = spd_val &0x0F ; +unsigned int ps = tenth_ns *100 + hundredth_ns *10 ; + +return ps; +} + +static unsigned int byte40_table_ps[8 ] = { +0 , +250 , +330 , +500 , +660 , +750 , +0 ,/* supposed to be RFC, but not sure what that means */ +0 /* Undefined */ +}; + +static unsigned int +compute_trfc_ps_from_spd (unsigned char trctrfc_ext,unsigned char trfc) +{ +unsigned int trfc_ps; + + trfc_ps = (((trctrfc_ext &0x1 ) *256 ) + trfc) *1000 + + byte40_table_ps[(trctrfc_ext >>1 ) &0x7 ]; + +return trfc_ps; +} + +static unsigned int +compute_trc_ps_from_spd (unsigned char trctrfc_ext,unsigned char trc) +{ +unsigned int trc_ps; + + trc_ps = trc *1000 + byte40_table_ps[(trctrfc_ext >>4 ) &0x7 ]; + +return trc_ps; +} + +/* +* Determine Refresh Rate. Ignore self refresh bit on DDR I. +* Table from SPD Spec, Byte 12, converted to picoseconds and +* filled in with "default" normal values. +*/ +static unsigned int +determine_refresh_rate_ps (const unsigned int spd_refresh) +{ +unsigned int refresh_time_ps[8 ] = { +15625000 ,/* 0 Normal 1.00x */ +3900000 ,/* 1 Reduced .25x */ +7800000 ,/* 2 Extended .50x */ +31300000 ,/* 3 Extended 2.00x */ +62500000 ,/* 4 Extended 4.00x */ +125000000 ,/* 5 Extended 8.00x */ +15625000 ,/* 6 Normal 1.00x filler */ +15625000 ,/* 7 Normal 1.00x filler */ + }; + +return refresh_time_ps[spd_refresh &0x7 ]; +} + +/* +* The purpose of this function is to compute a suitable +* CAS latency given the DRAM clock period. The SPD only +* defines at most 3 CAS latencies. Typically the slower in +* frequency the DIMM runs at, the shorter its CAS latency can. +* be. If the DIMM is operating at a sufficiently low frequency, +* it may be able to run at a CAS latency shorter than the +* shortest SPD-defined CAS latency. +* +* If a CAS latency is not found, 0 is returned. +* +* Do this by finding in the standard speed bin table the longest +* tCKmin that doesn't exceed the value of mclk_ps (tCK). +* +* An assumption made is that the SDRAM device allows the +* CL to be programmed for a value that is lower than those +* advertised by the SPD. This is not always the case, +* as those modes not defined in the SPD are optional. +* +* CAS latency de-rating based upon values JEDEC Standard No. 79-2C +* Table 40, "DDR2 SDRAM stanadard speed bins and tCK, tRCD, tRP, tRAS, +* and tRC for corresponding bin" +* +* ordinal 2, ddr2_speed_bins[1] contains tCK for CL=3 +* Not certain if any good value exists for CL=2 +*/ +/* CL2 CL3 CL4 CL5 CL6 */ +unsigned short ddr2_speed_bins[] = {0 ,5000 ,3750 ,3000 ,2500 }; + +unsigned int +compute_derated_DDR2_CAS_latency (unsigned int mclk_ps) +{ +const unsigned int num_speed_bins =ARRAY_SIZE (ddr2_speed_bins); +unsigned int lowest_tCKmin_found =0 ; +unsigned int lowest_tCKmin_CL =0 ; +unsigned int i; + +debug ("mclk_ps = %u\n" , mclk_ps); + +for (i =0 ; i < num_speed_bins; i++) { +unsigned int x = ddr2_speed_bins[i]; +debug ("i=%u, x = %u, lowest_tCKmin_found = %u\n" , + i, x, lowest_tCKmin_found); +if (x && x <= mclk_ps && x >= lowest_tCKmin_found ) { + lowest_tCKmin_found = x; + lowest_tCKmin_CL = i +2 ; + } + } + +debug ("lowest_tCKmin_CL = %u\n" , lowest_tCKmin_CL); + +return lowest_tCKmin_CL; +} + +/* +* ddr_compute_dimm_parameters for DDR2 SPD +* +* Compute DIMM parameters based upon the SPD information in spd. +* Writes the results to the dimm_params_t structure pointed by pdimm. +* +* FIXME: use #define for the retvals +*/ +unsigned int +ddr_compute_dimm_parameters (const ddr2_spd_eeprom_t *spd, +dimm_params_t *pdimm, +unsigned int dimm_number) +{ +unsigned int retval; + +if (spd->mem_type) { +if (spd->mem_type !=SPD_MEMTYPE_DDR2 ) { +printf ("DIMM %u: is not a DDR2 SPD.\n" , dimm_number); +return 1 ; + } + }else { +memset (pdimm,0 ,sizeof (dimm_params_t)); +return 1 ; + } + + retval =ddr2_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)); +memcpy (pdimm->mpart, spd->mpart,sizeof (pdimm->mpart) -1 ); + +/* DIMM organization parameters */ + pdimm->n_ranks = (spd->mod_ranks &0x7 ) +1 ; + pdimm->rank_density =compute_ranksize (spd->mem_type, spd->rank_dens); + pdimm->capacity = pdimm->n_ranks * pdimm->rank_density; + pdimm->data_width = spd->dataw; + pdimm->primary_sdram_width = spd->primw; + pdimm->ec_sdram_width = spd->ecw; + +/* FIXME: what about registered SO-DIMM? */ +switch (spd->dimm_type) { +case 0x01 :/* RDIMM */ +case 0x10 :/* Mini-RDIMM */ + pdimm->registered_dimm =1 ;/* register buffered */ +break ; + +case 0x02 :/* UDIMM */ +case 0x04 :/* SO-DIMM */ +case 0x08 :/* Micro-DIMM */ +case 0x20 :/* Mini-UDIMM */ + pdimm->registered_dimm =0 ;/* unbuffered */ +break ; + +default : +printf ("unknown dimm_type 0x%02X\n" , spd->dimm_type); +return 1 ; +break ; + } + +/* SDRAM device parameters */ + pdimm->n_row_addr = spd->nrow_addr; + pdimm->n_col_addr = spd->ncol_addr; + pdimm->n_banks_per_sdram_device = spd->nbanks; + pdimm->edc_config = spd->config; + pdimm->burst_lengths_bitmask = spd->burstl; + pdimm->row_density = spd->rank_dens; + +/* +* Calculate the Maximum Data Rate based on the Minimum Cycle time. +* The SPD clk_cycle field (tCKmin) is measured in tenths of +* nanoseconds and represented as BCD. +*/ + pdimm->tCKmin_X_ps + =convert_bcd_tenths_to_cycle_time_ps (spd->clk_cycle); + pdimm->tCKmin_X_minus_1_ps + =convert_bcd_tenths_to_cycle_time_ps (spd->clk_cycle2); + pdimm->tCKmin_X_minus_2_ps + =convert_bcd_tenths_to_cycle_time_ps (spd->clk_cycle3); + + pdimm->tCKmax_ps =convert_bcd_tenths_to_cycle_time_ps (spd->tckmax); + +/* +* Compute CAS latencies defined by SPD +* The SPD caslat_X should have at least 1 and at most 3 bits set. +* +* If cas_lat after masking is 0, the __ilog2 function returns +* 255 into the variable. This behavior is abused once. +*/ + pdimm->caslat_X =__ilog2 (spd->cas_lat); + pdimm->caslat_X_minus_1 =__ilog2 (spd->cas_lat + & ~(1 << pdimm->caslat_X)); + pdimm->caslat_X_minus_2 =__ilog2 (spd->cas_lat + & ~(1 << pdimm->caslat_X) + & ~(1 << pdimm->caslat_X_minus_1)); + +/* Compute CAS latencies below that defined by SPD */ + pdimm->caslat_lowest_derated + =compute_derated_DDR2_CAS_latency (get_memory_clk_period_ps ()); + +/* Compute timing parameters */ + pdimm->tRCD_ps = spd->trcd *250 ; + pdimm->tRP_ps = spd->trp *250 ; + pdimm->tRAS_ps = spd->tras *1000 ; + + pdimm->tWR_ps = spd->twr *250 ; + pdimm->tWTR_ps = spd->twtr *250 ; + pdimm->tRFC_ps =compute_trfc_ps_from_spd (spd->trctrfc_ext, spd->trfc); + + pdimm->tRRD_ps = spd->trrd *250 ; + pdimm->tRC_ps =compute_trc_ps_from_spd (spd->trctrfc_ext, spd->trc); + + pdimm->refresh_rate_ps =determine_refresh_rate_ps (spd->refresh); + + pdimm->tIS_ps =convert_bcd_hundredths_to_cycle_time_ps (spd->ca_setup); + pdimm->tIH_ps =convert_bcd_hundredths_to_cycle_time_ps (spd->ca_hold); + pdimm->tDS_ps + =convert_bcd_hundredths_to_cycle_time_ps (spd->data_setup); + pdimm->tDH_ps + =convert_bcd_hundredths_to_cycle_time_ps (spd->data_hold); + + pdimm->tRTP_ps = spd->trtp *250 ; + pdimm->tDQSQ_max_ps = spd->tdqsq *10 ; + pdimm->tQHS_ps = spd->tqhs *10 ; + +return 0 ; +}
Signature · 1 line
1.5.5.1
PATCH v5 5/10 FSL DDR: Add DDR2 support
--- cpu/mpc8xxx/ddr/ddr2_dimm_params.c | 339 ++++++++++++++++++++++++++++++++++++ 1 files changed, 339 insertions(+), 0 deletions(-) create mode 100644 cpu/mpc8xxx/ddr/ddr2_dimm_params.c
cpu/mpc8xxx/ddr/ddr2_dimm_params.c new file +339 -0
@@ -0,0 +1,339 @@ +/* +* Copyright 2008 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 +* 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. +* +* Study these table from Byte 31 of JEDEC SPD Spec. +* +* DDR I DDR II +* Bit Size Size +* --- ----- ------ +* 7 high 512MB 512MB +* 6 256MB 256MB +* 5 128MB 128MB +* 4 64MB 16GB +* 3 32MB 8GB +* 2 16MB 4GB +* 1 2GB 2GB +* 0 low 1GB 1GB +* +* Reorder Table to be linear by stripping the bottom +* 2 or 5 bits off and shifting them up to the top. +* +*/ +static phys_size_t +compute_ranksize (unsigned int mem_type,unsigned char row_dens) +{ +phys_size_t bsize; + +/* Bottom 5 bits up to the top. */ + bsize = ((row_dens >>5 ) | ((row_dens &31 ) <<3 )); + bsize <<=27ULL ; +debug ("DDR: DDR II rank density = 0x%08x\n" , bsize); + +return bsize; +} + +/* +* Convert a two-nibble BCD value into a cycle time. +* While the spec calls for nano-seconds, picos are returned. +* +* This implements the tables for bytes 9, 23 and 25 for both +* DDR I and II. No allowance for distinguishing the invalid +* fields absent for DDR I yet present in DDR II is made. +* (That is, cycle times of .25, .33, .66 and .75 ns are +* allowed for both DDR II and I.) +*/ +static unsigned int +convert_bcd_tenths_to_cycle_time_ps (unsigned int spd_val) +{ +/* Table look up the lower nibble, allow DDR I & II. */ +unsigned int tenths_ps[16 ] = { +0 , +100 , +200 , +300 , +400 , +500 , +600 , +700 , +800 , +900 , +250 ,/* This and the next 3 entries valid ... */ +330 ,/* ... only for tCK calculations. */ +660 , +750 , +0 ,/* undefined */ +0 /* undefined */ + }; + +unsigned int whole_ns = (spd_val &0xF0 ) >>4 ; +unsigned int tenth_ns = spd_val &0x0F ; +unsigned int ps = whole_ns *1000 + tenths_ps[tenth_ns]; + +return ps; +} + +static unsigned int +convert_bcd_hundredths_to_cycle_time_ps (unsigned int spd_val) +{ +unsigned int tenth_ns = (spd_val &0xF0 ) >>4 ; +unsigned int hundredth_ns = spd_val &0x0F ; +unsigned int ps = tenth_ns *100 + hundredth_ns *10 ; + +return ps; +} + +static unsigned int byte40_table_ps[8 ] = { +0 , +250 , +330 , +500 , +660 , +750 , +0 ,/* supposed to be RFC, but not sure what that means */ +0 /* Undefined */ +}; + +static unsigned int +compute_trfc_ps_from_spd (unsigned char trctrfc_ext,unsigned char trfc) +{ +unsigned int trfc_ps; + + trfc_ps = (((trctrfc_ext &0x1 ) *256 ) + trfc) *1000 + + byte40_table_ps[(trctrfc_ext >>1 ) &0x7 ]; + +return trfc_ps; +} + +static unsigned int +compute_trc_ps_from_spd (unsigned char trctrfc_ext,unsigned char trc) +{ +unsigned int trc_ps; + + trc_ps = trc *1000 + byte40_table_ps[(trctrfc_ext >>4 ) &0x7 ]; + +return trc_ps; +} + +/* +* Determine Refresh Rate. Ignore self refresh bit on DDR I. +* Table from SPD Spec, Byte 12, converted to picoseconds and +* filled in with "default" normal values. +*/ +static unsigned int +determine_refresh_rate_ps (const unsigned int spd_refresh) +{ +unsigned int refresh_time_ps[8 ] = { +15625000 ,/* 0 Normal 1.00x */ +3900000 ,/* 1 Reduced .25x */ +7800000 ,/* 2 Extended .50x */ +31300000 ,/* 3 Extended 2.00x */ +62500000 ,/* 4 Extended 4.00x */ +125000000 ,/* 5 Extended 8.00x */ +15625000 ,/* 6 Normal 1.00x filler */ +15625000 ,/* 7 Normal 1.00x filler */ + }; + +return refresh_time_ps[spd_refresh &0x7 ]; +} + +/* +* The purpose of this function is to compute a suitable +* CAS latency given the DRAM clock period. The SPD only +* defines at most 3 CAS latencies. Typically the slower in +* frequency the DIMM runs at, the shorter its CAS latency can. +* be. If the DIMM is operating at a sufficiently low frequency, +* it may be able to run at a CAS latency shorter than the +* shortest SPD-defined CAS latency. +* +* If a CAS latency is not found, 0 is returned. +* +* Do this by finding in the standard speed bin table the longest +* tCKmin that doesn't exceed the value of mclk_ps (tCK). +* +* An assumption made is that the SDRAM device allows the +* CL to be programmed for a value that is lower than those +* advertised by the SPD. This is not always the case, +* as those modes not defined in the SPD are optional. +* +* CAS latency de-rating based upon values JEDEC Standard No. 79-2C +* Table 40, "DDR2 SDRAM stanadard speed bins and tCK, tRCD, tRP, tRAS, +* and tRC for corresponding bin" +* +* ordinal 2, ddr2_speed_bins[1] contains tCK for CL=3 +* Not certain if any good value exists for CL=2 +*/ +/* CL2 CL3 CL4 CL5 CL6 */ +unsigned short ddr2_speed_bins[] = {0 ,5000 ,3750 ,3000 ,2500 }; + +unsigned int +compute_derated_DDR2_CAS_latency (unsigned int mclk_ps) +{ +const unsigned int num_speed_bins =ARRAY_SIZE (ddr2_speed_bins); +unsigned int lowest_tCKmin_found =0 ; +unsigned int lowest_tCKmin_CL =0 ; +unsigned int i; + +debug ("mclk_ps = %u\n" , mclk_ps); + +for (i =0 ; i < num_speed_bins; i++) { +unsigned int x = ddr2_speed_bins[i]; +debug ("i=%u, x = %u, lowest_tCKmin_found = %u\n" , + i, x, lowest_tCKmin_found); +if (x && x <= mclk_ps && x >= lowest_tCKmin_found ) { + lowest_tCKmin_found = x; + lowest_tCKmin_CL = i +2 ; + } + } + +debug ("lowest_tCKmin_CL = %u\n" , lowest_tCKmin_CL); + +return lowest_tCKmin_CL; +} + +/* +* ddr_compute_dimm_parameters for DDR2 SPD +* +* Compute DIMM parameters based upon the SPD information in spd. +* Writes the results to the dimm_params_t structure pointed by pdimm. +* +* FIXME: use #define for the retvals +*/ +unsigned int +ddr_compute_dimm_parameters (const ddr2_spd_eeprom_t *spd, +dimm_params_t *pdimm, +unsigned int dimm_number) +{ +unsigned int retval; + +if (spd->mem_type) { +if (spd->mem_type !=SPD_MEMTYPE_DDR2 ) { +printf ("DIMM %u: is not a DDR2 SPD.\n" , dimm_number); +return 1 ; + } + }else { +memset (pdimm,0 ,sizeof (dimm_params_t)); +return 1 ; + } + + retval =ddr2_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)); +memcpy (pdimm->mpart, spd->mpart,sizeof (pdimm->mpart) -1 ); + +/* DIMM organization parameters */ + pdimm->n_ranks = (spd->mod_ranks &0x7 ) +1 ; + pdimm->rank_density =compute_ranksize (spd->mem_type, spd->rank_dens); + pdimm->capacity = pdimm->n_ranks * pdimm->rank_density; + pdimm->data_width = spd->dataw; + pdimm->primary_sdram_width = spd->primw; + pdimm->ec_sdram_width = spd->ecw; + +/* FIXME: what about registered SO-DIMM? */ +switch (spd->dimm_type) { +case 0x01 :/* RDIMM */ +case 0x10 :/* Mini-RDIMM */ + pdimm->registered_dimm =1 ;/* register buffered */ +break ; + +case 0x02 :/* UDIMM */ +case 0x04 :/* SO-DIMM */ +case 0x08 :/* Micro-DIMM */ +case 0x20 :/* Mini-UDIMM */ + pdimm->registered_dimm =0 ;/* unbuffered */ +break ; + +default : +printf ("unknown dimm_type 0x%02X\n" , spd->dimm_type); +return 1 ; +break ; + } + +/* SDRAM device parameters */ + pdimm->n_row_addr = spd->nrow_addr; + pdimm->n_col_addr = spd->ncol_addr; + pdimm->n_banks_per_sdram_device = spd->nbanks; + pdimm->edc_config = spd->config; + pdimm->burst_lengths_bitmask = spd->burstl; + pdimm->row_density = spd->rank_dens; + +/* +* Calculate the Maximum Data Rate based on the Minimum Cycle time. +* The SPD clk_cycle field (tCKmin) is measured in tenths of +* nanoseconds and represented as BCD. +*/ + pdimm->tCKmin_X_ps + =convert_bcd_tenths_to_cycle_time_ps (spd->clk_cycle); + pdimm->tCKmin_X_minus_1_ps + =convert_bcd_tenths_to_cycle_time_ps (spd->clk_cycle2); + pdimm->tCKmin_X_minus_2_ps + =convert_bcd_tenths_to_cycle_time_ps (spd->clk_cycle3); + + pdimm->tCKmax_ps =convert_bcd_tenths_to_cycle_time_ps (spd->tckmax); + +/* +* Compute CAS latencies defined by SPD +* The SPD caslat_X should have at least 1 and at most 3 bits set. +* +* If cas_lat after masking is 0, the __ilog2 function returns +* 255 into the variable. This behavior is abused once. +*/ + pdimm->caslat_X =__ilog2 (spd->cas_lat); + pdimm->caslat_X_minus_1 =__ilog2 (spd->cas_lat + & ~(1 << pdimm->caslat_X)); + pdimm->caslat_X_minus_2 =__ilog2 (spd->cas_lat + & ~(1 << pdimm->caslat_X) + & ~(1 << pdimm->caslat_X_minus_1)); + +/* Compute CAS latencies below that defined by SPD */ + pdimm->caslat_lowest_derated + =compute_derated_DDR2_CAS_latency (get_memory_clk_period_ps ()); + +/* Compute timing parameters */ + pdimm->tRCD_ps = spd->trcd *250 ; + pdimm->tRP_ps = spd->trp *250 ; + pdimm->tRAS_ps = spd->tras *1000 ; + + pdimm->tWR_ps = spd->twr *250 ; + pdimm->tWTR_ps = spd->twtr *250 ; + pdimm->tRFC_ps =compute_trfc_ps_from_spd (spd->trctrfc_ext, spd->trfc); + + pdimm->tRRD_ps = spd->trrd *250 ; + pdimm->tRC_ps =compute_trc_ps_from_spd (spd->trctrfc_ext, spd->trc); + + pdimm->refresh_rate_ps =determine_refresh_rate_ps (spd->refresh); + + pdimm->tIS_ps =convert_bcd_hundredths_to_cycle_time_ps (spd->ca_setup); + pdimm->tIH_ps =convert_bcd_hundredths_to_cycle_time_ps (spd->ca_hold); + pdimm->tDS_ps + =convert_bcd_hundredths_to_cycle_time_ps (spd->data_setup); + pdimm->tDH_ps + =convert_bcd_hundredths_to_cycle_time_ps (spd->data_hold); + + pdimm->tRTP_ps = spd->trtp *250 ; + pdimm->tDQSQ_max_ps = spd->tdqsq *10 ; + pdimm->tQHS_ps = spd->tqhs *10 ; + +return 0 ; +}
Signature · 1 line
1.5.5.1
PATCH v5 5/10 FSL DDR: Add DDR2 support
Quoted 8 lines · Kumar Gala
Signed-off-by James Yang <[email protected]>Signed-off-by Jon Loeliger <[email protected]>Signed-off-by Kumar Gala <[email protected]>---
cpu/mpc8xxx/ddr/ddr2_dimm_params.c| 339 +++++++++++++++++++++++++++
+++++++++1 files changed, 339 insertions(+), 0 deletions(-)create mode 100644
cpu/mpc8xxx/ddr/ddr2_dimm_params.c
oops, this is an old version (changed to commit message on the real one, you should take:
'FSL DDR: Add DDR2 DIMM paramter support'
- k
PATCH v5 6/10 FSL DDR: Add 86xx specific register setting
In reply to Kumar Gala--- cpu/mpc86xx/Makefile | 6 +++ cpu/mpc86xx/ddr-8641.c | 86 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 92 insertions(+), 0 deletions(-) create mode 100644 cpu/mpc86xx/ddr-8641.c
cpu/mpc86xx/Makefile +6 -0
@@ -39,6 +39,12 @@ COBJS-y += interrupts.o COBJS-$(CONFIG_OF_LIBFDT) += fdt.o +ifeq ($(CONFIG_FSL_DDR2),y) +COBJS-$(CONFIG_MPC8641) += ddr-8641.o +# 8610 & 8641 are identical w/regards to DDR +COBJS-$(CONFIG_MPC8610) += ddr-8641.o +endif + ifneq ($(CONFIG_FSL_DDR2),y) COBJS-y += spd_sdram.o endif
cpu/mpc86xx/ddr-8641.c new file +86 -0
86 lines not on this page · raw message
Signature · 1 line
1.5.5.1
PATCH v5 7/10 FSL DDR: Convert MPC8641HPCN to new DDR code.
--- board/freescale/mpc8641hpcn/Makefile | 8 ++- board/freescale/mpc8641hpcn/ddr.c | 88 ++++++++++++++++++++++++ board/freescale/mpc8641hpcn/mpc8641hpcn.c | 6 +- include/configs/MPC8641HPCN.h | 105 ++++++++++++++--------------- 4 files changed, 146 insertions(+), 61 deletions(-) create mode 100644 board/freescale/mpc8641hpcn/ddr.c
board/freescale/mpc8641hpcn/Makefile +5 -3
@@ -25,10 +25,12 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(BOARD).a -COBJS := $(BOARD).o law.o +COBJS-y += $(BOARD).o +COBJS-y += law.o +COBJS-$(CONFIG_FSL_DDR2) += ddr.o -SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) -OBJS := $(addprefix $(obj),$(COBJS)) +SRCS := $(SOBJS:.o=.S) $(COBJS-y:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS-y)) SOBJS := $(addprefix $(obj),$(SOBJS)) $(LIB): $(obj).depend $(OBJS) $(SOBJS)
board/freescale/mpc8641hpcn/ddr.c new file +88 -0
88 lines not on this page · raw message
board/freescale/mpc8641hpcn/mpc8641hpcn.c +2 -4
@@ -25,7 +25,7 @@#include <asm/processor.h> #include <asm/immap_86xx.h> #include <asm/immap_fsl_pci.h> -#include <spd_sdram.h> +#include <asm/fsl_ddr_sdram.h> #include <asm/io.h> #include <libfdt.h> #include <fdt_support.h>
@@ -36,10 +36,8 @@extern void ddr_enable_ecc (unsigned int dram_size);#endif -void sdram_init (void );long int fixed_sdram (void ); -int board_early_init_f (void ) {return 0 ;
@@ -61,7 +59,7 @@ initdram(int board_type)long dram_size =0 ;#if defined(CONFIG_SPD_EEPROM ) - dram_size =spd_sdram (); + dram_size =fsl_ddr_sdram ();#else dram_size =fixed_sdram ();#endif
include/configs/MPC8641HPCN.h +50 -53
122 lines not on this page · raw message
Signature · 1 line
1.5.5.1
PATCH v5 8/10 FSL DDR: Convert MPC8610HPCD to new DDR code.
From: Jon Loeliger <[email protected]>
--- board/freescale/mpc8610hpcd/Makefile | 10 ++-- board/freescale/mpc8610hpcd/ddr.c | 79 +++++++++++++++++++++++++++++ board/freescale/mpc8610hpcd/mpc8610hpcd.c | 3 +- include/configs/MPC8610HPCD.h | 43 +++++++-------- 4 files changed, 106 insertions(+), 29 deletions(-) create mode 100644 board/freescale/mpc8610hpcd/ddr.c
board/freescale/mpc8610hpcd/Makefile +5 -5
@@ -23,14 +23,14 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(BOARD).a -COBJS := $(BOARD).o law.o +COBJS-y += $(BOARD).o +COBJS-$(CONFIG_FSL_DDR2) += ddr.o +COBJS-y += law.o COBJS-${CONFIG_FSL_DIU_FB} += mpc8610hpcd_diu.o -COBJS += ${COBJS-y} - -SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) -OBJS := $(addprefix $(obj),$(COBJS)) +SRCS := $(SOBJS:.o=.S) $(COBJS-y:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS-y)) SOBJS := $(addprefix $(obj),$(SOBJS)) $(LIB): $(obj).depend $(OBJS) $(SOBJS)
board/freescale/mpc8610hpcd/ddr.c new file +79 -0
79 lines not on this page · raw message
board/freescale/mpc8610hpcd/mpc8610hpcd.c +2 -1
@@ -26,6 +26,7 @@#include <asm/processor.h> #include <asm/immap_86xx.h> #include <asm/immap_fsl_pci.h> +#include <asm/fsl_ddr_sdram.h> #include <i2c.h> #include <asm/io.h> #include <libfdt.h>
@@ -122,7 +123,7 @@ initdram(int board_type)long dram_size =0 ;#if defined(CONFIG_SPD_EEPROM ) - dram_size =spd_sdram (); + dram_size =fsl_ddr_sdram ();#else dram_size =fixed_sdram ();#endif
include/configs/MPC8610HPCD.h +20 -23
80 lines not on this page · raw message
Signature · 1 line
1.5.5.1
PATCH v5 9/10 FSL DDR: Convert SBC8641D to new DDR code.
--- board/sbc8641d/Makefile | 8 ++- board/sbc8641d/ddr.c | 88 ++++++++++++++++++++++++++++++++++++++++++++ board/sbc8641d/sbc8641d.c | 5 +- include/configs/sbc8641d.h | 6 ++- 4 files changed, 99 insertions(+), 8 deletions(-) create mode 100644 board/sbc8641d/ddr.c
board/sbc8641d/Makefile +5 -3
@@ -25,10 +25,12 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(BOARD).a -COBJS := $(BOARD).o law.o +COBJS-y += $(BOARD).o +COBJS-y += law.o +COBJS-$(CONFIG_FSL_DDR2) += ddr.o -SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) -OBJS := $(addprefix $(obj),$(COBJS)) +SRCS := $(SOBJS:.o=.S) $(COBJS-y:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS-y)) SOBJS := $(addprefix $(obj),$(SOBJS)) $(LIB): $(obj).depend $(OBJS) $(SOBJS)
board/sbc8641d/ddr.c new file +88 -0
88 lines not on this page · raw message
board/sbc8641d/sbc8641d.c +2 -3
@@ -34,7 +34,7 @@#include <asm/processor.h> #include <asm/immap_86xx.h> #include <asm/immap_fsl_pci.h> -#include <spd_sdram.h> +#include <asm/fsl_ddr_sdram.h> #include <libfdt.h> #include <fdt_support.h>
@@ -42,7 +42,6 @@extern void ddr_enable_ecc (unsigned int dram_size);#endif -void sdram_init (void );long int fixed_sdram (void );int board_early_init_f (void )
@@ -62,7 +61,7 @@ phys_size_t initdram (int board_type)long dram_size =0 ;#if defined(CONFIG_SPD_EEPROM ) - dram_size =spd_sdram (); + dram_size =fsl_ddr_sdram ();#else dram_size =fixed_sdram ();#endif
include/configs/sbc8641d.h +4 -2
@@ -61,8 +61,6 @@#define CONFIG_HIGH_BATS 1/* High BATs supported and enabled */ #undef CONFIG_SPD_EEPROM/* Do not use SPD EEPROM for DDR setup*/ -#undef CONFIG_DDR_DLL/* possible DLL fix needed */ -#define CONFIG_DDR_2T_TIMING /* Sets the 2T timing bit */ #undef CONFIG_DDR_ECC/* only for ECC DDR module */ #define CONFIG_ECC_INIT_VIA_DDRCONTROLLER /* DDR controller or DMA? */ #define CONFIG_MEM_INIT_VALUE 0xDeadBeef
@@ -114,6 +112,10 @@#define MPC86xx_DDR_SDRAM_CLK_CNTL +#define CONFIG_NUM_DDR_CONTROLLERS 2 +#define CONFIG_DIMM_SLOTS_PER_CTLR 2 +#define CONFIG_CHIP_SELECTS_PER_CTRL (2 * CONFIG_DIMM_SLOTS_PER_CTLR) +#if defined(CONFIG_SPD_EEPROM )/* * Determine DDR configuration from I2C interface.
Signature · 1 line
1.5.5.1
PATCH v5 10/10 FSL DDR: Remove old SPD support from cpu/mpc86xx
All 86xx boards have been converted to the new code so we can remove the old SPD DDR setup code.
--- cpu/mpc86xx/Makefile | 6 - cpu/mpc86xx/spd_sdram.c | 1346 ----------------------------------------------- 2 files changed, 0 insertions(+), 1352 deletions(-) delete mode 100644 cpu/mpc86xx/spd_sdram.c
cpu/mpc86xx/Makefile +0 -6
@@ -39,15 +39,9 @@ COBJS-y += interrupts.o COBJS-$(CONFIG_OF_LIBFDT) += fdt.o -ifeq ($(CONFIG_FSL_DDR2),y) COBJS-$(CONFIG_MPC8641) += ddr-8641.o # 8610 & 8641 are identical w/regards to DDR COBJS-$(CONFIG_MPC8610) += ddr-8641.o -endif - -ifneq ($(CONFIG_FSL_DDR2),y) -COBJS-y += spd_sdram.o -endif SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS-y:.o=.c) OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS-y))
cpu/mpc86xx/spd_sdram.c deleted +0 -1346
1,346 lines not on this page · raw message
Signature · 1 line
1.5.5.1
v5 cover FSL DDR rework
In reply to Kumar GalaDear Kumar Gala,
Quoted 10 lines · In message <[email protected]> you…
01 - Add proper SPD definitions for DDR1/2/3
02 - FSL DDR: Provide a genericset_ddr_laws()
03 - FSL DDR: Rewrite the FSL mpc8xxx DDR controller setup code. 04 - FSL DDR: Add DDR1 DIMM paramter support
05 - FSL DDR: Add DDR2 DIMM paramter support
06 - FSL DDR: Add 86xx specific register setting
07 - FSL DDR: Convert MPC8641HPCN to new DDR code.
08 - FSL DDR: Convert MPC8610HPCD to new DDR code.
09 - FSL DDR: Convert SBC8641D to new DDR code.
10 - FSL DDR: Remove old SPD support from cpu/mpc86xx
All applied.
Quoted 5 lines
This is the latest spin of the DDR work and hopefully address some of the comments we discussioned on IRC.
I've converted ALL 86xx platforms and if these patches are acceptable I'll go ahead and do the 85xx platforms as a followup.
Thanks in advance.
Best regards,
Wolfgang Denk
Signature · 5 lines
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de Extreme feminine beauty is always disturbing. -- Spock, "The Cloud Minders", stardate 5818.4