blob: 1cf80a92fadb9f76d07fd0d1813ef8e5b28e6ba2 [file] [log] [blame]
Stefan Reinauer30140a52009-03-11 16:20:39 +00001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2008-2009 coresystems GmbH
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
Paul Menzela46a7122013-02-23 18:37:27 +010017 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Stefan Reinauer30140a52009-03-11 16:20:39 +000018 */
19
20#include <console/console.h>
Kyösti Mälkkiab56b3b2013-11-28 16:44:51 +020021#include <bootmode.h>
Patrick Georgi6444bd42012-07-06 11:31:39 +020022#include <delay.h>
Stefan Reinauer30140a52009-03-11 16:20:39 +000023#include <device/device.h>
24#include <device/pci.h>
25#include <device/pci_ids.h>
Sven Schnelleb629d142011-06-12 14:30:10 +020026#include <pc80/mc146818rtc.h>
Patrick Georgice6e9fe2012-07-20 12:37:06 +020027#include "i945.h"
Stefan Reinauer30140a52009-03-11 16:20:39 +000028
Patrick Georgi6444bd42012-07-06 11:31:39 +020029#define GDRST 0xc0
30
Stefan Reinauer30140a52009-03-11 16:20:39 +000031static void gma_func0_init(struct device *dev)
32{
33 u32 reg32;
34
Patrick Georgi6444bd42012-07-06 11:31:39 +020035 /* Unconditionally reset graphics */
36 pci_write_config8(dev, GDRST, 1);
37 udelay(50);
38 pci_write_config8(dev, GDRST, 0);
39 /* wait for device to finish */
40 while (pci_read_config8(dev, GDRST) & 1) { };
41
Stefan Reinauer30140a52009-03-11 16:20:39 +000042 /* IGD needs to be Bus Master */
43 reg32 = pci_read_config32(dev, PCI_COMMAND);
44 pci_write_config32(dev, PCI_COMMAND, reg32 | PCI_COMMAND_MASTER);
45
Denis 'GNUtoo' Cariklied7e29e2013-02-24 12:01:44 +010046
47#if !CONFIG_MAINBOARD_DO_NATIVE_VGA_INIT
48 /* PCI Init, will run VBIOS */
Stefan Reinauer30140a52009-03-11 16:20:39 +000049 pci_dev_init(dev);
Denis 'GNUtoo' Cariklied7e29e2013-02-24 12:01:44 +010050#endif
51
52
53#if CONFIG_MAINBOARD_DO_NATIVE_VGA_INIT
54 /* This should probably run before post VBIOS init. */
55 printk(BIOS_SPEW, "Initializing VGA without OPROM.\n");
Peter Stuge03e4ac62013-06-08 01:25:43 +020056 u32 iobase, mmiobase, graphics_base;
Denis 'GNUtoo' Cariklied7e29e2013-02-24 12:01:44 +010057 iobase = dev->resource_list[1].base;
58 mmiobase = dev->resource_list[0].base;
Denis 'GNUtoo' Carikli2186b652013-10-27 15:50:02 +010059 graphics_base = dev->resource_list[2].base + 0x20000;
Denis 'GNUtoo' Cariklied7e29e2013-02-24 12:01:44 +010060
Peter Stugec6f09972013-06-08 01:31:44 +020061 printk(BIOS_SPEW, "GMADR=0x%08x GTTADR=0x%08x\n",
Paul Menzeld235da12014-06-03 00:15:30 +020062 pci_read_config32(dev, GMADR),
63 pci_read_config32(dev, GTTADR)
Peter Stugec6f09972013-06-08 01:31:44 +020064 );
65
Denis 'GNUtoo' Cariklied7e29e2013-02-24 12:01:44 +010066 int i915lightup(u32 physbase, u32 iobase, u32 mmiobase, u32 gfx);
Kyösti Mälkkiab56b3b2013-11-28 16:44:51 +020067 int lightup_ok = i915lightup(uma_memory_base, iobase, mmiobase, graphics_base);
68 if (lightup_ok)
69 gfx_set_init_done(1);
Denis 'GNUtoo' Cariklied7e29e2013-02-24 12:01:44 +010070#endif
71
Stefan Reinauer30140a52009-03-11 16:20:39 +000072}
73
Patrick Georgice6e9fe2012-07-20 12:37:06 +020074/* This doesn't reclaim stolen UMA memory, but IGD could still
75 be reenabled later. */
76static void gma_func0_disable(struct device *dev)
77{
78 struct device *dev_host = dev_find_slot(0, PCI_DEVFN(0x0, 0));
79
80 pci_write_config16(dev, GCFC, 0xa00);
81 pci_write_config16(dev_host, GGC, (1 << 1));
82
83 unsigned int reg32 = pci_read_config32(dev_host, DEVEN);
84 reg32 &= ~(DEVEN_D2F0 | DEVEN_D2F1);
85 pci_write_config32(dev_host, DEVEN, reg32);
86
87 dev->enabled = 0;
88}
89
Stefan Reinauer30140a52009-03-11 16:20:39 +000090static void gma_func1_init(struct device *dev)
91{
92 u32 reg32;
Sven Schnelleb629d142011-06-12 14:30:10 +020093 u8 val;
Stefan Reinauer30140a52009-03-11 16:20:39 +000094
95 /* IGD needs to be Bus Master, also enable IO accesss */
96 reg32 = pci_read_config32(dev, PCI_COMMAND);
Stefan Reinauer109ab312009-08-12 16:08:05 +000097 pci_write_config32(dev, PCI_COMMAND, reg32 |
Stefan Reinauer30140a52009-03-11 16:20:39 +000098 PCI_COMMAND_MASTER | PCI_COMMAND_IO);
Sven Schnelleb629d142011-06-12 14:30:10 +020099
Alexandru Gagniuc72dccce2013-11-23 19:22:53 -0600100 if (get_option(&val, "tft_brightness") == CB_SUCCESS)
Sven Schnelleb629d142011-06-12 14:30:10 +0200101 pci_write_config8(dev, 0xf4, val);
102 else
103 pci_write_config8(dev, 0xf4, 0xff);
Stefan Reinauer30140a52009-03-11 16:20:39 +0000104}
105
106static void gma_set_subsystem(device_t dev, unsigned vendor, unsigned device)
107{
108 if (!vendor || !device) {
109 pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
110 pci_read_config32(dev, PCI_VENDOR_ID));
111 } else {
112 pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
113 ((device & 0xffff) << 16) | (vendor & 0xffff));
114 }
115}
116
117static struct pci_operations gma_pci_ops = {
118 .set_subsystem = gma_set_subsystem,
119};
120
121static struct device_operations gma_func0_ops = {
122 .read_resources = pci_dev_read_resources,
123 .set_resources = pci_dev_set_resources,
124 .enable_resources = pci_dev_enable_resources,
125 .init = gma_func0_init,
126 .scan_bus = 0,
127 .enable = 0,
Patrick Georgice6e9fe2012-07-20 12:37:06 +0200128 .disable = gma_func0_disable,
Stefan Reinauer30140a52009-03-11 16:20:39 +0000129 .ops_pci = &gma_pci_ops,
130};
131
132
133static struct device_operations gma_func1_ops = {
134 .read_resources = pci_dev_read_resources,
135 .set_resources = pci_dev_set_resources,
136 .enable_resources = pci_dev_enable_resources,
137 .init = gma_func1_init,
138 .scan_bus = 0,
139 .enable = 0,
140 .ops_pci = &gma_pci_ops,
141};
142
143static const struct pci_driver i945_gma_func0_driver __pci_driver = {
144 .ops = &gma_func0_ops,
145 .vendor = PCI_VENDOR_ID_INTEL,
146 .device = 0x27a2,
147};
148
149static const struct pci_driver i945_gma_func1_driver __pci_driver = {
150 .ops = &gma_func1_ops,
151 .vendor = PCI_VENDOR_ID_INTEL,
152 .device = 0x27a6,
153};
154