Bari Ari | 612163e3 | 2009-05-27 13:12:42 +0000 | [diff] [blame] | 1 | /* |
| 2 | * This file is part of the coreboot project. |
| 3 | * |
| 4 | * Copyright (C) 2009 One Laptop per Child, Association, 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. |
Bari Ari | 612163e3 | 2009-05-27 13:12:42 +0000 | [diff] [blame] | 14 | */ |
| 15 | |
| 16 | #include <arch/io.h> |
| 17 | #include <console/console.h> |
| 18 | #include <device/device.h> |
| 19 | #include <device/pci.h> |
| 20 | #include <device/pci_ops.h> |
| 21 | #include <device/pci_ids.h> |
| 22 | |
| 23 | #include <pc80/mc146818rtc.h> |
| 24 | #include <pc80/keyboard.h> |
| 25 | #include <pc80/i8259.h> |
| 26 | #include "vx800.h" |
Bari Ari | 612163e3 | 2009-05-27 13:12:42 +0000 | [diff] [blame] | 27 | |
Uwe Hermann | 7365004 | 2009-05-27 18:55:19 +0000 | [diff] [blame] | 28 | static const unsigned char pciIrqs[4] = { 0xa, 0x9, 0xb, 0xa }; |
Bari Ari | 612163e3 | 2009-05-27 13:12:42 +0000 | [diff] [blame] | 29 | |
Uwe Hermann | 7365004 | 2009-05-27 18:55:19 +0000 | [diff] [blame] | 30 | static const unsigned char vgaPins[4] = { 'A', 'B', 'C', 'D' }; //only INTA |
Bari Ari | 612163e3 | 2009-05-27 13:12:42 +0000 | [diff] [blame] | 31 | |
Uwe Hermann | 7365004 | 2009-05-27 18:55:19 +0000 | [diff] [blame] | 32 | static const unsigned char slotPins[4] = { 'A', 'A', 'A', 'A' }; //all 4 |
Bari Ari | 612163e3 | 2009-05-27 13:12:42 +0000 | [diff] [blame] | 33 | |
Uwe Hermann | 7365004 | 2009-05-27 18:55:19 +0000 | [diff] [blame] | 34 | static const unsigned char usbdevicePins[4] = { 'A', 'B', 'C', 'D' }; //only INTA |
| 35 | static const unsigned char sdioPins[4] = { 'A', 'B', 'C', 'D' }; //only INTA |
| 36 | static const unsigned char sd_ms_ctrl_Pins[4] = { 'B', 'C', 'D', 'A' }; //only INTA |
| 37 | static const unsigned char ce_ata_nf_ctrl_Pins[4] = { 'C', 'C', 'D', 'A' }; //only INTA |
Bari Ari | 612163e3 | 2009-05-27 13:12:42 +0000 | [diff] [blame] | 38 | |
Stefan Reinauer | 14e2277 | 2010-04-27 06:56:47 +0000 | [diff] [blame] | 39 | static const unsigned char hdacaudioPins[4] = { 'B', 'C', 'D', 'A' }; //only INTA |
Bari Ari | 612163e3 | 2009-05-27 13:12:42 +0000 | [diff] [blame] | 40 | |
| 41 | static unsigned char *pin_to_irq(const unsigned char *pin) |
| 42 | { |
| 43 | static unsigned char Irqs[4]; |
| 44 | int i; |
Uwe Hermann | 7365004 | 2009-05-27 18:55:19 +0000 | [diff] [blame] | 45 | for (i = 0; i < 4; i++) |
| 46 | Irqs[i] = pciIrqs[pin[i] - 'A']; |
Bari Ari | 612163e3 | 2009-05-27 13:12:42 +0000 | [diff] [blame] | 47 | |
| 48 | return Irqs; |
| 49 | } |
| 50 | |
| 51 | static void pci_routing_fixup(struct device *dev) |
| 52 | { |
Stefan Reinauer | c02b4fc | 2010-03-22 11:42:32 +0000 | [diff] [blame] | 53 | printk(BIOS_INFO, "%s: dev is %p\n", __FUNCTION__, dev); |
Bari Ari | 612163e3 | 2009-05-27 13:12:42 +0000 | [diff] [blame] | 54 | |
| 55 | /* set up PCI IRQ routing */ |
| 56 | pci_write_config8(dev, 0x55, pciIrqs[0] << 4); |
Uwe Hermann | 7365004 | 2009-05-27 18:55:19 +0000 | [diff] [blame] | 57 | pci_write_config8(dev, 0x56, pciIrqs[1] | (pciIrqs[2] << 4)); |
Bari Ari | 612163e3 | 2009-05-27 13:12:42 +0000 | [diff] [blame] | 58 | pci_write_config8(dev, 0x57, pciIrqs[3] << 4); |
| 59 | |
| 60 | /* VGA */ |
Stefan Reinauer | c02b4fc | 2010-03-22 11:42:32 +0000 | [diff] [blame] | 61 | printk(BIOS_INFO, "setting vga\n"); |
Bari Ari | 612163e3 | 2009-05-27 13:12:42 +0000 | [diff] [blame] | 62 | pci_assign_irqs(0, 0x1, pin_to_irq(vgaPins)); |
| 63 | |
| 64 | /* PCI slot */ |
Stefan Reinauer | c02b4fc | 2010-03-22 11:42:32 +0000 | [diff] [blame] | 65 | printk(BIOS_INFO, "setting pci slot\n"); |
Bari Ari | 612163e3 | 2009-05-27 13:12:42 +0000 | [diff] [blame] | 66 | pci_assign_irqs(0, 0x08, pin_to_irq(slotPins)); |
| 67 | |
| 68 | /* PCI slot */ |
Stefan Reinauer | c02b4fc | 2010-03-22 11:42:32 +0000 | [diff] [blame] | 69 | printk(BIOS_INFO, "setting USB Device Controller\n"); |
Bari Ari | 612163e3 | 2009-05-27 13:12:42 +0000 | [diff] [blame] | 70 | pci_assign_irqs(0, 0x0b, pin_to_irq(usbdevicePins)); |
| 71 | |
| 72 | /* PCI slot */ |
Stefan Reinauer | c02b4fc | 2010-03-22 11:42:32 +0000 | [diff] [blame] | 73 | printk(BIOS_INFO, "setting SDIO Controller\n"); |
Bari Ari | 612163e3 | 2009-05-27 13:12:42 +0000 | [diff] [blame] | 74 | pci_assign_irqs(0, 0x0c, pin_to_irq(sdioPins)); |
| 75 | |
| 76 | /* PCI slot */ |
Stefan Reinauer | c02b4fc | 2010-03-22 11:42:32 +0000 | [diff] [blame] | 77 | printk(BIOS_INFO, "setting SD $ MS Controller\n"); |
Bari Ari | 612163e3 | 2009-05-27 13:12:42 +0000 | [diff] [blame] | 78 | pci_assign_irqs(0, 0x0d, pin_to_irq(sd_ms_ctrl_Pins)); |
| 79 | |
| 80 | /* PCI slot */ |
Stefan Reinauer | c02b4fc | 2010-03-22 11:42:32 +0000 | [diff] [blame] | 81 | printk(BIOS_INFO, "setting CE-ATA NF Controller(Card Boot)\n"); |
Bari Ari | 612163e3 | 2009-05-27 13:12:42 +0000 | [diff] [blame] | 82 | pci_assign_irqs(0, 0x0e, pin_to_irq(ce_ata_nf_ctrl_Pins)); |
| 83 | |
| 84 | /* PCI slot */ |
Stefan Reinauer | c02b4fc | 2010-03-22 11:42:32 +0000 | [diff] [blame] | 85 | printk(BIOS_INFO, "setting ide\n"); |
Bari Ari | 612163e3 | 2009-05-27 13:12:42 +0000 | [diff] [blame] | 86 | //pci_assign_irqs(0, 0x0f, pin_to_irq(idePins)); |
| 87 | |
| 88 | /* Standard usb components */ |
Stefan Reinauer | c02b4fc | 2010-03-22 11:42:32 +0000 | [diff] [blame] | 89 | printk(BIOS_INFO, "setting usb1-2\n"); |
Uwe Hermann | 7365004 | 2009-05-27 18:55:19 +0000 | [diff] [blame] | 90 | // pci_assign_irqs(0, 0x10, pin_to_irq(usbPins)); |
Bari Ari | 612163e3 | 2009-05-27 13:12:42 +0000 | [diff] [blame] | 91 | |
| 92 | /* sound hardware */ |
Stefan Reinauer | c02b4fc | 2010-03-22 11:42:32 +0000 | [diff] [blame] | 93 | printk(BIOS_INFO, "setting hdac audio\n"); |
Bari Ari | 612163e3 | 2009-05-27 13:12:42 +0000 | [diff] [blame] | 94 | pci_assign_irqs(0, 0x14, pin_to_irq(hdacaudioPins)); |
| 95 | |
Stefan Reinauer | c02b4fc | 2010-03-22 11:42:32 +0000 | [diff] [blame] | 96 | printk(BIOS_SPEW, "%s: DONE\n", __FUNCTION__); |
Bari Ari | 612163e3 | 2009-05-27 13:12:42 +0000 | [diff] [blame] | 97 | } |
| 98 | |
Stefan Reinauer | 56a684a | 2010-04-07 15:40:26 +0000 | [diff] [blame] | 99 | static void setup_pm(device_t dev) |
Bari Ari | 612163e3 | 2009-05-27 13:12:42 +0000 | [diff] [blame] | 100 | { |
| 101 | u16 tmp; |
| 102 | /* Debounce LID and PWRBTN# Inputs for 16ms. */ |
| 103 | pci_write_config8(dev, 0x80, 0x20); |
| 104 | |
| 105 | /* Set ACPI base address to IO VX800_ACPI_IO_BASE */ |
Uwe Hermann | 7365004 | 2009-05-27 18:55:19 +0000 | [diff] [blame] | 106 | pci_write_config16(dev, 0x88, VX800_ACPI_IO_BASE | 1); |
Bari Ari | 612163e3 | 2009-05-27 13:12:42 +0000 | [diff] [blame] | 107 | |
| 108 | /* set ACPI irq to 9 */ |
| 109 | pci_write_config8(dev, 0x82, 0x49); |
| 110 | |
| 111 | /* Primary interupt channel, define wake events 0=IRQ0 15=IRQ15 1=en. */ |
Uwe Hermann | 7365004 | 2009-05-27 18:55:19 +0000 | [diff] [blame] | 112 | // pci_write_config16(dev, 0x84, 0x30f2); |
| 113 | pci_write_config16(dev, 0x84, 0x609a); // 0x609a?? |
Bari Ari | 612163e3 | 2009-05-27 13:12:42 +0000 | [diff] [blame] | 114 | |
| 115 | /* SMI output level to low, 7.5us throttle clock */ |
| 116 | pci_write_config8(dev, 0x8d, 0x18); |
| 117 | |
| 118 | /* GP Timer Control 1s */ |
| 119 | pci_write_config8(dev, 0x93, 0x88); |
Uwe Hermann | 7365004 | 2009-05-27 18:55:19 +0000 | [diff] [blame] | 120 | |
Bari Ari | 612163e3 | 2009-05-27 13:12:42 +0000 | [diff] [blame] | 121 | /* Power Well */ |
| 122 | pci_write_config8(dev, 0x94, 0x20); // 0x20?? |
| 123 | |
| 124 | /* 7 = stp to sust delay 1msec |
Uwe Hermann | 7365004 | 2009-05-27 18:55:19 +0000 | [diff] [blame] | 125 | * 6 = SUSST# Deasserted Before PWRGD for STD |
| 126 | */ |
Bari Ari | 612163e3 | 2009-05-27 13:12:42 +0000 | [diff] [blame] | 127 | pci_write_config8(dev, 0x95, 0xc0); // 0xc1?? |
| 128 | |
| 129 | /* Disable GP2 & GP3 Timer */ |
| 130 | pci_write_config8(dev, 0x98, 0); |
| 131 | |
| 132 | /* GP2 Timer Counter */ |
| 133 | pci_write_config8(dev, 0x99, 0xfb); |
| 134 | /* GP3 Timer Counter */ |
| 135 | //pci_write_config8(dev, 0x9a, 0x20); |
| 136 | |
| 137 | /* Multi Function Select 1 */ |
| 138 | pci_write_config8(dev, 0xe4, 0x00); |
| 139 | /* Multi Function Select 2 */ |
| 140 | pci_write_config8(dev, 0xe5, 0x41); //?? |
| 141 | |
Bari Ari | 612163e3 | 2009-05-27 13:12:42 +0000 | [diff] [blame] | 142 | /* Enable ACPI access (and setup like award) */ |
| 143 | pci_write_config8(dev, 0x81, 0x84); |
| 144 | |
| 145 | /* Clear status events. */ |
| 146 | outw(0xffff, VX800_ACPI_IO_BASE + 0x00); |
| 147 | outw(0xffff, VX800_ACPI_IO_BASE + 0x20); |
| 148 | outw(0xffff, VX800_ACPI_IO_BASE + 0x28); |
| 149 | outl(0xffffffff, VX800_ACPI_IO_BASE + 0x30); |
| 150 | |
| 151 | /* Disable SCI on GPIO. */ |
| 152 | outw(0x0, VX800_ACPI_IO_BASE + 0x22); |
| 153 | |
| 154 | /* Disable SMI on GPIO. */ |
| 155 | outw(0x0, VX800_ACPI_IO_BASE + 0x24); |
| 156 | |
| 157 | /* Disable all global enable SMIs. */ |
| 158 | outw(0x0, VX800_ACPI_IO_BASE + 0x2a); |
| 159 | |
| 160 | /* All SMI off, both IDE buses ON, PSON rising edge. */ |
| 161 | outw(0x0, VX800_ACPI_IO_BASE + 0x2c); |
| 162 | |
| 163 | /* Primary activity SMI disable. */ |
| 164 | outl(0x0, VX800_ACPI_IO_BASE + 0x34); |
| 165 | |
| 166 | /* GP timer reload on none. */ |
| 167 | outl(0x0, VX800_ACPI_IO_BASE + 0x38); |
| 168 | |
| 169 | /* Disable extended IO traps. */ |
| 170 | outb(0x0, VX800_ACPI_IO_BASE + 0x42); |
| 171 | |
| 172 | tmp = inw(VX800_ACPI_IO_BASE + 0x04); |
| 173 | /* SCI is generated for RTC/pwrBtn/slpBtn. */ |
| 174 | tmp |= 1; |
| 175 | outw(tmp, VX800_ACPI_IO_BASE + 0x04); |
| 176 | |
| 177 | /* Allow SLP# signal to assert LDTSTOP_L. |
| 178 | * Will work for C3 and for FID/VID change. |
| 179 | */ |
| 180 | outb(0x1, VX800_ACPI_IO_BASE + 0x11); |
| 181 | /* |
| 182 | outw(0x0, 0x424); |
| 183 | outw(0x0, 0x42a); |
| 184 | outw(0x1, 0x42c); |
| 185 | outl(0x0, 0x434); |
| 186 | outl(0x01, 0x438); |
| 187 | outb(0x0, 0x442); |
| 188 | outl(0xffff7fff, 0x448); |
| 189 | outw(0x001, 0x404); |
| 190 | */ |
| 191 | } |
Uwe Hermann | 7365004 | 2009-05-27 18:55:19 +0000 | [diff] [blame] | 192 | |
Stefan Reinauer | 56a684a | 2010-04-07 15:40:26 +0000 | [diff] [blame] | 193 | static void S3_ps2_kb_ms_wakeup(struct device *dev) |
Uwe Hermann | 7365004 | 2009-05-27 18:55:19 +0000 | [diff] [blame] | 194 | { |
| 195 | u8 enables; |
Bari Ari | 612163e3 | 2009-05-27 13:12:42 +0000 | [diff] [blame] | 196 | enables = pci_read_config8(dev, 0x51); |
| 197 | enables |= 2; |
| 198 | pci_write_config8(dev, 0x51, enables); |
Bari Ari | 612163e3 | 2009-05-27 13:12:42 +0000 | [diff] [blame] | 199 | |
Uwe Hermann | 7365004 | 2009-05-27 18:55:19 +0000 | [diff] [blame] | 200 | outb(0xe0, 0x2e); |
| 201 | outb(0x0b, 0x2f); //if 09,then only support kb wakeup |
| 202 | |
| 203 | outb(0xe1, 0x2e); //set any key scan code can wakeup |
Bari Ari | 612163e3 | 2009-05-27 13:12:42 +0000 | [diff] [blame] | 204 | outb(0x00, 0x2f); |
Uwe Hermann | 7365004 | 2009-05-27 18:55:19 +0000 | [diff] [blame] | 205 | |
| 206 | outb(0xe9, 0x2e); //set any mouse scan code can wakeup |
Bari Ari | 612163e3 | 2009-05-27 13:12:42 +0000 | [diff] [blame] | 207 | outb(0x00, 0x2f); |
| 208 | |
| 209 | enables &= 0xd; |
| 210 | pci_write_config8(dev, 0x51, enables); |
| 211 | |
Uwe Hermann | 7365004 | 2009-05-27 18:55:19 +0000 | [diff] [blame] | 212 | outb(inb(VX800_ACPI_IO_BASE + 0x02) | 0x20, VX800_ACPI_IO_BASE + 0x02); //ACPI golabe enable for sci smi trigger |
Stefan Reinauer | 14e2277 | 2010-04-27 06:56:47 +0000 | [diff] [blame] | 213 | outw(inw(VX800_ACPI_IO_BASE + 0x22) | 0x204, VX800_ACPI_IO_BASE + 0x22); //ACPI SCI on Internal KBC PME and mouse PME |
Bari Ari | 612163e3 | 2009-05-27 13:12:42 +0000 | [diff] [blame] | 214 | } |
Uwe Hermann | 7365004 | 2009-05-27 18:55:19 +0000 | [diff] [blame] | 215 | |
Stefan Reinauer | 56a684a | 2010-04-07 15:40:26 +0000 | [diff] [blame] | 216 | static void S3_usb_wakeup(struct device *dev) |
Bari Ari | 612163e3 | 2009-05-27 13:12:42 +0000 | [diff] [blame] | 217 | { |
Uwe Hermann | 7365004 | 2009-05-27 18:55:19 +0000 | [diff] [blame] | 218 | outw(inw(VX800_ACPI_IO_BASE + 0x22) | 0x4000, VX800_ACPI_IO_BASE + 0x22); //SCI on USB PME |
Bari Ari | 612163e3 | 2009-05-27 13:12:42 +0000 | [diff] [blame] | 219 | } |
| 220 | |
Stefan Reinauer | 56a684a | 2010-04-07 15:40:26 +0000 | [diff] [blame] | 221 | static void S3_lid_wakeup(struct device *dev) |
Bari Ari | 612163e3 | 2009-05-27 13:12:42 +0000 | [diff] [blame] | 222 | { |
Uwe Hermann | 7365004 | 2009-05-27 18:55:19 +0000 | [diff] [blame] | 223 | outw(inw(VX800_ACPI_IO_BASE + 0x22) | 0x800, VX800_ACPI_IO_BASE + 0x22); //SCI on LID PME |
Bari Ari | 612163e3 | 2009-05-27 13:12:42 +0000 | [diff] [blame] | 224 | } |
| 225 | |
Bari Ari | 612163e3 | 2009-05-27 13:12:42 +0000 | [diff] [blame] | 226 | /* This looks good enough to work, maybe */ |
| 227 | static void vx800_sb_init(struct device *dev) |
| 228 | { |
| 229 | unsigned char enables; |
| 230 | |
| 231 | // enable the internal I/O decode |
| 232 | enables = pci_read_config8(dev, 0x6C); |
| 233 | enables |= 0x80; |
| 234 | pci_write_config8(dev, 0x6C, enables); |
| 235 | |
| 236 | // Map 4MB of FLASH into the address space |
Uwe Hermann | 7365004 | 2009-05-27 18:55:19 +0000 | [diff] [blame] | 237 | // pci_write_config8(dev, 0x41, 0x7f); |
Bari Ari | 612163e3 | 2009-05-27 13:12:42 +0000 | [diff] [blame] | 238 | |
| 239 | // Set bit 6 of 0x40, because Award does it (IO recovery time) |
| 240 | // IMPORTANT FIX - EISA 0x4d0 decoding must be on so that PCI |
| 241 | // interrupts can be properly marked as level triggered. |
| 242 | enables = pci_read_config8(dev, 0x40); |
| 243 | enables |= 0x44; |
| 244 | pci_write_config8(dev, 0x40, enables); |
| 245 | |
| 246 | /* DMA Line buffer control */ |
| 247 | enables = pci_read_config8(dev, 0x42); |
| 248 | enables |= 0xf0; |
| 249 | pci_write_config8(dev, 0x42, enables); |
| 250 | |
| 251 | /* I/O recovery time */ |
| 252 | pci_write_config8(dev, 0x4c, 0x44); |
| 253 | |
| 254 | /* ROM memory cycles go to LPC. */ |
Uwe Hermann | 7365004 | 2009-05-27 18:55:19 +0000 | [diff] [blame] | 255 | pci_write_config8(dev, 0x59, 0x80); |
Bari Ari | 612163e3 | 2009-05-27 13:12:42 +0000 | [diff] [blame] | 256 | |
| 257 | /* Set 0x5b to 0x01 to match Award */ |
| 258 | //pci_write_config8(dev, 0x5b, 0x01); |
| 259 | enables = pci_read_config8(dev, 0x5b); |
| 260 | enables |= 0x01; |
| 261 | pci_write_config8(dev, 0x5b, enables); |
| 262 | |
Bari Ari | 612163e3 | 2009-05-27 13:12:42 +0000 | [diff] [blame] | 263 | /* Set Read Pass Write Control Enable */ |
| 264 | pci_write_config8(dev, 0x48, 0x0c); |
| 265 | |
| 266 | /* Set 0x58 to 0x42 APIC and RTC. */ |
| 267 | //pci_write_config8(dev, 0x58, 0x42); this cmd cause the irq0 can not be triggerd,since bit 5 was set to 0. |
Uwe Hermann | 7365004 | 2009-05-27 18:55:19 +0000 | [diff] [blame] | 268 | enables = pci_read_config8(dev, 0x58); |
| 269 | enables |= 0x41; // |
| 270 | pci_write_config8(dev, 0x58, enables); |
Bari Ari | 612163e3 | 2009-05-27 13:12:42 +0000 | [diff] [blame] | 271 | |
| 272 | /* Set bit 3 of 0x4f to match award (use INIT# as cpu reset) */ |
| 273 | enables = pci_read_config8(dev, 0x4f); |
| 274 | enables |= 0x08; |
| 275 | pci_write_config8(dev, 0x4f, enables); |
| 276 | |
| 277 | /* enable serial irq */ |
| 278 | pci_write_config8(dev, 0x52, 0x9); |
| 279 | |
| 280 | /* dma */ |
| 281 | pci_write_config8(dev, 0x53, 0x00); |
| 282 | |
| 283 | // Power management setup |
| 284 | setup_pm(dev); |
| 285 | |
| 286 | /* set up isa bus -- i/o recovery time, rom write enable, extend-ale */ |
| 287 | pci_write_config8(dev, 0x40, 0x54); |
| 288 | |
| 289 | // Start the rtc |
Gabe Black | b3f08c6 | 2014-04-30 17:12:25 -0700 | [diff] [blame] | 290 | cmos_init(0); |
Bari Ari | 612163e3 | 2009-05-27 13:12:42 +0000 | [diff] [blame] | 291 | } |
| 292 | |
| 293 | /* total kludge to get lxb to call our childrens set/enable functions - these are |
| 294 | not called unless this device has a resource to set - so set a dummy one */ |
Stefan Reinauer | 56a684a | 2010-04-07 15:40:26 +0000 | [diff] [blame] | 295 | static void vx800_read_resources(device_t dev) |
Bari Ari | 612163e3 | 2009-05-27 13:12:42 +0000 | [diff] [blame] | 296 | { |
| 297 | |
| 298 | struct resource *resource; |
| 299 | pci_dev_read_resources(dev); |
| 300 | resource = new_resource(dev, 1); |
Uwe Hermann | 7365004 | 2009-05-27 18:55:19 +0000 | [diff] [blame] | 301 | resource->flags |= |
| 302 | IORESOURCE_FIXED | IORESOURCE_ASSIGNED | IORESOURCE_IO | |
| 303 | IORESOURCE_STORED; |
Bari Ari | 612163e3 | 2009-05-27 13:12:42 +0000 | [diff] [blame] | 304 | resource->size = 2; |
| 305 | resource->base = 0x2e; |
Bari Ari | 612163e3 | 2009-05-27 13:12:42 +0000 | [diff] [blame] | 306 | } |
Uwe Hermann | 7365004 | 2009-05-27 18:55:19 +0000 | [diff] [blame] | 307 | |
Stefan Reinauer | 56a684a | 2010-04-07 15:40:26 +0000 | [diff] [blame] | 308 | static void vx800_set_resources(device_t dev) |
Bari Ari | 612163e3 | 2009-05-27 13:12:42 +0000 | [diff] [blame] | 309 | { |
| 310 | struct resource *resource; |
Uwe Hermann | 7365004 | 2009-05-27 18:55:19 +0000 | [diff] [blame] | 311 | resource = find_resource(dev, 1); |
Bari Ari | 612163e3 | 2009-05-27 13:12:42 +0000 | [diff] [blame] | 312 | resource->flags |= IORESOURCE_STORED; |
| 313 | pci_dev_set_resources(dev); |
| 314 | } |
| 315 | |
Bari Ari | 612163e3 | 2009-05-27 13:12:42 +0000 | [diff] [blame] | 316 | static void southbridge_init(struct device *dev) |
Uwe Hermann | 7365004 | 2009-05-27 18:55:19 +0000 | [diff] [blame] | 317 | { |
Stefan Reinauer | c02b4fc | 2010-03-22 11:42:32 +0000 | [diff] [blame] | 318 | printk(BIOS_DEBUG, "vx800 sb init\n"); |
Bari Ari | 612163e3 | 2009-05-27 13:12:42 +0000 | [diff] [blame] | 319 | vx800_sb_init(dev); |
| 320 | pci_routing_fixup(dev); |
| 321 | |
Uwe Hermann | 7365004 | 2009-05-27 18:55:19 +0000 | [diff] [blame] | 322 | setup_i8259(); // make sure interupt controller is configured before keyboard init |
Bari Ari | 612163e3 | 2009-05-27 13:12:42 +0000 | [diff] [blame] | 323 | |
Uwe Hermann | 7365004 | 2009-05-27 18:55:19 +0000 | [diff] [blame] | 324 | /* turn on keyboard and RTC, no need to visit this reg twice */ |
Edward O'Callaghan | def00be | 2014-04-30 05:01:52 +1000 | [diff] [blame] | 325 | pc_keyboard_init(); |
Stefan Reinauer | c8873ce | 2010-04-30 19:21:01 +0000 | [diff] [blame] | 326 | |
Stefan Reinauer | c02b4fc | 2010-03-22 11:42:32 +0000 | [diff] [blame] | 327 | printk(BIOS_DEBUG, "ps2 usb lid, you set who can wakeup system from s3 sleep\n"); |
Bari Ari | 612163e3 | 2009-05-27 13:12:42 +0000 | [diff] [blame] | 328 | S3_ps2_kb_ms_wakeup(dev); |
Uwe Hermann | 7365004 | 2009-05-27 18:55:19 +0000 | [diff] [blame] | 329 | S3_usb_wakeup(dev); |
Stefan Reinauer | c8873ce | 2010-04-30 19:21:01 +0000 | [diff] [blame] | 330 | S3_lid_wakeup(dev); |
Bari Ari | 612163e3 | 2009-05-27 13:12:42 +0000 | [diff] [blame] | 331 | |
| 332 | /* enable acpi cpu c3 state. (c2 state need not do anything.) |
| 333 | #1 |
| 334 | fadt->pm2_cnt_blk = 0x22;//to support cpu-c3 |
| 335 | fadt->p_lvl2_lat = 0x50; //this is the coreboot source |
| 336 | fadt->p_lvl3_lat = 0x320;// |
| 337 | fadt->pm2_cnt_len = 1;//to support cpu-c3 |
| 338 | #2 |
| 339 | ssdt? ->every cpu has a P_BLK address. set it to 0x10 (so that "Read Processor Level3 register(PMIORx15<7:0>) to enter C3 state"---VIA vx800 P SPEC ) |
Stefan Reinauer | 14e2277 | 2010-04-27 06:56:47 +0000 | [diff] [blame] | 340 | #3 write 0x17 in to PMIO=VX800_ACPI_IO_BASE + 0x26, following the describtion in the P-spec. |
Bari Ari | 612163e3 | 2009-05-27 13:12:42 +0000 | [diff] [blame] | 341 | 1 enable SLP# asserts in C3 state PMIORx26<1> =1 |
| 342 | 2 enable CPUSTP# asserts in C3 state; PMIORx26<2> =1 |
| 343 | 3 CLKRUN# is always asserted PMIORx26<3> =0 |
Stefan Reinauer | 14e2277 | 2010-04-27 06:56:47 +0000 | [diff] [blame] | 344 | 4 Disable PCISTP# When CLKRUN# is asserted |
| 345 | 1: PCISTP# will not assert When CLKRUN# is asserted |
Bari Ari | 612163e3 | 2009-05-27 13:12:42 +0000 | [diff] [blame] | 346 | PMIORx26<4> =1 |
Stefan Reinauer | 14e2277 | 2010-04-27 06:56:47 +0000 | [diff] [blame] | 347 | 5 This bit controls whether the CPU voltage is lowered when in C3/S1 state. |
| 348 | VRDSLP will be active in either this bit set in C3 or LVL4 register read |
Bari Ari | 612163e3 | 2009-05-27 13:12:42 +0000 | [diff] [blame] | 349 | PMIORx26<0> =0 |
Stefan Reinauer | 14e2277 | 2010-04-27 06:56:47 +0000 | [diff] [blame] | 350 | 6 Read Processor Level3 register(PMIORx15<7:0>) to enter C3 state PMIORx15 |
Bari Ari | 612163e3 | 2009-05-27 13:12:42 +0000 | [diff] [blame] | 351 | */ |
| 352 | outb(0x17, VX800_ACPI_IO_BASE + 0x26); |
| 353 | |
| 354 | } |
| 355 | |
| 356 | static struct device_operations vx800_lpc_ops = { |
Uwe Hermann | 7365004 | 2009-05-27 18:55:19 +0000 | [diff] [blame] | 357 | .read_resources = vx800_read_resources, |
| 358 | .set_resources = vx800_set_resources, |
Myles Watson | 7eac445 | 2010-06-17 16:16:56 +0000 | [diff] [blame] | 359 | .enable_resources = pci_dev_enable_resources, |
| 360 | .init = southbridge_init, |
Kyösti Mälkki | d0e212c | 2015-02-26 20:47:47 +0200 | [diff] [blame] | 361 | .scan_bus = scan_lpc_bus, |
Bari Ari | 612163e3 | 2009-05-27 13:12:42 +0000 | [diff] [blame] | 362 | }; |
| 363 | |
Stefan Reinauer | 8e96ba2 | 2010-03-16 23:33:29 +0000 | [diff] [blame] | 364 | static const struct pci_driver lpc_driver __pci_driver = { |
Uwe Hermann | 7365004 | 2009-05-27 18:55:19 +0000 | [diff] [blame] | 365 | .ops = &vx800_lpc_ops, |
Bari Ari | 612163e3 | 2009-05-27 13:12:42 +0000 | [diff] [blame] | 366 | .vendor = PCI_VENDOR_ID_VIA, |
| 367 | .device = PCI_DEVICE_ID_VIA_VX855_LPC, |
| 368 | }; |