]> git.sur5r.net Git - u-boot/commitdiff
fsl-ddr: Fix handling of >4G of memory when !CONFIG_PHYS_64BIT
authorKumar Gala <galak@kernel.crashing.org>
Fri, 12 Jun 2009 04:42:35 +0000 (23:42 -0500)
committerKumar Gala <galak@kernel.crashing.org>
Fri, 12 Jun 2009 14:15:50 +0000 (09:15 -0500)
The ddr code computes most things as 64-bit quantities and had some places
in the middle that it was using phy_addr_t and phys_size_t.

Instead we use unsigned long long through out and only at the last stage of
setting the LAWs and reporting the amount of memory to the board code do we
truncate down to what we can cover via phys_size_t.

This has the added benefit that the DDR controller itself is always setup
the same way regardless of how much memory we have.  Its only the LAW
setup that limits what is visible to the system.

Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
cpu/mpc8xxx/ddr/ctrl_regs.c
cpu/mpc8xxx/ddr/ddr.h
cpu/mpc8xxx/ddr/ddr1_dimm_params.c
cpu/mpc8xxx/ddr/ddr2_dimm_params.c
cpu/mpc8xxx/ddr/ddr3_dimm_params.c
cpu/mpc8xxx/ddr/main.c
cpu/mpc8xxx/ddr/util.c

index 490e3dc88e001d8a2f75672d4c2f676438e150bf..1689d680bdf6442bd715f808e6e2b2120bca6f51 100644 (file)
@@ -1199,8 +1199,7 @@ compute_fsl_memctl_config_regs(const memctl_options_t *popts,
 
        /* Chip Select Memory Bounds (CSn_BNDS) */
        for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) {
-               phys_size_t sa = 0;
-               phys_size_t ea = 0;
+               unsigned long long ea = 0, sa = 0;
 
                if (popts->ba_intlv_ctl && (i > 0) &&
                        ((popts->ba_intlv_ctl & 0x60) != FSL_DDR_CS2_CS3 )) {
index 9ffd5485cdca5d2d155606e19d1a12f0e5b74e06..f1220750df42fec4485a7a96e777b4b5268dc56c 100644 (file)
@@ -54,7 +54,7 @@ typedef struct {
 #define STEP_PROGRAM_REGS            (1 << 6)
 #define STEP_ALL                     0xFFF
 
-extern phys_size_t
+extern unsigned long long
 fsl_ddr_compute(fsl_ddr_info_t *pinfo, unsigned int start_step);
 
 extern const char * step_to_string(unsigned int step);
index 2e0a209b4fb3e20d4fcdcd8e70f1057b54f04da4..91847644180dfa861c3d08b1a351e01d852d96f1 100644 (file)
  * 2 or 5 bits off and shifting them up to the top.
  */
 
-static phys_size_t
+static unsigned long long
 compute_ranksize(unsigned int mem_type, unsigned char row_dens)
 {
-       phys_size_t bsize;
+       unsigned long long bsize;
 
        /* Bottom 2 bits up to the top. */
        bsize = ((row_dens >> 2) | ((row_dens & 3) << 6));
index 06a8eb68b70563d052bb77f8de6c2c3e21fbbe55..d9d0fa70eeb7d8be78af62d4fd1b1daac0e8ac03 100644 (file)
  * 2 or 5 bits off and shifting them up to the top.
  *
  */
-static phys_size_t
+static unsigned long long
 compute_ranksize(unsigned int mem_type, unsigned char row_dens)
 {
-       phys_size_t bsize;
+       unsigned long long bsize;
 
        /* Bottom 5 bits up to the top. */
        bsize = ((row_dens >> 5) | ((row_dens & 31) << 3));
index ca4be78ef356279a59a415a57735d49571451871..8d686ac5d9191e881d1e1d2e23dc73f148fc3a44 100644 (file)
  *     011             32bits
  *
  */
-static phys_size_t
+static unsigned long long
 compute_ranksize(const ddr3_spd_eeprom_t *spd)
 {
-       phys_size_t bsize;
+       unsigned long long bsize;
 
        int nbit_sdram_cap_bsize = 0;
        int nbit_primary_bus_width = 0;
index 305f7fbd4cafface96491d2cd17c2999520b38b3..6dae26bd3de540dd9f8e6464edd20e90e2bb158b 100644 (file)
@@ -215,9 +215,7 @@ int step_assign_addresses(fsl_ddr_info_t *pinfo,
        }
 
        if (*memctl_interleaving) {
-               phys_addr_t addr;
-               phys_size_t total_mem_per_ctlr = 0;
-
+               unsigned long long addr, total_mem_per_ctlr = 0;
                /*
                 * If interleaving between memory controllers,
                 * make each controller start at a base address
@@ -235,14 +233,13 @@ int step_assign_addresses(fsl_ddr_info_t *pinfo,
 
                for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
                        addr = 0;
-                       pinfo->common_timing_params[i].base_address =
-                                               (phys_addr_t)addr;
+                       pinfo->common_timing_params[i].base_address = 0ull;
                        for (j = 0; j < CONFIG_DIMM_SLOTS_PER_CTLR; j++) {
                                unsigned long long cap
                                        = pinfo->dimm_params[i][j].capacity;
 
                                pinfo->dimm_params[i][j].base_address = addr;
-                               addr += (phys_addr_t)(cap >> dbw_cap_adj[i]);
+                               addr += cap >> dbw_cap_adj[i];
                                total_mem_per_ctlr += cap >> dbw_cap_adj[i];
                        }
                }
@@ -252,18 +249,17 @@ int step_assign_addresses(fsl_ddr_info_t *pinfo,
                 * Simple linear assignment if memory
                 * controllers are not interleaved.
                 */
-               phys_size_t cur_memsize = 0;
+               unsigned long long cur_memsize = 0;
                for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
-                       phys_size_t total_mem_per_ctlr = 0;
+                       u64 total_mem_per_ctlr = 0;
                        pinfo->common_timing_params[i].base_address =
-                                               (phys_addr_t)cur_memsize;
+                                               cur_memsize;
                        for (j = 0; j < CONFIG_DIMM_SLOTS_PER_CTLR; j++) {
                                /* Compute DIMM base addresses. */
                                unsigned long long cap =
                                        pinfo->dimm_params[i][j].capacity;
-
                                pinfo->dimm_params[i][j].base_address =
-                                       (phys_addr_t)cur_memsize;
+                                       cur_memsize;
                                cur_memsize += cap >> dbw_cap_adj[i];
                                total_mem_per_ctlr += cap >> dbw_cap_adj[i];
                        }
@@ -275,13 +271,13 @@ int step_assign_addresses(fsl_ddr_info_t *pinfo,
        return 0;
 }
 
-phys_size_t
+unsigned long long
 fsl_ddr_compute(fsl_ddr_info_t *pinfo, unsigned int start_step)
 {
        unsigned int i, j;
        unsigned int all_controllers_memctl_interleaving = 0;
        unsigned int all_controllers_rank_interleaving = 0;
-       phys_size_t total_mem = 0;
+       unsigned long long total_mem = 0;
 
        fsl_ddr_cfg_regs_t *ddr_reg = pinfo->fsl_ddr_config_reg;
        common_timing_params_t *timing_params = pinfo->common_timing_params;
@@ -424,15 +420,6 @@ fsl_ddr_compute(fsl_ddr_info_t *pinfo, unsigned int start_step)
                        }
                }
 
-#if !defined(CONFIG_PHYS_64BIT)
-               /* Check for 4G or more with a 32-bit phys_addr_t.  Bad. */
-               if (max_end >= 0xff) {
-                       printf("This U-Boot only supports < 4G of DDR\n");
-                       printf("You could rebuild it with CONFIG_PHYS_64BIT\n");
-                       return CONFIG_MAX_MEM_MAPPED;
-               }
-#endif
-
                total_mem = 1 + (((unsigned long long)max_end << 24ULL)
                                    | 0xFFFFFFULL);
        }
@@ -450,7 +437,7 @@ phys_size_t fsl_ddr_sdram(void)
 {
        unsigned int i;
        unsigned int memctl_interleaved;
-       phys_size_t total_memory;
+       unsigned long long total_memory;
        fsl_ddr_info_t info;
 
        /* Reset info structure. */
@@ -515,7 +502,17 @@ phys_size_t fsl_ddr_sdram(void)
                }
        }
 
-       debug("total_memory = %llu\n", (u64)total_memory);
+       debug("total_memory = %llu\n", total_memory);
+
+#if !defined(CONFIG_PHYS_64BIT)
+       /* Check for 4G or more.  Bad. */
+       if (total_memory >= (1ull << 32)) {
+               printf("Detected %lld MB of memory\n", total_memory >> 20);
+               printf("This U-Boot only supports < 4G of DDR\n");
+               printf("You could rebuild it with CONFIG_PHYS_64BIT\n");
+               total_memory = CONFIG_MAX_MEM_MAPPED;
+       }
+#endif
 
        return total_memory;
 }
index 27c135b112c0a608e142a640cb4eec9a53c7f465..70dbee06dbce1350b6c9db0b2e7b9a38830a4c00 100644 (file)
@@ -64,6 +64,9 @@ __fsl_ddr_set_lawbar(const common_timing_params_t *memctl_common_params,
                           unsigned int memctl_interleaved,
                           unsigned int ctrl_num)
 {
+       unsigned long long base = memctl_common_params->base_address;
+       unsigned long long size = memctl_common_params->total_mem;
+
        /*
         * If no DIMMs on this controller, do not proceed any further.
         */
@@ -71,6 +74,13 @@ __fsl_ddr_set_lawbar(const common_timing_params_t *memctl_common_params,
                return;
        }
 
+#if !defined(CONFIG_PHYS_64BIT)
+       if (base >= CONFIG_MAX_MEM_MAPPED)
+               return;
+       if ((base + size) >= CONFIG_MAX_MEM_MAPPED)
+               size = CONFIG_MAX_MEM_MAPPED - base;
+#endif
+
        if (ctrl_num == 0) {
                /*
                 * Set up LAW for DDR controller 1 space.
@@ -78,16 +88,12 @@ __fsl_ddr_set_lawbar(const common_timing_params_t *memctl_common_params,
                unsigned int lawbar1_target_id = memctl_interleaved
                        ? LAW_TRGT_IF_DDR_INTRLV : LAW_TRGT_IF_DDR_1;
 
-               if (set_ddr_laws(memctl_common_params->base_address,
-                               memctl_common_params->total_mem,
-                               lawbar1_target_id) < 0) {
+               if (set_ddr_laws(base, size, lawbar1_target_id) < 0) {
                        printf("ERROR\n");
                        return ;
                }
        } else if (ctrl_num == 1) {
-               if (set_ddr_laws(memctl_common_params->base_address,
-                               memctl_common_params->total_mem,
-                               LAW_TRGT_IF_DDR_2) < 0) {
+               if (set_ddr_laws(base, size, LAW_TRGT_IF_DDR_2) < 0) {
                        printf("ERROR\n");
                        return ;
                }