83887b21993255b9a082cbd65f84f5afe7f0b350
[coreboot.git] / src / southbridge / amd / amd8111 / amd8111_lpc.c
1 /*
2  * (C) 2003 Linux Networx, SuSE Linux AG
3  *  2006.1 yhlu add dest apicid for IRQ0
4  */
5 #include <console/console.h>
6 #include <device/device.h>
7 #include <device/pci.h>
8 #include <device/pci_ids.h>
9 #include <device/pci_ops.h>
10 #include <pc80/mc146818rtc.h>
11 #include <pc80/isa-dma.h>
12 #include <cpu/x86/lapic.h>
13 #include <arch/ioapic.h>
14 #include <stdlib.h>
15 #include "amd8111.h"
16
17 #define NMI_OFF 0
18
19 static void enable_hpet(struct device *dev)
20 {
21         unsigned long hpet_address;
22
23         pci_write_config32(dev,0xa0, 0xfed00001);
24         hpet_address = pci_read_config32(dev,0xa0)& 0xfffffffe;
25         printk(BIOS_DEBUG, "enabling HPET @0x%lx\n", hpet_address);
26
27 }
28
29 static void lpc_init(struct device *dev)
30 {
31         uint8_t byte;
32         int nmi_option;
33
34         /* IO APIC initialization */
35         byte = pci_read_config8(dev, 0x4B);
36         byte |= 1;
37         pci_write_config8(dev, 0x4B, byte);
38         /* Don't rename IO APIC */
39         setup_ioapic(IO_APIC_ADDR, 0);
40
41         /* posted memory write enable */
42         byte = pci_read_config8(dev, 0x46);
43         pci_write_config8(dev, 0x46, byte | (1<<0));
44
45         /* Enable 5Mib Rom window */
46         byte = pci_read_config8(dev, 0x43);
47         byte |= 0xc0;
48         pci_write_config8(dev, 0x43, byte);
49
50         /* Enable Port 92 fast reset */
51         byte = pci_read_config8(dev, 0x41);
52         byte |= (1 << 5);
53         pci_write_config8(dev, 0x41, byte);
54
55         /* Enable Error reporting */
56         /* Set up sync flood detected */
57         byte = pci_read_config8(dev, 0x47);
58         byte |= (1 << 1);
59         pci_write_config8(dev, 0x47, byte);
60
61         /* Set up NMI on errors */
62         byte = pci_read_config8(dev, 0x40);
63         byte |= (1 << 1); /* clear PW2LPC error */
64         byte |= (1 << 6); /* clear LPCERR */
65         pci_write_config8(dev, 0x40, byte);
66         nmi_option = NMI_OFF;
67         get_option(&nmi_option, "nmi");
68         if (nmi_option) {
69                 byte |= (1 << 7); /* set NMI */
70                 pci_write_config8(dev, 0x40, byte);
71         }
72
73         /* Initialize the real time clock */
74         rtc_init(0);
75
76         /* Initialize isa dma */
77         isa_dma_init();
78
79         /* Initialize the High Precision Event Timers */
80         enable_hpet(dev);
81 }
82
83 static void amd8111_lpc_read_resources(device_t dev)
84 {
85         struct resource *res;
86
87         /* Get the normal PCI resources of this device. */
88         pci_dev_read_resources(dev);
89
90         /* Add an extra subtractive resource for both memory and I/O. */
91         res = new_resource(dev, IOINDEX_SUBTRACTIVE(0, 0));
92         res->base = 0;
93         res->size = 0x1000;
94         res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE |
95                      IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
96
97         res = new_resource(dev, IOINDEX_SUBTRACTIVE(1, 0));
98         res->base = 0xff800000;
99         res->size = 0x00800000; /* 8 MB for flash */
100         res->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE |
101                      IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
102
103         res = new_resource(dev, 3); /* IOAPIC */
104         res->base = 0xfec00000;
105         res->size = 0x00001000;
106         res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
107 }
108
109 static void lpci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
110 {
111         pci_write_config32(dev, 0x70,
112                            ((device & 0xffff) << 16) | (vendor & 0xffff));
113 }
114
115 static struct pci_operations lops_pci = {
116         .set_subsystem = lpci_set_subsystem,
117 };
118
119 static struct device_operations lpc_ops  = {
120         .read_resources   = amd8111_lpc_read_resources,
121         .set_resources    = pci_dev_set_resources,
122         .enable_resources = pci_dev_enable_resources,
123         .init             = lpc_init,
124         .scan_bus         = scan_static_bus,
125         .enable           = amd8111_enable,
126         .ops_pci          = &lops_pci,
127 };
128
129 static const struct pci_driver lpc_driver __pci_driver = {
130         .ops    = &lpc_ops,
131         .vendor = PCI_VENDOR_ID_AMD,
132         .device = PCI_DEVICE_ID_AMD_8111_ISA,
133 };