blob: d285d7f48df6f7c084d39007c482cb7c90a70784 [file] [log] [blame]
Karthikeyan Ramasubramaniana84d4f232022-02-02 10:10:03 -07001/* SPDX-License-Identifier: GPL-2.0-only */
2
Raul E Rangel96839d12022-03-24 16:55:44 -06003#include <amdblocks/espi.h>
Matt DeVillier74d9dac2023-06-08 12:32:58 -05004#include <amdblocks/reset.h>
Karthikeyan Ramasubramaniana84d4f232022-02-02 10:10:03 -07005#include <bootblock_common.h>
6#include <baseboard/variants.h>
Matt DeVillier74d9dac2023-06-08 12:32:58 -05007#include <console/console.h>
8#include <ec/google/chromeec/ec.h>
9#include <pc80/mc146818rtc.h>
Raul E Rangel879a2782022-03-24 17:06:47 -060010#include <soc/espi.h>
Matt DeVillier74d9dac2023-06-08 12:32:58 -050011#include <string.h>
12
13#define CMOS_EXTENDED_ADDR(x) (128 + (x))
14#define CMOS_MEM_RESTORE_OFFSET 0x0D
15#define CMOS_BITMAP_SKIP_RESET_TOGGLE 0x10
16#define HYNIX_PART_NAME "H9JCNNNCP3MLYR-N6E"
17#define HYNIX_PART_LEN 18
18
19/* Ensure SKIP_RESET_TOGGLE CMOS bit set for specific Hynix part on Frostflow, cleared otherwise */
20static void hynix_dram_cmos_check(void)
21{
22 char cbi_part_number[DIMM_INFO_PART_NUMBER_SIZE];
23 bool skip_reset_toggle, cmos_bit_set;
24 unsigned char byte_value;
25
26 byte_value = cmos_read(CMOS_EXTENDED_ADDR(CMOS_MEM_RESTORE_OFFSET));
27 cmos_bit_set = (byte_value & CMOS_BITMAP_SKIP_RESET_TOGGLE) != 0;
28
29 if (CONFIG(BOARD_GOOGLE_FROSTFLOW)) {
30
31 printk(BIOS_SPEW, "Checking DRAM part #\n");
32 if (google_chromeec_cbi_get_dram_part_num(
33 cbi_part_number, sizeof(cbi_part_number)) == 0) {
34
35 skip_reset_toggle = strncmp(cbi_part_number, HYNIX_PART_NAME, HYNIX_PART_LEN) == 0;
36 if (skip_reset_toggle) {
37 printk(BIOS_SPEW, "SKIP_RESET_TOGGLE needed, checking CMOS bit is set\n");
38 if (!cmos_bit_set) {
39 printk(BIOS_SPEW, "Bit is unset; setting and rebooting\n");
40 cmos_write((byte_value | CMOS_BITMAP_SKIP_RESET_TOGGLE),
41 CMOS_EXTENDED_ADDR(CMOS_MEM_RESTORE_OFFSET));
42 warm_reset();
43 }
44 printk(BIOS_SPEW, "Bit already set; nothing to do.\n");
45 return;
46 }
47 } else {
48 printk(BIOS_ERR, "Unable to read DRAM part # from CBI; CMOS bit will be cleared if set\n");
49 }
50 }
51 /* Ensure SKIP_RESET_TOGGLE bit cleared if not FF, not bad DRAM part, or error reading part # */
52 if (cmos_bit_set) {
53 printk(BIOS_SPEW, "CMOS SKIP_RESET_TOGGLE bit is set; clearing and rebooting\n");
54 cmos_write((byte_value & ~CMOS_BITMAP_SKIP_RESET_TOGGLE),
55 CMOS_EXTENDED_ADDR(CMOS_MEM_RESTORE_OFFSET));
56 warm_reset();
57 } else {
58 printk(BIOS_SPEW, "No change to CMOS SKIP_RESET_TOGGLE bit is needed\n");
59 }
60}
Karthikeyan Ramasubramaniana84d4f232022-02-02 10:10:03 -070061
Raul E Rangel96839d12022-03-24 16:55:44 -060062void mb_set_up_early_espi(void)
63{
64 size_t num_gpios;
65 const struct soc_amd_gpio *gpios;
66
67 variant_espi_gpio_table(&gpios, &num_gpios);
68 gpio_configure_pads(gpios, num_gpios);
Raul E Rangel879a2782022-03-24 17:06:47 -060069
70 espi_switch_to_spi1_pads();
Raul E Rangel96839d12022-03-24 16:55:44 -060071}
72
Karthikeyan Ramasubramaniana84d4f232022-02-02 10:10:03 -070073void bootblock_mainboard_early_init(void)
74{
Jon Murphy0bc013b2022-02-17 21:05:19 -070075 size_t num_gpios, override_num_gpios;
76 const struct soc_amd_gpio *gpios, *override_gpios;
77
78 variant_tpm_gpio_table(&gpios, &num_gpios);
79 gpio_configure_pads(gpios, num_gpios);
80
81 variant_early_gpio_table(&gpios, &num_gpios);
82 variant_early_override_gpio_table(&override_gpios, &override_num_gpios);
83 gpio_configure_pads_with_override(gpios, num_gpios, override_gpios, override_num_gpios);
Karthikeyan Ramasubramaniana84d4f232022-02-02 10:10:03 -070084}
Jon Murphy90424272022-02-16 06:34:39 -070085
86void bootblock_mainboard_init(void)
87{
88 size_t num_gpios;
89 const struct soc_amd_gpio *gpios;
90
Matt DeVillier74d9dac2023-06-08 12:32:58 -050091 hynix_dram_cmos_check();
92
Jon Murphy90424272022-02-16 06:34:39 -070093 variant_bootblock_gpio_table(&gpios, &num_gpios);
94 gpio_configure_pads(gpios, num_gpios);
95}