blob: c2a8721bba56ce85e8c337515b0122a3dcb8da84 [file] [log] [blame]
Nico Huberefe1fed2013-04-29 18:00:57 +02001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2007-2009 coresystems GmbH
5 * Copyright (C) 2011 The ChromiumOS Authors. All rights reserved.
6 * Copyright (C) 2013 secunet Security Networks AG
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; version 2 of the License.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
Nico Huberefe1fed2013-04-29 18:00:57 +020016 */
17
18#include <types.h>
19#include <string.h>
20#include <device/device.h>
21#include <device/pci_def.h>
22#include <device/pci_ops.h>
23#include <console/console.h>
Martin Roth356b5192017-06-24 21:53:37 -060024#if IS_ENABLED(CONFIG_VGA_ROM_RUN)
Nico Huberefe1fed2013-04-29 18:00:57 +020025#include <x86emu/x86emu.h>
26#endif
27#include <pc80/mc146818rtc.h>
Nico Huberefe1fed2013-04-29 18:00:57 +020028#include <arch/interrupt.h>
29#include <boot/coreboot_tables.h>
Nico Huberefe1fed2013-04-29 18:00:57 +020030#include <southbridge/intel/bd82x6x/pch.h>
31
Martin Roth356b5192017-06-24 21:53:37 -060032#if IS_ENABLED(CONFIG_VGA_ROM_RUN)
Nico Huberefe1fed2013-04-29 18:00:57 +020033static int int15_handler(void)
34{
35 int res = 0;
36
37 printk(BIOS_DEBUG, "%s: AX=%04x BX=%04x CX=%04x DX=%04x\n",
38 __func__, X86_AX, X86_BX, X86_CX, X86_DX);
39
Elyes HAOUAS0ce41f12018-11-13 10:03:31 +010040 switch (X86_EAX & 0xffff) {
Nico Huberefe1fed2013-04-29 18:00:57 +020041 case 0x5f34:
42 /*
43 * Set Panel Fitting Hook:
44 * bit 2 = Graphics Stretching
45 * bit 1 = Text Stretching
46 * bit 0 = Centering (do not set with bit1 or bit2)
47 * 0 = video bios default
48 */
49 X86_EAX &= 0xffff0000;
50 X86_EAX |= 0x005f;
51 X86_ECX &= 0xffffff00;
52 X86_ECX |= 0x00; /* Use video bios default */
53 res = 1;
54 break;
55 case 0x5f35:
56 /*
57 * Boot Display Device Hook:
58 * bit 0 = CRT
59 * bit 1 = TV (eDP)
60 * bit 2 = EFP
61 * bit 3 = LFP
62 * bit 4 = CRT2
63 * bit 5 = TV2 (eDP)
64 * bit 6 = EFP2
65 * bit 7 = LFP2
66 */
67 X86_EAX &= 0xffff0000;
68 X86_EAX |= 0x005f;
69 X86_ECX &= 0xffff0000;
70 X86_ECX |= 0x0000; /* Use video bios default */
71 res = 1;
72 break;
73 case 0x5f51:
74 /*
75 * Hook to select active LFP configuration:
76 * 00h = No LVDS, VBIOS does not enable LVDS
77 * 01h = Int-LVDS, LFP driven by integrated LVDS decoder
78 * 02h = SDVO-LVDS, LFP driven by SDVO decoder
79 * 03h = eDP, LFP Driven by Int-DisplayPort encoder
80 */
81 X86_EAX &= 0xffff0000;
82 X86_EAX |= 0x005f;
83 X86_ECX &= 0xffff0000;
84 X86_ECX |= 0x0000; /* TODO: Make this configurable in NVRAM? */
85 res = 1;
86 break;
Patrick Georgi7fc2da92014-06-27 12:17:17 +020087 case 0x5f40:
88 /*
89 * Boot Panel Type Hook:
90 * BL(in): 00h = LFP, 01h = LFP2
91 * CL(out): panel type id in table: 1..16
92 */
93 if (0 == (X86_EBX & 0xff)) {
Nico Huberefe1fed2013-04-29 18:00:57 +020094 X86_EAX &= 0xffff0000;
Patrick Georgi7fc2da92014-06-27 12:17:17 +020095 X86_EAX |= 0x015f;
Nico Huberefe1fed2013-04-29 18:00:57 +020096 res = 1;
Patrick Georgi7fc2da92014-06-27 12:17:17 +020097 } else if (1 == (X86_EBX & 0xff)) {
Nico Huberefe1fed2013-04-29 18:00:57 +020098 X86_EAX &= 0xffff0000;
Patrick Georgi7fc2da92014-06-27 12:17:17 +020099 X86_EAX |= 0x015f;
Nico Huberefe1fed2013-04-29 18:00:57 +0200100 res = 1;
Patrick Georgi7fc2da92014-06-27 12:17:17 +0200101 } else {
102 printk(BIOS_DEBUG,
103 "Unknown panel index %u "
104 "in INT15 function %04x!\n",
105 X86_EBX & 0xff, X86_EAX & 0xffff);
Nico Huberefe1fed2013-04-29 18:00:57 +0200106 }
107 break;
Patrick Georgi7fc2da92014-06-27 12:17:17 +0200108 case 0x5f52:
109 /*
110 * Panel Color Depth:
111 * 00h = 18 bit
112 * 01h = 24 bit
113 */
114 X86_EAX &= 0xffff0000;
115 X86_EAX |= 0x005f;
116 X86_ECX &= 0xffff0000;
117 X86_ECX |= 0x0001;
118 res = 1;
119 break;
120 case 0x5f14:
121 if ((X86_EBX & 0xffff) == 0x78f) {
122 /*
123 * Get Miscellaneous Status Hook:
124 * bit 2: AC power active?
125 * bit 1: lid closed?
126 * bit 0: docked?
127 */
128 X86_EAX &= 0xffff0000;
129 X86_EAX |= 0x015f;
130 res = 1;
131 } else {
132 printk(BIOS_DEBUG,
133 "Unknown BX 0x%04x in INT15 function %04x!\n",
134 X86_EBX & 0xffff, X86_EAX & 0xffff);
135 }
136 break;
137 case 0x5f49:
138 /*
139 * Get Inverter Type and Polarity:
140 * EBX: backlight control brightness: 0..255
141 * ECX:
142 * 0 = Enable PWM inverted, 2 = Enable PWM
143 * 1 = Enable I2C inverted, 3 = Enable I2C
144 */
145 X86_EAX &= 0xffff0000;
146 X86_EAX |= 0x015f;
147 res = 1;
148 break;
Elyes HAOUASbbcb8bc2016-09-29 21:00:13 +0200149 default:
Nico Huberefe1fed2013-04-29 18:00:57 +0200150 printk(BIOS_DEBUG, "Unknown INT15 function %04x!\n",
151 X86_EAX & 0xffff);
152 break;
153 }
154 return res;
155}
156#endif
157
Nico Huberefe1fed2013-04-29 18:00:57 +0200158
Nico Huberefe1fed2013-04-29 18:00:57 +0200159
Elyes HAOUASf10b5ff2016-10-06 19:49:55 +0200160/* mainboard_enable is executed as first thing after */
161/* enumerate_buses(). */
Nico Huberefe1fed2013-04-29 18:00:57 +0200162
Elyes HAOUASf65f297e2018-05-04 22:09:07 +0200163static void mainboard_enable(struct device *dev)
Nico Huberefe1fed2013-04-29 18:00:57 +0200164{
Martin Roth356b5192017-06-24 21:53:37 -0600165#if IS_ENABLED(CONFIG_PCI_OPTION_ROM_RUN_YABEL) || \
166 IS_ENABLED(CONFIG_PCI_OPTION_ROM_RUN_REALMODE)
Nico Huberefe1fed2013-04-29 18:00:57 +0200167 /* Install custom int15 handler for VGA OPROM */
168 mainboard_interrupt_handlers(0x15, &int15_handler);
169#endif
Patrick Georgif7381f82013-08-15 14:57:09 +0200170
171 unsigned disable = 0;
Alexandru Gagniuc72dccce2013-11-23 19:22:53 -0600172 if ((get_option(&disable, "ethernet1") == CB_SUCCESS) && disable) {
Kyösti Mälkkic70eed12018-05-22 02:18:00 +0300173 struct device *nic = pcidev_on_root(0x1c, 2);
Patrick Georgif7381f82013-08-15 14:57:09 +0200174 if (nic) {
175 printk(BIOS_DEBUG, "DISABLE FIRST NIC!\n");
176 nic->enabled = 0;
177 }
178 }
179 disable = 0;
Alexandru Gagniuc72dccce2013-11-23 19:22:53 -0600180 if ((get_option(&disable, "ethernet2") == CB_SUCCESS) && disable) {
Kyösti Mälkkic70eed12018-05-22 02:18:00 +0300181 struct device *nic = pcidev_on_root(0x1c, 3);
Patrick Georgif7381f82013-08-15 14:57:09 +0200182 if (nic) {
183 printk(BIOS_DEBUG, "DISABLE SECOND NIC!\n");
184 nic->enabled = 0;
185 }
186 }
Nico Huberefe1fed2013-04-29 18:00:57 +0200187}
188
189struct chip_operations mainboard_ops = {
190 .enable_dev = mainboard_enable,
191};