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
)) {
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) {
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");
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
));
44 printk(BIOS_SPEW
, "Bit already set; nothing to do.\n");
48 printk(BIOS_ERR
, "Unable to read DRAM part # from CBI; CMOS bit will be cleared if set\n");
51 /* Ensure SKIP_RESET_TOGGLE bit cleared if not FF, not bad DRAM part, or error reading part # */
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
));
58 printk(BIOS_SPEW
, "No change to CMOS SKIP_RESET_TOGGLE bit is needed\n");
62 void mb_set_up_early_espi(void)
65 const struct soc_amd_gpio
*gpios
;
67 variant_espi_gpio_table(&gpios
, &num_gpios
);
68 gpio_configure_pads(gpios
, num_gpios
);
70 espi_switch_to_spi1_pads();
73 void bootblock_mainboard_early_init(void)
75 size_t num_gpios
, override_num_gpios
;
76 const struct soc_amd_gpio
*gpios
, *override_gpios
;
78 variant_tpm_gpio_table(&gpios
, &num_gpios
);
79 gpio_configure_pads(gpios
, num_gpios
);
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
);
86 void bootblock_mainboard_init(void)
89 const struct soc_amd_gpio
*gpios
;
91 hynix_dram_cmos_check();
93 variant_bootblock_gpio_table(&gpios
, &num_gpios
);
94 gpio_configure_pads(gpios
, num_gpios
);