1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <amdblocks/espi.h>
4 #include <amdblocks/reset.h>
5 #include <bootblock_common.h>
6 #include <baseboard/variants.h>
7 #include <console/console.h>
8 #include <ec/google/chromeec/ec.h>
9 #include <pc80/mc146818rtc.h>
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
19 /* Ensure SKIP_RESET_TOGGLE CMOS bit set for specific Hynix part on Frostflow, cleared otherwise */
20 static void hynix_dram_cmos_check(void)
22 char cbi_part_number
[DIMM_INFO_PART_NUMBER_SIZE
];
23 bool skip_reset_toggle
, cmos_bit_set
;
24 unsigned char byte_value
;
26 byte_value
= cmos_read(CMOS_EXTENDED_ADDR(CMOS_MEM_RESTORE_OFFSET
));
27 cmos_bit_set
= (byte_value
& CMOS_BITMAP_SKIP_RESET_TOGGLE
) != 0;
29 if (CONFIG(BOARD_GOOGLE_FROSTFLOW
)) {
30 printk(BIOS_SPEW
, "Checking DRAM part #\n");
31 if (google_chromeec_cbi_get_dram_part_num(
32 cbi_part_number
, sizeof(cbi_part_number
)) == 0) {
33 skip_reset_toggle
= strncmp(cbi_part_number
, HYNIX_PART_NAME
, HYNIX_PART_LEN
) == 0;
34 if (skip_reset_toggle
) {
35 printk(BIOS_SPEW
, "SKIP_RESET_TOGGLE needed, checking CMOS bit is set\n");
37 printk(BIOS_SPEW
, "Bit is unset; setting and rebooting\n");
38 cmos_write((byte_value
| CMOS_BITMAP_SKIP_RESET_TOGGLE
),
39 CMOS_EXTENDED_ADDR(CMOS_MEM_RESTORE_OFFSET
));
42 printk(BIOS_SPEW
, "Bit already set; nothing to do.\n");
46 printk(BIOS_ERR
, "Unable to read DRAM part # from CBI; CMOS bit will be cleared if set\n");
49 /* Ensure SKIP_RESET_TOGGLE bit cleared if not FF, not bad DRAM part, or error reading part # */
51 printk(BIOS_SPEW
, "CMOS SKIP_RESET_TOGGLE bit is set; clearing and rebooting\n");
52 cmos_write((byte_value
& ~CMOS_BITMAP_SKIP_RESET_TOGGLE
),
53 CMOS_EXTENDED_ADDR(CMOS_MEM_RESTORE_OFFSET
));
56 printk(BIOS_SPEW
, "No change to CMOS SKIP_RESET_TOGGLE bit is needed\n");
60 void mb_set_up_early_espi(void)
63 const struct soc_amd_gpio
*gpios
;
65 variant_espi_gpio_table(&gpios
, &num_gpios
);
66 gpio_configure_pads(gpios
, num_gpios
);
68 espi_switch_to_spi1_pads();
71 void bootblock_mainboard_early_init(void)
73 size_t num_gpios
, override_num_gpios
;
74 const struct soc_amd_gpio
*gpios
, *override_gpios
;
76 variant_tpm_gpio_table(&gpios
, &num_gpios
);
77 gpio_configure_pads(gpios
, num_gpios
);
79 variant_early_gpio_table(&gpios
, &num_gpios
);
80 variant_early_override_gpio_table(&override_gpios
, &override_num_gpios
);
81 gpio_configure_pads_with_override(gpios
, num_gpios
, override_gpios
, override_num_gpios
);
84 void bootblock_mainboard_init(void)
87 const struct soc_amd_gpio
*gpios
;
89 hynix_dram_cmos_check();
91 variant_bootblock_gpio_table(&gpios
, &num_gpios
);
92 gpio_configure_pads(gpios
, num_gpios
);