blob: 0d14ff47cea91ecbb58b681e7ba067e67802fcc1 [file] [log] [blame]
Stefan Reinauerdebb11f2008-10-29 04:46:52 +00001/*
2 * This file is part of the coreboot project.
3 *
Stefan Reinauer54309d62009-01-20 22:53:10 +00004 * Copyright (C) 2008-2009 coresystems GmbH
Stefan Reinauerdebb11f2008-10-29 04:46:52 +00005 *
Stefan Reinauera8e11682009-03-11 14:54:18 +00006 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; version 2 of
9 * the License.
Stefan Reinauerdebb11f2008-10-29 04:46:52 +000010 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
Stefan Reinauerdebb11f2008-10-29 04:46:52 +000015 */
16
17#include <console/console.h>
18#include <device/device.h>
19#include <device/pci.h>
20#include <device/pci_ids.h>
21
22static void pci_init(struct device *dev)
23{
24 u16 reg16;
25 u32 reg32;
26
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +000027 printk(BIOS_DEBUG, "Initializing ICH7 PCIe bridge.\n");
Stefan Reinauer109ab312009-08-12 16:08:05 +000028
Stefan Reinauera8e11682009-03-11 14:54:18 +000029 /* Enable Bus Master */
30 reg32 = pci_read_config32(dev, PCI_COMMAND);
31 reg32 |= PCI_COMMAND_MASTER;
32 pci_write_config32(dev, PCI_COMMAND, reg32);
Stefan Reinauerdebb11f2008-10-29 04:46:52 +000033
Stefan Reinauera8e11682009-03-11 14:54:18 +000034 /* Set Cache Line Size to 0x10 */
35 // This has no effect but the OS might expect it
36 pci_write_config8(dev, 0x0c, 0x10);
Stefan Reinauerdebb11f2008-10-29 04:46:52 +000037
Stefan Reinauerdebb11f2008-10-29 04:46:52 +000038 reg16 = pci_read_config16(dev, 0x3e);
Stefan Reinauera8e11682009-03-11 14:54:18 +000039 reg16 &= ~(1 << 0); /* disable parity error response */
40 // reg16 &= ~(1 << 1); /* disable SERR */
41 reg16 |= (1 << 2); /* ISA enable */
Stefan Reinauerdebb11f2008-10-29 04:46:52 +000042 pci_write_config16(dev, 0x3e, reg16);
43
Stefan Reinauera8e11682009-03-11 14:54:18 +000044 /* Enable IO xAPIC on this PCIe port */
45 reg32 = pci_read_config32(dev, 0xd8);
46 reg32 |= (1 << 7);
47 pci_write_config32(dev, 0xd8, reg32);
Stefan Reinauerdebb11f2008-10-29 04:46:52 +000048
Stefan Reinauera8e11682009-03-11 14:54:18 +000049 /* Enable Backbone Clock Gating */
50 reg32 = pci_read_config32(dev, 0xe1);
51 reg32 |= (1 << 3) | (1 << 2) | (1 << 1) | (1 << 0);
52 pci_write_config32(dev, 0xe1, reg32);
Stefan Reinauerdebb11f2008-10-29 04:46:52 +000053
Stefan Reinauera8e11682009-03-11 14:54:18 +000054 /* Set VC0 transaction class */
Kyösti Mälkki8aa7e832013-07-26 08:52:10 +030055 reg32 = pci_read_config32(dev, 0x114);
Stefan Reinauera8e11682009-03-11 14:54:18 +000056 reg32 &= 0xffffff00;
57 reg32 |= 1;
Kyösti Mälkki8aa7e832013-07-26 08:52:10 +030058 pci_write_config32(dev, 0x114, reg32);
Stefan Reinauera8e11682009-03-11 14:54:18 +000059
60 /* Mask completion timeouts */
Kyösti Mälkki8aa7e832013-07-26 08:52:10 +030061 reg32 = pci_read_config32(dev, 0x148);
Stefan Reinauera8e11682009-03-11 14:54:18 +000062 reg32 |= (1 << 14);
Kyösti Mälkki8aa7e832013-07-26 08:52:10 +030063 pci_write_config32(dev, 0x148, reg32);
64
Stefan Reinauera8e11682009-03-11 14:54:18 +000065 /* Enable common clock configuration */
66 // Are there cases when we don't want that?
67 reg16 = pci_read_config16(dev, 0x50);
68 reg16 |= (1 << 6);
69 pci_write_config16(dev, 0x50, reg16);
70
Stefan Reinauerde3206a2010-02-22 06:09:43 +000071#ifdef EVEN_MORE_DEBUG
Stefan Reinauerdebb11f2008-10-29 04:46:52 +000072 reg32 = pci_read_config32(dev, 0x20);
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +000073 printk(BIOS_SPEW, " MBL = 0x%08x\n", reg32);
Stefan Reinauerdebb11f2008-10-29 04:46:52 +000074 reg32 = pci_read_config32(dev, 0x24);
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +000075 printk(BIOS_SPEW, " PMBL = 0x%08x\n", reg32);
Stefan Reinauerdebb11f2008-10-29 04:46:52 +000076 reg32 = pci_read_config32(dev, 0x28);
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +000077 printk(BIOS_SPEW, " PMBU32 = 0x%08x\n", reg32);
Stefan Reinauerdebb11f2008-10-29 04:46:52 +000078 reg32 = pci_read_config32(dev, 0x2c);
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +000079 printk(BIOS_SPEW, " PMLU32 = 0x%08x\n", reg32);
Stefan Reinauera8e11682009-03-11 14:54:18 +000080#endif
81
82 /* Clear errors in status registers */
83 reg16 = pci_read_config16(dev, 0x06);
84 //reg16 |= 0xf900;
85 pci_write_config16(dev, 0x06, reg16);
86
87 reg16 = pci_read_config16(dev, 0x1e);
88 //reg16 |= 0xf900;
89 pci_write_config16(dev, 0x1e, reg16);
Stefan Reinauerdebb11f2008-10-29 04:46:52 +000090}
91
Arthur Heymans3f111b02017-03-09 12:02:52 +010092static void pcie_set_subsystem(device_t dev, unsigned int vendor,
93 unsigned int device)
Stefan Reinauerdebb11f2008-10-29 04:46:52 +000094{
Stefan Reinauera8e11682009-03-11 14:54:18 +000095 /* NOTE: This is not the default position! */
96 if (!vendor || !device) {
97 pci_write_config32(dev, 0x94,
98 pci_read_config32(dev, 0));
99 } else {
100 pci_write_config32(dev, 0x94,
101 ((device & 0xffff) << 16) | (vendor & 0xffff));
102 }
Stefan Reinauerdebb11f2008-10-29 04:46:52 +0000103}
104
105static struct pci_operations pci_ops = {
Stefan Reinauera8e11682009-03-11 14:54:18 +0000106 .set_subsystem = pcie_set_subsystem,
Stefan Reinauerdebb11f2008-10-29 04:46:52 +0000107};
108
109static struct device_operations device_ops = {
110 .read_resources = pci_bus_read_resources,
111 .set_resources = pci_dev_set_resources,
112 .enable_resources = pci_bus_enable_resources,
113 .init = pci_init,
114 .scan_bus = pci_scan_bridge,
115 .ops_pci = &pci_ops,
116};
117
Patrick Georgiefff7332012-07-26 19:48:23 +0200118static const unsigned short i82801gx_pcie_ids[] = {
119 0x27d0, /* 82801GB/GR/GDH/GBM/GHM (ICH7/ICH7R/ICH7DH/ICH7-M/ICH7-M DH) */
120 0x27d2, /* 82801GB/GR/GDH/GBM/GHM (ICH7/ICH7R/ICH7DH/ICH7-M/ICH7-M DH) */
121 0x27d4, /* 82801GB/GR/GDH/GBM/GHM (ICH7/ICH7R/ICH7DH/ICH7-M/ICH7-M DH) */
122 0x27d6, /* 82801GB/GR/GDH/GBM/GHM (ICH7/ICH7R/ICH7DH/ICH7-M/ICH7-M DH) */
123 0x27e0, /* 82801GR/GDH/GHM (ICH7R/ICH7DH/ICH7-M DH) */
124 0x27e2, /* 82801GR/GDH/GHM (ICH7R/ICH7DH/ICH7-M DH) */
125 0
Stefan Reinauerdebb11f2008-10-29 04:46:52 +0000126};
127
Patrick Georgiefff7332012-07-26 19:48:23 +0200128static const struct pci_driver i82801gx_pcie __pci_driver = {
Arthur Heymans3f111b02017-03-09 12:02:52 +0100129 .ops = &device_ops,
130 .vendor = PCI_VENDOR_ID_INTEL,
131 .devices = i82801gx_pcie_ids,
Stefan Reinauerdebb11f2008-10-29 04:46:52 +0000132};