/* SPDX-License-Identifier: GPL-2.0-only */ #include <bootblock_common.h> #include <arch/io.h> #include <baseboard/variants.h> #include <device/pci_ops.h> #include <device/pnp_ops.h> #include <intelpch/espi.h> #include <soc/pci_devs.h> #include <superio/ite/common/ite.h> #include <superio/ite/it8613e/it8613e.h> #define it8613e_index (0x2e) #define it8613e_data (0x2f) #define it8613e_ecdata_base (0xa40) #define EC_DEV PNP_DEV(it8613e_index, IT8613E_EC) #define UART_DEV PNP_DEV(it8613e_index, IT8613E_SP1) /* * IT8613E/LX Super I/O Chip Initialization Settings */ struct initdata { u16 reg; u8 OpAnd; u8 OpOr; }; static const struct initdata init_values[] = { /* Entry ITE SIO configuration */ { it8613e_index, 0x00, 0x87 }, { it8613e_index, 0x00, 0x01 }, { it8613e_index, 0x00, 0x55 }, { it8613e_index, 0x00, 0x55 }, /* Start IT8613E/LX config */ { it8613e_index, 0x00, 0x23 }, { it8613e_data, 0x1f, 0x40 }, /* LDN: 04, EC */ { it8613e_index, 0x00, 0x07 }, { it8613e_data, 0x00, 0x04 }, { it8613e_index, 0x00, 0xf0 }, { it8613e_data, 0x00, 0x00 }, { it8613e_index, 0x00, 0xf1 }, { it8613e_data, 0x00, 0xbf }, { it8613e_index, 0x00, 0xf2 }, { it8613e_data, 0x00, 0x00 }, { it8613e_index, 0x00, 0xf3 }, { it8613e_data, 0x00, 0x00 }, { it8613e_index, 0x00, 0xf4 }, { it8613e_data, 0x00, 0x60 }, { it8613e_index, 0x00, 0xf5 }, { it8613e_data, 0x3f, 0x00 }, { it8613e_index, 0x00, 0xfa }, { it8613e_data, 0x00, 0x00 }, { it8613e_index, 0x00, 0xfb }, { it8613e_data, 0xf3, 0x0c }, /* LDN: 03, Unknown Device */ { it8613e_index, 0x00, 0x07 }, { it8613e_data, 0x00, 0x03 }, { it8613e_index, 0x00, 0xf0 }, { it8613e_data, 0xf7, 0x08 }, { it8613e_index, 0x00, 0x07 }, { it8613e_data, 0x00, 0x07 }, { it8613e_index, 0x00, 0x28 }, { it8613e_data, 0xbf, 0x00 }, { it8613e_index, 0x00, 0x72 }, { it8613e_data, 0xff, 0x00 }, { it8613e_index, 0x00, 0x2c }, { it8613e_data, 0xbf, 0x40 }, /* LDN: 04, EC */ { it8613e_index, 0x00, 0x07 }, { it8613e_data, 0x00, 0x04 }, /* Set IO1 to 0xa40 */ { it8613e_index, 0x00, 0x61 }, { it8613e_data, 0x00, 0x40 }, { it8613e_index, 0x00, 0x60 }, { it8613e_data, 0x00, 0x0a }, /* Set IO2 to 0xa30 */ { it8613e_index, 0x00, 0x62 }, { it8613e_data, 0x00, 0x0a }, { it8613e_index, 0x00, 0x63 }, { it8613e_data, 0x00, 0x30 }, /* Enable the EC Device */ { it8613e_index, 0x00, 0x30 }, { it8613e_data, 0x00, 0x01 }, /* for Environment Controller */ { 0x0a45, 0x00, 0x50 }, { 0x0a46, 0x00, 0xff }, { 0x0a45, 0x00, 0x51 }, { 0x0a46, 0x00, 0x38 }, { 0x0a45, 0x00, 0x00 }, { 0x0a46, 0x00, 0x01 }, { 0x0a45, 0x00, 0x0a }, { 0x0a46, 0x00, 0x64 }, { 0x0a45, 0x00, 0x8e }, { 0x0a46, 0x3f, 0xc0 }, { 0x0a45, 0x00, 0x00 }, { 0x0a46, 0x00, 0x40 }, /* */ { it8613e_index, 0x00, 0x23 }, { it8613e_data, 0xfe, 0x00 }, /* LDN: 07, GPIO */ { it8613e_index, 0x00, 0x07 }, { it8613e_data, 0x00, 0x07 }, { it8613e_index, 0x00, 0x25 }, { it8613e_data, 0x08, 0x00 }, { it8613e_index, 0x00, 0x26 }, { it8613e_data, 0x00, 0x00 }, { it8613e_index, 0x00, 0x27 }, { it8613e_data, 0x00, 0x00 }, { it8613e_index, 0x00, 0x28 }, { it8613e_data, 0x40, 0x00 }, { it8613e_index, 0x00, 0x29 }, { it8613e_data, 0x00, 0x00 }, { it8613e_index, 0x00, 0x71 }, { it8613e_data, 0x00, 0x00 }, { it8613e_index, 0x00, 0x72 }, { it8613e_data, 0x00, 0x90 }, { it8613e_index, 0x00, 0x73 }, { it8613e_data, 0x00, 0x00 }, { it8613e_index, 0x00, 0x2a }, { it8613e_data, 0xdf, 0x00 }, { it8613e_index, 0x00, 0x2b }, { it8613e_data, 0x0f, 0x00 }, { it8613e_index, 0x00, 0x2c }, { it8613e_data, 0x62, 0x00 }, /* LDN: 05, Keyboard */ { it8613e_index, 0x00, 0x07 }, { it8613e_data, 0x00, 0x05 }, /* Disable the Device */ { it8613e_index, 0x00, 0x30 }, { it8613e_data, 0x00, 0x00 }, /* LDN: 06, Mouse */ { it8613e_index, 0x00, 0x07 }, { it8613e_data, 0x00, 0x06 }, /* Disable the Device */ { it8613e_index, 0x00, 0x30 }, { it8613e_data, 0x00, 0x00 }, /* LDN: 05, Keyboard */ { it8613e_index, 0x00, 0x07 }, { it8613e_data, 0x00, 0x05 }, { it8613e_index, 0x00, 0xf0 }, { it8613e_data, 0xf7, 0x08 }, /* LDN: 04, EC */ { it8613e_index, 0x00, 0x07 }, { it8613e_data, 0x00, 0x04 }, { it8613e_index, 0x00, 0xf4 }, { it8613e_data, 0x7f, 0x80 }, { it8613e_index, 0x00, 0x70 }, { it8613e_data, 0x00, 0x00 }, /* exit ITE config */ { it8613e_index, 0x00, 0x02 }, { it8613e_data, 0x00, 0x02 }, }; static void sio_init(const struct initdata *table, const size_t count) { u8 val; for (size_t i = 0; i < count; i++) { if (table[i].OpAnd != 0) { val = inb(table->reg) & table[i].OpAnd; val |= table[i].OpOr; } else { val = table[i].OpOr; } outb(val, table[i].reg); } } static const struct initdata it8613e_initdata[] = { { 0x0007, 0x00, IT8613E_GPIO }, /* LDN GPIO */ { 0x0071, 0xf7, 0x00 }, /* ESPI_CLOCK */ { 0x0023, 0xf6, 0x00 }, { 0x002d, 0xfb, (1 << 1) }, { 0x0007, 0x00, IT8613E_CIR }, { 0x0030, 0x00, 0x00 }, { 0x0060, 0x00, 0x00 }, { 0x0061, 0x00, 0x00 }, { 0x0070, 0x00, 0x00 }, { 0x0007, 0x00, IT8613E_EC }, /* LDN EC */ { 0x00f0, 0x00, 0x00 }, { 0x00f1, 0x00, 0xbf }, { 0x00f2, 0x00, 0x00 }, { 0x00f3, 0x00, 0x00 }, { 0x00f4, 0x9f, 0x60 }, { 0x00f5, 0x3f, 0x00 }, { 0x00fa, 0x00, 0x00 }, { 0x00fb, 0xf3, 0x0c }, { 0x0007, 0x00, IT8613E_GPIO }, /* LDN GPIO */ { 0x0026, 0x00, 0x00 }, { 0x0029, 0x00, 0x00 }, { 0x002a, 0x7f, 0x80 }, { 0x002b, 0xbf, 0x00 }, }; static const struct initdata it8613e_ecdata[] = { { 0x0050, 0x00, 0xff }, { 0x0051, 0x00, 0x15 }, { 0x000a, 0x8f, 0x68 }, { 0x000b, 0x00, 0xc9 }, { 0x000c, 0xf8, 0x07 }, { 0x0013, 0x07, 0x70 }, { 0x0014, 0x7f, 0xc0 }, { 0x005c, 0x7f, 0x80 }, { 0x0056, 0x00, 0x68 }, { 0x0057, 0x00, 0x05 }, { 0x0059, 0x00, 0x00 }, { 0x005c, 0x7f, 0x00 }, { 0x0065, 0x60, 0x04 }, { 0x006d, 0x60, 0x04 }, { 0x0075, 0x60, 0x04 }, { 0x0089, 0x00, 0x30 }, { 0x008a, 0x00, 0x01 }, { 0x008b, 0x00, 0x02 }, { 0x008c, 0x00, 0x01 }, { 0x008e, 0x00, 0x20 }, { 0x0006, 0x00, 0x40 }, { 0x001d, 0x00, 0x14 }, { 0x001e, 0x00, 0x04 }, { 0x0006, 0x00, 0x00 }, { 0x0055, 0x7f, 0x80 }, { 0x0000, 0xbe, 0x41 }, { 0x0000, 0x00, 0x00 }, { 0x0000, 0x00, 0x00 }, }; static void it8613e_init(const u16 p_idx, const u16 p_dat, const struct initdata *table, const size_t count) { u8 val; for (size_t i = 0; i < count; i++) { outb(table[i].reg, p_idx); if (table[i].OpAnd == 0) { val = table[i].OpOr; } else { val = ((inb(p_dat) & table[i].OpAnd) | table[i].OpOr); } outb(val, p_dat); } } void bootblock_mainboard_early_init(void) { /* fixed io decode of espi */ pci_write_config32(PCH_DEV_ESPI, ESPI_IO_DEC, 0x3c030070); variant_configure_early_gpio_pads(); /* initial IT8613e/LX from table */ sio_init(init_values, ARRAY_SIZE(init_values)); pnp_enter_conf_state(EC_DEV); it8613e_init(it8613e_index, it8613e_data, it8613e_initdata, ARRAY_SIZE(it8613e_initdata)); pnp_exit_conf_state(EC_DEV); /* Environment Controller */ it8613e_init(it8613e_ecdata_base + 5, it8613e_ecdata_base + 6, it8613e_ecdata, ARRAY_SIZE(it8613e_ecdata)); /* 5VSB_CTRL# disable */ ite_reg_write(EC_DEV, 0xfa, 0); ite_disable_pme_out(EC_DEV); ite_ac_resume_southbridge(EC_DEV); ite_enable_serial(UART_DEV, CONFIG_TTYS0_BASE); }