1 /* SPDX-License-Identifier: GPL-2.0-only */
4 #include <device/pci_ops.h>
5 #include <device/pci_def.h>
6 #include <console/console.h>
7 #include <cpu/x86/smm.h>
9 #include <southbridge/intel/common/pmutil.h>
10 #include <ec/acpi/ec.h>
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)))
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)))
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 int mainboard_io_trap_handler(int smif
)
51 case SMI_DOCK_CONNECT
:
52 /* If there's an legacy I/O module present, we're not
53 * allowed to connect the Docking LPC Bus, as both Super I/O
54 * chips are using 0x2e as base address.
56 if (legacy_io_present())
59 if (!dock_connect()) {
60 /* set dock LED to indicate status */
64 /* blink dock LED to indicate failure */
70 case SMI_DOCK_DISCONNECT
:
76 case SMI_BRIGHTNESS_UP
:
77 mainboard_smi_brightness_up();
80 case SMI_BRIGHTNESS_DOWN
:
81 mainboard_smi_brightness_down();
88 /* On success, the IO Trap Handler returns 1
89 * On failure, the IO Trap Handler returns a value != 1 */
93 static void mainboard_smi_handle_ec_sci(void)
95 u8 status
= inb(EC_SC
);
98 if (!(status
& EC_SCI_EVT
))
102 printk(BIOS_DEBUG
, "EC event %#02x\n", event
);
107 mainboard_smi_brightness_up();
109 /* brightness down */
111 mainboard_smi_brightness_down();
119 mainboard_io_trap_handler(SMI_DOCK_DISCONNECT
);
123 mainboard_io_trap_handler(SMI_DOCK_CONNECT
);
130 void mainboard_smi_gpi(u32 gpi
)
132 if (gpi
& (1 << GPE_EC_SCI
))
133 mainboard_smi_handle_ec_sci();
136 int mainboard_smi_apmc(u8 data
)
139 case APM_CNT_ACPI_ENABLE
:
140 /* use 0x1600/0x1604 to prevent races with userspace */
141 ec_set_ports(0x1604, 0x1600);
142 /* route H8SCI to SCI */
143 gpi_route_interrupt(GPE_EC_SCI
, GPI_IS_SCI
);
145 case APM_CNT_ACPI_DISABLE
:
146 /* we have to use port 0x62/0x66, as 0x1600/0x1604 doesn't
147 provide a EC query function */
148 ec_set_ports(0x66, 0x62);
149 /* route H8SCI# to SMI */
150 gpi_route_interrupt(GPE_EC_SCI
, GPI_IS_SMI
);