2 * (C) 2003 Linux Networx, SuSE Linux AG
3 * Copyright 2004 Tyan Computer
5 * 2006.1 yhlu add dest apicid for IRQ0
7 #include <console/console.h>
8 #include <device/device.h>
9 #include <device/pci.h>
10 #include <device/pnp.h>
11 #include <device/pci_ids.h>
12 #include <device/pci_ops.h>
13 #include <pc80/mc146818rtc.h>
14 #include <pc80/isa-dma.h>
17 #include <cpu/x86/lapic.h>
20 #define CK804_CHIP_REV 2
26 unsigned int value_low, value_high;
29 static struct ioapicreg ioapicregvalues[] = {
30 #define ALL (0xff << 24)
32 #define DISABLED (1 << 16)
33 #define ENABLED (0 << 16)
34 #define TRIGGER_EDGE (0 << 15)
35 #define TRIGGER_LEVEL (1 << 15)
36 #define POLARITY_HIGH (0 << 13)
37 #define POLARITY_LOW (1 << 13)
38 #define PHYSICAL_DEST (0 << 11)
39 #define LOGICAL_DEST (1 << 11)
40 #define ExtINT (7 << 8)
44 /* IO-APIC virtual wire mode configuration */
45 /* mask, trigger, polarity, destination, delivery, vector */
46 { 0, ENABLED | TRIGGER_EDGE | POLARITY_HIGH | PHYSICAL_DEST | ExtINT, NONE},
56 { 10, DISABLED, NONE},
57 { 11, DISABLED, NONE},
58 { 12, DISABLED, NONE},
59 { 13, DISABLED, NONE},
60 { 14, DISABLED, NONE},
61 { 15, DISABLED, NONE},
62 { 16, DISABLED, NONE},
63 { 17, DISABLED, NONE},
64 { 18, DISABLED, NONE},
65 { 19, DISABLED, NONE},
66 { 20, DISABLED, NONE},
67 { 21, DISABLED, NONE},
68 { 22, DISABLED, NONE},
69 { 23, DISABLED, NONE},
70 /* Be careful and don't write past the end... */
73 static void setup_ioapic(unsigned long ioapic_base)
76 unsigned long value_low, value_high;
77 // unsigned long ioapic_base = 0xfec00000;
78 volatile unsigned long *l;
79 struct ioapicreg *a = ioapicregvalues;
81 ioapicregvalues[0].value_high = lapicid()<<(56-32);
83 l = (unsigned long *) ioapic_base;
85 for (i = 0; i < sizeof(ioapicregvalues) / sizeof(ioapicregvalues[0]);
87 l[0] = (a->reg * 2) + 0x10;
90 l[0] = (a->reg *2) + 0x11;
93 if ((i==0) && (value_low == 0xffffffff)) {
94 printk_warning("IO APIC not responding.\n");
97 printk_spew("for IRQ, reg 0x%08x value 0x%08x 0x%08x\n",
98 a->reg, a->value_low, a->value_high);
103 #define PREVIOUS_POWER_STATE 0x7A
105 #define MAINBOARD_POWER_OFF 0
106 #define MAINBOARD_POWER_ON 1
107 #define SLOW_CPU_OFF 0
108 #define SLOW_CPU__ON 1
110 #ifndef MAINBOARD_POWER_ON_AFTER_POWER_FAIL
111 #define MAINBOARD_POWER_ON_AFTER_POWER_FAIL MAINBOARD_POWER_ON
114 static void lpc_common_init(device_t dev)
119 /* IO APIC initialization */
120 byte = pci_read_config8(dev, 0x74);
121 byte |= (1<<0); // enable APIC
122 pci_write_config8(dev, 0x74, byte);
123 dword = pci_read_config32(dev, PCI_BASE_ADDRESS_1); // 0x14
128 dword = pci_read_config32(dev, 0xe4);
130 pci_write_config32(dev, 0xe4, dword);
135 static void lpc_slave_init(device_t dev)
137 lpc_common_init(dev);
140 static void rom_dummy_write(device_t dev){
144 old = pci_read_config8(dev, 0x88);
147 pci_write_config8(dev, 0x88, new);
150 old = pci_read_config8(dev, 0x6d);
153 pci_write_config8(dev, 0x6d, new);
157 p = (uint8_t *)0xffffffe0;
163 old = pci_read_config8(dev, 0x6d);
166 pci_write_config8(dev, 0x6d, new);
172 static void enable_hpet(struct device *dev)
174 unsigned long hpet_address;
176 pci_write_config32(dev,0x44, 0xfed00001);
177 hpet_address=pci_read_config32(dev,0x44)& 0xfffffffe;
178 printk_debug("enabling HPET @0x%x\n", hpet_address);
182 static void lpc_init(device_t dev)
189 lpc_common_init(dev);
191 #if CK804_CHIP_REV==1
192 if(dev->bus->secondary!=1) return;
196 /* posted memory write enable */
197 byte = pci_read_config8(dev, 0x46);
198 pci_write_config8(dev, 0x46, byte | (1<<0));
201 /* power after power fail */
203 on = MAINBOARD_POWER_ON_AFTER_POWER_FAIL;
204 get_option(&on, "power_on_after_fail");
205 byte = pci_read_config8(dev, PREVIOUS_POWER_STATE);
210 pci_write_config8(dev, PREVIOUS_POWER_STATE, byte);
211 printk_info("set power %s after power fail\n", on?"on":"off");
213 /* Throttle the CPU speed down for testing */
215 get_option(&on, "slow_cpu");
219 pm10_bar = (pci_read_config16(dev, 0x60)&0xff00);
220 outl(((on<<1)+0x10) ,(pm10_bar + 0x10));
221 dword = inl(pm10_bar + 0x10);
223 printk_debug("Throttling CPU %2d.%1.1d percent.\n",
224 (on*12)+(on>>1),(on&1)*5);
228 // default is enabled
229 /* Enable Port 92 fast reset */
230 byte = pci_read_config8(dev, 0xe8);
232 pci_write_config8(dev, 0xe8, byte);
235 /* Enable Error reporting */
236 /* Set up sync flood detected */
237 byte = pci_read_config8(dev, 0x47);
239 pci_write_config8(dev, 0x47, byte);
241 /* Set up NMI on errors */
242 byte = inb(0x70); // RTC70
244 nmi_option = NMI_OFF;
245 get_option(&nmi_option, "nmi");
247 byte &= ~(1 << 7); /* set NMI */
249 byte |= ( 1 << 7); // Can not mask NMI from PCI-E and NMI_NOW
251 if( byte != byte_old) {
255 /* Initialize the real time clock */
258 /* Initialize isa dma */
261 /* Initialize the High Precision Event Timers */
264 rom_dummy_write(dev);
268 static void ck804_lpc_read_resources(device_t dev)
270 struct resource *res;
273 /* Get the normal pci resources of this device */
274 pci_dev_read_resources(dev); // We got one for APIC, or one more for TRAP
276 /* Get Resource for ACPI, SYSTEM_CONTROL, ANALOG_CONTROL */
277 for (index = 0x60; index <= 0x68; index+=4) { // We got another 3.
278 pci_get_resource(dev, index);
280 compact_resources(dev);
282 /* Add an extra subtractive resource for both memory and I/O */
283 res = new_resource(dev, IOINDEX_SUBTRACTIVE(0, 0));
284 res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED;
286 res = new_resource(dev, IOINDEX_SUBTRACTIVE(1, 0));
287 res->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED;
292 * @brief Enable resources for children devices
294 * @param dev the device whos children's resources are to be enabled
296 * This function is call by the global enable_resources() indirectly via the
297 * device_operation::enable_resources() method of devices.
299 * Indirect mutual recursion:
300 * enable_childrens_resources() -> enable_resources()
301 * enable_resources() -> device_operation::enable_resources()
302 * device_operation::enable_resources() -> enable_children_resources()
304 static void ck804_lpc_enable_childrens_resources(device_t dev)
307 uint32_t reg, reg_var[4];
311 reg = pci_read_config32(dev, 0xa0);
313 for (link = 0; link < dev->links; link++) {
315 for (child = dev->link[link].children; child; child = child->sibling) {
316 enable_resources(child);
317 if(child->have_resources && (child->path.type == DEVICE_PATH_PNP)) {
318 for(i=0;i<child->resources;i++) {
319 struct resource *res;
320 unsigned long base, end; // don't need long long
321 res = &child->resource[i];
322 if(!(res->flags & IORESOURCE_IO)) continue;
324 end = resource_end(res);
325 printk_debug("ck804 lpc decode:%s, base=0x%08x, end=0x%08x\r\n",dev_path(child),base, end);
328 reg |= (1<<0); break;
330 reg |= (1<<1); break;
331 case 0x378: // Parallal 1
332 reg |= (1<<24); break;
334 reg |= (1<<20); break;
335 case 0x220: // Aduio 0
336 reg |= (1<<8); break;
337 case 0x300: // Midi 0
338 reg |= (1<<12); break;
340 if( base == 0x290 || base >= 0x400) {
341 if(var_num>=4) continue; // only 4 var ; compact them ?
342 reg |= (1<<(28+var_num));
343 reg_var[var_num++] = (base & 0xffff)|((end & 0xffff)<<16);
349 pci_write_config32(dev, 0xa0, reg);
350 for(i=0;i<var_num;i++) {
351 pci_write_config32(dev, 0xa8 + i*4, reg_var[i]);
357 static void ck804_lpc_enable_resources(device_t dev)
359 pci_dev_enable_resources(dev);
360 ck804_lpc_enable_childrens_resources(dev);
363 static void lpci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
365 pci_write_config32(dev, 0x40,
366 ((device & 0xffff) << 16) | (vendor & 0xffff));
369 static struct pci_operations lops_pci = {
370 .set_subsystem = lpci_set_subsystem,
373 static struct device_operations lpc_ops = {
374 .read_resources = ck804_lpc_read_resources,
375 .set_resources = pci_dev_set_resources,
376 .enable_resources = ck804_lpc_enable_resources,
378 .scan_bus = scan_static_bus,
379 // .enable = ck804_enable,
380 .ops_pci = &lops_pci,
382 static struct pci_driver lpc_driver __pci_driver = {
384 .vendor = PCI_VENDOR_ID_NVIDIA,
385 .device = PCI_DEVICE_ID_NVIDIA_CK804_LPC,
388 static struct pci_driver lpc_driver_pro __pci_driver = {
390 .vendor = PCI_VENDOR_ID_NVIDIA,
391 .device = PCI_DEVICE_ID_NVIDIA_CK804_PRO,
394 #if CK804_CHIP_REV == 1
395 static struct pci_driver lpc_driver_slave __pci_driver = {
397 .vendor = PCI_VENDOR_ID_NVIDIA,
398 .device = PCI_DEVICE_ID_NVIDIA_CK804_SLAVE,
401 static struct device_operations lpc_slave_ops = {
402 .read_resources = ck804_lpc_read_resources,
403 .set_resources = pci_dev_set_resources,
404 .enable_resources = pci_dev_enable_resources,
405 .init = lpc_slave_init,
406 // .enable = ck804_enable,
407 .ops_pci = &lops_pci,
410 static struct pci_driver lpc_driver_slave __pci_driver = {
411 .ops = &lpc_slave_ops,
412 .vendor = PCI_VENDOR_ID_NVIDIA,
413 .device = PCI_DEVICE_ID_NVIDIA_CK804_SLAVE,