blob: 27aa3b532868042105fdd6a0ff20e225eb818886 [file] [log] [blame]
Angel Ponsa21dff62020-04-03 01:22:24 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Nico Huberefe1fed2013-04-29 18:00:57 +02002
3#include <types.h>
Nico Huberefe1fed2013-04-29 18:00:57 +02004#include <device/device.h>
5#include <device/pci_def.h>
Nico Huberefe1fed2013-04-29 18:00:57 +02006#include <console/console.h>
Julius Wernercd49cce2019-03-05 16:53:33 -08007#if CONFIG(VGA_ROM_RUN)
Nico Huberefe1fed2013-04-29 18:00:57 +02008#include <x86emu/x86emu.h>
9#endif
Kyösti Mälkkicbf95712020-01-05 08:05:45 +020010#include <option.h>
Nico Huberefe1fed2013-04-29 18:00:57 +020011#include <arch/interrupt.h>
Nico Huberefe1fed2013-04-29 18:00:57 +020012#include <southbridge/intel/bd82x6x/pch.h>
13
Julius Wernercd49cce2019-03-05 16:53:33 -080014#if CONFIG(VGA_ROM_RUN)
Nico Huberefe1fed2013-04-29 18:00:57 +020015static int int15_handler(void)
16{
17 int res = 0;
18
19 printk(BIOS_DEBUG, "%s: AX=%04x BX=%04x CX=%04x DX=%04x\n",
20 __func__, X86_AX, X86_BX, X86_CX, X86_DX);
21
Elyes HAOUAS0ce41f12018-11-13 10:03:31 +010022 switch (X86_EAX & 0xffff) {
Nico Huberefe1fed2013-04-29 18:00:57 +020023 case 0x5f34:
24 /*
25 * Set Panel Fitting Hook:
26 * bit 2 = Graphics Stretching
27 * bit 1 = Text Stretching
28 * bit 0 = Centering (do not set with bit1 or bit2)
Elyes HAOUAS6dc9d032020-02-16 16:22:52 +010029 * 0 = video BIOS default
Nico Huberefe1fed2013-04-29 18:00:57 +020030 */
31 X86_EAX &= 0xffff0000;
32 X86_EAX |= 0x005f;
33 X86_ECX &= 0xffffff00;
Elyes HAOUAS6dc9d032020-02-16 16:22:52 +010034 X86_ECX |= 0x00; /* Use video BIOS default */
Nico Huberefe1fed2013-04-29 18:00:57 +020035 res = 1;
36 break;
37 case 0x5f35:
38 /*
39 * Boot Display Device Hook:
40 * bit 0 = CRT
41 * bit 1 = TV (eDP)
42 * bit 2 = EFP
43 * bit 3 = LFP
44 * bit 4 = CRT2
45 * bit 5 = TV2 (eDP)
46 * bit 6 = EFP2
47 * bit 7 = LFP2
48 */
49 X86_EAX &= 0xffff0000;
50 X86_EAX |= 0x005f;
51 X86_ECX &= 0xffff0000;
Elyes HAOUAS6dc9d032020-02-16 16:22:52 +010052 X86_ECX |= 0x0000; /* Use video BIOS default */
Nico Huberefe1fed2013-04-29 18:00:57 +020053 res = 1;
54 break;
55 case 0x5f51:
56 /*
57 * Hook to select active LFP configuration:
58 * 00h = No LVDS, VBIOS does not enable LVDS
59 * 01h = Int-LVDS, LFP driven by integrated LVDS decoder
60 * 02h = SDVO-LVDS, LFP driven by SDVO decoder
61 * 03h = eDP, LFP Driven by Int-DisplayPort encoder
62 */
63 X86_EAX &= 0xffff0000;
64 X86_EAX |= 0x005f;
65 X86_ECX &= 0xffff0000;
66 X86_ECX |= 0x0000; /* TODO: Make this configurable in NVRAM? */
67 res = 1;
68 break;
Patrick Georgi7fc2da92014-06-27 12:17:17 +020069 case 0x5f40:
70 /*
71 * Boot Panel Type Hook:
72 * BL(in): 00h = LFP, 01h = LFP2
73 * CL(out): panel type id in table: 1..16
74 */
75 if (0 == (X86_EBX & 0xff)) {
Nico Huberefe1fed2013-04-29 18:00:57 +020076 X86_EAX &= 0xffff0000;
Patrick Georgi7fc2da92014-06-27 12:17:17 +020077 X86_EAX |= 0x015f;
Nico Huberefe1fed2013-04-29 18:00:57 +020078 res = 1;
Patrick Georgi7fc2da92014-06-27 12:17:17 +020079 } else if (1 == (X86_EBX & 0xff)) {
Nico Huberefe1fed2013-04-29 18:00:57 +020080 X86_EAX &= 0xffff0000;
Patrick Georgi7fc2da92014-06-27 12:17:17 +020081 X86_EAX |= 0x015f;
Nico Huberefe1fed2013-04-29 18:00:57 +020082 res = 1;
Patrick Georgi7fc2da92014-06-27 12:17:17 +020083 } else {
84 printk(BIOS_DEBUG,
85 "Unknown panel index %u "
86 "in INT15 function %04x!\n",
87 X86_EBX & 0xff, X86_EAX & 0xffff);
Nico Huberefe1fed2013-04-29 18:00:57 +020088 }
89 break;
Patrick Georgi7fc2da92014-06-27 12:17:17 +020090 case 0x5f52:
91 /*
92 * Panel Color Depth:
93 * 00h = 18 bit
94 * 01h = 24 bit
95 */
96 X86_EAX &= 0xffff0000;
97 X86_EAX |= 0x005f;
98 X86_ECX &= 0xffff0000;
99 X86_ECX |= 0x0001;
100 res = 1;
101 break;
102 case 0x5f14:
103 if ((X86_EBX & 0xffff) == 0x78f) {
104 /*
105 * Get Miscellaneous Status Hook:
106 * bit 2: AC power active?
107 * bit 1: lid closed?
108 * bit 0: docked?
109 */
110 X86_EAX &= 0xffff0000;
111 X86_EAX |= 0x015f;
112 res = 1;
113 } else {
114 printk(BIOS_DEBUG,
115 "Unknown BX 0x%04x in INT15 function %04x!\n",
116 X86_EBX & 0xffff, X86_EAX & 0xffff);
117 }
118 break;
119 case 0x5f49:
120 /*
121 * Get Inverter Type and Polarity:
122 * EBX: backlight control brightness: 0..255
123 * ECX:
124 * 0 = Enable PWM inverted, 2 = Enable PWM
125 * 1 = Enable I2C inverted, 3 = Enable I2C
126 */
127 X86_EAX &= 0xffff0000;
128 X86_EAX |= 0x015f;
129 res = 1;
130 break;
Elyes HAOUASbbcb8bc2016-09-29 21:00:13 +0200131 default:
Nico Huberefe1fed2013-04-29 18:00:57 +0200132 printk(BIOS_DEBUG, "Unknown INT15 function %04x!\n",
133 X86_EAX & 0xffff);
134 break;
135 }
136 return res;
137}
138#endif
139
Nico Huberefe1fed2013-04-29 18:00:57 +0200140
Elyes HAOUASf65f297e2018-05-04 22:09:07 +0200141static void mainboard_enable(struct device *dev)
Nico Huberefe1fed2013-04-29 18:00:57 +0200142{
Julius Wernercd49cce2019-03-05 16:53:33 -0800143#if CONFIG(PCI_OPTION_ROM_RUN_YABEL) || \
144 CONFIG(PCI_OPTION_ROM_RUN_REALMODE)
Nico Huberefe1fed2013-04-29 18:00:57 +0200145 /* Install custom int15 handler for VGA OPROM */
146 mainboard_interrupt_handlers(0x15, &int15_handler);
147#endif
Angel Pons88dcb312021-04-26 17:10:28 +0200148 unsigned int disable = get_uint_option("ethernet1", 0);
Angel Ponsf8a5eb22020-11-02 22:49:51 +0100149 if (disable) {
Kyösti Mälkkic70eed12018-05-22 02:18:00 +0300150 struct device *nic = pcidev_on_root(0x1c, 2);
Patrick Georgif7381f82013-08-15 14:57:09 +0200151 if (nic) {
152 printk(BIOS_DEBUG, "DISABLE FIRST NIC!\n");
153 nic->enabled = 0;
154 }
155 }
Angel Pons88dcb312021-04-26 17:10:28 +0200156 disable = get_uint_option("ethernet2", 0);
Angel Ponsf8a5eb22020-11-02 22:49:51 +0100157 if (disable) {
Kyösti Mälkkic70eed12018-05-22 02:18:00 +0300158 struct device *nic = pcidev_on_root(0x1c, 3);
Patrick Georgif7381f82013-08-15 14:57:09 +0200159 if (nic) {
160 printk(BIOS_DEBUG, "DISABLE SECOND NIC!\n");
161 nic->enabled = 0;
162 }
163 }
Nico Huberefe1fed2013-04-29 18:00:57 +0200164}
165
166struct chip_operations mainboard_ops = {
167 .enable_dev = mainboard_enable,
168};