powerpc/mpc83xx: Migrate from spd_sdram to unified DDR driver
authorYork Sun <yorksun@freescale.com>
Fri, 26 Aug 2011 18:32:44 +0000 (11:32 -0700)
committerKumar Gala <galak@kernel.crashing.org>
Fri, 30 Sep 2011 00:01:06 +0000 (19:01 -0500)
Unified DDR driver is maintained for better performance, robustness and bug
fixes. Upgrading to use unified DDR driver for MPC83xx takes advantage of
overall improvement. It requires changes for board files to customize
platform-dependent parameters.

To utilize the unified DDR driver, a board needs to define CONFIG_FSL_DDRx
in the header file. No more boards will be accepted without such definition.

Note: the workaround for erratum DDR6 for the very old MPC834x Rev 1.0/1.1
and MPC8360 Rev 1.1/1.2 parts is not migrated to unified driver.

Signed-off-by: Kim Phillips <kim.phillips@freescale.com>
Signed-off-by: York Sun <yorksun@freescale.com>
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
12 files changed:
Makefile
arch/powerpc/cpu/mpc83xx/Makefile
arch/powerpc/cpu/mpc83xx/ecc.c
arch/powerpc/cpu/mpc83xx/law.c [new file with mode: 0644]
arch/powerpc/cpu/mpc83xx/speed.c
arch/powerpc/cpu/mpc85xx/ddr-gen2.c
arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c
arch/powerpc/cpu/mpc8xxx/ddr/util.c
arch/powerpc/include/asm/config.h
arch/powerpc/include/asm/immap_83xx.h
common/Makefile
include/common.h

index 5981870227c2203b90161e8caf07b1e75c902ba1..ddcf5332b487418dc95751fe30efc1269c85bda5 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -253,6 +253,7 @@ LIBS += drivers/power/libpower.o
 LIBS += drivers/spi/libspi.o
 ifeq ($(CPU),mpc83xx)
 LIBS += drivers/qe/libqe.o
+LIBS += arch/powerpc/cpu/mpc8xxx/ddr/libddr.o
 LIBS += arch/powerpc/cpu/mpc8xxx/lib8xxx.o
 endif
 ifeq ($(CPU),mpc85xx)
index 3979b6fbab69b990cc95930ccb6c1279b6252e75..b3530361843fe9757639377bfa7e6e98e3594b17 100644 (file)
@@ -34,7 +34,6 @@ COBJS-y += cpu.o
 COBJS-y += cpu_init.o
 COBJS-y += speed.o
 COBJS-y += interrupts.o
-COBJS-y += spd_sdram.o
 COBJS-y += ecc.o
 COBJS-$(CONFIG_QE) += qe_io.o
 COBJS-$(CONFIG_FSL_SERDES) += serdes.o
@@ -42,6 +41,13 @@ COBJS-$(CONFIG_PCI) += pci.o
 COBJS-$(CONFIG_PCIE) += pcie.o
 COBJS-$(CONFIG_OF_LIBFDT) += fdt.o
 
+ifdef CONFIG_FSL_DDR2
+COBJS-$(CONFIG_MPC8349) += ddr-gen2.o
+else
+COBJS-y += spd_sdram.o
+endif
+COBJS-$(CONFIG_FSL_DDR2) += law.o
+
 COBJS  := $(COBJS-y)
 SRCS   := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
 OBJS   := $(addprefix $(obj),$(SOBJS) $(COBJS))
@@ -52,6 +58,18 @@ all: $(obj).depend $(START) $(LIB)
 $(LIB):        $(OBJS)
        $(call cmd_link_o_target, $(OBJS))
 
+$(obj)ddr-gen1.c:
+       @rm -f $(obj)ddr-gen1.c
+       ln -sf $(SRCTREE)/arch/powerpc/cpu/mpc85xx/ddr-gen1.c $(obj)ddr-gen1.c
+
+$(obj)ddr-gen2.c:
+       @rm -f $(obj)ddr-gen2.c
+       ln -sf $(SRCTREE)/arch/powerpc/cpu/mpc85xx/ddr-gen2.c $(obj)ddr-gen2.c
+
+$(obj)ddr-gen3.c:
+       @rm -f $(obj)ddr-gen3.c
+       ln -sf $(SRCTREE)/arch/powerpc/cpu/mpc85xx/ddr-gen3.c $(obj)ddr-gen3.c
+
 #########################################################################
 
 # defines $(obj).depend target
index f8eab96b1993fd0a06ec7d29c096ec1000ce8753..717365c8d1950be29f52f83c77a131a0adba1fc1 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2007 Freescale Semiconductor, Inc.
+ * Copyright (C) 2007-2011 Freescale Semiconductor, Inc.
  *
  * Dave Liu <daveliu@freescale.com>
  * based on the contribution of Marian Balakowicz <m8@semihalf.com>
 #if defined(CONFIG_DDR_ECC) && defined(CONFIG_DDR_ECC_CMD)
 void ecc_print_status(void)
 {
-       volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
-       volatile ddr83xx_t *ddr = &immap->ddr;
+       immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
+#ifdef CONFIG_FSL_DDR2
+       ccsr_ddr_t *ddr = &immap->ddr;
+#else
+       ddr83xx_t *ddr = &immap->ddr;
+#endif
 
        printf("\nECC mode: %s\n\n",
               (ddr->sdram_cfg & SDRAM_CFG_ECC_EN) ? "ON" : "OFF");
@@ -100,8 +104,12 @@ void ecc_print_status(void)
 
 int do_ecc(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
 {
-       volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
-       volatile ddr83xx_t *ddr = &immap->ddr;
+       immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
+#ifdef CONFIG_FSL_DDR2
+       ccsr_ddr_t *ddr = &immap->ddr;
+#else
+       ddr83xx_t *ddr = &immap->ddr;
+#endif
        volatile u32 val;
        u64 *addr;
        u32 count;
diff --git a/arch/powerpc/cpu/mpc83xx/law.c b/arch/powerpc/cpu/mpc83xx/law.c
new file mode 100644 (file)
index 0000000..66c88b6
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2011 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_law.h>
+#include <asm/mmu.h>
+
+int set_ddr_laws(u64 start, u64 sz, enum law_trgt_if id)
+{
+       immap_t *immap = (immap_t *)CONFIG_SYS_IMMR;
+       law83xx_t *ecm = &immap->sysconf.ddrlaw[0];
+       u64 start_align, law_sz;
+       int law_sz_enc;
+
+       if (start == 0)
+               start_align = 1ull << (LAW_SIZE_2G + 1);
+       else
+               start_align = 1ull << (ffs64(start) - 1);
+       law_sz = min(start_align, sz);
+       law_sz_enc = __ilog2_u64(law_sz) - 1;
+
+       /*
+        * Set up LAWBAR for all of DDR.
+        */
+       ecm->bar = start & 0xfffff000;
+       ecm->ar  = (LAWAR_EN | (id << 20) | (LAWAR_SIZE & law_sz_enc));
+       debug("DDR:bar=0x%08x\n", ecm->bar);
+       debug("DDR:ar=0x%08x\n", ecm->ar);
+
+       /* recalculate size based on what was actually covered by the law */
+       law_sz = 1ull << __ilog2_u64(law_sz);
+
+       /* 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;
+               ecm = &immap->sysconf.ddrlaw[1];
+               ecm->bar = start & 0xfffff000;
+               ecm->ar  = (LAWAR_EN | (id << 20) | (LAWAR_SIZE & law_sz_enc));
+               debug("DDR:bar=0x%08x\n", ecm->bar);
+               debug("DDR:ar=0x%08x\n", ecm->ar);
+       } else {
+               return 0;
+       }
+
+       /* do we still have anything to map */
+       sz = sz - law_sz;
+       if (sz)
+               return 1;
+
+       return 0;
+}
index 4542ab1ac4636826cc505c2adb29bdbe063a18bd..f78099d2feb8d95230d0f6166493fc19983b4fb2 100644 (file)
@@ -507,6 +507,15 @@ ulong get_bus_freq(ulong dummy)
        return gd->csb_clk;
 }
 
+/********************************************
+ * get_ddr_freq
+ * return ddr bus freq in Hz
+ *********************************************/
+ulong get_ddr_freq(ulong dummy)
+{
+       return gd->mem_clk;
+}
+
 int do_clocks (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
 {
        char buf[32];
index 655f99c028ea70536d109630f2cb03652481e90e..10f36856de729ef162e9dd0f6411c3de8da83b46 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2008 Freescale Semiconductor, Inc.
+ * Copyright 2008-2011 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
@@ -18,7 +18,11 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,
                             unsigned int ctrl_num)
 {
        unsigned int i;
-       volatile ccsr_ddr_t *ddr = (void *)CONFIG_SYS_MPC85xx_DDR_ADDR;
+#ifdef CONFIG_MPC83xx
+       ccsr_ddr_t *ddr = (void *)CONFIG_SYS_MPC83xx_DDR_ADDR;
+#else
+       ccsr_ddr_t *ddr = (void *)CONFIG_SYS_MPC85xx_DDR_ADDR;
+#endif
 
        if (ctrl_num) {
                printf("%s unexpected ctrl_num = %u\n", __FUNCTION__, ctrl_num);
index dd4fceaf88ff0160b12d67b4883ae7685b8e8933..15cd375ae367c94f74b52836a858460d3b53091c 100644 (file)
@@ -18,7 +18,9 @@
 
 #include "ddr.h"
 
-#ifdef CONFIG_MPC85xx
+#ifdef CONFIG_MPC83xx
+       #define _DDR_ADDR CONFIG_SYS_MPC83xx_DDR_ADDR
+#elif defined(CONFIG_MPC85xx)
        #define _DDR_ADDR CONFIG_SYS_MPC85xx_DDR_ADDR
 #elif defined(CONFIG_MPC86xx)
        #define _DDR_ADDR CONFIG_SYS_MPC86xx_DDR_ADDR
index c6441311c34ca437ac140f7c46c4b7865354f5e7..eb6a17a8503de6732db1e3489eabd1adbd5215a4 100644 (file)
@@ -129,10 +129,13 @@ fsl_ddr_set_lawbar(const common_timing_params_t *memctl_common_params,
 
 void board_add_ram_info(int use_default)
 {
-#if defined(CONFIG_MPC85xx)
-       volatile ccsr_ddr_t *ddr = (void *)(CONFIG_SYS_MPC85xx_DDR_ADDR);
+#if defined(CONFIG_MPC83xx)
+       immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
+       ccsr_ddr_t *ddr = (void *)&immap->ddr;
+#elif defined(CONFIG_MPC85xx)
+       ccsr_ddr_t *ddr = (void *)(CONFIG_SYS_MPC85xx_DDR_ADDR);
 #elif defined(CONFIG_MPC86xx)
-       volatile ccsr_ddr_t *ddr = (void *)(CONFIG_SYS_MPC86xx_DDR_ADDR);
+       ccsr_ddr_t *ddr = (void *)(CONFIG_SYS_MPC86xx_DDR_ADDR);
 #endif
 #if (CONFIG_NUM_DDR_CONTROLLERS > 1)
        uint32_t cs0_config = in_be32(&ddr->cs0_config);
index c5e5c9cfc85f31f9ec7137df293ddeabc3df79bf..d13863693954669d54c1f4467040bcec45a05cc2 100644 (file)
 #define CONFIG_SYS_BOOT_GET_KBD
 
 #ifndef CONFIG_MAX_MEM_MAPPED
-#if defined(CONFIG_4xx) || defined(CONFIG_E500) || defined(CONFIG_MPC86xx)
+#if    defined(CONFIG_4xx)             || \
+       defined(CONFIG_E500)            || \
+       defined(CONFIG_MPC86xx)         || \
+       defined(CONFIG_E300)
 #define CONFIG_MAX_MEM_MAPPED  ((phys_size_t)2 << 30)
 #else
 #define CONFIG_MAX_MEM_MAPPED  (256 << 20)
index cc0293acd49ffb50ec87698bcde7a4f1fc69397a..8d4c9cb4f7d02ee567cc81a6b5079504f5686e99 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2004-2009 Freescale Semiconductor, Inc.
+ * Copyright 2004-2011 Freescale Semiconductor, Inc.
  *
  * MPC83xx Internal Memory Map
  *
@@ -285,6 +285,105 @@ typedef struct qesba83xx {
 /*
  * DDR Memory Controller Memory Map
  */
+#if defined(CONFIG_FSL_DDR2) || defined(CONFIG_FSL_DDR3)
+typedef struct ccsr_ddr {
+       u32     cs0_bnds;               /* Chip Select 0 Memory Bounds */
+       u8      res1[4];
+       u32     cs1_bnds;               /* Chip Select 1 Memory Bounds */
+       u8      res2[4];
+       u32     cs2_bnds;               /* Chip Select 2 Memory Bounds */
+       u8      res3[4];
+       u32     cs3_bnds;               /* Chip Select 3 Memory Bounds */
+       u8      res4[100];
+       u32     cs0_config;             /* Chip Select Configuration */
+       u32     cs1_config;             /* Chip Select Configuration */
+       u32     cs2_config;             /* Chip Select Configuration */
+       u32     cs3_config;             /* Chip Select Configuration */
+       u8      res4a[48];
+       u32     cs0_config_2;           /* Chip Select Configuration 2 */
+       u32     cs1_config_2;           /* Chip Select Configuration 2 */
+       u32     cs2_config_2;           /* Chip Select Configuration 2 */
+       u32     cs3_config_2;           /* Chip Select Configuration 2 */
+       u8      res5[48];
+       u32     timing_cfg_3;           /* SDRAM Timing Configuration 3 */
+       u32     timing_cfg_0;           /* SDRAM Timing Configuration 0 */
+       u32     timing_cfg_1;           /* SDRAM Timing Configuration 1 */
+       u32     timing_cfg_2;           /* SDRAM Timing Configuration 2 */
+       u32     sdram_cfg;              /* SDRAM Control Configuration */
+       u32     sdram_cfg_2;            /* SDRAM Control Configuration 2 */
+       u32     sdram_mode;             /* SDRAM Mode Configuration */
+       u32     sdram_mode_2;           /* SDRAM Mode Configuration 2 */
+       u32     sdram_md_cntl;          /* SDRAM Mode Control */
+       u32     sdram_interval;         /* SDRAM Interval Configuration */
+       u32     sdram_data_init;        /* SDRAM Data initialization */
+       u8      res6[4];
+       u32     sdram_clk_cntl;         /* SDRAM Clock Control */
+       u8      res7[20];
+       u32     init_addr;              /* training init addr */
+       u32     init_ext_addr;          /* training init extended addr */
+       u8      res8_1[16];
+       u32     timing_cfg_4;           /* SDRAM Timing Configuration 4 */
+       u32     timing_cfg_5;           /* SDRAM Timing Configuration 5 */
+       u8      reg8_1a[8];
+       u32     ddr_zq_cntl;            /* ZQ calibration control*/
+       u32     ddr_wrlvl_cntl;         /* write leveling control*/
+       u8      reg8_1aa[4];
+       u32     ddr_sr_cntr;            /* self refresh counter */
+       u32     ddr_sdram_rcw_1;        /* Control Words 1 */
+       u32     ddr_sdram_rcw_2;        /* Control Words 2 */
+       u8      reg_1ab[8];
+       u32     ddr_wrlvl_cntl_2;       /* write leveling control 2 */
+       u32     ddr_wrlvl_cntl_3;       /* write leveling control 3 */
+       u8      res8_1b[104];
+       u32     sdram_mode_3;           /* SDRAM Mode Configuration 3 */
+       u32     sdram_mode_4;           /* SDRAM Mode Configuration 4 */
+       u32     sdram_mode_5;           /* SDRAM Mode Configuration 5 */
+       u32     sdram_mode_6;           /* SDRAM Mode Configuration 6 */
+       u32     sdram_mode_7;           /* SDRAM Mode Configuration 7 */
+       u32     sdram_mode_8;           /* SDRAM Mode Configuration 8 */
+       u8      res8_1ba[0x908];
+       u32     ddr_dsr1;               /* Debug Status 1 */
+       u32     ddr_dsr2;               /* Debug Status 2 */
+       u32     ddr_cdr1;               /* Control Driver 1 */
+       u32     ddr_cdr2;               /* Control Driver 2 */
+       u8      res8_1c[200];
+       u32     ip_rev1;                /* IP Block Revision 1 */
+       u32     ip_rev2;                /* IP Block Revision 2 */
+       u32     eor;                    /* Enhanced Optimization Register */
+       u8      res8_2[252];
+       u32     mtcr;                   /* Memory Test Control Register */
+       u8      res8_3[28];
+       u32     mtp1;                   /* Memory Test Pattern 1 */
+       u32     mtp2;                   /* Memory Test Pattern 2 */
+       u32     mtp3;                   /* Memory Test Pattern 3 */
+       u32     mtp4;                   /* Memory Test Pattern 4 */
+       u32     mtp5;                   /* Memory Test Pattern 5 */
+       u32     mtp6;                   /* Memory Test Pattern 6 */
+       u32     mtp7;                   /* Memory Test Pattern 7 */
+       u32     mtp8;                   /* Memory Test Pattern 8 */
+       u32     mtp9;                   /* Memory Test Pattern 9 */
+       u32     mtp10;                  /* Memory Test Pattern 10 */
+       u8      res8_4[184];
+       u32     data_err_inject_hi;     /* Data Path Err Injection Mask High */
+       u32     data_err_inject_lo;     /* Data Path Err Injection Mask Low */
+       u32     ecc_err_inject;         /* Data Path Err Injection Mask ECC */
+       u8      res9[20];
+       u32     capture_data_hi;        /* Data Path Read Capture High */
+       u32     capture_data_lo;        /* Data Path Read Capture Low */
+       u32     capture_ecc;            /* Data Path Read Capture ECC */
+       u8      res10[20];
+       u32     err_detect;             /* Error Detect */
+       u32     err_disable;            /* Error Disable */
+       u32     err_int_en;
+       u32     capture_attributes;     /* Error Attrs Capture */
+       u32     capture_address;        /* Error Addr Capture */
+       u32     capture_ext_address;    /* Error Extended Addr Capture */
+       u32     err_sbe;                /* Single-Bit ECC Error Management */
+       u8      res11[164];
+       u32     debug[32];              /* debug_1 to debug_32 */
+       u8      res12[128];
+} ccsr_ddr_t;
+#else
 typedef struct ddr_cs_bnds {
        u32 csbnds;
        u8 res0[4];
@@ -334,6 +433,7 @@ typedef struct ddr83xx {
        u32 debug_reg;
        u8 res9[0xFC];
 } ddr83xx_t;
+#endif
 
 /*
  * DUART
@@ -641,7 +741,11 @@ typedef struct immap {
        u8                      dll_ddr[0x100];
        u8                      dll_lbc[0x100];
        u8                      res1[0xE00];
-       ddr83xx_t               ddr;            /* DDR Memory Controller Memory */
+#if defined(CONFIG_FSL_DDR2) || defined(CONFIG_FSL_DDR3)
+       ccsr_ddr_t              ddr;    /* DDR Memory Controller Memory */
+#else
+       ddr83xx_t               ddr;    /* DDR Memory Controller Memory */
+#endif
        fsl_i2c_t               i2c[2];         /* I2C Controllers */
        u8                      res2[0x1300];
        duart83xx_t             duart[2];       /* DUART */
@@ -869,10 +973,15 @@ typedef struct immap {
 } immap_t;
 #endif
 
+#define CONFIG_SYS_MPC83xx_DDR_OFFSET  (0x2000)
+#define CONFIG_SYS_MPC83xx_DDR_ADDR \
+                       (CONFIG_SYS_IMMR + CONFIG_SYS_MPC83xx_DDR_OFFSET)
 #define CONFIG_SYS_MPC83xx_DMA_OFFSET  (0x8000)
-#define CONFIG_SYS_MPC83xx_DMA_ADDR    (CONFIG_SYS_IMMR + CONFIG_SYS_MPC83xx_DMA_OFFSET)
+#define CONFIG_SYS_MPC83xx_DMA_ADDR \
+                       (CONFIG_SYS_IMMR + CONFIG_SYS_MPC83xx_DMA_OFFSET)
 #define CONFIG_SYS_MPC83xx_ESDHC_OFFSET        (0x2e000)
-#define CONFIG_SYS_MPC83xx_ESDHC_ADDR  (CONFIG_SYS_IMMR + CONFIG_SYS_MPC83xx_ESDHC_OFFSET)
+#define CONFIG_SYS_MPC83xx_ESDHC_ADDR \
+                       (CONFIG_SYS_IMMR + CONFIG_SYS_MPC83xx_ESDHC_OFFSET)
 
 #ifndef CONFIG_SYS_MPC83xx_USB_OFFSET
 #define CONFIG_SYS_MPC83xx_USB_OFFSET  0x23000
index 2edbd71474091e87b47a03b9b482f57c44d9eab5..371a0d99bafe609dcc1b856285c64aa6d7ddae07 100644 (file)
@@ -162,7 +162,13 @@ COBJS-$(CONFIG_CMD_XIMG) += cmd_ximg.o
 COBJS-$(CONFIG_YAFFS2) += cmd_yaffs2.o
 
 # others
-COBJS-$(CONFIG_DDR_SPD) += ddr_spd.o
+ifdef CONFIG_DDR_SPD
+SPD := y
+endif
+ifdef CONFIG_SPD_EEPROM
+SPD := y
+endif
+COBJS-$(SPD) += ddr_spd.o
 COBJS-$(CONFIG_HWCONFIG) += hwconfig.o
 COBJS-$(CONFIG_CONSOLE_MUX) += iomux.o
 COBJS-y += flash.o
index 05e2f728e7377a38f3b69cc91b3f7d11e3ea8aac..bcc00e82b78c73b7d86e2e4a5881156d5bc873a4 100644 (file)
@@ -580,10 +580,12 @@ ulong get_PERCLK3(void);
 ulong  get_bus_freq  (ulong);
 int get_serial_clock(void);
 
+#if defined(CONFIG_MPC83xx) || defined(CONFIG_MPC85xx)
+ulong get_ddr_freq(ulong);
+#endif
 #if defined(CONFIG_MPC85xx)
 typedef MPC85xx_SYS_INFO sys_info_t;
 void   get_sys_info  ( sys_info_t * );
-ulong  get_ddr_freq  (ulong);
 #endif
 #if defined(CONFIG_MPC86xx)
 typedef MPC86xx_SYS_INFO sys_info_t;