blob: 28496b15badfa84989025de6d88992f49f47e062 [file] [log] [blame]
Angel Pons47f26db2020-04-05 13:22:34 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Aaron Durbinc625d092013-10-04 16:00:07 -05002
Aaron Durbin1f5eb1f2013-10-08 15:33:39 -05003#include <cbfs.h>
Aaron Durbinc625d092013-10-04 16:00:07 -05004#include <console/console.h>
Julius Werner18ea2d32014-10-07 16:42:17 -07005#include <soc/gpio.h>
6#include <soc/mrc_wrapper.h>
7#include <soc/romstage.h>
Matt DeVillierce0a5642017-01-12 12:19:21 -06008#include <variant/variant.h>
Aaron Durbin1f5eb1f2013-10-08 15:33:39 -05009
Aaron Durbin100b14d2013-11-27 16:51:26 -060010static void *get_spd_pointer(char *spd_file_content, int total_spds, int *dual)
Aaron Durbin1f5eb1f2013-10-08 15:33:39 -050011{
12 int ram_id = 0;
13
Matt DeVillierce0a5642017-01-12 12:19:21 -060014 /* The ram_id[2:0] pullups are too large for the default 20K
Aaron Durbin6c52ba72013-10-16 09:21:55 -070015 * pulldown on the pad. Therefore, disable the internal pull resistor to
16 * read high values correctly. */
Aaron Durbin4177db52014-02-05 14:55:26 -060017 ssus_disable_internal_pull(GPIO_SSUS_37_PAD);
18 ssus_disable_internal_pull(GPIO_SSUS_38_PAD);
19 ssus_disable_internal_pull(GPIO_SSUS_39_PAD);
Matt DeVillier474a7c52017-02-07 22:07:56 -060020#ifdef GPIO_SSUS_40_PAD_USE_PULLDOWN
21 /* To prevent floating pin on shipped systems. */
22 ssus_enable_internal_pull(GPIO_SSUS_40_PAD, PAD_PULL_DOWN | PAD_PU_20K);
Elyes HAOUAS2526fd42018-05-22 12:29:05 +020023#elif defined(GPIO_SSUS_40_PAD)
Matt DeVillier9be3f5d2017-01-16 17:32:38 -060024 ssus_disable_internal_pull(GPIO_SSUS_40_PAD);
25#endif
Aaron Durbin1f5eb1f2013-10-08 15:33:39 -050026 ram_id |= (ssus_get_gpio(GPIO_SSUS_37_PAD) << 0);
27 ram_id |= (ssus_get_gpio(GPIO_SSUS_38_PAD) << 1);
28 ram_id |= (ssus_get_gpio(GPIO_SSUS_39_PAD) << 2);
Matt DeVillier9be3f5d2017-01-16 17:32:38 -060029#ifdef GPIO_SSUS_40_PAD
30 ram_id |= (ssus_get_gpio(GPIO_SSUS_40_PAD) << 3);
31#endif
Aaron Durbin6c52ba72013-10-16 09:21:55 -070032 printk(BIOS_DEBUG, "ram_id=%d, total_spds: %d\n", ram_id, total_spds);
33
Aaron Durbin1f5eb1f2013-10-08 15:33:39 -050034 if (ram_id >= total_spds)
35 return NULL;
36
Aaron Durbin100b14d2013-11-27 16:51:26 -060037 /* Single channel configs */
38 if (dual_channel_config & (1 << ram_id))
39 *dual = 1;
40
Aaron Durbin1f5eb1f2013-10-08 15:33:39 -050041 return &spd_file_content[SPD_SIZE * ram_id];
42}
43
Kyösti Mälkki3e772792019-08-16 17:37:48 +030044void mainboard_fill_mrc_params(struct mrc_params *mp)
Aaron Durbinc625d092013-10-04 16:00:07 -050045{
Aaron Durbin1f5eb1f2013-10-08 15:33:39 -050046 void *spd_content;
Aaron Durbin100b14d2013-11-27 16:51:26 -060047 int dual_channel = 0;
Aaron Durbin899d13d2015-05-15 23:39:23 -050048 void *spd_file;
49 size_t spd_fsize;
Aaron Durbin1f5eb1f2013-10-08 15:33:39 -050050
Julius Werner834b3ec2020-03-04 16:52:08 -080051 spd_file = cbfs_map("spd.bin", &spd_fsize);
Aaron Durbin1f5eb1f2013-10-08 15:33:39 -050052 if (!spd_file)
53 die("SPD data not found.");
54
Aaron Durbin899d13d2015-05-15 23:39:23 -050055 spd_content = get_spd_pointer(spd_file, spd_fsize / SPD_SIZE,
Aaron Durbin100b14d2013-11-27 16:51:26 -060056 &dual_channel);
Aaron Durbin1f5eb1f2013-10-08 15:33:39 -050057
Kyösti Mälkki3e772792019-08-16 17:37:48 +030058 mp->mainboard.dram_type = DRAM_DDR3L;
59 mp->mainboard.dram_info_location = DRAM_INFO_SPD_MEM,
60 mp->mainboard.weaker_odt_settings = 1,
61
62 mp->mainboard.dram_data[0] = spd_content;
63 if (dual_channel)
64 mp->mainboard.dram_data[1] = spd_content;
Aaron Durbinc625d092013-10-04 16:00:07 -050065}