mb/google/nissa/var/rull: Add 6W and 15W DPTF parameters
[coreboot2.git] / src / mainboard / lenovo / t60 / smihandler.c
blobf3c34e51f089184458baedcebd2506fef0954d81
1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <arch/io.h>
4 #include <device/pci_ops.h>
5 #include <device/pci_def.h>
6 #include <console/console.h>
7 #include <cpu/x86/smm.h>
8 #include <soc/nvs.h>
9 #include <southbridge/intel/common/pmutil.h>
10 #include <ec/acpi/ec.h>
11 #include "dock.h"
12 #include "smi.h"
14 #define GPE_EC_SCI 12
16 #define LVTMA_BL_MOD_LEVEL 0x7af9 /* ATI Radeon backlight level */
18 static void mainboard_smi_brightness_down(void)
20 uint32_t reg32 = pci_read_config32(PCI_DEV(1, 0, 0), PCI_BASE_ADDRESS_2) & ~0xf;
21 u8 *bar = (void *)(uintptr_t)reg32;
23 /* Validate pointer before using it */
24 if (!bar || smm_points_to_smram(bar, LVTMA_BL_MOD_LEVEL + sizeof(uint8_t)))
25 return;
27 printk(BIOS_DEBUG, "bar: %p, level %02X\n", bar, *(bar+LVTMA_BL_MOD_LEVEL));
28 *(bar+LVTMA_BL_MOD_LEVEL) &= 0xf0;
29 if (*(bar+LVTMA_BL_MOD_LEVEL) > 0x10)
30 *(bar+LVTMA_BL_MOD_LEVEL) -= 0x10;
33 static void mainboard_smi_brightness_up(void)
35 uint32_t reg32 = pci_read_config32(PCI_DEV(1, 0, 0), PCI_BASE_ADDRESS_2) & ~0xf;
36 u8 *bar = (void *)(uintptr_t)reg32;
38 /* Validate pointer before using it */
39 if (!bar || smm_points_to_smram(bar, LVTMA_BL_MOD_LEVEL + sizeof(uint8_t)))
40 return;
42 printk(BIOS_DEBUG, "bar: %p, level %02X\n", bar, *(bar+LVTMA_BL_MOD_LEVEL));
43 *(bar+LVTMA_BL_MOD_LEVEL) |= 0x0f;
44 if (*(bar+LVTMA_BL_MOD_LEVEL) < 0xf0)
45 *(bar+LVTMA_BL_MOD_LEVEL) += 0x10;
48 static void mainboard_smi_dock_connect(void)
50 /* If there's an legacy I/O module present, we're not
51 * allowed to connect the Docking LPC Bus, as both Super I/O
52 * chips are using 0x2e as base address.
54 if (legacy_io_present())
55 return;
57 if (!dock_connect()) {
58 /* set dock LED to indicate status */
59 ec_write(0x0c, 0x08);
60 ec_write(0x0c, 0x89);
61 } else {
62 /* blink dock LED to indicate failure */
63 ec_write(0x0c, 0xc8);
64 ec_write(0x0c, 0x09);
68 static void mainboard_smi_dock_disconnect(void)
70 dock_disconnect();
71 ec_write(0x0c, 0x09);
72 ec_write(0x0c, 0x08);
75 int mainboard_io_trap_handler(int smif)
77 switch (smif) {
78 case SMI_DOCK_CONNECT:
79 mainboard_smi_dock_connect();
80 break;
82 case SMI_DOCK_DISCONNECT:
83 mainboard_smi_dock_disconnect();
84 break;
86 case SMI_BRIGHTNESS_UP:
87 mainboard_smi_brightness_up();
88 break;
90 case SMI_BRIGHTNESS_DOWN:
91 mainboard_smi_brightness_down();
92 break;
94 default:
95 return 0;
98 /* On success, the IO Trap Handler returns 1
99 * On failure, the IO Trap Handler returns a value != 1 */
100 return 1;
103 static void mainboard_smi_handle_ec_sci(void)
105 u8 status = inb(EC_SC);
106 u8 event;
108 if (!(status & EC_SCI_EVT))
109 return;
111 event = ec_query();
112 printk(BIOS_DEBUG, "EC event %#02x\n", event);
114 switch (event) {
115 /* brightness up */
116 case 0x14:
117 mainboard_smi_brightness_up();
118 break;
119 /* brightness down */
120 case 0x15:
121 mainboard_smi_brightness_down();
122 break;
123 /* Fn-F9 Key */
124 case 0x18:
125 /* power loss */
126 case 0x27:
127 /* undock event */
128 case 0x50:
129 mainboard_smi_dock_disconnect();
130 break;
131 /* dock event */
132 case 0x37:
133 mainboard_smi_dock_connect();
134 break;
135 default:
136 break;
140 void mainboard_smi_gpi(u32 gpi)
142 if (gpi & (1 << GPE_EC_SCI))
143 mainboard_smi_handle_ec_sci();
146 int mainboard_smi_apmc(u8 data)
148 switch (data) {
149 case APM_CNT_ACPI_ENABLE:
150 /* use 0x1600/0x1604 to prevent races with userspace */
151 ec_set_ports(0x1604, 0x1600);
152 /* route H8SCI to SCI */
153 gpi_route_interrupt(GPE_EC_SCI, GPI_IS_SCI);
154 break;
155 case APM_CNT_ACPI_DISABLE:
156 /* we have to use port 0x62/0x66, as 0x1600/0x1604 doesn't
157 provide a EC query function */
158 ec_set_ports(0x66, 0x62);
159 /* route H8SCI# to SMI */
160 gpi_route_interrupt(GPE_EC_SCI, GPI_IS_SMI);
161 break;
162 default:
163 break;
165 return 0;