static void *smp_write_config_table(void *v) { struct mp_config_table *mc; int bus_isa; unsigned char bus_8131_1; unsigned char bus_8131_2; unsigned char bus_8111_1; mc = (void *)(((char *)v) + SMP_FLOATING_TABLE_LEN); mptable_init(mc, LOCAL_APIC_ADDR); smp_write_processors(mc); { device_t dev; /* 8111 */ dev = dev_find_slot(1, PCI_DEVFN(0x03,0)); if (dev) { bus_8111_1 = pci_read_config8(dev, PCI_SECONDARY_BUS); } else { printk(BIOS_DEBUG, "ERROR - could not find PCI 1:03.0, using defaults\n"); bus_8111_1 = 4; } /* 8131-1 */ dev = dev_find_slot(1, PCI_DEVFN(0x01,0)); if (dev) { bus_8131_1 = pci_read_config8(dev, PCI_SECONDARY_BUS); } else { printk(BIOS_DEBUG, "ERROR - could not find PCI 1:01.0, using defaults\n"); bus_8131_1 = 2; } /* 8131-2 */ dev = dev_find_slot(1, PCI_DEVFN(0x02,0)); if (dev) { bus_8131_2 = pci_read_config8(dev, PCI_SECONDARY_BUS); } else { printk(BIOS_DEBUG, "ERROR - could not find PCI 1:02.0, using defaults\n"); bus_8131_2 = 3; } } mptable_write_buses(mc, NULL, &bus_isa); /* IOAPIC handling */ smp_write_ioapic(mc, 2, 0x11, IO_APIC_ADDR); { device_t dev; struct resource *res; /* 8131 apic 3 */ dev = dev_find_slot(1, PCI_DEVFN(0x01,1)); if (dev) { res = find_resource(dev, PCI_BASE_ADDRESS_0); if (res) { smp_write_ioapic(mc, 0x03, 0x11, res->base); } } /* 8131 apic 4 */ dev = dev_find_slot(1, PCI_DEVFN(0x02,1)); if (dev) { res = find_resource(dev, PCI_BASE_ADDRESS_0); if (res) { smp_write_ioapic(mc, 0x04, 0x11, res->base); } } } mptable_add_isa_interrupts(mc, bus_isa, 0x2, 0); /* Standard local interrupt assignments */ mptable_lintsrc(mc, bus_isa); /* PCI Slot 1 */ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8131_2, (1<<2)|0, 0x02, 0x11); smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8131_2, (1<<2)|1, 0x02, 0x12); smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8131_2, (1<<2)|2, 0x02, 0x13); smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8131_2, (1<<2)|3, 0x02, 0x10); /* PCI Slot 2 */ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8131_2, (2<<2)|0, 0x02, 0x12); smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8131_2, (2<<2)|1, 0x02, 0x13); smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8131_2, (2<<2)|2, 0x02, 0x10); smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8131_2, (2<<2)|3, 0x02, 0x11); /* PCI Slot 3 */ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8131_1, (1<<2)|0, 0x02, 0x11); smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8131_1, (1<<2)|1, 0x02, 0x12); smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8131_1, (1<<2)|2, 0x02, 0x13); smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8131_1, (1<<2)|3, 0x02, 0x10); /* PCI Slot 4 */ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8131_1, (2<<2)|0, 0x02, 0x12); smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8131_1, (2<<2)|1, 0x02, 0x13); smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8131_1, (2<<2)|2, 0x02, 0x10); smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8131_1, (2<<2)|3, 0x02, 0x11); /* PCI Slot 5 */ // FIXME get the irqs right, it's just hacked to work for now smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8111_1, (5<<2)|0, 0x02, 0x11); smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8111_1, (5<<2)|1, 0x02, 0x12); smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8111_1, (5<<2)|2, 0x02, 0x13); smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8111_1, (5<<2)|3, 0x02, 0x10); /* PCI Slot 6 */ // FIXME get the irqs right, it's just hacked to work for now smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8111_1, (4<<2)|0, 0x02, 0x10); smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8111_1, (4<<2)|1, 0x02, 0x11); smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8111_1, (4<<2)|2, 0x02, 0x12); smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8111_1, (4<<2)|3, 0x02, 0x13); /* On board nics */ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8131_1, (3<<2)|0, 0x02, 0x13); smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8131_1, (4<<2)|0, 0x02, 0x13); /* There is no extension information... */ /* Compute the checksums */ return mptable_finalize(mc); }
static void *smp_write_config_table(void *v) { struct mp_config_table *mc; int bus_isa; u32 apicid_sr5650; device_t dev; uint8_t sp5100_bus_number; mc = (void *)(((char *)v) + SMP_FLOATING_TABLE_LEN); mptable_init(mc, LOCAL_APIC_ADDR); smp_write_processors(mc); get_bus_conf(); if (IS_ENABLED(CONFIG_ENABLE_APIC_EXT_ID) && (CONFIG_APIC_ID_OFFSET > 0)) apicid_sp5100 = 0x0; else apicid_sp5100 = 0x20; apicid_sr5650 = apicid_sp5100 + 1; mptable_write_buses(mc, NULL, &bus_isa); /* I/O APICs: APIC ID Version State Address */ { uint32_t *dword_ptr; uint32_t dword; uint16_t word; uint8_t byte; sp5100_bus_number = 0; //bus_sp5100[0]; TODO: why bus_sp5100[0] use same value of bus_sr5650[0] assigned by get_pci1234(), instead of 0. dev = dev_find_slot(sp5100_bus_number, PCI_DEVFN(sbdn_sp5100 + 0x14, 0)); if (dev) { dword_ptr = (u32 *)(pci_read_config32(dev, 0x74) & 0xfffffff0); smp_write_ioapic(mc, apicid_sp5100, 0x11, dword_ptr); /* Initialize interrupt mapping */ /* USB 1 & 2 */ word = pci_read_config16(dev, 0xbe); word &= ~0x3f3f; word |= 0x0; /* 0: INTA, ...., 7: INTH */ word |= (0x1 << 3); /* 0: INTA, ...., 7: INTH */ word |= (0x2 << 8); /* 0: INTA, ...., 7: INTH */ word |= (0x3 << 11); /* 0: INTA, ...., 7: INTH */ pci_write_config16(dev, 0xbe, word); /* USB 3 */ byte = pci_read_config8(dev, 0x63); byte &= 0xf8; byte |= (0x2 << 4); /* 0: INTA, ...., 7: INTH */ pci_write_config8(dev, 0x63, byte); dword = pci_read_config32(dev, 0xac); /* SATA */ dword &= ~(7 << 26); dword |= (0x6 << 26); /* 0: INTA, ...., 7: INTH */ /* Hide IDE */ dword &= ~(0x00080000); /* dword_ptr |= 1 << 22; PIC and APIC co exists */ pci_write_config32(dev, 0xac, dword); /* * 00:12.0: PROG SATA : INT F * 00:13.0: INTA USB_0 * 00:13.1: INTB USB_1 * 00:13.2: INTC USB_2 * 00:13.3: INTD USB_3 * 00:13.4: INTC USB_4 * 00:13.5: INTD USB2 * 00:14.1: INTA IDE * 00:14.2: Prog HDA : INT E * 00:14.5: INTB ACI * 00:14.6: INTB MCI */ } dev = dev_find_slot(0, PCI_DEVFN(0, 0)); if (dev) { pci_write_config32(dev, 0xF8, 0x1); dword_ptr = (u32 *)(pci_read_config32(dev, 0xFC) & 0xfffffff0); smp_write_ioapic(mc, apicid_sr5650, 0x11, dword_ptr); } } /* I/O Ints: Type Polarity Trigger Bus ID IRQ APIC ID PIN# */ #define IO_LOCAL_INT(type, intr, apicid, pin) \ smp_write_lintsrc(mc, (type), MP_IRQ_TRIGGER_EDGE | MP_IRQ_POLARITY_HIGH, bus_isa, (intr), (apicid), (pin)); mptable_add_isa_interrupts(mc, bus_isa, apicid_sp5100, 0); /* SR5650 devices */ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0, (((0)<<2)|(2)), apicid_sr5650, 31); /* Device 0 Function 2 (LNKA, APIC pin 31) */ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0, (((2)<<2)|(0)), apicid_sr5650, 28); /* Device 2 (LNKE, APIC pin 28) */ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0, (((4)<<2)|(0)), apicid_sr5650, 28); /* Device 4 (LNKF, APIC pin 28) */ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0, (((9)<<2)|(0)), apicid_sr5650, 29); /* Device 9 (LNKG, APIC pin 29) */ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0, (((10)<<2)|(0)), apicid_sr5650, 30); /* Device 10 (LNKG, APIC pin 30) */ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0, (((11)<<2)|(0)), apicid_sr5650, 30); /* Device 11 (LNKG, APIC pin 30) */ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0, (((12)<<2)|(0)), apicid_sr5650, 30); /* Device 12 (LNKG, APIC pin 30) */ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0, (((13)<<2)|(0)), apicid_sr5650, 30); /* Device 13 (LNKG, APIC pin 30)) */ dev = dev_find_slot(0, PCI_DEVFN(0x2, 0)); if (dev && dev->enabled) { uint8_t bus_pci = dev->link_list->secondary; smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_pci, (((0)<<0x2)|(0)), apicid_sr5650, 0); /* card behind dev2 */ } dev = dev_find_slot(0, PCI_DEVFN(0x4, 0)); if (dev && dev->enabled) { uint8_t bus_pci = dev->link_list->secondary; smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_pci, (((0)<<0x4)|(0)), apicid_sr5650, 0); /* PIKE */ } dev = dev_find_slot(0, PCI_DEVFN(0x9, 0)); if (dev && dev->enabled) { uint8_t bus_pci = dev->link_list->secondary; smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_pci, (((0)<<0x9)|(0)), apicid_sr5650, 23); /* NIC A */ } dev = dev_find_slot(0, PCI_DEVFN(0xa, 0)); if (dev && dev->enabled) { uint8_t bus_pci = dev->link_list->secondary; smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_pci, (((0)<<0xa)|(0)), apicid_sr5650, 24); /* NIC B */ } dev = dev_find_slot(0, PCI_DEVFN(0xb, 0)); if (dev && dev->enabled) { uint8_t bus_pci = dev->link_list->secondary; smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_pci, (((0)<<0xb)|(0)), apicid_sr5650, 0); /* card behind dev11 */ } dev = dev_find_slot(0, PCI_DEVFN(0xc, 0)); if (dev && dev->enabled) { uint8_t bus_pci = dev->link_list->secondary; smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_pci, (((0)<<0xc)|(0)), apicid_sr5650, 0); /* card behind dev12 */ } dev = dev_find_slot(0, PCI_DEVFN(0xd, 0)); if (dev && dev->enabled) { uint8_t bus_pci = dev->link_list->secondary; smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_pci, (((0)<<0xd)|(0)), apicid_sr5650, 0); /* card behind dev13 */ } /* PCI interrupts are level triggered, and are * associated with a specific bus/device/function tuple. */ #define PCI_INT(bus, dev, interrupt_signal, pin) \ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, (bus), (((dev)<<2)|(interrupt_signal)), apicid_sp5100, (pin)) /* USB1 */ PCI_INT(sp5100_bus_number, 0x12, 0x0, 0x10); /* OHCI0 Port 0~2 */ PCI_INT(sp5100_bus_number, 0x12, 0x1, 0x11); /* OHCI1 Port 3~5 */ /* USB2 */ PCI_INT(sp5100_bus_number, 0x13, 0x0, 0x12); /* OHCI0 Port 6~8 */ PCI_INT(sp5100_bus_number, 0x13, 0x1, 0x13); /* EHCI Port 6~11 */ /* USB3 */ PCI_INT(sp5100_bus_number, 0x14, 0x3, 0x12); /* OHCI0 Port 12~13 */ /* SATA */ PCI_INT(sp5100_bus_number, 0x11, 0x0, 0x16); /* 6, INTG */ /* PCI slots */ dev = dev_find_slot(0, PCI_DEVFN(0x14, 4)); if (dev && dev->enabled) { u8 bus_pci = dev->link_list->secondary; /* PCI_SLOT 0. */ PCI_INT(bus_pci, 0x1, 0x0, 0x15); PCI_INT(bus_pci, 0x1, 0x1, 0x16); PCI_INT(bus_pci, 0x1, 0x2, 0x17); PCI_INT(bus_pci, 0x1, 0x3, 0x14); /* PCI_SLOT 1. */ PCI_INT(bus_pci, 0x2, 0x0, 0x14); PCI_INT(bus_pci, 0x2, 0x1, 0x15); PCI_INT(bus_pci, 0x2, 0x2, 0x16); PCI_INT(bus_pci, 0x2, 0x3, 0x17); /* PCI_SLOT 2. */ PCI_INT(bus_pci, 0x3, 0x0, 0x16); PCI_INT(bus_pci, 0x3, 0x1, 0x17); PCI_INT(bus_pci, 0x3, 0x2, 0x14); PCI_INT(bus_pci, 0x3, 0x3, 0x15); } /*Local Ints: Type Polarity Trigger Bus ID IRQ APIC ID PIN# */ IO_LOCAL_INT(mp_ExtINT, 0x0, MP_APIC_ALL, 0x0); IO_LOCAL_INT(mp_NMI, 0x0, MP_APIC_ALL, 0x1); /* There is no extension information... */ /* Compute the checksums */ return mptable_finalize(mc); }
void get_bus_conf(void) { unsigned apicid_base; device_t dev; int i; struct mb_sysconf_t *m; if(get_bus_conf_done==1) return; //do it only once get_bus_conf_done = 1; sysconf.mb = &mb_sysconf; m = sysconf.mb; sysconf.hc_possible_num = sizeof(pci1234x)/sizeof(pci1234x[0]); for(i=0;i<sysconf.hc_possible_num; i++) { sysconf.pci1234[i] = pci1234x[i]; sysconf.hcdn[i] = hcdnx[i]; } get_sblk_pci1234(); sysconf.sbdn = (sysconf.hcdn[0] >> 8) & 0xff; m->sbdn2 = sysconf.hcdn[0] & 0xff; // bcm5780 m->bus_bcm5785_0 = (sysconf.pci1234[0] >> 16) & 0xff; m->bus_bcm5780[0] = m->bus_bcm5785_0; /* bcm5785 */ printk(BIOS_DEBUG, "search for def %d.0 on bus %d\n",sysconf.sbdn,m->bus_bcm5785_0); dev = dev_find_slot(m->bus_bcm5785_0, PCI_DEVFN(sysconf.sbdn,0)); if (dev) { printk(BIOS_DEBUG, "found dev %s...\n",dev_path(dev)); m->bus_bcm5785_1 = pci_read_config8(dev, PCI_SECONDARY_BUS); printk(BIOS_DEBUG, "secondary is %d...\n",m->bus_bcm5785_1); dev = dev_find_slot(m->bus_bcm5785_1, PCI_DEVFN(0xd,0)); printk(BIOS_DEBUG, "now found %s...\n",dev_path(dev)); if(dev) { m->bus_bcm5785_1_1 = pci_read_config8(dev, PCI_SECONDARY_BUS); } } else { printk(BIOS_DEBUG, "ERROR - could not find PCI %02x:%02x.0, using defaults\n", m->bus_bcm5785_0, sysconf.sbdn); } /* bcm5780 */ for(i = 1; i < 6; i++) { dev = dev_find_slot(m->bus_bcm5780[0], PCI_DEVFN(m->sbdn2 + i - 1,0)); if(dev) { m->bus_bcm5780[i] = pci_read_config8(dev, PCI_SECONDARY_BUS); } else { printk(BIOS_DEBUG, "ERROR - could not find PCI %02x:%02x.0, using defaults\n", m->bus_bcm5780[0], m->sbdn2+i-1); } } /*I/O APICs: APIC ID Version State Address*/ #if CONFIG_LOGICAL_CPUS apicid_base = get_apicid_base(3); #else apicid_base = CONFIG_MAX_PHYSICAL_CPUS; #endif for(i=0;i<3;i++) m->apicid_bcm5785[i] = apicid_base+i; }
static void i82801gx_power_options(device_t dev) { u8 reg8; u16 reg16, pmbase; u32 reg32; const char *state; /* Get the chip configuration */ config_t *config = dev->chip_info; int pwr_on=CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL; int nmi_option; /* Which state do we want to goto after g3 (power restored)? * 0 == S0 Full On * 1 == S5 Soft Off * * If the option is not existent (Laptops), use MAINBOARD_POWER_ON. */ pwr_on = MAINBOARD_POWER_ON; get_option(&pwr_on, "power_on_after_fail"); reg8 = pci_read_config8(dev, GEN_PMCON_3); reg8 &= 0xfe; switch (pwr_on) { case MAINBOARD_POWER_OFF: reg8 |= 1; state = "off"; break; case MAINBOARD_POWER_ON: reg8 &= ~1; state = "on"; break; case MAINBOARD_POWER_KEEP: reg8 &= ~1; state = "state keep"; break; default: state = "undefined"; } reg8 |= (3 << 4); /* avoid #S4 assertions */ reg8 &= ~(1 << 3); /* minimum assertion is 1 to 2 RTCCLK */ pci_write_config8(dev, GEN_PMCON_3, reg8); printk(BIOS_INFO, "Set power %s after power failure.\n", state); /* Set up NMI on errors. */ reg8 = inb(0x61); reg8 &= 0x0f; /* Higher Nibble must be 0 */ reg8 &= ~(1 << 3); /* IOCHK# NMI Enable */ // reg8 &= ~(1 << 2); /* PCI SERR# Enable */ reg8 |= (1 << 2); /* PCI SERR# Disable for now */ outb(reg8, 0x61); reg8 = inb(0x70); nmi_option = NMI_OFF; get_option(&nmi_option, "nmi"); if (nmi_option) { printk(BIOS_INFO, "NMI sources enabled.\n"); reg8 &= ~(1 << 7); /* Set NMI. */ } else { printk(BIOS_INFO, "NMI sources disabled.\n"); reg8 |= ( 1 << 7); /* Can't mask NMI from PCI-E and NMI_NOW */ } outb(reg8, 0x70); /* Enable CPU_SLP# and Intel Speedstep, set SMI# rate down */ reg16 = pci_read_config16(dev, GEN_PMCON_1); reg16 &= ~(3 << 0); // SMI# rate 1 minute reg16 |= (1 << 2); // CLKRUN_EN - Mobile/Ultra only reg16 |= (1 << 3); // Speedstep Enable - Mobile/Ultra only reg16 |= (1 << 5); // CPUSLP_EN Desktop only if (config->c4onc3_enable) reg16 |= (1 << 7); // another laptop wants this? // reg16 &= ~(1 << 10); // BIOS_PCI_EXP_EN - Desktop/Mobile only reg16 |= (1 << 10); // BIOS_PCI_EXP_EN - Desktop/Mobile only #if DEBUG_PERIODIC_SMIS /* Set DEBUG_PERIODIC_SMIS in i82801gx.h to debug using * periodic SMIs. */ reg16 |= (3 << 0); // Periodic SMI every 8s #endif pci_write_config16(dev, GEN_PMCON_1, reg16); // Set the board's GPI routing. i82801gx_gpi_routing(dev); pmbase = pci_read_config16(dev, 0x40) & 0xfffe; outl(config->gpe0_en, pmbase + GPE0_EN); outw(config->alt_gp_smi_en, pmbase + ALT_GP_SMI_EN); /* Set up power management block and determine sleep mode */ reg32 = inl(pmbase + 0x04); // PM1_CNT reg32 &= ~(7 << 10); // SLP_TYP reg32 |= (1 << 1); // enable C3->C0 transition on bus master reg32 |= (1 << 0); // SCI_EN outl(reg32, pmbase + 0x04); }
static void azalia_init(struct device *dev) { u32 base; struct resource *res; u32 codec_mask; u8 reg8; u32 reg32; // ESD reg32 = pci_read_config32(dev, 0x134); reg32 &= 0xff00ffff; reg32 |= (2 << 16); pci_write_config32(dev, 0x134, reg32); // Link1 description reg32 = pci_read_config32(dev, 0x140); reg32 &= 0xff00ffff; reg32 |= (2 << 16); pci_write_config32(dev, 0x140, reg32); // Port VC0 Resource Control Register reg32 = pci_read_config32(dev, 0x114); reg32 &= 0xffffff00; reg32 |= 1; pci_write_config32(dev, 0x114, reg32); // VCi traffic class reg8 = pci_read_config8(dev, 0x44); reg8 |= (7 << 0); // TC7 pci_write_config8(dev, 0x44, reg8); // VCi Resource Control reg32 = pci_read_config32(dev, 0x120); reg32 |= (1 << 31); reg32 |= (1 << 24); // VCi ID reg32 |= (0x80 << 0); // VCi map pci_write_config32(dev, 0x120, reg32); /* Set Bus Master */ reg32 = pci_read_config32(dev, PCI_COMMAND); pci_write_config32(dev, PCI_COMMAND, reg32 | PCI_COMMAND_MASTER); reg8 = pci_read_config8(dev, 0x4d); // Docking Status reg8 &= ~(1 << 7); // Docking not supported pci_write_config8(dev, 0x4d, reg8); /* Lock some R/WO bits by writing their current value. */ reg32 = pci_read_config32(dev, 0x74); pci_write_config32(dev, 0x74, reg32); res = find_resource(dev, 0x10); if (!res) return; // NOTE this will break as soon as the Azalia get's a bar above // 4G. Is there anything we can do about it? base = (u32)res->base; printk(BIOS_DEBUG, "Azalia: base = %08x\n", (u32)base); codec_mask = codec_detect(base); if (codec_mask) { printk(BIOS_DEBUG, "Azalia: codec_mask = %02x\n", codec_mask); codecs_init(dev, base, codec_mask); } }
/* * SB600 enables all USB controllers by default in SMBUS Control. * SB600 enables SATA by default in SMBUS Control. */ static void sm_init(device_t dev) { u8 byte; u8 byte_old; u32 dword; u32 ioapic_base; u32 on; u32 nmi_option; printk(BIOS_INFO, "sm_init().\n"); ioapic_base = pci_read_config32(dev, 0x74) & (0xffffffe0); /* some like mem resource, but does not have enable bit */ /* Don't rename APIC ID */ clear_ioapic(ioapic_base); dword = pci_read_config8(dev, 0x62); dword |= 1 << 2; pci_write_config8(dev, 0x62, dword); dword = pci_read_config32(dev, 0x78); dword |= 1 << 9; pci_write_config32(dev, 0x78, dword); /* enable 0xCD6 0xCD7 */ /* bit 10: MultiMediaTimerIrqEn */ dword = pci_read_config8(dev, 0x64); dword |= 1 << 10; pci_write_config8(dev, 0x64, dword); /* enable serial irq */ byte = pci_read_config8(dev, 0x69); byte |= 1 << 7; /* enable serial irq function */ byte &= ~(0xF << 2); byte |= 4 << 2; /* set NumSerIrqBits=4 */ pci_write_config8(dev, 0x69, byte); byte = pm_ioread(0x61); byte |= 1 << 1; /* Set to enable NB/SB handshake during IOAPIC interrupt for AMD K8/K7 */ pm_iowrite(0x61, byte); /* disable SMI */ byte = pm_ioread(0x53); byte |= 1 << 3; pm_iowrite(0x53, byte); /* power after power fail */ on = CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL; get_option(&on, "power_on_after_fail"); byte = pm_ioread(0x74); byte &= ~0x03; if (on) { byte |= 1 << 0; } byte |= 1 << 2; pm_iowrite(0x74, byte); printk(BIOS_INFO, "set power %s after power fail\n", on ? "on" : "off"); /* sb600 rpr:2.3.3: */ byte = pm_ioread(0x9A); byte |= 1 << 5 | 1 << 4 | 1 << 2; pm_iowrite(0x9A, byte); byte = pm_ioread(0x8F); byte |= 1 << 5; byte &= ~(1 << 4); pm_iowrite(0x8F, byte); pm_iowrite(0x8B, 0x01); pm_iowrite(0x8A, 0x90); pm_iowrite(0x88, 0x10); /* A21 */ byte = pm_ioread(0x7C); byte |= 1 << 0; pm_iowrite(0x7C, byte); byte = pm_ioread(0x68); byte &= ~(1 << 1); /* 2.6 */ byte |= 1 << 2; pm_iowrite(0x68, byte); /* 2.6 */ byte = pm_ioread(0x65); byte &= ~(1 << 7); pm_iowrite(0x65, byte); /* 2.3.4 */ byte = pm_ioread(0x52); byte &= ~0x2F; byte |= 0x8; pm_iowrite(0x52, byte); byte = pm_ioread(0x8D); byte &= ~(1 << 6); pm_iowrite(0x8D, byte); byte = pm_ioread(0x61); byte &= ~(1 << 2); pm_iowrite(0x61, byte); byte = pm_ioread(0x42); byte &= ~(1 << 2); pm_iowrite(0x42, byte); /* Set up NMI on errors */ byte = inb(0x70); /* RTC70 */ byte_old = byte; nmi_option = NMI_OFF; get_option(&nmi_option, "nmi"); if (nmi_option) { byte &= ~(1 << 7); /* set NMI */ printk(BIOS_INFO, "++++++++++set NMI+++++\n"); } else { byte |= (1 << 7); /* Can not mask NMI from PCI-E and NMI_NOW */ printk(BIOS_INFO, "++++++++++no set NMI+++++\n"); } byte &= ~(1 << 7); if (byte != byte_old) { outb(byte, 0x70); } /* 2.10 IO Trap Settings */ abcfg_reg(0x10090, 1 << 16, 1 << 16); /* ab index */ pci_write_config32(dev, 0xF0, AB_INDX); /* Initialize the real time clock */ cmos_init(0); /*3.4 Enabling IDE/PCIB Prefetch for Performance Enhancement */ abcfg_reg(0x10060, 9 << 17, 9 << 17); abcfg_reg(0x10064, 9 << 17, 9 << 17); /* 3.5 Enabling OHCI Prefetch for Performance Enhancement */ abcfg_reg(0x80, 1 << 0, 1<< 0); /* 3.6 B-Link Client's Credit Variable Settings for the Downstream Arbitration Equation */ /* 3.7 Enabling Additional Address Bits Checking in Downstream */ abcfg_reg(0x9c, 3 << 0, 3 << 0); /* 3.8 Set B-Link Prefetch Mode */ abcfg_reg(0x80, 3 << 17, 3 << 17); /* 3.9 Enabling Detection of Upstream Interrupts */ abcfg_reg(0x94, 1 << 20,1 << 20); /* 3.10: Enabling Downstream Posted Transactions to Pass Non-Posted * Transactions for the K8 Platform (for All Revisions) */ abcfg_reg(0x10090, 1 << 8, 1 << 8); /* 3.11:Programming Cycle Delay for AB and BIF Clock Gating */ /* 3.12: Enabling AB and BIF Clock Gating */ abcfg_reg(0x10054, 0xFFFF0000, 0x1040000); abcfg_reg(0x54, 0xFF << 16, 4 << 16); printk(BIOS_INFO, "3.11, ABCFG:0x54\n"); abcfg_reg(0x54, 1 << 24, 1 << 24); printk(BIOS_INFO, "3.12, ABCFG:0x54\n"); abcfg_reg(0x98, 0x0000FF00, 0x00004700); /* 3.13:Enabling AB Int_Arbiter Enhancement (for All Revisions) */ abcfg_reg(0x10054, 0x0000FFFF, 0x07FF); /* 3.14:Enabling L1 on A-link Express */ axcfg_reg(0x68, 0x00000003, 0x2); axindxp_reg(0xa0, 0x0000F000, 0x6000); abcfg_reg(0x10098, 0xFFFFFFFF, 0x4000); abcfg_reg(0x04, 0xFFFFFFFF, 0x6); printk(BIOS_INFO, "sm_init() end\n"); /* Enable NbSb virtual channel */ axcfg_reg(0x114, 0x3f << 1, 0 << 1); axcfg_reg(0x120, 0x7f << 1, 0x7f << 1); axcfg_reg(0x120, 7 << 24, 1 << 24); axcfg_reg(0x120, 1 << 31, 1 << 31); abcfg_reg(0x50, 1 << 3, 1 << 3); }
unsigned long get_top_of_ram(void) { u16 reg_tom = pci_read_config8(MCU, 0x88); return (((unsigned long)reg_tom) << 24) - (256 << 20); }
static void *smp_write_config_table(void *v) { struct mp_config_table *mc; int bus_isa; mc = (void *)(((char *)v) + SMP_FLOATING_TABLE_LEN); mptable_init(mc, LOCAL_APIC_ADDR); smp_write_processors(mc); get_bus_conf(); mptable_write_buses(mc, NULL, &bus_isa); /* I/O APICs: APIC ID Version State Address */ { device_t dev; u32 dword; u8 byte; dev = dev_find_slot(bus_sb600[0], PCI_DEVFN(sbdn_sb600 + 0x14, 0)); if (dev) { dword = pci_read_config32(dev, 0x74) & 0xfffffff0; smp_write_ioapic(mc, apicid_sb600, 0x11,(void *) dword); /* Initialize interrupt mapping */ /* aza */ byte = pci_read_config8(dev, 0x63); byte &= 0xf8; byte |= 0; /* 0: INTA, ...., 7: INTH */ pci_write_config8(dev, 0x63, byte); /* SATA */ dword = pci_read_config32(dev, 0xac); dword &= ~(7 << 26); dword |= 6 << 26; /* 0: INTA, ...., 7: INTH */ /* dword |= 1<<22; PIC and APIC co exists */ pci_write_config32(dev, 0xac, dword); /* * 00:12.0: PROG SATA : INT F * 00:13.0: INTA USB_0 * 00:13.1: INTB USB_1 * 00:13.2: INTC USB_2 * 00:13.3: INTD USB_3 * 00:13.4: INTC USB_4 * 00:13.5: INTD USB2 * 00:14.1: INTA IDE * 00:14.2: Prog HDA : INT E * 00:14.5: INTB ACI * 00:14.6: INTB MCI */ } } /* I/O Ints: Type Polarity Trigger Bus ID IRQ APIC ID PIN# */ #define IO_LOCAL_INT(type, intr, apicid, pin) \ smp_write_lintsrc(mc, (type), MP_IRQ_TRIGGER_EDGE | MP_IRQ_POLARITY_HIGH, bus_isa, (intr), (apicid), (pin)); mptable_add_isa_interrupts(mc, bus_isa, apicid_sb600, 0); /*Local Ints: Type Polarity Trigger Bus ID IRQ APIC ID PIN# */ IO_LOCAL_INT(mp_ExtINT, 0x0, MP_APIC_ALL, 0x0); IO_LOCAL_INT(mp_NMI, 0x0, MP_APIC_ALL, 0x1); /* There is no extension information... */ /* Compute the checksums */ return mptable_finalize(mc); }
static void i82801dx_power_options(struct device *dev) { u8 reg8; u16 reg16, pmbase; u32 reg32; const char *state; int pwr_on = CONFIG_MAINBOARD_POWER_FAILURE_STATE; int nmi_option; /* Which state do we want to goto after g3 (power restored)? * 0 == S0 Full On * 1 == S5 Soft Off * * If the option is not existent (Laptops), use MAINBOARD_POWER_ON. */ pwr_on = MAINBOARD_POWER_ON; get_option(&pwr_on, "power_on_after_fail"); reg8 = pci_read_config8(dev, GEN_PMCON_3); reg8 &= 0xfe; switch (pwr_on) { case MAINBOARD_POWER_OFF: reg8 |= 1; state = "off"; break; case MAINBOARD_POWER_ON: reg8 &= ~1; state = "on"; break; case MAINBOARD_POWER_KEEP: reg8 &= ~1; state = "state keep"; break; default: state = "undefined"; } reg8 &= ~(1 << 3); /* minimum asssertion is 1 to 2 RTCCLK */ pci_write_config8(dev, GEN_PMCON_3, reg8); printk(BIOS_INFO, "Set power %s after power failure.\n", state); /* Set up NMI on errors. */ reg8 = inb(0x61); reg8 &= 0x0f; /* Higher Nibble must be 0 */ reg8 &= ~(1 << 3); /* IOCHK# NMI Enable */ // reg8 &= ~(1 << 2); /* PCI SERR# Enable */ reg8 |= (1 << 2); /* PCI SERR# Disable for now */ outb(reg8, 0x61); reg8 = inb(0x70); nmi_option = NMI_OFF; get_option(&nmi_option, "nmi"); if (nmi_option) { printk(BIOS_INFO, "NMI sources enabled.\n"); reg8 &= ~(1 << 7); /* Set NMI. */ } else { printk(BIOS_INFO, "NMI sources disabled.\n"); reg8 |= (1 << 7); /* Disable NMI. */ } outb(reg8, 0x70); /* Set SMI# rate down and enable CPU_SLP# */ reg16 = pci_read_config16(dev, GEN_PMCON_1); reg16 &= ~(3 << 0); // SMI# rate 1 minute reg16 |= (1 << 5); // CPUSLP_EN Desktop only pci_write_config16(dev, GEN_PMCON_1, reg16); pmbase = pci_read_config16(dev, 0x40) & 0xfffe; /* Set up power management block and determine sleep mode */ reg32 = inl(pmbase + 0x04); // PM1_CNT reg32 &= ~(7 << 10); // SLP_TYP reg32 |= (1 << 0); // SCI_EN outl(reg32, pmbase + 0x04); }
static void lpc_init(device_t dev) { uint8_t byte; uint8_t byte_old; int on; int nmi_option; printk(BIOS_DEBUG, "LPC_INIT -------->\n"); pc_keyboard_init(); lpc_usb_legacy_init(dev); lpc_common_init(dev); /* power after power fail */ on = CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL; get_option(&on, "power_on_after_fail"); byte = pci_read_config8(dev, PREVIOUS_POWER_STATE); byte &= ~0x40; if (!on) { byte |= 0x40; } pci_write_config8(dev, PREVIOUS_POWER_STATE, byte); printk(BIOS_INFO, "set power %s after power fail\n", on?"on":"off"); /* Throttle the CPU speed down for testing */ on = SLOW_CPU_OFF; get_option(&on, "slow_cpu"); if(on) { uint16_t pm10_bar; uint32_t dword; pm10_bar = (pci_read_config16(dev, 0x60)&0xff00); outl(((on<<1)+0x10) ,(pm10_bar + 0x10)); dword = inl(pm10_bar + 0x10); on = 8-on; printk(BIOS_DEBUG, "Throttling CPU %2d.%1.1d percent.\n", (on*12)+(on>>1),(on&1)*5); } /* Enable Error reporting */ /* Set up sync flood detected */ byte = pci_read_config8(dev, 0x47); byte |= (1 << 1); pci_write_config8(dev, 0x47, byte); /* Set up NMI on errors */ byte = inb(0x70); // RTC70 byte_old = byte; nmi_option = NMI_OFF; get_option(&nmi_option, "nmi"); if (nmi_option) { byte &= ~(1 << 7); /* set NMI */ } else { byte |= ( 1 << 7); // Can not mask NMI from PCI-E and NMI_NOW } if( byte != byte_old) { outb(byte, 0x70); } /* Initialize the real time clock */ cmos_init(0); /* Initialize isa dma */ isa_dma_init(); printk(BIOS_DEBUG, "LPC_INIT <--------\n"); }
static void *smp_write_config_table(void *v) { struct mp_config_table *mc; u32 apicid_sp5100; u32 apicid_sr5650; device_t dev; u32 dword; mc = (void *)(((char *)v) + SMP_FLOATING_TABLE_LEN); mptable_init(mc, LOCAL_APIC_ADDR); smp_write_processors(mc); get_bus_conf(); mptable_write_buses(mc, NULL, &bus_isa); /* * AGESA v5 Apply apic enumeration rules * For systems with >= 16 APICs, put the IO-APICs at 0..n and * put the local-APICs at m..z * For systems with < 16 APICs, put the Local-APICs at 0..n and * put the IO-APICs at (n + 1)..z */ if (CONFIG_MAX_CPUS >= 16) apicid_sp5100 = 0x0; else apicid_sp5100 = CONFIG_MAX_CPUS + 1; apicid_sr5650 = apicid_sp5100 + 1; dev = dev_find_slot(0, PCI_DEVFN(sbdn_sp5100 + 0x14, 0)); if (dev) { /* Set SP5100 IOAPIC ID */ dword = pci_read_config32(dev, 0x74) & 0xfffffff0; smp_write_ioapic(mc, apicid_sp5100, 0x20, dword); #ifdef UNUSED_CODE u8 byte; /* Initialize interrupt mapping */ /* aza */ byte = pci_read_config8(dev, 0x63); byte &= 0xf8; byte |= 0; /* 0: INTA, ...., 7: INTH */ pci_write_config8(dev, 0x63, byte); /* SATA */ dword = pci_read_config32(dev, 0xAC); dword &= ~(7 << 26); dword |= 6 << 26; /* 0: INTA, ...., 7: INTH */ /* dword |= 1<<22; PIC and APIC co exists */ pci_write_config32(dev, 0xAC, dword); #endif /* * 00:12.0: PROG SATA : INT F * 00:13.0: INTA USB_0 * 00:13.1: INTB USB_1 * 00:13.2: INTC USB_2 * 00:13.3: INTD USB_3 * 00:13.4: INTC USB_4 * 00:13.5: INTD USB2 * 00:14.1: INTA IDE * 00:14.2: Prog HDA : INT E * 00:14.5: INTB ACI * 00:14.6: INTB MCI */ /* Set RS5650 IOAPIC ID */ dev = dev_find_slot(0, PCI_DEVFN(0, 0)); if (dev) { pci_write_config32(dev, 0xF8, 0x1); dword = pci_read_config32(dev, 0xFC) & 0xfffffff0; smp_write_ioapic(mc, apicid_sr5650, 0x20, dword); } } /* I/O Ints: Type Polarity Trigger Bus ID IRQ APIC ID PIN# */ #define IO_LOCAL_INT(type, intr, apicid, pin) \ smp_write_lintsrc(mc, (type), MP_IRQ_TRIGGER_EDGE | MP_IRQ_POLARITY_HIGH, bus_isa, (intr), (apicid), (pin)); mptable_add_isa_interrupts(mc, bus_isa, apicid_sp5100, 0); /* PCI interrupts are level triggered, and are * associated with a specific bus/device/function tuple. */ #define PCI_INT(bus, dev, int_sign, pin) \ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, (bus), (((dev)<<2)|(int_sign)), apicid_sp5100, (pin)) /* SMBUS */ //PCI_INT(0x0, 0x14, 0x0, 0x10); //not generate interrupt, 3Ch hardcoded to 0 /* HD Audio */ PCI_INT(0x0, 0x14, 0x2, 0x10); /* USB */ /* OHCI0, OHCI1 hard-wired to 01h, corresponding to using INTA# */ /* EHCI hard-wired to 02h, corresponding to using INTB# */ /* USB1 */ PCI_INT(0x0, 0x12, 0x0, 0x10); /* OHCI0 Port 0~2 */ PCI_INT(0x0, 0x12, 0x1, 0x10); /* OHCI1 Port 3~5 */ PCI_INT(0x0, 0x12, 0x2, 0x11); /* EHCI Port 0~5 */ /* USB2 */ PCI_INT(0x0, 0x13, 0x0, 0x10); /* OHCI0 Port 6~8 */ PCI_INT(0x0, 0x13, 0x1, 0x10); /* OHCI1 Port 9~11 */ PCI_INT(0x0, 0x13, 0x2, 0x11); /* EHCI Port 6~11 */ /* USB3 EHCI hard-wired to 03h, corresponding to using INTC# */ PCI_INT(0x0, 0x14, 0x5, 0x12); /* OHCI0 Port 12~13 */ /* SATA */ PCI_INT(0x0, 0x11, 0x0, 0x16); //6, INTG /* on board NIC & Slot PCIE. */ /* configuration B doesnt need dev 5,6,7 */ /* * PCI_INT(bus_sr5650[0x5], 0x0, 0x0, 0x11); * PCI_INT(bus_sr5650[0x6], 0x0, 0x0, 0x12); * PCI_INT(bus_sr5650[0x7], 0x0, 0x0, 0x13); */ //smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0, (((13)<<2)|(0)), apicid_sr5650, 28); /* dev d */ //smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_sr5650[13], (((0)<<2)|(1)), apicid_sr5650, 0); /* card behind dev13 */ /* PCI slots */ /* PCI_SLOT 0. */ PCI_INT(bus_sp5100[1], 0x5, 0x0, 0x14); PCI_INT(bus_sp5100[1], 0x5, 0x1, 0x15); PCI_INT(bus_sp5100[1], 0x5, 0x2, 0x16); PCI_INT(bus_sp5100[1], 0x5, 0x3, 0x17); /* PCI_SLOT 1. */ PCI_INT(bus_sp5100[1], 0x6, 0x0, 0x15); PCI_INT(bus_sp5100[1], 0x6, 0x1, 0x16); PCI_INT(bus_sp5100[1], 0x6, 0x2, 0x17); PCI_INT(bus_sp5100[1], 0x6, 0x3, 0x14); /* PCI_SLOT 2. */ PCI_INT(bus_sp5100[1], 0x7, 0x0, 0x16); PCI_INT(bus_sp5100[1], 0x7, 0x1, 0x17); PCI_INT(bus_sp5100[1], 0x7, 0x2, 0x14); PCI_INT(bus_sp5100[1], 0x7, 0x3, 0x15); /*Local Ints: Type Polarity Trigger Bus ID IRQ APIC ID PIN# */ IO_LOCAL_INT(mp_ExtINT, 0, MP_APIC_ALL, 0x0); IO_LOCAL_INT(mp_NMI, 0, MP_APIC_ALL, 0x1); /* There is no extension information... */ /* Compute the checksums */ return mptable_finalize(mc); }
static int gpio_ich6_ofdata_to_platdata(struct udevice *dev) { struct ich6_bank_platdata *plat = dev_get_platdata(dev); pci_dev_t pci_dev; /* handle for 0:1f:0 */ u8 tmpbyte; u16 tmpword; u32 tmplong; u16 gpiobase; int offset; /* Where should it be? */ pci_dev = PCI_BDF(0, 0x1f, 0); /* Is the device present? */ tmpword = pci_read_config16(pci_dev, PCI_VENDOR_ID); if (tmpword != PCI_VENDOR_ID_INTEL) { debug("%s: wrong VendorID\n", __func__); return -ENODEV; } tmpword = pci_read_config16(pci_dev, PCI_DEVICE_ID); debug("Found %04x:%04x\n", PCI_VENDOR_ID_INTEL, tmpword); /* * We'd like to validate the Device ID too, but pretty much any * value is either a) correct with slight differences, or b) * correct but undocumented. We'll have to check a bunch of other * things instead... */ /* I/O should already be enabled (it's a RO bit). */ tmpword = pci_read_config16(pci_dev, PCI_COMMAND); if (!(tmpword & PCI_COMMAND_IO)) { debug("%s: device IO not enabled\n", __func__); return -ENODEV; } /* Header Type must be normal (bits 6-0 only; see spec.) */ tmpbyte = pci_read_config8(pci_dev, PCI_HEADER_TYPE); if ((tmpbyte & 0x7f) != PCI_HEADER_TYPE_NORMAL) { debug("%s: invalid Header type\n", __func__); return -ENODEV; } /* Base Class must be a bridge device */ tmpbyte = pci_read_config8(pci_dev, PCI_CLASS_CODE); if (tmpbyte != PCI_CLASS_CODE_BRIDGE) { debug("%s: invalid class\n", __func__); return -ENODEV; } /* Sub Class must be ISA */ tmpbyte = pci_read_config8(pci_dev, PCI_CLASS_SUB_CODE); if (tmpbyte != PCI_CLASS_SUB_CODE_BRIDGE_ISA) { debug("%s: invalid subclass\n", __func__); return -ENODEV; } /* Programming Interface must be 0x00 (no others exist) */ tmpbyte = pci_read_config8(pci_dev, PCI_CLASS_PROG); if (tmpbyte != 0x00) { debug("%s: invalid interface type\n", __func__); return -ENODEV; } /* * GPIOBASE moved to its current offset with ICH6, but prior to * that it was unused (or undocumented). Check that it looks * okay: not all ones or zeros. * * Note we don't need check bit0 here, because the Tunnel Creek * GPIO base address register bit0 is reserved (read returns 0), * while on the Ivybridge the bit0 is used to indicate it is an * I/O space. */ tmplong = pci_read_config32(pci_dev, PCI_CFG_GPIOBASE); if (tmplong == 0x00000000 || tmplong == 0xffffffff) { debug("%s: unexpected GPIOBASE value\n", __func__); return -ENODEV; } /* * Okay, I guess we're looking at the right device. The actual * GPIO registers are in the PCI device's I/O space, starting * at the offset that we just read. Bit 0 indicates that it's * an I/O address, not a memory address, so mask that off. */ gpiobase = tmplong & 0xfffe; offset = fdtdec_get_int(gd->fdt_blob, dev->of_offset, "reg", -1); if (offset == -1) { debug("%s: Invalid register offset %d\n", __func__, offset); return -EINVAL; } plat->base_addr = gpiobase + offset; plat->bank_name = fdt_getprop(gd->fdt_blob, dev->of_offset, "bank-name", NULL); return 0; }
static void ide_init(struct device *dev) { struct southbridge_sis_sis966_config *conf; /* Enable ide devices so the linux ide driver will work */ uint32_t dword; uint16_t word; uint8_t byte; conf = dev->chip_info; printk(BIOS_DEBUG, "IDE_INIT:---------->\n"); //-------------- enable IDE (SiS5513) ------------------------- { uint8_t temp8; int i=0; while(SiS_SiS5513_init[i][0] != 0) { temp8 = pci_read_config8(dev, SiS_SiS5513_init[i][0]); temp8 &= SiS_SiS5513_init[i][1]; temp8 |= SiS_SiS5513_init[i][2]; pci_write_config8(dev, SiS_SiS5513_init[i][0], temp8); i++; }; } //----------------------------------------------------------- word = pci_read_config16(dev, 0x50); /* Ensure prefetch is disabled */ word &= ~((1 << 15) | (1 << 13)); if (conf->ide1_enable) { /* Enable secondary ide interface */ word |= (1<<0); printk(BIOS_DEBUG, "IDE1 \t"); } if (conf->ide0_enable) { /* Enable primary ide interface */ word |= (1<<1); printk(BIOS_DEBUG, "IDE0\n"); } word |= (1<<12); word |= (1<<14); pci_write_config16(dev, 0x50, word); byte = 0x20 ; // Latency: 64-->32 pci_write_config8(dev, 0xd, byte); dword = pci_read_config32(dev, 0xf8); dword |= 12; pci_write_config32(dev, 0xf8, dword); #if DEBUG_IDE { int i; printk(BIOS_DEBUG, "****** IDE PCI config ******"); printk(BIOS_DEBUG, "\n 03020100 07060504 0B0A0908 0F0E0D0C"); for(i=0;i<0xff;i+=4){ if((i%16)==0) printk(BIOS_DEBUG, "\n%02x: ", i); printk(BIOS_DEBUG, "%08x ", pci_read_config32(dev,i)); } printk(BIOS_DEBUG, "\n"); } #endif printk(BIOS_DEBUG, "IDE_INIT:<----------\n"); }
static int via_cx700_int15_handler(void) { int res = 0; u8 mem_speed; #define MEMORY_SPEED_66MHZ (0 << 4) #define MEMORY_SPEED_100MHZ (1 << 4) #define MEMORY_SPEED_133MHZ (1 << 4) #define MEMORY_SPEED_200MHZ (3 << 4) // DDR200 #define MEMORY_SPEED_266MHZ (4 << 4) // DDR266 #define MEMORY_SPEED_333MHZ (5 << 4) // DDR333 #define MEMORY_SPEED_400MHZ (6 << 4) // DDR400 #define MEMORY_SPEED_533MHZ (7 << 4) // DDR533 #define MEMORY_SPEED_667MHZ (8 << 4) // DDR667 const u8 memory_mapping[6] = { MEMORY_SPEED_200MHZ, MEMORY_SPEED_266MHZ, MEMORY_SPEED_333MHZ, MEMORY_SPEED_400MHZ, MEMORY_SPEED_533MHZ, MEMORY_SPEED_667MHZ }; printk(BIOS_DEBUG, "via_cx700_int15_handler\n"); switch(X86_EAX & 0xffff) { case 0x5f00: /* VGA POST Initialization Signal */ X86_EAX = (X86_EAX & 0xffff0000 ) | 0x5f; res = 1; break; case 0x5f01: /* Software Panel Type Configuration */ X86_EAX = (X86_EAX & 0xffff0000 ) | 0x5f; // panel type = 2 = 1024 * 768 X86_ECX = (X86_ECX & 0xffffff00 ) | 2; res = 1; break; case 0x5f27: /* Boot Device Selection */ X86_EAX = (X86_EAX & 0xffff0000 ) | 0x5f; X86_EBX = 0x00000000; // 0 -> default X86_ECX = 0x00000000; // 0 -> default // TV Layout - default X86_EDX = (X86_EDX & 0xffffff00) | 0; res = 1; break; case 0x5f0b: /* Get Expansion Setting */ X86_EAX = (X86_EAX & 0xffff0000 ) | 0x5f; X86_ECX = X86_ECX & 0xffffff00; // non-expansion // regs->ecx = regs->ecx & 0xffffff00 | 1; // expansion res = 1; break; case 0x5f0f: /* VGA Post Completion */ X86_EAX = (X86_EAX & 0xffff0000 ) | 0x5f; res = 1; break; case 0x5f18: X86_EAX = (X86_EAX & 0xffff0000 ) | 0x5f; #define UMA_SIZE_8MB (3 << 0) #define UMA_SIZE_16MB (4 << 0) #define UMA_SIZE_32MB (5 << 0) X86_EBX = (X86_EBX & 0xffff0000 ) | MEMORY_SPEED_533MHZ | UMA_SIZE_32MB; mem_speed = pci_read_config8(dev_find_slot(0, PCI_DEVFN(0, 4)), SCRATCH_DRAM_FREQ); if (mem_speed > 5) mem_speed = 5; X86_EBX |= memory_mapping[mem_speed]; res = 1; break; default: printk(BIOS_DEBUG, "Unknown INT15 function %04x!\n", X86_EAX & 0xffff); break; } return res; }
static void azalia_init(struct device *dev) { u8 *base; struct resource *res; u32 codec_mask; u8 reg8; u32 reg32; // ESD reg32 = pci_read_config32(dev, 0x134); reg32 &= 0xff00ffff; reg32 |= (2 << 16); pci_write_config32(dev, 0x134, reg32); // Link1 description reg32 = pci_read_config32(dev, 0x140); reg32 &= 0xff00ffff; reg32 |= (2 << 16); pci_write_config32(dev, 0x140, reg32); // Port VC0 Resource Control Register reg32 = pci_read_config32(dev, 0x114); reg32 &= 0xffffff00; reg32 |= 1; pci_write_config32(dev, 0x114, reg32); // VCi traffic class reg8 = pci_read_config8(dev, 0x44); reg8 |= (7 << 0); // TC7 pci_write_config8(dev, 0x44, reg8); // VCi Resource Control reg32 = pci_read_config32(dev, 0x120); reg32 |= (1 << 31); reg32 |= (1 << 24); // VCi ID reg32 |= (0x80 << 0); // VCi map pci_write_config32(dev, 0x120, reg32); /* Set Bus Master */ reg32 = pci_read_config32(dev, PCI_COMMAND); pci_write_config32(dev, PCI_COMMAND, reg32 | PCI_COMMAND_MASTER); pci_write_config8(dev, 0x3c, 0x0a); // unused? // TODO Actually check if we're AC97 or HDA instead of hardcoding this // here, in devicetree.cb and/or romstage.c. reg8 = pci_read_config8(dev, 0x40); reg8 |= (1 << 3); // Clear Clock Detect Bit pci_write_config8(dev, 0x40, reg8); reg8 &= ~(1 << 3); // Keep CLKDETCLR from clearing the bit over and over pci_write_config8(dev, 0x40, reg8); reg8 |= (1 << 2); // Enable clock detection pci_write_config8(dev, 0x40, reg8); mdelay(1); reg8 = pci_read_config8(dev, 0x40); printk(BIOS_DEBUG, "Azalia: codec type: %s\n", (reg8 & (1 << 1))?"Azalia":"AC97"); // reg8 = pci_read_config8(dev, 0x40); // Audio Control reg8 |= 1; // Select Azalia mode. This needs to be controlled via devicetree.cb pci_write_config8(dev, 0x40, reg8); reg8 = pci_read_config8(dev, 0x4d); // Docking Status reg8 &= ~(1 << 7); // Docking not supported pci_write_config8(dev, 0x4d, reg8); #if 0 /* Set routing pin */ pci_write_config32(dev, 0xf8, 0x0); pci_write_config8(dev, 0xfc, 0xAA); /* Set INTA */ pci_write_config8(dev, 0x63, 0x0); /* Enable azalia, disable ac97 */ // pm_iowrite(0x59, 0xB); #endif res = find_resource(dev, 0x10); if (!res) return; // NOTE this will break as soon as the Azalia get's a bar above // 4G. Is there anything we can do about it? base = res2mmio(res, 0, 0); printk(BIOS_DEBUG, "Azalia: base = %08x\n", (u32)base); codec_mask = codec_detect(base); if (codec_mask) { printk(BIOS_DEBUG, "Azalia: codec_mask = %02x\n", codec_mask); codecs_init(dev, base, codec_mask); } }
/* * set thermal config */ static void set_thermal_config(void) { u8 byte, byte2; u16 word; u32 dword; device_t sm_dev; /* set adt7475 */ ADT7475_write_byte(0x40, 0x04); /* Config Register 6 */ ADT7475_write_byte(0x10, 0x00); /* Config Register 7 */ ADT7475_write_byte(0x11, 0x00); /* set Offset 64 format, enable THERM on Remote 1& Remote 2 */ ADT7475_write_byte(0x7c, 0xa0); /* No offset for remote 2 */ ADT7475_write_byte(0x72, 0x00); /* PWM 1 configuration register CPU fan controlled by CPU Thermal Diode */ ADT7475_write_byte(0x5c, 0x02); /* PWM 3 configuration register Case fan controlled by 690 temp */ ADT7475_write_byte(0x5e, 0x42); /* remote 1 low temp limit */ ADT7475_write_byte(0x4e, 0x00); /* remote 1 High temp limit (90C) */ ADT7475_write_byte(0x4f, 0x9a); /* remote2 Low Temp Limit */ ADT7475_write_byte(0x52, 0x00); /* remote2 High Limit (90C) */ ADT7475_write_byte(0x53, 0x9a); /* remote 1 therm temp limit (95C) */ ADT7475_write_byte(0x6a, 0x9f); /* remote 2 therm temp limit (95C) */ ADT7475_write_byte(0x6c, 0x9f); /* PWM 1 minimum duty cycle (37%) */ ADT7475_write_byte(0x64, 0x60); /* PWM 1 Maximum duty cycle (100%) */ ADT7475_write_byte(0x38, 0xff); /* PWM 3 minimum duty cycle (37%) */ ADT7475_write_byte(0x66, 0x60); /* PWM 3 Maximum Duty Cycle (100%) */ ADT7475_write_byte(0x3a, 0xff); /* Remote 1 temperature Tmin (32C) */ ADT7475_write_byte(0x67, 0x60); /* Remote 2 temperature Tmin (32C) */ ADT7475_write_byte(0x69, 0x60); /* remote 1 Trange (53C ramp range) */ ADT7475_write_byte(0x5f, 0xe8); /* remote 2 Trange (53C ramp range) */ ADT7475_write_byte(0x61, 0xe8); /* PWM2 Duty cycle */ ADT7475_write_byte(0x65, 0x00); /* PWM2 Disabled */ ADT7475_write_byte(0x5d, 0x80); /* PWM2 Max Duty Cycle */ ADT7475_write_byte(0x39, 0x00); /* Config Register 3 - enable smbalert & therm */ ADT7475_write_byte(0x78, 0x03); /* Config Register 4 - enable therm output */ ADT7475_write_byte(0x7d, 0x09); /* Interrupt Mask Register 2 - Mask SMB alert for Therm Conditions, Fan 2 fault, SmbAlert Fan for Therm Timer event */ ADT7475_write_byte(0x75, 0x2a); /* Config Register 1 Set Start bit */ ADT7475_write_byte(0x40, 0x05); /* Read status register to clear any old errors */ byte2 = ADT7475_read_byte(0x42); byte = ADT7475_read_byte(0x41); /* remote 1 temperature offset */ ADT7475_write_byte(0x70, 0x00); printk(BIOS_INFO, "Init adt7475 end , status 0x42 %02x, status 0x41 %02x\n", byte2, byte); /* sb600 setting for thermal config. Set SB600 GPM5 to trigger ACPI event */ /* set GPM5 as GPM5, not DDR3_memory disable */ byte = pm_ioread(0x8f); byte |= 1 << 6; /* enable GPE */ pm_iowrite(0x8f, byte); /* GPM5 as GPIO not USB OC */ sm_dev = dev_find_slot(0, PCI_DEVFN(0x14, 0)); dword = pci_read_config32(sm_dev, 0x64); dword |= 1 << 19; pci_write_config32(sm_dev, 0x64, dword); /* Enable Client Management Index/Data registers */ dword = pci_read_config32(sm_dev, 0x78); dword |= 1 << 11; /* Cms_enable */ pci_write_config32(sm_dev, 0x78, dword); /* MiscfuncEnable */ byte = pci_read_config8(sm_dev, 0x41); byte |= (1 << 5); pci_write_config8(sm_dev, 0x41, byte); /* set GPM5 as input */ /* set index register 0C50h to 13h (miscellaneous control) */ outb(0x13, 0xC50); /* CMIndex */ /* set CM data register 0C51h bits [7:6] to 01b to set Input/Out control */ byte = inb(0xC51); /* CMData */ byte &= 0x3f; byte |= 1 << 6; outb(byte, 0xC51); /* set GPM port 0C52h bit 5 to 1 to tri-state the GPM port */ byte = inb(0xc52); /* GpmPort */ byte |= 1 << 5; outb(byte, 0xc52); /* set CM data register 0C51h bits [7:6] to 00b to set GPM port for read */ byte = inb(0xc51); byte &= 0x3f; outb(byte, 0xc51); /* trigger SCI/SMI */ byte = pm_ioread(0x34); byte &= 0xcf; pm_iowrite(0x34, byte); /* set GPM5 to not wake from s5 */ byte = pm_ioread(0x77); byte &= ~(1 << 5); pm_iowrite(0x77, byte); /* trigger on falling edge */ byte = pm_ioread(0x38); byte &= ~(1 << 2); pm_iowrite(0x38, byte); /* set SB600 GPIO 64 to GPIO with pull-up */ byte = pm2_ioread(0x42); byte &= 0x3f; pm2_iowrite(0x42, byte); /* set GPIO 64 to input */ word = pci_read_config16(sm_dev, 0x56); word |= 1 << 7; pci_write_config16(sm_dev, 0x56, word); /* set GPIO 64 internal pull-up */ byte = pm2_ioread(0xf0); byte &= 0xee; pm2_iowrite(0xf0, byte); /* set Talert to be active low */ byte = pm_ioread(0x67); byte &= ~(1 << 5); pm_iowrite(0x67, byte); /* set Talert to generate ACPI event */ byte = pm_ioread(0x3c); byte &= 0xf3; pm_iowrite(0x3c, byte); /* THERMTRIP pin */ /* byte = pm_ioread(0x68); * byte |= 1 << 3; * pm_iowrite(0x68, byte); * * byte = pm_ioread(0x55); * byte |= 1 << 0; * pm_iowrite(0x55, byte); * * byte = pm_ioread(0x67); * byte &= ~( 1 << 6); * pm_iowrite(0x67, byte); */ }
static void azalia_init(struct device *dev) { u8 *base; struct resource *res; u32 codec_mask; u8 reg8; u16 reg16; u32 reg32; /* Find base address */ res = find_resource(dev, PCI_BASE_ADDRESS_0); if (!res) return; // NOTE this will break as soon as the Azalia get's a bar above // 4G. Is there anything we can do about it? base = res2mmio(res, 0, 0); printk(BIOS_DEBUG, "Azalia: base = %08x\n", (u32)base); if (RCBA32(0x2030) & (1 << 31)) { reg32 = pci_read_config32(dev, 0x120); reg32 &= 0xf8ffff01; reg32 |= (1 << 24); // 2 << 24 for server reg32 |= RCBA32(0x2030) & 0xfe; pci_write_config32(dev, 0x120, reg32); reg16 = pci_read_config16(dev, 0x78); reg16 |= (1 << 11); pci_write_config16(dev, 0x78, reg16); } else printk(BIOS_DEBUG, "Azalia: V1CTL disabled.\n"); reg32 = pci_read_config32(dev, 0x114); reg32 &= ~0xfe; pci_write_config32(dev, 0x114, reg32); // Set VCi enable bit reg32 = pci_read_config32(dev, 0x120); reg32 |= (1 << 31); pci_write_config32(dev, 0x120, reg32); // Enable HDMI codec: reg32 = pci_read_config32(dev, 0xc4); reg32 |= (1 << 1); pci_write_config32(dev, 0xc4, reg32); reg8 = pci_read_config8(dev, 0x43); reg8 |= (1 << 6); pci_write_config8(dev, 0x43, reg8); reg32 = pci_read_config32(dev, 0xd0); reg32 &= ~(1 << 31); pci_write_config32(dev, 0xd0, reg32); /* Set Bus Master */ reg32 = pci_read_config32(dev, PCI_COMMAND); pci_write_config32(dev, PCI_COMMAND, reg32 | PCI_COMMAND_MASTER); pci_write_config8(dev, 0x3c, 0x0a); // unused? /* Codec Initialization Programming Sequence */ /* Take controller out of reset */ reg32 = read32(base + 0x08); reg32 |= (1 << 0); write32(base + 0x08, reg32); /* Wait 1ms */ udelay(1000); // reg8 = pci_read_config8(dev, 0x40); // Audio Control reg8 |= 1; // Select Azalia mode. This needs to be controlled via devicetree.cb pci_write_config8(dev, 0x40, reg8); reg8 = pci_read_config8(dev, 0x4d); // Docking Status reg8 &= ~(1 << 7); // Docking not supported pci_write_config8(dev, 0x4d, reg8); codec_mask = codec_detect(base); if (codec_mask) { printk(BIOS_DEBUG, "Azalia: codec_mask = %02x\n", codec_mask); codecs_init(dev, base, codec_mask); } /* Enable dynamic clock gating */ reg8 = pci_read_config8(dev, 0x43); reg8 &= ~0x7; reg8 |= (1 << 2) | (1 << 0); pci_write_config8(dev, 0x43, reg8); }
static void bcm5785_early_setup(void) { uint8_t byte; uint32_t dword; pci_devfn_t dev; //F0 // enable device on bcm5785 at first dev = pci_locate_device(PCI_ID(0x1166, 0x0205), 0); dword = pci_read_config32(dev, 0x64); dword |= (1<<15) | (1<<11) | (1<<3); // ioapci enable dword |= (1<<8); // USB enable dword |= /* (1<<27)|*/(1<<14); // IDE enable pci_write_config32(dev, 0x64, dword); byte = pci_read_config8(dev, 0x84); byte |= (1<<0); // SATA enable pci_write_config8(dev, 0x84, byte); // WDT and cf9 for later in ramstage to call hard_reset bcm5785_enable_wdt_port_cf9(); bcm5785_enable_msg(); // IDE related //F0 byte = pci_read_config8(dev, 0x4e); byte |= (1<<4); //enable IDE ext regs pci_write_config8(dev, 0x4e, byte); //F1 dev = pci_locate_device(PCI_ID(0x1166, 0x0214), 0); byte = pci_read_config8(dev, 0x48); byte &= ~1; // disable pri channel pci_write_config8(dev, 0x48, byte); pci_write_config8(dev, 0xb0, 0x01); pci_write_config8(dev, 0xb2, 0x02); byte = pci_read_config8(dev, 0x06); byte |= (1<<4); // so b0, b2 can not be changed from now pci_write_config8(dev, 0x06, byte); byte = pci_read_config8(dev, 0x49); byte |= 1; // enable second channel pci_write_config8(dev, 0x49, byte); //F2 dev = pci_locate_device(PCI_ID(0x1166, 0x0234), 0); byte = pci_read_config8(dev, 0x40); byte |= (1<<3)|(1<<2); // LPC Retry, LPC to PCI DMA enable pci_write_config8(dev, 0x40, byte); pci_write_config32(dev, 0x60, 0x0000ffff); // LPC Memory hole start and end // USB related pci_write_config8(dev, 0x90, 0x40); pci_write_config8(dev, 0x92, 0x06); pci_write_config8(dev, 0x9c, 0x7c); //PHY timinig register pci_write_config8(dev, 0xa4, 0x02); //mask reg - low/full speed func pci_write_config8(dev, 0xa5, 0x02); //mask reg - low/full speed func pci_write_config8(dev, 0xa6, 0x00); //mask reg - high speed func pci_write_config8(dev, 0xb4, 0x40); }
static void pci_domain_set_resources(device_t dev) { /* * the order is important to find the correct RAM size. */ u8 ramregs[] = { 0x43, 0x42, 0x41, 0x40 }; device_t mc_dev; u32 pci_tolm; u8 reg; printk(BIOS_SPEW, "Entering vx800 pci_domain_set_resources.\n"); pci_tolm = find_pci_tolm(dev->link_list); mc_dev = dev_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VX855_MEMCTRL, 0); if (mc_dev) { unsigned long tomk, tolmk; unsigned char rambits; u8 i, idx; /* * once the register value is not zero, the ramsize is * this register's value multiply 64 * 1024 * 1024 */ for (rambits = 0, i = 0; i < ARRAY_SIZE(ramregs); i++) { rambits = pci_read_config8(mc_dev, ramregs[i]); if (rambits != 0) break; } /* Get memory size and frame buffer from northbridge's registers. if register with invalid value we set frame buffer size to 32M for default, but it won't happen. */ reg = pci_read_config8(mc_dev, 0xa1); reg &= 0x70; reg = reg >> 4; /* TOP 1M SM Memory */ if (reg == 0x0) tomk = (((rambits << 6) - 32 - VIACONFIG_TOP_SM_SIZE_MB) * 1024); // Set frame buffer 32M for default else tomk = (((rambits << 6) - (4 << reg) - VIACONFIG_TOP_SM_SIZE_MB) * 1024); printk(BIOS_SPEW, "tomk is 0x%lx\n", tomk); /* Compute the Top Of Low Memory, in Kb */ tolmk = pci_tolm >> 10; if (tolmk >= tomk) { /* The PCI hole does does not overlap the memory. */ tolmk = tomk; } /* Report the memory regions */ idx = 10; /* TODO: Hole needed? */ ram_resource(dev, idx++, 0, 640); /* first 640k */ /* Leave a hole for vga, 0xa0000 - 0xc0000 */ ram_resource(dev, idx++, 768, (tolmk - 768)); } assign_resources(dev->link_list); }
static void i82801ix_power_options(device_t dev) { u8 reg8; u16 reg16, pmbase; u32 reg32; const char *state; /* Get the chip configuration */ config_t *config = dev->chip_info; int pwr_on=CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL; int nmi_option; /* BIOS must program... */ reg32 = pci_read_config32(dev, 0xac); pci_write_config32(dev, 0xac, reg32 | (1 << 30) | (3 << 8)); /* Which state do we want to goto after g3 (power restored)? * 0 == S0 Full On * 1 == S5 Soft Off * * If the option is not existent (Laptops), use MAINBOARD_POWER_ON. */ if (get_option(&pwr_on, "power_on_after_fail") != CB_SUCCESS) pwr_on = MAINBOARD_POWER_ON; reg8 = pci_read_config8(dev, D31F0_GEN_PMCON_3); reg8 &= 0xfe; switch (pwr_on) { case MAINBOARD_POWER_OFF: reg8 |= 1; state = "off"; break; case MAINBOARD_POWER_ON: reg8 &= ~1; state = "on"; break; case MAINBOARD_POWER_KEEP: reg8 &= ~1; state = "state keep"; break; default: state = "undefined"; } reg8 |= (3 << 4); /* avoid #S4 assertions */ reg8 &= ~(1 << 3); /* minimum asssertion is 1 to 2 RTCCLK */ pci_write_config8(dev, D31F0_GEN_PMCON_3, reg8); printk(BIOS_INFO, "Set power %s after power failure.\n", state); /* Set up NMI on errors. */ reg8 = inb(0x61); reg8 &= 0x0f; /* Higher Nibble must be 0 */ reg8 &= ~(1 << 3); /* IOCHK# NMI Enable */ // reg8 &= ~(1 << 2); /* PCI SERR# Enable */ reg8 |= (1 << 2); /* PCI SERR# Disable for now */ outb(reg8, 0x61); reg8 = inb(0x74); /* Read from 0x74 as 0x70 is write only. */ nmi_option = NMI_OFF; get_option(&nmi_option, "nmi"); if (nmi_option) { printk(BIOS_INFO, "NMI sources enabled.\n"); reg8 &= ~(1 << 7); /* Set NMI. */ } else { printk(BIOS_INFO, "NMI sources disabled.\n"); reg8 |= ( 1 << 7); /* Can't mask NMI from PCI-E and NMI_NOW */ } outb(reg8, 0x70); /* Enable CPU_SLP# and Intel Speedstep, set SMI# rate down */ reg16 = pci_read_config16(dev, D31F0_GEN_PMCON_1); reg16 &= ~(3 << 0); // SMI# rate 1 minute reg16 |= (1 << 2); // CLKRUN_EN - Mobile/Ultra only reg16 |= (1 << 3); // Speedstep Enable - Mobile/Ultra only reg16 |= (1 << 5); // CPUSLP_EN Desktop only if (config->c4onc3_enable) reg16 |= (1 << 7); // another laptop wants this? // reg16 &= ~(1 << 10); // BIOS_PCI_EXP_EN - Desktop/Mobile only reg16 |= (1 << 10); // BIOS_PCI_EXP_EN - Desktop/Mobile only #if DEBUG_PERIODIC_SMIS /* Set DEBUG_PERIODIC_SMIS in i82801ix.h to debug using * periodic SMIs. */ reg16 |= (3 << 0); // Periodic SMI every 8s #endif if (config->c5_enable) reg16 |= (1 << 11); /* Enable C5, C6 and PMSYNC# */ pci_write_config16(dev, D31F0_GEN_PMCON_1, reg16); /* Set exit timings for C5/C6. */ if (config->c5_enable) { reg8 = pci_read_config8(dev, D31F0_C5_EXIT_TIMING); reg8 &= ~((7 << 3) | (7 << 0)); if (config->c6_enable) reg8 |= (5 << 3) | (3 << 0); /* 38-44us PMSYNC# to STPCLK#, 95-102us DPRSTP# to STP_CPU# */ else reg8 |= (0 << 3) | (1 << 0); /* 16-17us PMSYNC# to STPCLK#, 34-40us DPRSTP# to STP_CPU# */ pci_write_config8(dev, D31F0_C5_EXIT_TIMING, reg8); } // Set the board's GPI routing. i82801ix_gpi_routing(dev); pmbase = pci_read_config16(dev, 0x40) & 0xfffe; outl(config->gpe0_en, pmbase + 0x28); outw(config->alt_gp_smi_en, pmbase + 0x38); /* Set up power management block and determine sleep mode */ reg16 = inw(pmbase + 0x00); /* PM1_STS */ outw(reg16, pmbase + 0x00); /* Clear status bits. At least bit11 (power button override) must be cleared or SCI will be constantly fired and OSPM must not know about it (ACPI spec says to ignore the bit). */ reg32 = inl(pmbase + 0x04); // PM1_CNT reg32 &= ~(7 << 10); // SLP_TYP outl(reg32, pmbase + 0x04); /* Set duty cycle for hardware throttling (defaults to 0x0: 50%). */ reg32 = inl(pmbase + 0x10); reg32 &= ~(7 << 5); reg32 |= (config->throttle_duty & 7) << 5; outl(reg32, pmbase + 0x10); }
void cache_as_ram_main(unsigned long bist, unsigned long cpu_init_detectedx) { u32 val; u8 byte; device_t dev; val = agesawrapper_amdinitmmio(); hudson_lpc_port80(); //__asm__ volatile ("1: jmp 1b"); /* TODO: */ dev = PCI_DEV(0, 0x14, 3);//pci_locate_device(PCI_ID(0x1002, 0x439D), 0); byte = pci_read_config8(dev, 0x48); byte |= 3; /* 2e, 2f */ pci_write_config8(dev, 0x48, byte); if (!cpu_init_detectedx && boot_cpu()) { post_code(0x30); post_code(0x31); lpc47n217_enable_serial(SERIAL_DEV, CONFIG_TTYS0_BASE); outb(0x24, 0xcd6); outb(0x1, 0xcd7); outb(0xea, 0xcd6); outb(0x1, 0xcd7); *(u8 *)0xfed80101 = 0x98; console_init(); } /* Halt if there was a built in self test failure */ post_code(0x34); report_bist_failure(bist); /* Load MPB */ val = cpuid_eax(1); printk(BIOS_DEBUG, "BSP Family_Model: %08x \n", val); printk(BIOS_DEBUG, "cpu_init_detectedx = %08lx \n", cpu_init_detectedx); post_code(0x37); printk(BIOS_DEBUG, "agesawrapper_amdinitreset "); val = agesawrapper_amdinitreset(); if(val) { printk(BIOS_DEBUG, "agesawrapper_amdinitreset failed: %x \n", val); } post_code(0x39); val = agesawrapper_amdinitearly (); if(val) { printk(BIOS_DEBUG, "agesawrapper_amdinitearly failed: %x \n", val); } printk(BIOS_DEBUG, "Got past agesawrapper_amdinitearly\n"); int s3resume = acpi_is_wakeup_early() && acpi_s3_resume_allowed(); if (!s3resume) { post_code(0x40); val = agesawrapper_amdinitpost (); if(val) { printk(BIOS_DEBUG, "agesawrapper_amdinitpost failed: %x \n", val); } printk(BIOS_DEBUG, "Got past agesawrapper_amdinitpost\n"); post_code(0x41); val = agesawrapper_amdinitenv (); if(val) { printk(BIOS_DEBUG, "agesawrapper_amdinitenv failed: %x \n", val); } printk(BIOS_DEBUG, "Got past agesawrapper_amdinitenv\n"); disable_cache_as_ram(); } else { /* S3 detect */ printk(BIOS_INFO, "S3 detected\n"); post_code(0x60); printk(BIOS_DEBUG, "agesawrapper_amdinitresume "); val = agesawrapper_amdinitresume(); if (val) printk(BIOS_DEBUG, "error level: %x \n", val); else printk(BIOS_DEBUG, "passed.\n"); printk(BIOS_DEBUG, "agesawrapper_amds3laterestore "); val = agesawrapper_amds3laterestore (); if (val) printk(BIOS_DEBUG, "error level: %x \n", val); else printk(BIOS_DEBUG, "passed.\n"); post_code(0x61); prepare_for_resume(); } post_code(0x50); copy_and_run(); post_code(0x54); /* Should never see this post code. */ }
static void pci_init(device_t dev) { u32 dword; u16 word; u8 byte; /* RPR 5.1 Enables the PCI-bridge subtractive decode */ /* This setting is strongly recommended since it supports some legacy PCI add-on cards,such as BIOS debug cards */ printk_info("Enables the PCI-bridge subtractive decode\n"); byte = pci_read_config8(dev, 0x4B); byte |= 1 << 7; pci_write_config8(dev, 0x4B, byte); byte = pci_read_config8(dev, 0x40); byte |= 1 << 5; pci_write_config8(dev, 0x40, byte); //vga pci card support //lycheng /* PCI Command: Enable IO response */ byte = pci_read_config8(dev, 0x04); byte |= (1 << 0)|(1 << 5)|(1 << 1)|(1 << 2); pci_write_config8(dev, 0x04, byte); /* PCI Command: VGA enable */ byte = pci_read_config8(dev, 0x3e); byte |= (1 << 3); pci_write_config8(dev, 0x3e, byte); //end vga pci card support /* RPR5.2 PCI-bridge upstream dual address window */ /* this setting is applicable if the system memory is more than 4GB,and the PCI device can support dual address access */ printk_info("PCI-bridge upstream dual address window\n"); byte = pci_read_config8(dev, 0x50); //byte |= 1 << 0; byte &= ~(1 << 0); pci_write_config8(dev, 0x50, byte); /* RPR 5.3 PCI bus 64-byte DMA read access */ /* Enhance the PCI bus DMA performance */ printk_info("PCI bus 64-byte DMA read access\n"); byte = pci_read_config8(dev, 0x4B); byte |= 1 << 4; pci_write_config8(dev, 0x4B, byte); /* RPR 5.4 Enables the PCIB writes to be cacheline aligned. */ /* The size of the writes will be set in the Cacheline Register */ printk_info("Enables the PCIB writes to be cacheline aligned.\n"); byte = pci_read_config8(dev, 0x40); byte |= 1 << 1; pci_write_config8(dev, 0x40, byte); /* RPR 5.5 Enables the PCIB to retain ownership of the bus on the Primary side and on the Secondary side when GNT# is deasserted */ printk_info("Enables the PCIB to retain ownership of the bus\n"); pci_write_config8(dev, 0x0D, 0x40); pci_write_config8(dev, 0x1B, 0x40); /* RPR 5.6 Enable the command matching checking function on "Memory Read" & "Memory Read Line" commands */ printk_info("Enable the command matching checking function\n"); byte = pci_read_config8(dev, 0x4B); byte |= 1 << 6; pci_write_config8(dev, 0x4B, byte); /* RPR 5.7 When enabled, the PCI arbiter checks for the Bus Idle before asserting GNT# */ printk_info("the PCI arbiter checks for the Bus Idle before asserting GNT#\n"); byte = pci_read_config8(dev, 0x4B); byte |= 1 << 0; pci_write_config8(dev, 0x4B, byte); /* RPR 5.8 Adjusts the GNT# de-assertion time */ printk_info("Adjusts the GNT# de-assertion time\n"); word = pci_read_config16(dev, 0x64); word |= 1 << 12; pci_write_config16(dev, 0x64, word); /* RPR 5.9 Fast Back to Back transactions support */ printk_info("Fast Back to Back transactions support\n"); byte = pci_read_config8(dev, 0x48); byte |= 1 << 2; /* pci_write_config8(dev, 0x48, byte); */ /* RPR 5.10 Enable Lock Operation */ /* byte = pci_read_config8(dev, 0x48); */ byte |= 1 << 3; pci_write_config8(dev, 0x48, byte); /* RPR 5.11 Enable additional optional PCI clock */ printk_info("Enable additional optional PCI clock\n"); word = pci_read_config16(dev, 0x64); word |= 1 << 8; pci_write_config16(dev, 0x64, word); /* RPR 5.12 Enable One-Prefetch-Channel Mode */ printk_info("Enable One-Prefetch-Channel Mode\n"); dword = pci_read_config32(dev, 0x64); dword |= 1 << 20; pci_write_config32(dev, 0x64, dword); /* RPR 5.13 Disable PCIB MSI Capability */ printk_info("Disable PCIB MSI Capability\n"); byte = pci_read_config8(dev, 0x40); byte &= ~(1 << 3); pci_write_config8(dev, 0x40, byte); /* rpr5.14 Adjusting CLKRUN# */ printk_info("Adjusting CLKRUN\n"); dword = pci_read_config32(dev, 0x64); dword |= (1 << 15); pci_write_config32(dev, 0x64, dword); }
/* * SB700 enables all USB controllers by default in SMBUS Control. * SB700 enables SATA by default in SMBUS Control. */ static void sm_init(device_t dev) { u8 byte; u8 byte_old; u8 rev; u32 dword; void *ioapic_base; uint32_t power_state; uint32_t enable_legacy_usb; u32 nmi_option; printk(BIOS_INFO, "sm_init().\n"); rev = get_sb700_revision(dev); /* This works in a similar fashion to a memory resource, but without an enable bit */ ioapic_base = (void *)(pci_read_config32(dev, 0x74) & (0xffffffe0)); setup_ioapic(ioapic_base, 0); /* Don't rename IOAPIC ID. */ enable_legacy_usb = 1; get_option(&enable_legacy_usb, "enable_legacy_usb"); /* 2.10 Interrupt Routing/Filtering */ byte = pci_read_config8(dev, 0x62); if (enable_legacy_usb) byte |= 0x3; else byte &= ~0x3; pci_write_config8(dev, 0x62, byte); byte = pci_read_config8(dev, 0x67); if (enable_legacy_usb) byte |= 0x1 << 7; else byte &= ~(0x1 << 7); pci_write_config8(dev, 0x67, byte); /* Delay back to back interrupts to the CPU. */ dword = pci_read_config16(dev, 0x64); dword |= 1 << 13; pci_write_config16(dev, 0x64, dword); /* rrg:K8 INTR Enable (BIOS should set this bit after PIC initialization) */ /* rpr 2.1 Enabling Legacy Interrupt */ dword = pci_read_config8(dev, 0x62); dword |= 1 << 2; pci_write_config8(dev, 0x62, dword); dword = pci_read_config32(dev, 0x78); dword |= 1 << 9; pci_write_config32(dev, 0x78, dword); /* enable 0xCD6 0xCD7 */ /* bit 10: MultiMediaTimerIrqEn */ dword = pci_read_config8(dev, 0x64); dword |= 1 << 10; pci_write_config8(dev, 0x64, dword); /* enable serial irq */ byte = pci_read_config8(dev, 0x69); byte |= 1 << 7; /* enable serial irq function */ byte &= ~(0xF << 2); byte |= 4 << 2; /* set NumSerIrqBits=4 */ pci_write_config8(dev, 0x69, byte); /* Sx State Settings * Note: These 2 registers need to be set correctly for the S-state * to work properly. Otherwise the system may hang during resume * from the S-state. */ /*Use 8us clock for delays in the S-state resume timing sequence.*/ byte = pm_ioread(0x65); byte &= ~(1 << 7); pm_iowrite(0x65, byte); /* Delay the APIC interrupt to the CPU until the system has fully resumed from the S-state. */ byte = pm_ioread(0x68); byte |= 1 << 2; pm_iowrite(0x68, byte); /* IRQ0From8254 */ byte = pci_read_config8(dev, 0x41); byte &= ~(1 << 7); pci_write_config8(dev, 0x41, byte); byte = pm_ioread(0x61); if (IS_ENABLED(CONFIG_CPU_AMD_MODEL_10XXX)) byte &= ~(1 << 1); /* Clear for non-K8 CPUs */ else byte |= 1 << 1; /* Set to enable NB/SB handshake during IOAPIC interrupt for AMD K8/K7 */ pm_iowrite(0x61, byte); /* disable SMI */ byte = pm_ioread(0x53); byte |= 1 << 3; pm_iowrite(0x53, byte); /* power after power fail */ power_state = CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL; get_option(&power_state, "power_on_after_fail"); if (power_state > 2) { printk(BIOS_WARNING, "Invalid power_on_after_fail setting, using default\n"); power_state = CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL; } byte = pm_ioread(0x74); byte &= ~0x03; if (power_state == POWER_MODE_OFF) byte |= 0x0; else if (power_state == POWER_MODE_ON) byte |= 0x1; else if (power_state == POWER_MODE_LAST) byte |= 0x2; byte |= 1 << 2; pm_iowrite(0x74, byte); printk(BIOS_INFO, "set power \"%s\" after power fail\n", power_mode_names[power_state]); byte = pm_ioread(0x68); byte &= ~(1 << 1); /* 2.7 */ byte |= 1 << 2; pm_iowrite(0x68, byte); /* 2.7 */ byte = pm_ioread(0x65); byte &= ~(1 << 7); pm_iowrite(0x65, byte); /* 2.16 */ byte = pm_ioread(0x55); byte |= 1 << 5; pm_iowrite(0x55, byte); byte = pm_ioread(0xD7); byte |= 1 << 6 | 1 << 1; pm_iowrite(0xD7, byte); /* 2.15 */ byte = pm_ioread(0x42); byte &= ~(1 << 2); pm_iowrite(0x42, byte); /* Set up NMI on errors */ byte = inb(0x70); /* RTC70 */ byte_old = byte; nmi_option = NMI_OFF; get_option(&nmi_option, "nmi"); if (nmi_option) { byte &= ~(1 << 7); /* set NMI */ printk(BIOS_INFO, "++++++++++set NMI+++++\n"); } else { byte |= (1 << 7); /* Can not mask NMI from PCI-E and NMI_NOW */ printk(BIOS_INFO, "++++++++++no set NMI+++++\n"); } byte &= ~(1 << 7); if (byte != byte_old) { outb(byte, 0x70); } /*rpr v2.13 2.22 SMBUS PCI Config */ byte = pci_read_config8(dev, 0xE1); if ((REV_SB700_A11 == rev) || REV_SB700_A12 == rev) { byte |= 1 << 0; } /*Set bit2 to 1, enable Io port 60h read/write SMi trapping and *Io port 64h write Smi trapping. conflict with ps2 keyboard */ //byte |= 1 << 2 | 1 << 3 | 1 << 4; byte |= 1 << 3 | 1 << 4; pci_write_config8(dev, 0xE1, byte); /* 2.5 Enabling Non-Posted Memory Write */ axindxc_reg(0x10, 1 << 9, 1 << 9); /* 2.11 IO Trap Settings */ abcfg_reg(0x10090, 1 << 16, 1 << 16); /* ab index */ pci_write_config32(dev, 0xF0, AB_INDX); /* Initialize the real time clock */ cmos_init(0); /* 4.3 Enabling Upstream DMA Access */ axcfg_reg(0x04, 1 << 2, 1 << 2); /* 4.4 Enabling IDE/PCIB Prefetch for Performance Enhancement */ abcfg_reg(0x10060, 9 << 17, 9 << 17); abcfg_reg(0x10064, 9 << 17, 9 << 17); /* 4.5 Enabling OHCI Prefetch for Performance Enhancement, A12 */ abcfg_reg(0x80, 1 << 0, 1<< 0); /* 4.6 B-Link Client's Credit Variable Settings for the Downstream Arbitration Equation */ /* 4.7 Enabling Additional Address Bits Checking in Downstream */ /* 4.16 IO write and SMI ordering enhancement*/ abcfg_reg(0x9c, 3 << 0, 3 << 0); if (REV_SB700_A12 == rev) { abcfg_reg(0x9c, 1 << 8, 1 << 8); } else if (rev >= REV_SB700_A14) { abcfg_reg(0x9c, 1 << 8, 0 << 8); } if (REV_SB700_A15 == rev) { abcfg_reg(0x90, 1 << 21, 1 << 21); abcfg_reg(0x9c, 1 << 5 | 1 << 9 | 1 << 15, 1 << 5 | 1 << 9 | 1 << 15); } /* 4.8 Set B-Link Prefetch Mode */ abcfg_reg(0x80, 3 << 17, 3 << 17); /* 4.9 Enabling Detection of Upstream Interrupts */ abcfg_reg(0x94, 1 << 20 | 0x7FFFF, 1 << 20 | 0x00FEE); /* 4.10: Enabling Downstream Posted Transactions to Pass Non-Posted * Transactions for the K8 Platform (for All Revisions) */ abcfg_reg(0x10090, 1 << 8, 1 << 8); /* Set ACPI Software clock Throttling Period to 244 us*/ byte = pm_ioread(0x68); byte &= ~(3 << 6); byte |= (2 << 6); /* 244us */ pm_iowrite(0x68, byte); if (REV_SB700_A15 == rev) { u16 word; /* rpr v2.13 4.18 Enabling Posted Pass Non-Posted Downstream */ axindxc_reg(0x02, 1 << 9, 1 << 9); abcfg_reg(0x9C, 0x00007CC0, 0x00007CC0); abcfg_reg(0x1009C, 0x00000030, 0x00000030); abcfg_reg(0x10090, 0x00001E00, 0x00001E00); /* rpr v2.13 4.19 Enabling Posted Pass Non-Posted Upstream */ abcfg_reg(0x58, 0x0000F800, 0x0000E800); /* rpr v2.13 4.20 64 bit Non-Posted Memory Write Support */ axindxc_reg(0x02, 1 << 10, 1 << 10); /* rpr v2.13 2.38 Unconditional Shutdown */ byte = pci_read_config8(dev, 0x43); byte &= ~(1 << 3); pci_write_config8(dev, 0x43, byte); word = pci_read_config16(dev, 0x38); word |= 1 << 12; pci_write_config16(dev, 0x38, word); byte |= 1 << 3; pci_write_config8(dev, 0x43, byte); /* Enable southbridge MMIO decode */ dword = pci_read_config32(dev, SB_MMIO_CFG_REG); dword &= ~(0xffffff << 8); dword |= SB_MMIO_BASE_ADDRESS; dword |= 0x1; pci_write_config32(dev, SB_MMIO_CFG_REG, dword); } byte = pci_read_config8(dev, 0xAE); if (IS_ENABLED(CONFIG_ENABLE_APIC_EXT_ID)) byte |= 1 << 4; byte |= 1 << 5; /* ACPI_DISABLE_TIMER_IRQ_ENHANCEMENT_FOR_8254_TIMER */ byte |= 1 << 6; /* Enable arbiter between APIC and PIC interrupts */ pci_write_config8(dev, 0xAE, byte); /* 4.11:Programming Cycle Delay for AB and BIF Clock Gating */ /* 4.12: Enabling AB and BIF Clock Gating */ abcfg_reg(0x10054, 0xFFFF0000, 0x1040000); abcfg_reg(0x54, 0xFF << 16, 4 << 16); abcfg_reg(0x54, 1 << 24, 0 << 24); abcfg_reg(0x98, 0x0000FF00, 0x00004700); /* 4.13:Enabling AB Int_Arbiter Enhancement (for All Revisions) */ abcfg_reg(0x10054, 0x0000FFFF, 0x07FF); /* 4.14:Enabling Requester ID for upstream traffic. */ abcfg_reg(0x98, 1 << 16, 1 << 16); /* 9.2: Enabling IDE Data Bus DD7 Pull Down Resistor */ byte = pm2_ioread(0xE5); byte |= 1 << 2; pm2_iowrite(0xE5, byte); /* Enable IDE controller. */ byte = pm_ioread(0x59); byte &= ~(1 << 1); pm_iowrite(0x59, byte); /* Enable SCI as irq9. */ outb(0x4, 0xC00); outb(0x9, 0xC01); printk(BIOS_INFO, "sm_init() end\n"); /* Enable NbSb virtual channel */ axcfg_reg(0x114, 0x3f << 1, 0 << 1); axcfg_reg(0x120, 0x7f << 1, 0x7f << 1); axcfg_reg(0x120, 7 << 24, 1 << 24); axcfg_reg(0x120, 1 << 31, 1 << 31); abcfg_reg(0x50, 1 << 3, 1 << 3); }
static void sata_init(struct device *dev) { u8 byte; u16 word; u32 dword; u8 rev_id; u32 sata_bar5; u16 sata_bar0, sata_bar1, sata_bar2, sata_bar3, sata_bar4; int i, j; device_t sm_dev; /* SATA SMBus Disable */ sm_dev = dev_find_slot(0, PCI_DEVFN(0x14, 0)); byte = pci_read_config8(sm_dev, 0xad); /* Disable SATA SMBUS */ byte |= (1 << 0); /* Enable SATA and power saving */ byte |= (1 << 1); byte |= (1 << 5); pci_write_config8(sm_dev, 0xad, byte); /* RPR 7.2 SATA Initialization */ /* Set the interrupt Mapping to INTG# */ byte = pci_read_config8(sm_dev, 0xaf); byte = 0x6 << 2; pci_write_config8(sm_dev, 0xaf, byte); /* get rev_id */ rev_id = pci_read_config8(sm_dev, 0x08) - 0x28; /* get base address */ sata_bar5 = pci_read_config32(dev, 0x24) & ~0x3FF; sata_bar0 = pci_read_config16(dev, 0x10) & ~0x7; sata_bar1 = pci_read_config16(dev, 0x14) & ~0x3; sata_bar2 = pci_read_config16(dev, 0x18) & ~0x7; sata_bar3 = pci_read_config16(dev, 0x1C) & ~0x3; sata_bar4 = pci_read_config16(dev, 0x20) & ~0xf; printk(BIOS_SPEW, "sata_bar0=%x\n", sata_bar0); /* 3030 */ printk(BIOS_SPEW, "sata_bar1=%x\n", sata_bar1); /* 3070 */ printk(BIOS_SPEW, "sata_bar2=%x\n", sata_bar2); /* 3040 */ printk(BIOS_SPEW, "sata_bar3=%x\n", sata_bar3); /* 3080 */ printk(BIOS_SPEW, "sata_bar4=%x\n", sata_bar4); /* 3000 */ printk(BIOS_SPEW, "sata_bar5=%x\n", sata_bar5); /* e0309000 */ /* disable combined mode */ byte = pci_read_config8(sm_dev, 0xAD); byte &= ~(1 << 3); pci_write_config8(sm_dev, 0xAD, byte); /* Program the 2C to 0x43801002 */ dword = 0x43801002; pci_write_config32(dev, 0x2c, dword); /* SERR-Enable */ word = pci_read_config16(dev, 0x04); word |= (1 << 8); pci_write_config16(dev, 0x04, word); /* Dynamic power saving */ byte = pci_read_config8(dev, 0x40); byte |= (1 << 2); pci_write_config8(dev, 0x40, byte); /* Set SATA Operation Mode, Set to IDE mode */ byte = pci_read_config8(dev, 0x40); byte |= (1 << 0); byte |= (1 << 4); pci_write_config8(dev, 0x40, byte); dword = 0x01018f00; pci_write_config32(dev, 0x8, dword); byte = pci_read_config8(dev, 0x40); byte &= ~(1 << 0); pci_write_config8(dev, 0x40, byte); /* Enable the SATA watchdog counter */ byte = pci_read_config8(dev, 0x44); byte |= (1 << 0); pci_write_config8(dev, 0x44, byte); /* Set bit 29 and 24 for A12 */ dword = pci_read_config32(dev, 0x40); if (rev_id < 0x14) /* before A12 */ dword |= (1 << 29); else dword &= ~(1 << 29); /* A14 and above */ pci_write_config32(dev, 0x40, dword); /* set bit 21 for A12 */ dword = pci_read_config32(dev, 0x48); if (rev_id < 0x14) /* before A12 */ dword |= 1 << 24 | 1 << 21; else { dword &= ~(1 << 24 | 1 << 21); /* A14 and above */ dword &= ~0xFF80; /* 15:7 */ dword |= 1 << 15 | 0x7F << 7; } pci_write_config32(dev, 0x48, dword); /* Program the watchdog counter to 0x10 */ byte = 0x10; pci_write_config8(dev, 0x46, byte); sb7xx_51xx_setup_sata_phys(dev); /* Enable the I/O, MM, BusMaster access for SATA */ byte = pci_read_config8(dev, 0x4); byte |= 7 << 0; pci_write_config8(dev, 0x4, byte); #if CONFIG_SOUTHBRIDGE_AMD_SUBTYPE_SP5100 /* Master Latency Timer */ pci_write_config32(dev, 0xC, 0x00004000); #endif /* RPR7.7 SATA drive detection. */ /* Use BAR5+0x128,BAR0 for Primary Slave */ /* Use BAR5+0x1A8,BAR0 for Primary Slave */ /* Use BAR5+0x228,BAR2 for Secondary Master */ /* Use BAR5+0x2A8,BAR2 for Secondary Slave */ /* Use BAR5+0x328,PATA_BAR0/2 for Primary/Secondary master emulation */ /* Use BAR5+0x3A8,PATA_BAR0/2 for Primary/Secondary Slave emulation */ /* TODO: port 4,5, which are PATA emulations. What are PATA_BARs? */ for (i = 0; i < 4; i++) { byte = read8(sata_bar5 + 0x128 + 0x80 * i); printk(BIOS_SPEW, "SATA port %i status = %x\n", i, byte); byte &= 0xF; if( byte == 0x1 ) { /* If the drive status is 0x1 then we see it but we aren't talking to it. */ /* Try to do something about it. */ printk(BIOS_SPEW, "SATA device detected but not talking. Trying lower speed.\n"); /* Read in Port-N Serial ATA Control Register */ byte = read8(sata_bar5 + 0x12C + 0x80 * i); /* Set Reset Bit and 1.5g bit */ byte |= 0x11; write8((sata_bar5 + 0x12C + 0x80 * i), byte); /* Wait 1ms */ mdelay(1); /* Clear Reset Bit */ byte &= ~0x01; write8((sata_bar5 + 0x12C + 0x80 * i), byte); /* Wait 1ms */ mdelay(1); /* Reread status */ byte = read8(sata_bar5 + 0x128 + 0x80 * i); printk(BIOS_SPEW, "SATA port %i status = %x\n", i, byte); byte &= 0xF; } if (byte == 0x3) { for (j = 0; j < 10; j++) { if (!sata_drive_detect(i, ((i / 2) == 0) ? sata_bar0 : sata_bar2)) break; } printk(BIOS_DEBUG, "%s %s device is %sready after %i tries\n", (i / 2) ? "Secondary" : "Primary", (i % 2 ) ? "Slave" : "Master", (j == 10) ? "not " : "", (j == 10) ? j : j + 1); } else { printk(BIOS_DEBUG, "No %s %s SATA drive on Slot%i\n", (i / 2) ? "Secondary" : "Primary", (i % 2 ) ? "Slave" : "Master", i); } } /* Below is CIM InitSataLateFar */ /* Enable interrupts from the HBA */ byte = read8(sata_bar5 + 0x4); byte |= 1 << 1; write8((sata_bar5 + 0x4), byte); /* Clear error status */ write32((sata_bar5 + 0x130), 0xFFFFFFFF); write32((sata_bar5 + 0x1b0), 0xFFFFFFFF); write32((sata_bar5 + 0x230), 0xFFFFFFFF); write32((sata_bar5 + 0x2b0), 0xFFFFFFFF); write32((sata_bar5 + 0x330), 0xFFFFFFFF); write32((sata_bar5 + 0x3b0), 0xFFFFFFFF); /* Clear SATA status,Firstly we get the AcpiGpe0BlkAddr */ /* ????? why CIM does not set the AcpiGpe0BlkAddr , but use it??? */ /* word = 0x0000; */ /* word = pm_ioread(0x28); */ /* byte = pm_ioread(0x29); */ /* word |= byte<<8; */ /* printk(BIOS_DEBUG, "AcpiGpe0Blk addr = %x\n", word); */ /* write32(word, 0x80000000); */ }
/** * @brief Enable resources for children devices * * @param dev the device whos children's resources are to be enabled * */ static void hudson_lpc_enable_childrens_resources(device_t dev) { struct bus *link; u32 reg, reg_x; int var_num = 0; u16 reg_var[3]; u16 reg_size[1] = {512}; u8 wiosize = pci_read_config8(dev, 0x74); /* Be bit relaxed, tolerate that LPC region might be bigger than resource we try to fit, * do it like this for all regions < 16 bytes. If there is a resource > 16 bytes * it must be 512 bytes to be able to allocate the fresh LPC window. * * AGESA likes to enable already one LPC region in wide port base 0x64-0x65, * using DFLT_SIO_PME_BASE_ADDRESS, 512 bytes size * The code tries to check if resource can fit into this region */ reg = pci_read_config32(dev, 0x44); reg_x = pci_read_config32(dev, 0x48); /* check if ranges are free and not use them if entry is just already taken */ if (reg_x & (1 << 2)) var_num = 1; /* just in case check if someone did not manually set other ranges too */ if (reg_x & (1 << 24)) var_num = 2; if (reg_x & (1 << 25)) var_num = 3; /* check AGESA region size */ if (wiosize & (1 << 0)) reg_size[0] = 16; reg_var[2] = pci_read_config16(dev, 0x90); reg_var[1] = pci_read_config16(dev, 0x66); reg_var[0] = pci_read_config16(dev, 0x64); for (link = dev->link_list; link; link = link->next) { device_t child; for (child = link->children; child; child = child->sibling) { if (child->enabled && (child->path.type == DEVICE_PATH_PNP)) { struct resource *res; for (res = child->resource_list; res; res = res->next) { u32 base, end; /* don't need long long */ u32 rsize, set = 0, set_x = 0; if (!(res->flags & IORESOURCE_IO)) continue; base = res->base; end = resource_end(res); /* find a resource size */ printk(BIOS_DEBUG, "hudson lpc decode:%s, base=0x%08x, end=0x%08x\n", dev_path(child), base, end); switch (base) { case 0x60: /* KB */ case 0x64: /* MS */ set |= (1 << 29); rsize = 1; break; case 0x3f8: /* COM1 */ set |= (1 << 6); rsize = 8; break; case 0x2f8: /* COM2 */ set |= (1 << 7); rsize = 8; break; case 0x378: /* Parallel 1 */ set |= (1 << 0); set |= (1 << 1); /* + 0x778 for ECP */ rsize = 8; break; case 0x3f0: /* FD0 */ set |= (1 << 26); rsize = 8; break; case 0x220: /* 0x220 - 0x227 */ set |= (1 << 8); rsize = 8; break; case 0x228: /* 0x228 - 0x22f */ set |= (1 << 9); rsize = 8; break; case 0x238: /* 0x238 - 0x23f */ set |= (1 << 10); rsize = 8; break; case 0x300: /* 0x300 -0x301 */ set |= (1 << 18); rsize = 2; break; case 0x400: set_x |= (1 << 16); rsize = 0x40; break; case 0x480: set_x |= (1 << 17); rsize = 0x40; case 0x500: set_x |= (1 << 18); rsize = 0x40; break; case 0x580: set_x |= (1 << 19); rsize = 0x40; break; case 0x4700: set_x |= (1 << 22); rsize = 0xc; break; case 0xfd60: set_x |= (1 << 23); rsize = 16; break; default: rsize = 0; /* try AGESA allocated region in region 0 */ if ((var_num > 0) && ((base >=reg_var[0]) && ((base + res->size) <= (reg_var[0] + reg_size[0])))) rsize = reg_size[0]; } /* check if region found and matches the enable */ if (res->size <= rsize) { reg |= set; reg_x |= set_x; /* check if we can fit resource in variable range */ } else if ((var_num < 3) && ((res->size <= 16) || (res->size == 512))) { /* use variable ranges if pre-defined do not match */ switch (var_num) { case 0: reg_x |= (1 << 2); if (res->size <= 16) { wiosize |= (1 << 0); } break; case 1: reg_x |= (1 << 24); if (res->size <= 16) wiosize |= (1 << 2); break; case 2: reg_x |= (1 << 25); if (res->size <= 16) wiosize |= (1 << 3); break; } reg_var[var_num++] = base & 0xffff; } else { printk(BIOS_ERR, "cannot fit LPC decode region:%s, base=0x%08x, end=0x%08x\n", dev_path(child), base, end); } } } } } pci_write_config32(dev, 0x44, reg); pci_write_config32(dev, 0x48, reg_x); /* Set WideIO for as many IOs found (fall through is on purpose) */ switch (var_num) { case 3: pci_write_config16(dev, 0x90, reg_var[2]); /* fall through */ case 2: pci_write_config16(dev, 0x66, reg_var[1]); /* fall through */ case 1: pci_write_config16(dev, 0x64, reg_var[0]); break; } pci_write_config8(dev, 0x74, wiosize); }
dword |= (1 << 23); pci_write_config32(dev, 0xe4, dword); #endif } static void lpc_slave_init(device_t dev) { lpc_common_init(dev); } static void rom_dummy_write(device_t dev) { u8 old, new; u8 *p; old = pci_read_config8(dev, 0x88); new = old | 0xc0; if (new != old) pci_write_config8(dev, 0x88, new); /* Enable write. */ old = pci_read_config8(dev, 0x6d); new = old | 0x01; if (new != old) pci_write_config8(dev, 0x6d, new); /* Dummy write. */ p = (u8 *) 0xffffffe0; old = 0; *p = old; old = *p;
SpdBAData = (u8) (CurrentDimminfo->SPDDataBuf [SPD_SDRAM_NO_OF_BANKS]); if (SpdBAData == 4) Count = 2; else if (SpdBAData == 8) Count = 3; else Count = 0; if (Count < Bank) Bank = Count; } Shift <<= 2; } Data = pci_read_config8(MEMCTRL, 0x69); Data &= ~0xc0; Data |= (Bank << 6); pci_write_config8(MEMCTRL, 0x69, Data); if (DramAttr->DimmNumChB > 0) { CurrentDimminfo = &(DramAttr->DimmInfo[3]); //this Rank in a dimm SpdBAData = (u8) (CurrentDimminfo->SPDDataBuf[SPD_SDRAM_NO_OF_BANKS]); if (SpdBAData == 4) Bank = 2; else if (SpdBAData == 2) Bank = 1; else Bank = 0; pci_write_config8(MEMCTRL, 0x87, Bank);
static void *smp_write_config_table(void *v) { struct mp_config_table *mc; int bus_isa; unsigned char bus_8111_0; unsigned char bus_8111_1; unsigned char bus_8131_1; unsigned char bus_8131_2; mc = (void *)(((char *)v) + SMP_FLOATING_TABLE_LEN); mptable_init(mc, LOCAL_APIC_ADDR); smp_write_processors(mc); { device_t dev; /* 8111 */ dev = dev_find_slot(1, PCI_DEVFN(0x03,0)); if (dev) { bus_8111_0 = pci_read_config8(dev, PCI_PRIMARY_BUS); bus_8111_1 = pci_read_config8(dev, PCI_SECONDARY_BUS); } else { printk(BIOS_DEBUG, "ERROR - could not find PCI 1:03.0, using defaults\n"); bus_8111_0 = 1; bus_8111_1 = 4; } /* 8131-1 */ dev = dev_find_slot(1, PCI_DEVFN(0x01,0)); if (dev) { bus_8131_1 = pci_read_config8(dev, PCI_SECONDARY_BUS); } else { printk(BIOS_DEBUG, "ERROR - could not find PCI 1:01.0, using defaults\n"); bus_8131_1 = 2; } /* 8131-2 */ dev = dev_find_slot(1, PCI_DEVFN(0x02,0)); if (dev) { bus_8131_2 = pci_read_config8(dev, PCI_SECONDARY_BUS); } else { printk(BIOS_DEBUG, "ERROR - could not find PCI 1:02.0, using defaults\n"); bus_8131_2 = 3; } } mptable_write_buses(mc, NULL, &bus_isa); /* Legacy IOAPIC #2 */ smp_write_ioapic(mc, 2, 0x11, VIO_APIC_VADDR); { device_t dev; struct resource *res; /* 8131-1 apic #3 */ dev = dev_find_slot(1, PCI_DEVFN(0x01,1)); if (dev) { res = find_resource(dev, PCI_BASE_ADDRESS_0); if (res) { smp_write_ioapic(mc, 0x03, 0x11, res2mmio(res, 0, 0)); } } /* 8131-2 apic #4 */ dev = dev_find_slot(1, PCI_DEVFN(0x02,1)); if (dev) { res = find_resource(dev, PCI_BASE_ADDRESS_0); if (res) { smp_write_ioapic(mc, 0x04, 0x11, res2mmio(res, 0, 0)); } } } mptable_add_isa_interrupts(mc, bus_isa, 0x2, 0); /* PCI Ints: Type Polarity Trigger Bus ID PCIDEVNUM|IRQ APIC ID PIN# */ /* Integrated SMBus 2.0 */ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8111_0, (0x04<<2)|3, 0x2, 0x13); /* Integrated AMD AC97 Audio */ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8111_0, (0x04<<2)|1, 0x2, 0x11); /* Integrated AMD USB */ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8111_1, (0x00<<2)|3, 0x2, 0x13); /* On board ATI Rage XL */ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8111_1, (0x05<<2)|0, 0x2, 0x10); /* On board Broadcom nics */ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8131_1, (0x01<<2)|0, 0x3, 0x00); smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8131_1, (0x01<<2)|1, 0x3, 0x01); /* On board LSI SCSI */ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8131_1, (0x02<<2)|0, 0x3, 0x02); /* PCI Slot 1 PCIX */ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8131_2, (0x03<<2)|0, 0x2, 0x10); smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8131_2, (0x03<<2)|1, 0x2, 0x11); smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8131_2, (0x03<<2)|2, 0x2, 0x12); smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8131_2, (0x03<<2)|3, 0x2, 0x13); /* PCI Slot 2 PCIX */ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8131_2, (0x04<<2)|0, 0x2, 0x11); smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8131_2, (0x04<<2)|1, 0x2, 0x12); smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8131_2, (0x04<<2)|2, 0x2, 0x13); smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8131_2, (0x04<<2)|3, 0x2, 0x10); /* Standard local interrupt assignments: * Type Polarity Trigger Bus ID IRQ APIC ID PIN# */ mptable_lintsrc(mc, bus_isa); /* There is no extension information... */ /* Compute the checksums */ return mptable_finalize(mc); }
/* sbDevicesPorInitTable */ void sb700_devices_por_init(void) { device_t dev; u8 byte; /* SMBus Device, BDF:0-20-0 */ dev = _pci_make_tag(0, 20, 0); /* sbPorAtStartOfTblCfg */ /* Set A-Link bridge access address. This address is set at device 14h, function 0, register 0xf0. * This is an I/O address. The I/O address must be on 16-byte boundry. */ printk_info("set a-link bridge access address\n"); //pci_write_config32(dev, 0xf0, AB_INDX); pci_write_config32(dev, 0xf0, 0x00000cd8); /* To enable AB/BIF DMA access, a specific register inside the BIF register space needs to be configured first. */ /*Enables the SB600 to send transactions upstream over A-Link Express interface. */ printk_info("To enable ab bif dam access\n"); axcfg_reg(0x04, 1 << 2, 1 << 2); axindxc_reg(0x21, 0xff, 0); /* 2.3.5:Enabling Non-Posted Memory Write for the K8 Platform */ printk_info("Enabling Non-Posted Memory Write for the K8 Platform\n"); axindxc_reg(0x10, 1 << 9, 1 << 9); /* END of sbPorAtStartOfTblCfg */ /* sbDevicesPorInitTables */ /* set smbus iobase */ printk_info("set smbus iobase\n"); //pci_write_config32(dev, 0x10, SMBUS_IO_BASE | 1); //vga lycheng pci_write_config32(dev, 0x90, SMBUS_IO_BASE | 1); /* enable smbus controller interface */ printk_info("enable smbus controller interface\n"); byte = pci_read_config8(dev, 0xd2); byte |= (1 << 0); pci_write_config8(dev, 0xd2, byte); #if 0 /* set smbus 1, ASF 2.0 (Alert Standard Format), iobase */ printk_info("enable smbus 1, ASF 2.0\n"); pci_write_config16(dev, 0x58, SMBUS_IO_BASE | 0x11); #endif /* TODO: I don't know the useage of followed two lines. I copied them from CIM. */ pci_write_config8(dev, 0x0a, 0x1); pci_write_config8(dev, 0x0b, 0x6); /* KB2RstEnable */ printk_info("KB2RstEnable\n"); pci_write_config8(dev, 0x40, 0xd4); /* Enable ISA Address 0-960K decoding */ printk_info("Enable ISA address decoding\n"); pci_write_config8(dev, 0x48, 0x0f); /* Enable ISA Address 0xC0000-0xDFFFF decode */ printk_info("Enable ISA address 0xc0000-0xdffff decode\n"); pci_write_config8(dev, 0x49, 0xff); /* Enable decode cycles to IO C50, C51, C52 GPM controls. */ printk_info("Enable decode cycles to IO controls\n"); byte = pci_read_config8(dev, 0x41); byte &= 0x80; byte |= 0x33; pci_write_config8(dev, 0x41, byte); /* Legacy DMA Prefetch Enhancement, CIM masked it. */ /* pci_write_config8(dev, 0x43, 0x1); */ /* Disabling Legacy USB Fast SMI# */ printk_info("Disabling Legacy USB Fast SMI\n"); byte = pci_read_config8(dev, 0x62); byte |= 0x24; pci_write_config8(dev, 0x62, byte); /* Features Enable */ printk_info("Features Enable\n"); pci_write_config32(dev, 0x64, 0x829E7DBF); /* bit10: Enables the HPET interrupt. */ /* SerialIrq Control */ printk_info("SerialIrq Control\n"); pci_write_config8(dev, 0x69, 0x90); /* Test Mode, PCIB_SReset_En Mask is set. */ pci_write_config8(dev, 0x6c, 0x20); /* IO Address Enable, CIM set 0x78 only and masked 0x79. */ printk_info("IO Address Enable\n"); /*pci_write_config8(dev, 0x79, 0x4F); */ pci_write_config8(dev, 0x78, 0xFF); //#ifndef ENABLE_SATA #if 1 /* TODO: set ide as primary, if you want to boot from IDE, you'd better set it.Or add a configuration line.*/ printk_info("set ide as primary\n"); byte = pci_read_config8(dev, 0xAD); byte |= 0x1<<3; byte &= ~(0x1<<4); pci_write_config8(dev, 0xAD, byte); /* This register is not used on sb700. It came from older chipset. */ /*pci_write_config8(dev, 0x95, 0xFF); */ #endif /* Set smbus iospace enable, I don't know why write 0x04 into reg5 that is reserved */ printk_info("Set smbus iospace enable\n"); pci_write_config16(dev, 0x4, 0x0407); #if 1 /* clear any lingering errors, so the transaction will run */ printk_info("IO Address Enable\n"); //OUTB(INB(0xba000000 + SMBUS_IO_BASE + SMBHSTSTAT), 0xba000000 + SMBUS_IO_BASE + SMBHSTSTAT); OUTB(INB(BONITO_PCIIO_BASE_VA + SMBUS_IO_BASE + SMBHSTSTAT), BONITO_PCIIO_BASE_VA + SMBUS_IO_BASE + SMBHSTSTAT); #endif /* IDE Device, BDF:0-20-1 */ printk_info("sb700_devices_por_init(): IDE Device, BDF:0-20-1\n"); //dev = pci_locate_device(PCI_ID(0x1002, 0x438C), 0); dev = _pci_make_tag(0, 20, 1); /* Disable prefetch */ printk_info("Disable prefetch\n"); byte = pci_read_config8(dev, 0x63); byte |= 0x1; pci_write_config8(dev, 0x63, byte); /* LPC Device, BDF:0-20-3 */ printk_info("sb700_devices_por_init(): LPC Device, BDF:0-20-3\n"); //dev = pci_locate_device(PCI_ID(0x1002, 0x438D), 0); dev = _pci_make_tag(0, 20, 3); /* DMA enable */ printk_info("DMA enable\n"); pci_write_config8(dev, 0x40, 0x04); /* IO Port Decode Enable */ printk_info("IO Port Decode Enable\n"); pci_write_config8(dev, 0x44, 0xFF); pci_write_config8(dev, 0x45, 0xFF); pci_write_config8(dev, 0x46, 0xC3); pci_write_config8(dev, 0x47, 0xFF); /* IO/Mem Port Decode Enable, I don't know why CIM disable some ports. * Disable LPC TimeOut counter, enable SuperIO Configuration Port (2e/2f), * Alternate SuperIO Configuration Port (4e/4f), Wide Generic IO Port (64/65). * Enable bits for LPC ROM memory address range 1&2 for 1M ROM setting.*/ printk_info("IO/Mem Port Decode Enable\n"); byte = pci_read_config8(dev, 0x48); byte |= (1 << 1) | (1 << 0); /* enable Super IO config port 2e-2h, 4e-4f */ byte |= (1 << 3) | (1 << 4); /* enable for LPC ROM address range1&2, Enable 512KB rom access at 0xFFF80000 - 0xFFFFFFFF */ byte |= 1 << 6; /* enable for RTC I/O range */ pci_write_config8(dev, 0x48, byte); pci_write_config8(dev, 0x49, 0xFF); /* Enable 0x480-0x4bf, 0x4700-0x470B */ byte = pci_read_config8(dev, 0x4A); byte |= ((1 << 1) + (1 << 6)); /*0x42, save the configuraion for port 0x80. */ pci_write_config8(dev, 0x4A, byte); /* Set LPC ROM size, it has been done in sb700_lpc_init(). * enable LPC ROM range, 0xfff8: 512KB, 0xfff0: 1MB; * enable LPC ROM range, 0xfff8: 512KB, 0xfff0: 1MB * pci_write_config16(dev, 0x68, 0x000e) * pci_write_config16(dev, 0x6c, 0xfff0);*/ /* Enable Tpm12_en and Tpm_legacy. I don't know what is its usage and copied from CIM. */ printk_info("Enable Tpm12_en and Tpm_legacy\n"); pci_write_config8(dev, 0x7C, 0x05); /* P2P Bridge, BDF:0-20-4, the configuration of the registers in this dev are copied from CIM, * TODO: I don't know what are their mean? */ printk_info("sb700_devices_por_init(): P2P Bridge, BDF:0-20-4\n"); //dev = pci_locate_device(PCI_ID(0x1002, 0x4384), 0); dev = _pci_make_tag(0, 20, 4); /* I don't know why CIM tried to write into a read-only reg! */ /*pci_write_config8(dev, 0x0c, 0x20) */ ; /* Arbiter enable. */ printk_info("Arbiter enable\n"); pci_write_config8(dev, 0x43, 0xff); /* Set PCDMA request into hight priority list. */ /* pci_write_config8(dev, 0x49, 0x1) */ ; pci_write_config8(dev, 0x40, 0x26); /* I don't know why CIM set reg0x1c as 0x11. * System will block at sdram_initialize() if I set it before call sdram_initialize(). * If it is necessary to set reg0x1c as 0x11, please call this function after sdram_initialize(). * pci_write_config8(dev, 0x1c, 0x11); * pci_write_config8(dev, 0x1d, 0x11);*/ /*CIM set this register; but I didn't find its description in RPR. On DBM690T platform, I didn't find different between set and skip this register. But on Filbert platform, the DEBUG message from serial port on Peanut board can't be displayed after the bit0 of this register is set. pci_write_config8(dev, 0x04, 0x21); */ printk_info("CIM set this register\n"); pci_write_config8(dev, 0x0d, 0x40); pci_write_config8(dev, 0x1b, 0x40); /* Enable PCIB_DUAL_EN_UP will fix potential problem with PCI cards. */ printk_info("enable pcib_dual_en_up\n"); pci_write_config8(dev, 0x50, 0x01); #ifdef ENABLE_SATA /* SATA Device, BDF:0-17-0, Non-Raid-5 SATA controller */ printk_info("sb700_devices_por_init(): SATA Device, BDF:0-17-0\n"); //dev = pci_locate_device(PCI_ID(0x1002, 0x4380), 0); dev = _pci_make_tag(0, 17, 0); /*PHY Global Control, we are using A14. * default: 0x2c40 for ASIC revision A12 and below * 0x2c00 for ASIC revision A13 and above.*/ printk_info("PHY Global Control\n"); pci_write_config16(dev, 0x86, 0x2C00); #endif }
static void sata_init(struct device *dev) { u8 byte; u16 word; u32 dword; u8 rev_id; void *sata_bar5; u16 sata_bar0, sata_bar1, sata_bar2, sata_bar3, sata_bar4; int i, j; struct southbridge_ati_sb800_config *conf; conf = dev->chip_info; struct device *sm_dev; /* SATA SMBus Disable */ sm_dev = pcidev_on_root(0x14, 0); /* get rev_id */ rev_id = pci_read_config8(sm_dev, 0x08) - 0x2F; /* get base address */ sata_bar5 = (void *)(pci_read_config32(dev, 0x24) & ~0x3FF); sata_bar0 = pci_read_config16(dev, 0x10) & ~0x7; sata_bar1 = pci_read_config16(dev, 0x14) & ~0x3; sata_bar2 = pci_read_config16(dev, 0x18) & ~0x7; sata_bar3 = pci_read_config16(dev, 0x1C) & ~0x3; sata_bar4 = pci_read_config16(dev, 0x20) & ~0xf; printk(BIOS_SPEW, "sata_bar0=%x\n", sata_bar0); /* 3030 */ printk(BIOS_SPEW, "sata_bar1=%x\n", sata_bar1); /* 3070 */ printk(BIOS_SPEW, "sata_bar2=%x\n", sata_bar2); /* 3040 */ printk(BIOS_SPEW, "sata_bar3=%x\n", sata_bar3); /* 3080 */ printk(BIOS_SPEW, "sata_bar4=%x\n", sata_bar4); /* 3000 */ printk(BIOS_SPEW, "sata_bar5=%p\n", sata_bar5); /* e0309000 */ /* SERR-Enable */ word = pci_read_config16(dev, 0x04); word |= (1 << 8); pci_write_config16(dev, 0x04, word); /* Set SATA Operation Mode, Set to IDE mode */ byte = pci_read_config8(dev, 0x40); byte |= (1 << 0); //byte |= (1 << 4); pci_write_config8(dev, 0x40, byte); dword = 0x01018f00; pci_write_config32(dev, 0x8, dword); /* Program the 2C to 0x43801002 */ dword = 0x43801002; pci_write_config32(dev, 0x2c, dword); pci_write_config8(dev, 0x34, 0x70); /* 8.11 SATA MSI and D3 Power State Capability */ dword = read32(sata_bar5 + 0xFC); dword &= ~(1 << 11); /* rpr 8.8. Disabling Aggressive Link Power Management */ dword &= ~(1 << 12); /* rpr 8.9.1 Disabling Port Multiplier support. */ dword &= ~(1 << 10); /* rpr 8.9.2 disabling FIS-based Switching support */ dword &= ~(1 << 19); /* rpr 8.10. Disabling CCC (Command Completion Coalescing) Support */ write32((sata_bar5 + 0xFC), dword); dword = read32(sata_bar5 + 0xF8); dword &= ~(0x3F << 22); /* rpr 8.9.2 disabling FIS-based Switching support */ write32(sata_bar5 + 0xF8, dword); byte = pci_read_config8(dev, 0x40); byte &= ~(1 << 0); pci_write_config8(dev, 0x40, byte); /* rpr 8.3 */ printk(BIOS_SPEW, "rev_id=%x\n", rev_id); dword = pci_read_config32(dev, 0x84); if (rev_id == 0x11) /* A11 */ dword |= 1 << 22; pci_write_config32(dev, 0x84, dword); /* rpr8.12 Program the watchdog counter to 0x20 */ byte = pci_read_config8(dev, 0x44); byte |= 1 << 0; pci_write_config8(dev, 0x44, byte); pci_write_config8(dev, 0x46, 0x20); sb800_setup_sata_phys(dev); /* Enable the I/O, MM, BusMaster access for SATA */ byte = pci_read_config8(dev, 0x4); byte |= 7 << 0; pci_write_config8(dev, 0x4, byte); /* RPR7.7 SATA drive detection. */ /* Use BAR5+0x128,BAR0 for Primary Slave */ /* Use BAR5+0x1A8,BAR0 for Primary Slave */ /* Use BAR5+0x228,BAR2 for Secondary Master */ /* Use BAR5+0x2A8,BAR2 for Secondary Slave */ /* Use BAR5+0x328,PATA_BAR0/2 for Primary/Secondary master emulation */ /* Use BAR5+0x3A8,PATA_BAR0/2 for Primary/Secondary Slave emulation */ /* TODO: port 4,5, which are PATA emulations. What are PATA_BARs? */ for (i = 0; i < 4; i++) { byte = read8(sata_bar5 + 0x128 + 0x80 * i); printk(BIOS_SPEW, "SATA port %i status = %x\n", i, byte); byte &= 0xF; if (byte == 0x1) { /* If the drive status is 0x1 then we see it but we aren't talking to it. */ /* Try to do something about it. */ printk(BIOS_SPEW, "SATA device detected but not talking. Trying lower speed.\n"); /* Read in Port-N Serial ATA Control Register */ byte = read8(sata_bar5 + 0x12C + 0x80 * i); /* Set Reset Bit and 1.5g bit */ byte |= 0x11; write8((sata_bar5 + 0x12C + 0x80 * i), byte); /* Wait 1ms */ mdelay(1); /* Clear Reset Bit */ byte &= ~0x01; write8((sata_bar5 + 0x12C + 0x80 * i), byte); /* Wait 1ms */ mdelay(1); /* Reread status */ byte = read8(sata_bar5 + 0x128 + 0x80 * i); printk(BIOS_SPEW, "SATA port %i status = %x\n", i, byte); byte &= 0xF; } if (byte == 0x3) { for (j = 0; j < 10; j++) { if (!sata_drive_detect(i, ((i / 2) == 0) ? sata_bar0 : sata_bar2)) break; } printk(BIOS_DEBUG, "%s %s device is %sready after %i tries\n", (i / 2) ? "Secondary" : "Primary", (i % 2) ? "Slave" : "Master", (j == 10) ? "not " : "", (j == 10) ? j : j + 1); } else { printk(BIOS_DEBUG, "No %s %s SATA drive on Slot%i\n", (i / 2) ? "Secondary" : "Primary", (i % 2) ? "Slave" : "Master", i); } } /* Below is CIM InitSataLateFar */ /* Enable interrupts from the HBA */ byte = read8(sata_bar5 + 0x4); byte |= 1 << 1; write8((sata_bar5 + 0x4), byte); /* Clear error status */ write32((sata_bar5 + 0x130), 0xFFFFFFFF); write32((sata_bar5 + 0x1b0), 0xFFFFFFFF); write32((sata_bar5 + 0x230), 0xFFFFFFFF); write32((sata_bar5 + 0x2b0), 0xFFFFFFFF); write32((sata_bar5 + 0x330), 0xFFFFFFFF); write32((sata_bar5 + 0x3b0), 0xFFFFFFFF); /* Clear SATA status,Firstly we get the AcpiGpe0BlkAddr */ /* ????? why CIM does not set the AcpiGpe0BlkAddr, but use it??? */ /* word = 0x0000; */ /* word = pm_ioread(0x28); */ /* byte = pm_ioread(0x29); */ /* word |= byte<<8; */ /* printk(BIOS_DEBUG, "AcpiGpe0Blk addr = %x\n", word); */ /* write32(word, 0x80000000); */ }