summaryrefslogtreecommitdiff
path: root/src/mainboard/lattepanda/mu/bootblock.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mainboard/lattepanda/mu/bootblock.c')
-rw-r--r--src/mainboard/lattepanda/mu/bootblock.c270
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);
+}