blob: 3325a743c8a2318d35620e4fc3d9c618f047990f [file] [log] [blame]
Ronald G. Minnich182615d2004-08-24 16:20:46 +00001/*
2 * (C) 2003 Linux Networx, SuSE Linux AG
3 * (C) 2004 Tyan Computer
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>
Ronald G. Minnich182615d2004-08-24 16:20:46 +000010#include <pc80/mc146818rtc.h>
11#include "i82801dbm.h"
12
13void isa_dma_init(void); /* from /pc80/isa-dma.c */
14
15#define NMI_OFF 0
16
17void i82801dbm_enable_ioapic( struct device *dev)
18{
19 uint32_t dword;
20 volatile uint32_t *ioapic_sba = (volatile uint32_t *)0xfec00000;
21 volatile uint32_t *ioapic_sbd = (volatile uint32_t *)0xfec00010;
22
23 dword = pci_read_config32(dev, GEN_CNTL);
24 dword |= (3 << 7); /* enable ioapic */
25 dword |= (1 <<13); /* coprocessor error enable */
26 dword |= (1 << 1); /* delay transaction enable */
27 dword |= (1 << 2); /* DMA collection buf enable */
28 pci_write_config32(dev, GEN_CNTL, dword);
29 printk_debug("ioapic southbridge enabled %x\n",dword);
30 *ioapic_sba=0;
31 *ioapic_sbd=(2<<24);
32 //lyh *ioapic_sba=3;
33 //lyh *ioapic_sbd=1;
34 *ioapic_sba=0;
35 dword=*ioapic_sbd;
36 printk_debug("Southbridge apic id = %x\n",dword);
37 if(dword!=(2<<24))
38 for(;;);
39 //lyh *ioapic_sba=3;
40 //lyh dword=*ioapic_sbd;
41 //lyh printk_debug("Southbridge apic DT = %x\n",dword);
42 //lyh if(dword!=1)
43 //lyh for(;;);
44
45
46}
47void i82801dbm_enable_serial_irqs( struct device *dev)
48{
49 pci_write_config8(dev, SERIRQ_CNTL, (1 << 7)|(1 << 6)|((21 - 17) << 2)|(0<< 0));
50}
51void i82801dbm_lpc_route_dma( struct device *dev, uint8_t mask)
52{
53 uint16_t word;
54 int i;
55 word = pci_read_config8(dev, PCI_DMA_CFG);
56 word &= ((1 << 10) - (1 << 8));
57 for(i = 0; i < 8; i++) {
58 if (i == 4)
59 continue;
60 word |= ((mask & (1 << i))? 3:1) << (i*2);
61 }
62 pci_write_config16(dev, PCI_DMA_CFG, word);
63}
64void i82801dbm_rtc_init(struct device *dev)
65{
66 uint8_t byte;
67 uint32_t dword;
68 int rtc_failed;
69 byte = pci_read_config8(dev, GEN_PMCON_3);
70 rtc_failed = byte & RTC_FAILED;
71 if (rtc_failed) {
72 byte &= ~(1 << 1); /* preserve the power fail state */
73 pci_write_config8(dev, GEN_PMCON_3, byte);
74 }
75 dword = pci_read_config32(dev, GEN_STS);
76 rtc_failed |= dword & (1 << 2);
77 rtc_init(rtc_failed);
78}
79
80
81void i82801dbm_1f0_misc(struct device *dev)
82{
83 pci_write_config16(dev, PCICMD, 0x014f);
84 pci_write_config32(dev, PMBASE, 0x00001001);
85 pci_write_config8(dev, ACPI_CNTL, 0x10);
86 pci_write_config32(dev, GPIO_BASE, 0x00001181);
87 pci_write_config8(dev, GPIO_CNTL, 0x10);
88 pci_write_config32(dev, PIRQA_ROUT, 0x0A05030B);
89 pci_write_config8(dev, PIRQE_ROUT, 0x07);
90 pci_write_config8(dev, RTC_CONF, 0x04);
91 pci_write_config8(dev, COM_DEC, 0x10); //lyh E0->
92 pci_write_config16(dev, LPC_EN, 0x000F); //LYH 000D->
93}
94
95static void enable_hpet(struct device *dev)
96{
97 const unsigned long hpet_address = 0xfed0000;
98
99 uint32_t dword;
100 uint32_t code = (0 & 0x3);
101
102 dword = pci_read_config32(dev, GEN_CNTL);
103 dword |= (1 << 17); /* enable hpet */
104 /*Bits [16:15]Memory Address Range
105 00 FED0_0000h - FED0_03FFh
106 01 FED0_1000h - FED0_13FFh
107 10 FED0_2000h - FED0_23FFh
108 11 FED0_3000h - FED0_33FFh*/
109
110 dword &= ~(3 << 15); /* clear it */
111 dword |= (code<<15);
112
113 printk_debug("enabling HPET @0x%x\n", hpet_address | (code <<12) );
114}
115
116static void lpc_init(struct device *dev)
117{
118 uint8_t byte;
119 int pwr_on=-1;
120 int nmi_option;
121
122 /* IO APIC initialization */
123 i82801dbm_enable_ioapic(dev);
124
125 i82801dbm_enable_serial_irqs(dev);
126
127 /* posted memory write enable */
128 byte = pci_read_config8(dev, 0x46);
129 pci_write_config8(dev, 0x46, byte | (1<<0));
130
131 /* power after power fail */
132 /* FIXME this doesn't work! */
133 /* Which state do we want to goto after g3 (power restored)?
134 * 0 == S0 Full On
135 * 1 == S5 Soft Off
136 */
137 pci_write_config8(dev, GEN_PMCON_3, pwr_on?0:1);
138 printk_info("set power %s after power fail\n", pwr_on?"on":"off");
139#if 0
140 /* Enable Error reporting */
141 /* Set up sync flood detected */
142 byte = pci_read_config8(dev, 0x47);
143 byte |= (1 << 1);
144 pci_write_config8(dev, 0x47, byte);
145#endif
146
147 /* Set up NMI on errors */
148 byte = pci_read_config8(dev, 0x61);
149 byte |= (1 << 3); /* IOCHK# NMI Enable */
150 byte |= (1 << 6); /* PCI SERR# Enable */
151 pci_write_config8(dev, 0x61, byte);
152 byte = pci_read_config8(dev, 0x70);
153 nmi_option = NMI_OFF;
154 get_option(&nmi_option, "nmi");
155 if (nmi_option) {
156 byte |= (1 << 7); /* set NMI */
157 pci_write_config8(dev, 0x70, byte);
158 }
159
160 /* Initialize the real time clock */
161 i82801dbm_rtc_init(dev);
162
163 i82801dbm_lpc_route_dma(dev, 0xff);
164
165 /* Initialize isa dma */
166 isa_dma_init();
167
168 i82801dbm_1f0_misc(dev);
169 /* Initialize the High Precision Event Timers */
170 enable_hpet(dev);
171}
172
173static void i82801dbm_lpc_read_resources(device_t dev)
174{
Eric Biederman4f9265f2004-10-22 02:33:51 +0000175 struct resource *res;
Ronald G. Minnich182615d2004-08-24 16:20:46 +0000176
177 /* Get the normal pci resources of this device */
178 pci_dev_read_resources(dev);
179
Ronald G. Minnich182615d2004-08-24 16:20:46 +0000180 /* Add an extra subtractive resource for both memory and I/O */
Eric Biederman4f9265f2004-10-22 02:33:51 +0000181 res = new_resource(dev, IOINDEX_SUBTRACTIVE(0, 0));
182 res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED;
183
184 res = new_resource(dev, IOINDEX_SUBTRACTIVE(1, 0));
185 res->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED;
186}
187
188static void i82801dbm_lpc_enable_resources(device_t dev)
189{
190 pci_dev_enable_resources(dev);
191 enable_childrens_resources(dev);
Ronald G. Minnich182615d2004-08-24 16:20:46 +0000192}
193
194static struct device_operations lpc_ops = {
195 .read_resources = i82801dbm_lpc_read_resources,
196 .set_resources = pci_dev_set_resources,
Eric Biederman4f9265f2004-10-22 02:33:51 +0000197 .enable_resources = i82801dbm_lpc_enable_resources,
Ronald G. Minnich182615d2004-08-24 16:20:46 +0000198 .init = lpc_init,
199 .scan_bus = scan_static_bus,
200 .enable = i82801dbm_enable,
201};
202
203static struct pci_driver lpc_driver __pci_driver = {
204 .ops = &lpc_ops,
205 .vendor = PCI_VENDOR_ID_INTEL,
Ronald G. Minniche6552bc2004-08-25 15:40:47 +0000206 .device = PCI_DEVICE_ID_INTEL_82801DBM_1F0,
Ronald G. Minnich182615d2004-08-24 16:20:46 +0000207};