blob: c2c7f510d8abdde7d6fc9f735dba703c8446d86c [file] [log] [blame]
Angel Pons7d3e1612024-04-12 17:02:24 +02001/* SPDX-License-Identifier: GPL-2.0-only */
2
3#include <cbmem.h>
4#include <console/console.h>
5#include <device/dram/ddr2.h>
6#include <device/dram/ddr3.h>
7#include <device/smbus_host.h>
8#include <lib.h>
9#include <memory_info.h>
10#include <spd.h>
11
12#include "gm45.h"
13#include "chip.h"
14
15static u8 get_dimm_mod_type(const sysinfo_t *sysinfo, const int idx)
16{
17 if (sysinfo->spd_type == DDR2) {
18 return smbus_read_byte(sysinfo->spd_map[idx], 20) & SPD_DDR2_DIMM_TYPE_MASK;
19 } else {
20 return smbus_read_byte(sysinfo->spd_map[idx], 3) & 0xf;
21 }
22}
23
24static void ddr3_read_ids(const sysinfo_t *sysinfo, struct dimm_info *dimm, const int idx)
25{
26 const u8 addr = sysinfo->spd_map[idx];
27 for (int k = 0; k < SPD_DIMM_SERIAL_LEN; k++) {
28 dimm->serial[k] = smbus_read_byte(addr, SPD_DIMM_SERIAL_NUM + k);
29 }
30 for (int k = 0; k < SPD_DIMM_PART_LEN; k++) {
31 dimm->module_part_number[k] = smbus_read_byte(addr, SPD_DIMM_PART_NUM + k);
32 }
33 dimm->mod_id = (smbus_read_byte(addr, SPD_DIMM_MOD_ID2) << 8) |
34 (smbus_read_byte(addr, SPD_DIMM_MOD_ID1) << 0);
35}
36
37static u32 get_mem_clock_mt(const int clock_index)
38{
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;
43 default: return 0;
44 }
45}
46
47void setup_sdram_meminfo(const sysinfo_t *sysinfo)
48{
49 struct memory_info *mem_info = cbmem_add(CBMEM_ID_MEMINFO, sizeof(struct memory_info));
50 if (!mem_info)
51 die("Failed to add memory info to CBMEM.\n");
52
53 memset(mem_info, 0, sizeof(struct memory_info));
54
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);
57
58 int dimm_cnt = 0;
59
60 int ch;
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;
70 dimm->dimm_num = 0;
71 dimm->bank_locator = ch;
72 /* TODO: Handle DDR2 SPDs */
73 if (sysinfo->spd_type == DDR3) {
74 ddr3_read_ids(sysinfo, dimm, idx);
75 }
76 dimm->mod_type = get_dimm_mod_type(sysinfo, idx);
77 dimm->bus_width = MEMORY_BUS_WIDTH_64;
78 dimm_cnt++;
79 }
80 mem_info->dimm_cnt = dimm_cnt;
81
82 mem_info->ecc_type = MEMORY_ARRAY_ECC_NONE;
83 mem_info->max_capacity_mib = 8192;
84 mem_info->number_of_devices = 2;
85}