blob: b1e0c7bbe8812a1d5234a611c2d1f31ea1247557 [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>
Patrick Georgi6444bd42012-07-06 11:31:39 +020021#include <delay.h>
Stefan Reinauer30140a52009-03-11 16:20:39 +000022#include <device/device.h>
23#include <device/pci.h>
24#include <device/pci_ids.h>
Sven Schnelleb629d142011-06-12 14:30:10 +020025#include <pc80/mc146818rtc.h>
Patrick Georgice6e9fe2012-07-20 12:37:06 +020026#include "i945.h"
Stefan Reinauer30140a52009-03-11 16:20:39 +000027
Patrick Georgi6444bd42012-07-06 11:31:39 +020028#define GDRST 0xc0
29
Stefan Reinauer30140a52009-03-11 16:20:39 +000030static void gma_func0_init(struct device *dev)
31{
32 u32 reg32;
33
Patrick Georgi6444bd42012-07-06 11:31:39 +020034 /* Unconditionally reset graphics */
35 pci_write_config8(dev, GDRST, 1);
36 udelay(50);
37 pci_write_config8(dev, GDRST, 0);
38 /* wait for device to finish */
39 while (pci_read_config8(dev, GDRST) & 1) { };
40
Stefan Reinauer30140a52009-03-11 16:20:39 +000041 /* IGD needs to be Bus Master */
42 reg32 = pci_read_config32(dev, PCI_COMMAND);
43 pci_write_config32(dev, PCI_COMMAND, reg32 | PCI_COMMAND_MASTER);
44
45 pci_dev_init(dev);
46}
47
Patrick Georgice6e9fe2012-07-20 12:37:06 +020048/* This doesn't reclaim stolen UMA memory, but IGD could still
49 be reenabled later. */
50static void gma_func0_disable(struct device *dev)
51{
52 struct device *dev_host = dev_find_slot(0, PCI_DEVFN(0x0, 0));
53
54 pci_write_config16(dev, GCFC, 0xa00);
55 pci_write_config16(dev_host, GGC, (1 << 1));
56
57 unsigned int reg32 = pci_read_config32(dev_host, DEVEN);
58 reg32 &= ~(DEVEN_D2F0 | DEVEN_D2F1);
59 pci_write_config32(dev_host, DEVEN, reg32);
60
61 dev->enabled = 0;
62}
63
Stefan Reinauer30140a52009-03-11 16:20:39 +000064static void gma_func1_init(struct device *dev)
65{
66 u32 reg32;
Sven Schnelleb629d142011-06-12 14:30:10 +020067 u8 val;
Stefan Reinauer30140a52009-03-11 16:20:39 +000068
69 /* IGD needs to be Bus Master, also enable IO accesss */
70 reg32 = pci_read_config32(dev, PCI_COMMAND);
Stefan Reinauer109ab312009-08-12 16:08:05 +000071 pci_write_config32(dev, PCI_COMMAND, reg32 |
Stefan Reinauer30140a52009-03-11 16:20:39 +000072 PCI_COMMAND_MASTER | PCI_COMMAND_IO);
Sven Schnelleb629d142011-06-12 14:30:10 +020073
74 if (!get_option(&val, "tft_brightness"))
75 pci_write_config8(dev, 0xf4, val);
76 else
77 pci_write_config8(dev, 0xf4, 0xff);
Stefan Reinauer30140a52009-03-11 16:20:39 +000078}
79
80static void gma_set_subsystem(device_t dev, unsigned vendor, unsigned device)
81{
82 if (!vendor || !device) {
83 pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
84 pci_read_config32(dev, PCI_VENDOR_ID));
85 } else {
86 pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
87 ((device & 0xffff) << 16) | (vendor & 0xffff));
88 }
89}
90
91static struct pci_operations gma_pci_ops = {
92 .set_subsystem = gma_set_subsystem,
93};
94
95static struct device_operations gma_func0_ops = {
96 .read_resources = pci_dev_read_resources,
97 .set_resources = pci_dev_set_resources,
98 .enable_resources = pci_dev_enable_resources,
99 .init = gma_func0_init,
100 .scan_bus = 0,
101 .enable = 0,
Patrick Georgice6e9fe2012-07-20 12:37:06 +0200102 .disable = gma_func0_disable,
Stefan Reinauer30140a52009-03-11 16:20:39 +0000103 .ops_pci = &gma_pci_ops,
104};
105
106
107static struct device_operations gma_func1_ops = {
108 .read_resources = pci_dev_read_resources,
109 .set_resources = pci_dev_set_resources,
110 .enable_resources = pci_dev_enable_resources,
111 .init = gma_func1_init,
112 .scan_bus = 0,
113 .enable = 0,
114 .ops_pci = &gma_pci_ops,
115};
116
117static const struct pci_driver i945_gma_func0_driver __pci_driver = {
118 .ops = &gma_func0_ops,
119 .vendor = PCI_VENDOR_ID_INTEL,
120 .device = 0x27a2,
121};
122
123static const struct pci_driver i945_gma_func1_driver __pci_driver = {
124 .ops = &gma_func1_ops,
125 .vendor = PCI_VENDOR_ID_INTEL,
126 .device = 0x27a6,
127};
128