1 /* SPDX-License-Identifier: GPL-2.0-only */
4 #include <console/console.h>
5 #include <device/dram/ddr2.h>
6 #include <device/dram/ddr3.h>
7 #include <device/smbus_host.h>
9 #include <memory_info.h>
15 static u8
get_dimm_mod_type(const sysinfo_t
*sysinfo
, const int idx
)
17 if (sysinfo
->spd_type
== DDR2
) {
18 return smbus_read_byte(sysinfo
->spd_map
[idx
], 20) & SPD_DDR2_DIMM_TYPE_MASK
;
20 return smbus_read_byte(sysinfo
->spd_map
[idx
], 3) & 0xf;
24 static void ddr3_read_ids(const sysinfo_t
*sysinfo
, struct dimm_info
*dimm
, const int idx
)
26 const u8 addr
= sysinfo
->spd_map
[idx
];
27 for (int k
= 0; k
< SPD_DDR3_SERIAL_LEN
; k
++) {
28 dimm
->serial
[k
] = smbus_read_byte(addr
, SPD_DDR3_SERIAL_NUM
+ k
);
30 for (int k
= 0; k
< SPD_DDR3_PART_LEN
; k
++) {
31 dimm
->module_part_number
[k
] = smbus_read_byte(addr
, SPD_DDR3_PART_NUM
+ k
);
33 dimm
->mod_id
= (smbus_read_byte(addr
, SPD_DDR3_MOD_ID2
) << 8) |
34 (smbus_read_byte(addr
, SPD_DDR3_MOD_ID1
) << 0);
37 static u32
get_mem_clock_mt(const int clock_index
)
39 switch (clock_index
) {
40 case MEM_CLOCK_1067MT
: return 1067;
41 case MEM_CLOCK_800MT
: return 800;
42 case MEM_CLOCK_667MT
: return 667;
47 void setup_sdram_meminfo(const sysinfo_t
*sysinfo
)
49 struct memory_info
*mem_info
= cbmem_add(CBMEM_ID_MEMINFO
, sizeof(struct memory_info
));
51 die("Failed to add memory info to CBMEM.\n");
53 memset(mem_info
, 0, sizeof(struct memory_info
));
55 const u16 ddr_type
= (sysinfo
->spd_type
== DDR2
) ? MEMORY_TYPE_DDR2
: MEMORY_TYPE_DDR3
;
56 const u32 ddr_freq_mt
= get_mem_clock_mt(sysinfo
->selected_timings
.mem_clock
);
61 FOR_EACH_POPULATED_CHANNEL(sysinfo
->dimms
, ch
) {
62 struct dimm_info
*dimm
= &mem_info
->dimm
[dimm_cnt
];
63 const int idx
= ch
* 2;
64 const int ranks
= sysinfo
->dimms
[ch
].ranks
;
65 dimm
->dimm_size
= (256 << sysinfo
->dimms
[ch
].chip_capacity
) * ranks
;
66 dimm
->ddr_type
= ddr_type
;
67 dimm
->ddr_frequency
= ddr_freq_mt
;
68 dimm
->rank_per_dimm
= ranks
;
69 dimm
->channel_num
= ch
;
71 dimm
->bank_locator
= ch
;
72 /* TODO: Handle DDR2 SPDs */
73 if (sysinfo
->spd_type
== DDR3
) {
74 ddr3_read_ids(sysinfo
, dimm
, idx
);
76 dimm
->mod_type
= get_dimm_mod_type(sysinfo
, idx
);
77 dimm
->bus_width
= MEMORY_BUS_WIDTH_64
;
80 mem_info
->dimm_cnt
= dimm_cnt
;
82 mem_info
->ecc_type
= MEMORY_ARRAY_ECC_NONE
;
83 mem_info
->max_capacity_mib
= 8192;
84 mem_info
->number_of_devices
= 2;