blob: 4dd6083b1e995756448f78d909bd4c8e059a809a [file] [log] [blame]
zbao246e84b2012-07-13 18:47:03 +08001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2010 Advanced Micro Devices, Inc.
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
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20#include <console/console.h>
21#include <device/device.h>
22#include <device/pci.h>
23#include <device/pnp.h>
24#include <device/pci_ids.h>
25#include <device/pci_ops.h>
26#include <pc80/mc146818rtc.h>
27#include <pc80/isa-dma.h>
28#include <bitops.h>
29#include <arch/io.h>
30#include "hudson.h"
31
32static void lpc_init(device_t dev)
33{
34 u8 byte;
35 u32 dword;
36 device_t sm_dev;
37
38 /* Enable the LPC Controller */
39 sm_dev = dev_find_slot(0, PCI_DEVFN(0x14, 0));
40 dword = pci_read_config32(sm_dev, 0x64);
41 dword |= 1 << 20;
42 pci_write_config32(sm_dev, 0x64, dword);
43
44 /* Initialize isa dma */
45 isa_dma_init();
46
47 /* Enable DMA transaction on the LPC bus */
48 byte = pci_read_config8(dev, 0x40);
49 byte |= (1 << 2);
50 pci_write_config8(dev, 0x40, byte);
51
52 /* Disable the timeout mechanism on LPC */
53 byte = pci_read_config8(dev, 0x48);
54 byte &= ~(1 << 7);
55 pci_write_config8(dev, 0x48, byte);
56
57 /* Disable LPC MSI Capability */
58 byte = pci_read_config8(dev, 0x78);
59 byte &= ~(1 << 1);
60 byte &= ~(1 << 0); /* Keep the old way. i.e., when bus master/DMA cycle is going
61 on on LPC, it holds PCI grant, so no LPC slave cycle can
62 interrupt and visit LPC. */
63 pci_write_config8(dev, 0x78, byte);
64
65 /* bit0: Enable prefetch a cacheline (64 bytes) when Host reads code from SPI rom */
66 /* bit3: Fix SPI_CS# timing issue when running at 66M. TODO:A12. */
67 byte = pci_read_config8(dev, 0xBB);
68 byte |= 1 << 0 | 1 << 3;
69 pci_write_config8(dev, 0xBB, byte);
70}
71
72static void hudson_lpc_read_resources(device_t dev)
73{
74 struct resource *res;
75
76 /* Get the normal pci resources of this device */
77 pci_dev_read_resources(dev); /* We got one for APIC, or one more for TRAP */
78
79 pci_get_resource(dev, 0xA0); /* SPI ROM base address */
80
81 /* Add an extra subtractive resource for both memory and I/O. */
82 res = new_resource(dev, IOINDEX_SUBTRACTIVE(0, 0));
83 res->base = 0;
84 res->size = 0x1000;
85 res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE |
86 IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
87
88 res = new_resource(dev, IOINDEX_SUBTRACTIVE(1, 0));
89 res->base = 0xff800000;
90 res->size = 0x00800000; /* 8 MB for flash */
91 res->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE |
92 IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
93
94 //res = new_resource(dev, 3); /* IOAPIC */
95 //res->base = 0xfec00000;
96 //res->size = 0x00001000;
97 //res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
98
99 compact_resources(dev);
100}
101
102static void hudson_lpc_set_resources(struct device *dev)
103{
104 struct resource *res;
105
106 pci_dev_set_resources(dev);
107
108 /* Specical case. SPI Base Address. The SpiRomEnable should be set. */
109 res = find_resource(dev, 0xA0);
110 pci_write_config32(dev, 0xA0, res->base | 1 << 1);
111
112}
113
114/**
115 * @brief Enable resources for children devices
116 *
117 * @param dev the device whos children's resources are to be enabled
118 *
119 */
120static void hudson_lpc_enable_childrens_resources(device_t dev)
121{
122 printk(BIOS_DEBUG, "hudson_lpc_enable_childrens_resources\n");
123
124}
125
126static void hudson_lpc_enable_resources(device_t dev)
127{
128 pci_dev_enable_resources(dev);
129 hudson_lpc_enable_childrens_resources(dev);
130}
131
132static struct pci_operations lops_pci = {
133 .set_subsystem = pci_dev_set_subsystem,
134};
135
136static struct device_operations lpc_ops = {
137 .read_resources = hudson_lpc_read_resources,
138 .set_resources = hudson_lpc_set_resources,
139 .enable_resources = hudson_lpc_enable_resources,
140 .init = lpc_init,
141 .scan_bus = scan_static_bus,
142 .ops_pci = &lops_pci,
143};
144static const struct pci_driver lpc_driver __pci_driver = {
145 .ops = &lpc_ops,
146 .vendor = PCI_VENDOR_ID_AMD,
147 .device = PCI_DEVICE_ID_ATI_SB900_LPC,
148};