diff options
author | Jason Schildt <jschildt@gmail.com> | 2005-08-09 21:53:07 +0000 |
---|---|---|
committer | Jason Schildt <jschildt@gmail.com> | 2005-08-09 21:53:07 +0000 |
commit | 6e44b422b3b26a4ce5b98fca12d0f3ef7d7af110 (patch) | |
tree | 4f94702f435949875bed8f725928cb571b7f40c8 /src/northbridge/amd/amdk8/raminit.c | |
parent | dc2454eb944c2ea9201bd650d7bc9942d4653a6c (diff) | |
download | coreboot-6e44b422b3b26a4ce5b98fca12d0f3ef7d7af110.tar.xz |
- Merge from linuxbios-lnxi (Linux Networx repository) up to public tree.
- Special version for HDAMA rev G with 33Mhz test and reboot out.
- Support for CPU rev E, dual core, memory hoisting,
- corrected an SST flashing problem. Kernel bug work around (NUMA)
- added a Kernel bug work around for assigning CPU's to memory.
r2@gog: svnadmin | 2005-08-03 08:47:54 -0600
Create local LNXI branch
r1110@gog: jschildt | 2005-08-09 10:35:51 -0600
- Merge from Tom Zimmerman's additions to the hdama code for dual core
and 33Mhz fix.
r1111@gog: jschildt | 2005-08-09 11:07:11 -0600
Stable Release tag for HDAMA-1.1.8.10 and HDAMA-1.1.8.10LANL
r1112@gog: jschildt | 2005-08-09 15:09:32 -0600
- temporarily removing hdama tag to update to public repository. Will
reset tag after update.
git-svn-id: svn://svn.coreboot.org/coreboot/trunk@2004 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
Diffstat (limited to 'src/northbridge/amd/amdk8/raminit.c')
-rw-r--r-- | src/northbridge/amd/amdk8/raminit.c | 156 |
1 files changed, 74 insertions, 82 deletions
diff --git a/src/northbridge/amd/amdk8/raminit.c b/src/northbridge/amd/amdk8/raminit.c index 5d9c320637..d211f4bcc1 100644 --- a/src/northbridge/amd/amdk8/raminit.c +++ b/src/northbridge/amd/amdk8/raminit.c @@ -585,6 +585,16 @@ static void hw_enable_ecc(const struct mem_controller *ctrl) } +static void e_step_cpu(const struct mem_controller *ctrl) +{ + uint32_t dcl,data32; + + /* set bit 29 (upper cs map) of function 2 offset 0x90 */ + dcl = pci_read_config32(ctrl->f2, DRAM_CONFIG_LOW); + dcl |= DCL_UpperCSMap; + pci_write_config32(ctrl->f2, DRAM_CONFIG_LOW, dcl); +} + static int is_dual_channel(const struct mem_controller *ctrl) { uint32_t dcl; @@ -714,28 +724,14 @@ hw_err: return sz; } -static const unsigned cs_map_aa[15] = { - /* (row=12, col=8)(14, 12) ---> (0, 0) (2, 4) */ - 0, 1, 3, 6, 0, - 0, 2, 4, 7, 9, - 0, 0, 5, 8,10, -}; - static void set_dimm_size(const struct mem_controller *ctrl, struct dimm_size sz, unsigned index) { - uint32_t base0, base1, map; + uint32_t base0, base1; uint32_t dch; if (sz.side1 != sz.side2) { sz.side2 = 0; } - map = pci_read_config32(ctrl->f2, DRAM_BANK_ADDR_MAP); - map &= ~(0xf << (index * 4)); -#if K8_4RANK_DIMM_SUPPORT == 1 - if(sz.rank == 4) { - map &= ~(0xf << ( (index + 2) * 4)); - } -#endif /* For each base register. * Place the dimm size in 32 MB quantities in the bits 31 - 21. @@ -747,22 +743,6 @@ static void set_dimm_size(const struct mem_controller *ctrl, struct dimm_size sz /* Make certain side1 of the dimm is at least 32MB */ if (sz.side1 >= (25 +3)) { - if(is_cpu_pre_d0()) { - map |= (sz.side1 - (25 + 3)) << (index *4); -#if K8_4RANK_DIMM_SUPPORT == 1 - if(sz.rank == 4) { - map |= (sz.side1 - (25 + 3)) << ( (index + 2) * 4); - } -#endif - } - else { - map |= cs_map_aa[(sz.rows - 12) * 5 + (sz.col - 8) ] << (index*4); -#if K8_4RANK_DIMM_SUPPORT == 1 - if(sz.rank == 4) { - map |= cs_map_aa[(sz.rows - 12) * 5 + (sz.col - 8) ] << ( (index + 2) * 4); - } -#endif - } base0 = (1 << ((sz.side1 - (25 + 3)) + 21)) | 1; } @@ -791,8 +771,6 @@ static void set_dimm_size(const struct mem_controller *ctrl, struct dimm_size sz } #endif - pci_write_config32(ctrl->f2, DRAM_BANK_ADDR_MAP, map); - /* Enable the memory clocks for this DIMM */ if (base0) { dch = pci_read_config32(ctrl->f2, DRAM_CONFIG_HIGH); @@ -806,6 +784,52 @@ static void set_dimm_size(const struct mem_controller *ctrl, struct dimm_size sz } } + +static void set_dimm_map(const struct mem_controller *ctrl, + struct dimm_size sz, unsigned index) +{ + static const unsigned cs_map_aa[15] = { + /* (row=12, col=8)(14, 12) ---> (0, 0) (2, 4) */ + 0, 1, 3, 6, 0, + 0, 2, 4, 7, 9, + 0, 0, 5, 8,10, + }; + uint32_t map; + int row,col; + + map = pci_read_config32(ctrl->f2, DRAM_BANK_ADDR_MAP); + map &= ~(0xf << (index * 4)); + +#if K8_4RANK_DIMM_SUPPORT == 1 + if(sz.rank == 4) { + map &= ~(0xf << ( (index + 2) * 4)); + } +#endif + + if (is_cpu_pre_d0()) { + map |= (sz.side1 - (25 + 3)) << (index *4); +#if K8_4RANK_DIMM_SUPPORT == 1 + if(sz.rank == 4) { + map |= (sz.side1 - (25 + 3)) << ( (index + 2) * 4); + } +#endif + } else { + unsigned val; + val = cs_map_aa[(sz.rows - 12) * 5 + (sz.col - 8) ]; + if(val == 0) { + print_err("Invalid Column or Row count\r\n"); + val = 7; + } + map |= val << (index*4); +#if K8_4RANK_DIMM_SUPPORT == 1 + if(sz.rank == 4) { + map |= val << ( (index + 2) * 4); + } +#endif + } + pci_write_config32(ctrl->f2, DRAM_BANK_ADDR_MAP, map); +} + static long spd_set_ram_size(const struct mem_controller *ctrl, long dimm_mask) { int i; @@ -820,6 +844,7 @@ static long spd_set_ram_size(const struct mem_controller *ctrl, long dimm_mask) return -1; /* Report SPD error */ } set_dimm_size(ctrl, sz, i); + set_dimm_map(ctrl, sz, i); } return dimm_mask; } @@ -865,6 +890,13 @@ static void set_top_mem(unsigned tom_k) print_spew_hex32(tom_k); print_spew(" KB\r\n"); +#if 0 + /* Report the amount of memory. */ + print_debug("RAM: 0x"); + print_debug_hex32(tom_k); + print_debug(" KB\r\n"); +#endif + /* Now set top of memory */ msr_t msr; msr.lo = (tom_k & 0x003fffff) << 10; @@ -971,7 +1003,7 @@ static unsigned long interleave_chip_selects(const struct mem_controller *ctrl) if(is_dual_channel(ctrl)) { /* Also we run out of address mask bits if we try and interleave 8 4GB dimms */ if ((bits == 3) && (common_size == (1 << (32 - 3)))) { -// print_debug("8 4GB chip selects cannot be interleaved\r\n"); + print_spew("8 4GB chip selects cannot be interleaved\r\n"); return 0; } csbase_inc <<=1; @@ -981,7 +1013,7 @@ static unsigned long interleave_chip_selects(const struct mem_controller *ctrl) csbase_inc = csbase_low_d0[common_cs_mode]; if(is_dual_channel(ctrl)) { if( (bits==3) && (common_cs_mode > 8)) { -// print_debug("8 cs_mode>8 chip selects cannot be interleaved\r\n"); + print_spew("8 cs_mode>8 chip selects cannot be interleaved\r\n"); return 0; } csbase_inc <<=1; @@ -1100,25 +1132,6 @@ unsigned long memory_end_k(const struct mem_controller *ctrl, int max_node_id) return end_k; } -#if K8_E0_MEM_HOLE_SIZEK != 0 -#define K8_E0_MEM_HOLE_LIMITK 4*1024*1024 -#define K8_E0_MEM_HOLE_BASEK (K8_E0_MEM_HOLE_LIMITK - K8_E0_MEM_HOLE_SIZEK ) - -static void set_e0_mem_hole(const struct mem_controller *ctrl, unsigned base_k) -{ - /* Route the addresses to the controller node */ - unsigned val; - - val = pci_read_config32(ctrl->f1,0xf0); - - val &= 0x00ff00fe; - val = (K8_E0_MEM_HOLE_BASEK << 10) | ((K8_E0_MEM_HOLE_SIZEK+base_k)>>(16-10)) | 1; - - pci_write_config32(ctrl->f1, 0xf0, val); -} - -#endif - static void order_dimms(const struct mem_controller *ctrl) { unsigned long tom_k, base_k; @@ -1135,14 +1148,6 @@ static void order_dimms(const struct mem_controller *ctrl) /* Compute the memory base address */ base_k = memory_end_k(ctrl, ctrl->node_id); tom_k += base_k; -#if K8_E0_MEM_HOLE_SIZEK != 0 - if(!is_cpu_pre_e0()) { - /* See if I need to check the range cover hole */ - if ((base_k <= K8_E0_MEM_HOLE_BASEK) && (tom_k > K8_E0_MEM_HOLE_BASEK)) { - tom_k += K8_E0_MEM_HOLE_SIZEK; - } - } -#endif route_dram_accesses(ctrl, base_k, tom_k); set_top_mem(tom_k); } @@ -2145,12 +2150,11 @@ static void sdram_set_spd_registers(const struct mem_controller *ctrl) struct spd_set_memclk_result result; const struct mem_param *param; long dimm_mask; -#if 1 + if (!controller_present(ctrl)) { -// print_debug("No memory controller present\r\n"); + print_debug("No memory controller present\r\n"); return; } -#endif hw_enable_ecc(ctrl); activate_spd_rom(ctrl); dimm_mask = spd_detect_dimms(ctrl); @@ -2176,6 +2180,10 @@ static void sdram_set_spd_registers(const struct mem_controller *ctrl) if (dimm_mask < 0) goto hw_spd_err; order_dimms(ctrl); + if( !is_cpu_pre_e0() ) { + print_debug("E step CPU\r\n"); + e_step_cpu(ctrl); + } return; hw_spd_err: /* Unrecoverable error reading SPD data */ @@ -2280,22 +2288,6 @@ static void sdram_enable(int controllers, const struct mem_controller *ctrl) } while(((dcl & DCL_MemClrStatus) == 0) || ((dcl & DCL_DramEnable) == 0) ); } - // init e0 mem hole here -#if K8_E0_MEM_HOLE_SIZEK != 0 - if (!is_cpu_pre_e0()) { - uint32_t base, limit; - unsigned base_k, limit_k; - base = pci_read_config32(ctrl->f1, 0x40 + (i << 3)); - limit = pci_read_config32(ctrl->f1, 0x44 + (i << 3)); - base_k = (base & 0xffff0000) >> 2; - limit_k = ((limit + 0x00010000) & 0xffff0000) >> 2; - if ((base_k <= K8_E0_MEM_HOLE_BASEK) && (limit_k > K8_E0_MEM_HOLE_BASEK)) { - set_e0_mem_hole(ctrl+i, base_k); - } - } - -#endif - print_debug(" done\r\n"); } @@ -2308,7 +2300,7 @@ static void sdram_enable(int controllers, const struct mem_controller *ctrl) 5. for node interleaving we need to set mem hole to every node ( need recalcute hole offset in f0 for every node) */ -#if USE_DCACHE_RAM == 0 +#if CONFIG_DCACHE_RAM == 0 /* Make certain the first 1M of memory is intialized */ print_debug("Clearing initial memory region: "); |