diff options
Diffstat (limited to 'src/mainboard/lattepanda/mu/bootblock.c')
-rw-r--r-- | src/mainboard/lattepanda/mu/bootblock.c | 270 |
1 files changed, 270 insertions, 0 deletions
diff --git a/src/mainboard/lattepanda/mu/bootblock.c b/src/mainboard/lattepanda/mu/bootblock.c new file mode 100644 index 0000000000..4d0216c63b --- /dev/null +++ b/src/mainboard/lattepanda/mu/bootblock.c @@ -0,0 +1,270 @@ +/* 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); +} |