1 /* SPDX-License-Identifier: GPL-2.0-only */
4 #include <bootblock_common.h>
5 #include <device/pci_ops.h>
6 #include <device/pnp_ops.h>
7 #include <device/pnp.h>
8 #include <southbridge/intel/i82801dx/i82801dx.h>
9 #include <superio/smsc/lpc47m10x/lpc47m10x.h>
11 #define SERIAL_DEV PNP_DEV(0x2e, LPC47M10X2_SP1)
12 #define GPIO_DEV PNP_DEV(0x2e, LPC47M10X2_PME)
13 #define PME_BASE 0xe00
17 * 1-2 0:1f.0 0xd4 GEN_STA SAFE_MODE = 0
18 * 2-3 0:1f.0 0xd4 GEN_STA SAFE_MODE = 1
21 static void enable_gpio(void)
23 const pci_devfn_t dev
= PCI_DEV(0, 0x1f, 0);
25 /* These should go under sb/. */
26 pci_write_config8(dev
, COM_DEC
, 0x10);
27 pci_write_config16(dev
, LPC_EN
, 0x300F);
29 pnp_enter_conf_state(GPIO_DEV
);
30 pnp_set_logical_device(GPIO_DEV
);
31 pnp_set_enable(GPIO_DEV
, 0);
32 pnp_set_iobase(GPIO_DEV
, PNP_IDX_IO0
, PME_BASE
);
33 pnp_set_enable(GPIO_DEV
, 1);
34 pnp_exit_conf_state(GPIO_DEV
);
36 pci_write_config16(dev
, GEN1_DEC
, PME_BASE
| 0x01);
39 static void gpio_write(u8 addr
, u8 val
)
41 outb(val
, PME_BASE
+ addr
);
44 static void gpio_read_write(u8 addr
, u8 amask
, u8 omask
)
46 u8 val
= inb(PME_BASE
+ addr
);
49 outb(val
, PME_BASE
+ addr
);
52 static void configure_gpios(void)
55 gpio_write(0x23, 0x00); /* push-pull output */
56 gpio_write(0x24, 0x81); /* open-drain but input ? */
57 gpio_write(0x25, 0x01);
58 gpio_write(0x26, 0x01);
59 gpio_write(0x27, 0x01);
60 gpio_write(0x28, 0x01);
61 gpio_write(0x29, 0x01);
62 gpio_write(0x2a, 0x00); /* push-pull output */
65 gpio_write(0x2b, 0x01);
66 gpio_write(0x2c, 0x0c); /* nDS1 floppy select */
67 gpio_write(0x2d, 0x00); /* push-pull output */
68 gpio_write(0x2f, 0x01);
69 gpio_write(0x30, 0x01);
70 gpio_write(0x31, 0x01);
71 gpio_write(0x32, 0x04); /* nIO_SMI */
74 gpio_write(0x33, 0x04); /* FAN_TACH2 */
75 gpio_write(0x34, 0x01);
76 gpio_write(0x35, 0x01);
77 gpio_write(0x36, 0x01);
78 gpio_write(0x37, 0x01);
79 gpio_write(0x38, 0x01);
80 gpio_write(0x39, 0x04); /* nKBDRESET */
81 gpio_write(0x3a, 0x04); /* A20M */
84 gpio_write(0x3b, 0x84); /* DRVDEN0 open-drain */
85 gpio_write(0x3c, 0x04); /* DRVDEN1 push/pull */
86 gpio_write(0x3d, 0x84); /* nIO_PME open-drain */
87 gpio_write(0x3e, 0x01);
89 /* GP50-GP57 to UART signals */
90 gpio_write(0x3f, 0x05);
91 gpio_write(0x40, 0x05);
92 gpio_write(0x41, 0x05);
93 gpio_write(0x42, 0x04);
94 gpio_write(0x43, 0x05);
95 gpio_write(0x44, 0x04);
96 gpio_write(0x45, 0x05);
97 gpio_write(0x46, 0x04);
100 gpio_write(0x47, 0x86); /* LED1 invert open-drain */
101 gpio_write(0x48, 0x81); /* open-drain but input */
103 /* Set initial output bits */
104 gpio_read_write(0x4b, 0xff, 0x81); /* GP1 */
105 gpio_read_write(0x4c, ~0x01, 0x00); /* GP2 */
106 gpio_read_write(0x4d, 0xff, 0x80); /* GP3 */
107 gpio_read_write(0x4e, ~0x08, 0x00); /* GP4 */
110 gpio_write(0x5d, 0x00);
113 void bootblock_mainboard_early_init(void)
118 /* Get the serial port configured. */
119 lpc47m10x_enable_serial(SERIAL_DEV
, CONFIG_TTYS0_BASE
);