void set_pcie_reset(void) { u8 byte; u16 word; struct device *sm_dev; /* set 0 to bit1 :disable GPM9 as SLP_S2 output */ /* set 0 to bit2 :disable GPM8 as AZ_RST output */ byte = pm_ioread(0x8d); byte &= ~((1 << 1) | (1 << 2)); pm_iowrite(0x8d, byte); /* set the GPM8 and GPM9 output enable and the value to 0 */ byte = pm_ioread(0x94); byte &= ~((1 << 2) | (1 << 3)); byte &= ~((1 << 0) | (1 << 1)); pm_iowrite(0x94, byte); /* set the GPIO65 output enable and the value is 0 */ sm_dev = pcidev_on_root(0x14, 0); word = pci_read_config16(sm_dev, 0x7e); word &= ~(1 << 0); word &= ~(1 << 4); pci_write_config16(sm_dev, 0x7e, word); }
/* set thermal config */ static void set_thermal_config(void) { u8 byte; u16 word; device_t sm_dev; /* set ADT 7461 */ ADT7461_write_byte(0x0B, 0x50); /* Local Temperature Hight limit */ ADT7461_write_byte(0x0C, 0x00); /* Local Temperature Low limit */ ADT7461_write_byte(0x0D, 0x50); /* External Temperature Hight limit High Byte */ ADT7461_write_byte(0x0E, 0x00); /* External Temperature Low limit High Byte */ ADT7461_write_byte(0x19, 0x55); /* External THERM limit */ ADT7461_write_byte(0x20, 0x55); /* Local THERM limit */ byte = ADT7461_read_byte(0x02); /* read status register to clear it */ ARA_read_byte(0x05); /* A hardware alert can only be cleared by the master sending an ARA as a read command */ printk(BIOS_INFO, "Init adt7461 end , status 0x02 %02x\n", byte); /* sb600 settings for thermal config */ /* set SB600 GPIO 64 to GPIO with pull-up */ byte = pm2_ioread(0x42); byte &= 0x3f; pm2_iowrite(0x42, byte); /* set GPIO 64 to input */ sm_dev = dev_find_slot(0, PCI_DEVFN(0x14, 0)); 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); */ }
/* * set gpio40 gfx */ static void set_gpio40_gfx(void) { u8 byte; // u16 word; u32 dword; device_t sm_dev; /* disable the GPIO40 as CLKREQ2# function */ byte = pm_ioread(0xd3); byte &= ~(1 << 7); pm_iowrite(0xd3, byte); /* disable the GPIO40 as CLKREQ3# function */ byte = pm_ioread(0xd4); byte &= ~(1 << 0); pm_iowrite(0xd4, byte); /* enable pull up for GPIO68 */ byte = pm2_ioread(0xf1); byte &= ~(1 << 4); pm2_iowrite(0xf1, byte); /* access the smbus extended register */ sm_dev = dev_find_slot(0, PCI_DEVFN(0x14, 0)); /*if the dev3 is present, set the gfx to 2x8 lanes*/ /*otherwise set the gfx to 1x16 lanes*/ if(is_dev3_present()){ printk(BIOS_INFO, "Dev3 is present. GFX Configuration is Two x8 slots\n"); /* when the gpio40 is configured as GPIO, this will enable the output */ pci_write_config32(sm_dev, 0xf8, 0x4); dword = pci_read_config32(sm_dev, 0xfc); dword &= ~(1 << 10); /* When the gpio40 is configured as GPIO, this will represent the output value*/ /* 1 :enable two x8 , 0 : master slot enable only */ dword |= (1 << 26); pci_write_config32(sm_dev, 0xfc, dword); }else{ printk(BIOS_INFO, "Dev3 is not present. GFX Configuration is One x16 slot\n"); /* when the gpio40 is configured as GPIO, this will enable the output */ pci_write_config32(sm_dev, 0xf8, 0x4); dword = pci_read_config32(sm_dev, 0xfc); dword &= ~(1 << 10); /* When the gpio40 is configured as GPIO, this will represent the output value*/ /* 1 :enable two x8 , 0 : master slot enable only */ dword &= ~(1 << 26); pci_write_config32(sm_dev, 0xfc, dword); } }
static void usb_init(struct device *dev) { u8 byte; u16 word; u32 dword; /* Enable OHCI0-4 and EHCI Controllers */ device_t sm_dev; sm_dev = dev_find_slot(0, PCI_DEVFN(0x14, 0)); byte = pci_read_config8(sm_dev, 0x68); byte |= 0x3F; pci_write_config8(sm_dev, 0x68, byte); /* RPR 5.2 Enables the USB PME Event,Enable USB resume support */ byte = pm_ioread(0x61); byte |= 1 << 6; pm_iowrite(0x61, byte); byte = pm_ioread(0x65); byte |= 1 << 2; pm_iowrite(0x65, byte); /* RPR 5.3 Support USB device wakeup from the S4/S5 state */ byte = pm_ioread(0x65); byte &= ~(1 << 0); pm_iowrite(0x65, byte); /* RPR 5.6 Enable the USB controller to get reset by any software that generate a PCIRst# condition */ byte = pm_ioread(0x65); byte |= (1 << 4); pm_iowrite(0x65, byte); /* RPR 5.11 Disable OHCI MSI Capability */ word = pci_read_config16(dev, 0x40); word |= (0x1F << 8); pci_write_config16(dev, 0x40, word); /* RPR 5.8 Disable the OHCI Dynamic Power Saving feature */ dword = pci_read_config32(dev, 0x50); dword &= ~(1 << 16); pci_write_config32(dev, 0x50, dword); /* RPR 5.12 Enable prevention of OHCI accessing the invalid system memory address range */ word = pci_read_config16(dev, 0x50); word |= 1 << 15; pci_write_config16(dev, 0x50, word); /* RPR 5.15 Disable SMI handshake in between USB and ACPI for USB legacy support. */ /* The BIOS should always set this bit to prevent the malfunction on USB legacy keyboard/mouse support */ word = pci_read_config16(dev, 0x50); word |= 1 << 12; pci_write_config16(dev, 0x50, word); }
static void sb800_sm_read_resources(device_t dev) { struct resource *res; u8 byte; /* rpr2.14: Hides SM bus controller Bar1 where stores HPET MMIO base address */ byte = pm_ioread(0x55); byte |= 1 << 7; pm_iowrite(0x55, byte); /* Get the normal pci resources of this device */ /* pci_dev_read_resources(dev); */ byte = pm_ioread(0x55); byte &= ~(1 << 7); pm_iowrite(0x55, byte); /* apic */ res = new_resource(dev, 0x74); res->base = 0xfec00000; res->size = 256 * 0x10; res->limit = 0xFEFFFFFUL; /* res->base + res->size -1; */ res->align = 8; res->gran = 8; res->flags = IORESOURCE_MEM | IORESOURCE_FIXED; #if 0 /* Linux ACPI crashes when it is 1. For late debugging. */ res = new_resource(dev, 0x14); /* TODO: hpet */ res->base = 0xfed00000; /* reset hpet to widely accepted address */ res->size = 0x400; res->limit = 0xFFFFFFFFUL; /* res->base + res->size -1; */ res->align = 8; res->gran = 8; res->flags = IORESOURCE_MEM | IORESOURCE_FIXED; #endif /* dev->command |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; */ /* smbus */ //res = new_resource(dev, 0x90); //res->base = 0xB00; //res->size = 0x10; //res->limit = 0xFFFFUL; /* res->base + res->size -1; */ //res->align = 8; //res->gran = 8; //res->flags = IORESOURCE_IO | IORESOURCE_FIXED; compact_resources(dev); }
static void pcie_rst_toggle(u8 val) { u8 byte; byte = pm_ioread(0x8d); byte &= ~(3 << 1); pm_iowrite(0x8d, byte); byte = pm_ioread(0x94); /* Output enable */ byte &= ~(3 << 2); /* Toggle GPM8, GPM9 */ byte &= ~(3 << 0); byte |= val; pm_iowrite(0x94, byte); }
/******************************************************** * pistachio uses a BCM5787 as on-board NIC. * It has a pin named LOW_POWER to enable it into LOW POWER state. * In order to run NIC, we should let it out of Low power state. This pin is * controlled by GPM8. * RRG4.2.3 GPM as GPIO * GPM pins can be used as GPIO. The GPM I/O functions is controlled by three registers: * I/O C50, C51, C52, PM I/O94, 95, 96. * RRG4.2.3.1 GPM pins as Input * RRG4.2.3.2 GPM pins as Output * The R77 (on BRASS) / R81 (on Bronze) is not load! * So NIC can work whether this function runs. ********************************************************/ static void enable_onboard_nic(void) { u8 byte; printk(BIOS_INFO, "%s.\n", __func__); /* enable GPM8 output */ byte = pm_ioread(0x95); byte &= 0xfe; pm_iowrite(0x95, byte); /* GPM8 outputs low. */ byte = pm_ioread(0x94); byte &= 0xfe; pm_iowrite(0x94, byte); }
void speaker_init(uint8_t time) { /* SB600 RRG. * Options_0 - RW - 8 bits - [PM_Reg: 60h]. * SpkrEn, bit[5]=1b, Setting this bit will configure GPIO2 to be speaker output. */ #ifdef __PRE_RAM__ pmio_write(0x60, (pmio_read(0x60) | (1<<5))); #else pm_iowrite(0x60, (pm_ioread(0x60) | (1<<5))); #endif /* __PRE_RAM__ */ /* SB600 RRG. * Tmr1CntrlWord - RW - 8 bits - [IO_Reg: 43h]. * ModeSelect, bit[3:1]=011b, Square wave output. * CmmandSelect, bit[5:4]=11b, Read/write least, and then most significant byte. * CounterSelect, bit[7:6]=10b, Select counter 2. */ outb(0xb6, 0x43); /* SB600 RRG. * TimerCh2- RW - 8 bits - [IO_Reg: 42h]. */ outb(time, 0x42); }
static void sb800_sm_set_resources(struct device *dev) { struct resource *res; u8 byte; pci_dev_set_resources(dev); /* rpr2.14: Make HPET MMIO decoding controlled by the memory enable bit in command register of LPC ISA bridage */ byte = pm_ioread(0x52); byte |= 1 << 6; pm_iowrite(0x52, byte); res = find_resource(dev, 0x74); printk(BIOS_INFO, "sb800_sm_set_resources, res->base=0x%llx\n", res->base); //pci_write_config32(dev, 0x74, res->base | 1 << 3); pm_iowrite(0x34, res->base | 0x7); pm_iowrite(0x35, (res->base >> 8) & 0xFF); pm_iowrite(0x36, (res->base >> 16) & 0xFF); pm_iowrite(0x37, (res->base >> 24) & 0xFF); #if 0 /* TODO:hpet */ res = find_resource(dev, 0x14); pci_write_config32(dev, 0x14, res->base); #endif //res = find_resource(dev, 0x90); //pci_write_config32(dev, 0x90, res->base | 1); }
static void usb_init(struct device *dev) { u8 byte; u16 word; u32 dword; /* 6.1 Enable OHCI0-4 and EHCI Controllers */ device_t sm_dev; sm_dev = dev_find_slot(0, PCI_DEVFN(0x14, 0)); byte = pci_read_config8(sm_dev, 0x68); byte |= 0xFF; pci_write_config8(sm_dev, 0x68, byte); /* RPR 6.2 Enables the USB PME Event,Enable USB resume support */ byte = pm_ioread(0x61); byte |= 1 << 6; pm_iowrite(0x61, byte); byte = pm_ioread(0x65); byte |= 1 << 2; pm_iowrite(0x65, byte); /* RPR 6.3 Support USB device wakeup from the S4/S5 state */ byte = pm_ioread(0x65); byte &= ~(1 << 0); pm_iowrite(0x65, byte); /* RPR 6.5 Enable the USB controller to get reset by any software that generate a PCIRst# condition */ byte = pm_ioread(0x65); byte |= (1 << 4); pm_iowrite(0x65, byte); /* USB_ADVANCED_SLEEP_CONTROL */ byte = pm_ioread(0x95); byte &= ~(7 << 0); byte |= 6 << 0; /* Advanced sleep up to 6 uframes */ pm_iowrite(0x95, byte); /* RPR 6.10 Disable OHCI MSI Capability. */ word = pci_read_config16(dev, 0x40); word |= (0x3 << 8); pci_write_config16(dev, 0x40, word); /* USB-1_OHCI0_Corner Case S3 Wake Up */ dword = pci_read_config32(dev, 0x50); dword |= (1 << 16); pci_write_config32(dev, 0x50, dword); }
static void *smp_write_config_table(void *v) { struct mp_config_table *mc; u32 dword; u8 byte; 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 */ dword = 0; dword = pm_ioread(0x34) & 0xF0; dword |= (pm_ioread(0x35) & 0xFF) << 8; dword |= (pm_ioread(0x36) & 0xFF) << 16; dword |= (pm_ioread(0x37) & 0xFF) << 24; smp_write_ioapic(mc, apicid_sb800, 0x11,(void *) dword); for (byte = 0x0; byte < sizeof(intr_data); byte ++) { outb(byte | 0x80, 0xC00); outb(intr_data[byte], 0xC01); } /* I/O Ints: Type Polarity Trigger Bus ID IRQ APIC ID PIN# */ #define IO_LOCAL_INT(type, intr, apicid, pin) \ smp_write_intsrc(mc, (type), MP_IRQ_TRIGGER_EDGE | MP_IRQ_POLARITY_HIGH, bus_isa, (intr), (apicid), (pin)); mptable_add_isa_interrupts(mc, bus_isa, apicid_sb800, 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); }
void pmio_enable_bits(u32 reg_pos, u32 mask, u32 val) { u8 reg_old, reg; reg = reg_old = pm_ioread(reg_pos); reg &= ~mask; reg |= val; if (reg != reg_old) { pm_iowrite(reg_pos, reg); } }
static void set_pmio_enable_bits(device_t sm_dev, u32 reg_pos, u32 mask, u32 val) { u8 reg_old, reg; reg = reg_old = pm_ioread(reg_pos); reg &= ~mask; reg |= val; if (reg != reg_old) { pm_iowrite(reg_pos, reg); } }
/* SB600 VFSMAF (VID/FID System Management Action Field) is 010b by default. RPR 2.3.3 C-state and VID/FID change for the K8 platform. */ void enable_fid_change_on_sb(u32 sbbusn, u32 sbdn) { u8 byte; byte = pm_ioread(0x9a); byte &= ~0x34; byte |= 0x04; // single core pm_iowrite(0x9a, byte); byte = pm_ioread(0x8f); byte &= ~0x30; byte |= 0x20; pm_iowrite(0x8f, byte); pm_iowrite(0x8b, 0x01); pm_iowrite(0x8a, 0x90); if(get_sb600_revision() > REV_SB600_A13) pm_iowrite(0x88, 0x10); else pm_iowrite(0x88, 0x06); byte = pm_ioread(0x7c); byte &= ~0x01; byte |= 0x01; pm_iowrite(0x7c, byte); /*Must be 0 for K8 platform.*/ byte = pm_ioread(0x68); byte &= ~0x01; pm_iowrite(0x68, byte); /*Must be 0 for K8 platform.*/ byte = pm_ioread(0x8d); byte &= ~(1<<6); pm_iowrite(0x8d, byte); byte = pm_ioread(0x61); byte &= ~0x04; pm_iowrite(0x61, byte); byte = pm_ioread(0x42); byte &= ~0x04; pm_iowrite(0x42, byte); if(get_sb600_revision() == REV_SB600_A21) { pm_iowrite(0x89, 0x10); byte = pm_ioread(0x52); byte |= 0x80; pm_iowrite(0x52, byte); } }
static void hda_init(struct device *dev) { u8 byte; u32 dword; u32 base; struct resource *res; u32 codec_mask; device_t sm_dev; /* Enable azalia - PM_io 0x59[3], no ac97 in sb700. */ byte = pm_ioread(0x59); byte |= 1 << 3; pm_iowrite(0x59, byte); /* Find the SMBus */ /* FIXME: Need to find out why the call below crashes. */ /*sm_dev = dev_find_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_ATI_SB700_SM, 0);*/ sm_dev = dev_find_slot(0, PCI_DEVFN(0x14, 0)); /* Set routing pin - SMBus ExtFunc (0xf8/0xfc) */ pci_write_config32(sm_dev, 0xf8, 0x00); pci_write_config8(sm_dev, 0xfc, 0xAA); /* Set INTA - SMBus 0x63 [2..0] */ byte = pci_read_config8(sm_dev, 0x63); byte &= ~0x7; byte |= 0x0; /* INTA:0x0 - INTH:0x7 */ pci_write_config8(sm_dev, 0x63, byte); /* Program the 2C to 0x437b1002 */ dword = 0x437b1002; pci_write_config32(dev, 0x2c, dword); /* Read in BAR */ /* Is this right? HDA allows for a 64-bit BAR * but this is only setup for a 32-bit one */ res = find_resource(dev, 0x10); if (!res) return; base = (u32)res->base; printk(BIOS_DEBUG, "base = 0x%x\n", base); codec_mask = codec_detect(base); if (codec_mask) { printk(BIOS_DEBUG, "codec_mask = %02x\n", codec_mask); codecs_init(base, codec_mask); } }
/* * set gpio40 gfx */ static void set_gpio40_gfx(void) { u8 byte; // u16 word; u32 dword; struct device *sm_dev; /* disable the GPIO40 as CLKREQ2# function */ byte = pm_ioread(0xd3); byte &= ~(1 << 7); pm_iowrite(0xd3, byte); /* disable the GPIO40 as CLKREQ3# function */ byte = pm_ioread(0xd4); byte &= ~(1 << 0); pm_iowrite(0xd4, byte); /* enable pull up for GPIO68 */ byte = pm2_ioread(0xf1); byte &= ~(1 << 4); pm2_iowrite(0xf1, byte); /* access the smbus extended register */ sm_dev = pcidev_on_root(0x14, 0); /* set the gfx to 1x16 lanes */ printk(BIOS_INFO, "Dev3 is not present. GFX Configuration is One x16 slot\n"); /* when the gpio40 is configured as GPIO, this will enable the output */ pci_write_config32(sm_dev, 0xf8, 0x4); dword = pci_read_config32(sm_dev, 0xfc); dword &= ~(1 << 10); /* When the gpio40 is configured as GPIO, this will represent the output value*/ /* 1 :enable two x8 , 0 : master slot enable only */ dword &= ~(1 << 26); pci_write_config32(sm_dev, 0xfc, dword); }
static void usb_init(struct device *dev) { u8 byte; u16 word; /* 7.1 Enable OHCI0-4 and EHCI Controllers */ /* pmio 0xEF; */ /* RPR 7.2 USB S4/S5 Wake-up or PHY Power-down Support */ byte = pm_ioread(0xF0); byte |= 1 << 0; /* A12, USB Wake from S5 not supported on the platform */ pm_iowrite(0xF0, byte); /* RPR 7.4 Enable the USB controller to get reset by any software that generate a PCIRst# condition */ byte = pm_ioread(0xF0); byte |= (1 << 2); byte |= 3 << 8; /* rpr 7.5 */ pm_iowrite(0xF0, byte); /* RPR 7.9 Disable OHCI MSI Capability. */ word = pci_read_config16(dev, 0x40); word |= (0x1 << 8); pci_write_config16(dev, 0x40, word); }
void set_pcie_dereset() { u8 byte; u16 word; device_t sm_dev; /* set 0 to bit1 :disable GPM9 as SLP_S2 output */ /* set 0 to bit2 :disable GPM8 as AZ_RST output */ byte = pm_ioread(0x8d); byte &= ~((1 << 1) | (1 << 2)); pm_iowrite(0x8d, byte); /* set the GPM8 and GPM9 output enable and the value to 1 */ byte = pm_ioread(0x94); byte &= ~((1 << 2) | (1 << 3)); byte |= ((1 << 0) | (1 << 1)); pm_iowrite(0x94, byte); /* set the GPIO65 output enable and the value is 1 */ sm_dev = dev_find_slot(0, PCI_DEVFN(0x14, 0)); word = pci_read_config16(sm_dev, 0x7e); word |= (1 << 0); word &= ~(1 << 4); pci_write_config16(sm_dev, 0x7e, word); }
static void sb600_sm_set_resources(struct device *dev) { struct resource *res; u8 byte; pci_dev_set_resources(dev); /* rpr2.14: Make HPET MMIO decoding controlled by the memory enable bit in command register of LPC ISA bridge */ byte = pm_ioread(0x52); byte |= 1 << 6; pm_iowrite(0x52, byte); res = find_resource(dev, 0x74); pci_write_config32(dev, 0x74, res->base | 1 << 3); res = find_resource(dev, 0x14); pci_write_config32(dev, 0x14, res->base); res = find_resource(dev, 0x10); pci_write_config32(dev, 0x10, res->base | 1); }
/*************************************************** * This board, the TIM-8690 has two Marvel 88e5056 PCI-E * 10/100/1000 chips on board. * Both of their pin PERSTn pins are connected to GPIO 5 of the * SB600 southbridge. ****************************************************/ static void enable_onboard_nic(void) { u8 byte; device_t sm_dev; printk(BIOS_INFO, "enable_onboard_nic.\n"); sm_dev = dev_find_slot(0, PCI_DEVFN(0x14, 0)); byte = pci_read_config8(sm_dev, 0x9a); byte |= ( 1 << 7); pci_write_config8(sm_dev, 0x9a, byte); byte=pm_ioread(0x59); byte &= ~( 1<< 5); pm_iowrite(0x59,byte); byte = pci_read_config8(sm_dev, 0xA8); byte |= (1 << 1); //set bit 1 to high pci_write_config8(sm_dev, 0xA8, byte); }
static void *smp_write_config_table(void *v) { struct mp_config_table *mc; int bus_isa; int boot_apic_id; unsigned apic_version; unsigned cpu_features; unsigned cpu_feature_flags; struct cpuid_result result; unsigned long cpu_flag; mc = (void *)(((char *)v) + SMP_FLOATING_TABLE_LEN); mptable_init(mc, LAPIC_ADDR); memcpy(mc->mpc_oem, "AMD ", 8); /*Inagua used dure core cpu with one die */ boot_apic_id = lapicid(); apic_version = lapic_read(LAPIC_LVR) & 0xff; result = cpuid(1); cpu_features = result.eax; cpu_feature_flags = result.edx; cpu_flag = MPC_CPU_ENABLED | MPC_CPU_BOOTPROCESSOR; smp_write_processor(mc, 0, apic_version, cpu_flag, cpu_features, cpu_feature_flags ); cpu_flag = MPC_CPU_ENABLED; smp_write_processor(mc, 1, apic_version, cpu_flag, cpu_features, cpu_feature_flags ); get_bus_conf(); //mptable_write_buses(mc, NULL, &bus_isa); my_smp_write_bus(mc, 0, "PCI "); my_smp_write_bus(mc, 1, "PCI "); bus_isa = 0x02; my_smp_write_bus(mc, bus_isa, "ISA "); /* I/O APICs: APIC ID Version State Address */ device_t dev; u32 dword; u8 byte; dword = 0; dword = pm_ioread(0x34) & 0xF0; dword |= (pm_ioread(0x35) & 0xFF) << 8; dword |= (pm_ioread(0x36) & 0xFF) << 16; dword |= (pm_ioread(0x37) & 0xFF) << 24; /* Set IO APIC ID onto IO_APIC_ID */ write32 (dword, 0x00); write32 (dword + 0x10, IO_APIC_ID << 24); apicid_sb900 = IO_APIC_ID; smp_write_ioapic(mc, apicid_sb900, 0x21, dword); /* PIC IRQ routine */ for (byte = 0x0; byte < sizeof(picr_data); byte ++) { outb(byte, 0xC00); outb(picr_data[byte], 0xC01); } /* APIC IRQ routine */ for (byte = 0x0; byte < sizeof(intr_data); byte ++) { outb(byte | 0x80, 0xC00); outb(intr_data[byte], 0xC01); } /* 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_sb900, 0); /*I/O Ints: Type Trigger Polarity Bus ID IRQ APIC ID PIN# */ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x0, apicid_sb900, 0x0); smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x1, apicid_sb900, 0x1); smp_write_intsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x2, apicid_sb900, 0x2); smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x3, apicid_sb900, 0x3); smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x4, apicid_sb900, 0x4); smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0, 0x49, apicid_sb900, 0x11); smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x6, apicid_sb900, 0x6); smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x7, apicid_sb900, 0x7); smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x8, apicid_sb900, 0x8); smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x9, apicid_sb900, 0x9); smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_isa, 0xa, apicid_sb900, 0xa); smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_isa, 0x1c, apicid_sb900, 0x13); smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xc, apicid_sb900, 0xc); smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xd, apicid_sb900, 0xd); smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xe, apicid_sb900, 0xe); smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xf, apicid_sb900, 0xf); /* 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_sb900, (pin)) /* Internal VGA */ PCI_INT(0x0, 0x01, 0x0, intr_data[0x02]); PCI_INT(0x0, 0x01, 0x1, intr_data[0x03]); /* SMBUS */ PCI_INT(0x0, 0x14, 0x0, 0x10); /* HD Audio */ PCI_INT(0x0, 0x14, 0x0, intr_data[0x13]); /* USB */ PCI_INT(0x0, 0x12, 0x0, intr_data[0x30]); PCI_INT(0x0, 0x12, 0x1, intr_data[0x31]); PCI_INT(0x0, 0x13, 0x0, intr_data[0x32]); PCI_INT(0x0, 0x13, 0x1, intr_data[0x33]); PCI_INT(0x0, 0x16, 0x0, intr_data[0x34]); PCI_INT(0x0, 0x16, 0x1, intr_data[0x35]); PCI_INT(0x0, 0x14, 0x2, intr_data[0x36]); /* sata */ PCI_INT(0x0, 0x11, 0x0, intr_data[0x40]); PCI_INT(0x0, 0x11, 0x0, intr_data[0x41]); /* on board NIC & Slot PCIE. */ /* PCI slots */ /* PCI_SLOT 0. */ PCI_INT(bus_sb900[1], 0x5, 0x0, 0x14); PCI_INT(bus_sb900[1], 0x5, 0x1, 0x15); PCI_INT(bus_sb900[1], 0x5, 0x2, 0x16); PCI_INT(bus_sb900[1], 0x5, 0x3, 0x17); /* PCI_SLOT 1. */ PCI_INT(bus_sb900[1], 0x6, 0x0, 0x15); PCI_INT(bus_sb900[1], 0x6, 0x1, 0x16); PCI_INT(bus_sb900[1], 0x6, 0x2, 0x17); PCI_INT(bus_sb900[1], 0x6, 0x3, 0x14); /* PCI_SLOT 2. */ PCI_INT(bus_sb900[1], 0x7, 0x0, 0x16); PCI_INT(bus_sb900[1], 0x7, 0x1, 0x17); PCI_INT(bus_sb900[1], 0x7, 0x2, 0x14); PCI_INT(bus_sb900[1], 0x7, 0x3, 0x15); PCI_INT(bus_sb900[2], 0x0, 0x0, 0x12); PCI_INT(bus_sb900[2], 0x0, 0x1, 0x13); PCI_INT(bus_sb900[2], 0x0, 0x2, 0x14); /* PCIe Lan*/ PCI_INT(0x0, 0x06, 0x0, 0x13); /* FCH PCIe PortA */ PCI_INT(0x0, 0x15, 0x0, 0x10); /* FCH PCIe PortB */ PCI_INT(0x0, 0x15, 0x1, 0x11); /* FCH PCIe PortC */ PCI_INT(0x0, 0x15, 0x2, 0x12); /* FCH PCIe PortD */ PCI_INT(0x0, 0x15, 0x3, 0x13); /*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 */ mc->mpe_checksum = smp_compute_checksum(smp_next_mpc_entry(mc), mc->mpe_length); mc->mpc_checksum = smp_compute_checksum(mc, mc->mpc_length); printk(BIOS_DEBUG, "Wrote the mp table end at: %p - %p\n", mc, smp_next_mpe_entry(mc)); return smp_next_mpe_entry(mc); }
static void *smp_write_config_table(void *v) { struct mp_config_table *mc; int bus_isa; u32 dword; u8 byte; mc = (void *)(((char *)v) + SMP_FLOATING_TABLE_LEN); mptable_init(mc, LOCAL_APIC_ADDR); memcpy(mc->mpc_oem, "AMD ", 8); smp_write_processors(mc); get_bus_conf(); //mptable_write_buses(mc, NULL, &bus_isa); my_smp_write_bus(mc, 0, "PCI "); my_smp_write_bus(mc, 1, "PCI "); bus_isa = 0x02; my_smp_write_bus(mc, bus_isa, "ISA "); /* I/O APICs: APIC ID Version State Address */ dword = 0; dword = pm_ioread(0x34) & 0xF0; dword |= (pm_ioread(0x35) & 0xFF) << 8; dword |= (pm_ioread(0x36) & 0xFF) << 16; dword |= (pm_ioread(0x37) & 0xFF) << 24; /* Set IO APIC ID onto IO_APIC_ID */ write32 (dword, 0x00); write32 (dword + 0x10, IO_APIC_ID << 24); apicid_hudson = IO_APIC_ID; smp_write_ioapic(mc, apicid_hudson, 0x21, dword); /* PIC IRQ routine */ for (byte = 0x0; byte < sizeof(picr_data); byte ++) { outb(byte, 0xC00); outb(picr_data[byte], 0xC01); } /* APIC IRQ routine */ for (byte = 0x0; byte < sizeof(intr_data); byte ++) { outb(byte | 0x80, 0xC00); outb(intr_data[byte], 0xC01); } /* 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_hudson, 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_hudson, (pin)) /* Internal VGA */ PCI_INT(0x0, 0x01, 0x0, intr_data[0x02]); PCI_INT(0x0, 0x01, 0x1, intr_data[0x03]); /* SMBUS */ PCI_INT(0x0, 0x14, 0x0, 0x10); /* HD Audio */ PCI_INT(0x0, 0x14, 0x0, intr_data[0x13]); /* USB */ PCI_INT(0x0, 0x12, 0x0, intr_data[0x30]); PCI_INT(0x0, 0x12, 0x1, intr_data[0x31]); PCI_INT(0x0, 0x13, 0x0, intr_data[0x32]); PCI_INT(0x0, 0x13, 0x1, intr_data[0x33]); PCI_INT(0x0, 0x16, 0x0, intr_data[0x34]); PCI_INT(0x0, 0x16, 0x1, intr_data[0x35]); PCI_INT(0x0, 0x14, 0x2, intr_data[0x36]); /* sata */ PCI_INT(0x0, 0x11, 0x0, intr_data[0x40]); PCI_INT(0x0, 0x11, 0x0, intr_data[0x41]); /* on board NIC & Slot PCIE. */ /* PCI slots */ /* PCI_SLOT 0. */ PCI_INT(bus_hudson[1], 0x5, 0x0, 0x14); PCI_INT(bus_hudson[1], 0x5, 0x1, 0x15); PCI_INT(bus_hudson[1], 0x5, 0x2, 0x16); PCI_INT(bus_hudson[1], 0x5, 0x3, 0x17); PCI_INT(bus_hudson[2], 0x0, 0x0, 0x12); PCI_INT(bus_hudson[2], 0x0, 0x1, 0x13); PCI_INT(bus_hudson[2], 0x0, 0x2, 0x14); /* PCIe Lan*/ PCI_INT(0x0, 0x06, 0x0, 0x13); /* FCH PCIe PortA */ PCI_INT(0x0, 0x15, 0x0, 0x10); /* FCH PCIe PortB */ PCI_INT(0x0, 0x15, 0x1, 0x11); /* FCH PCIe PortC */ PCI_INT(0x0, 0x15, 0x2, 0x12); /* FCH PCIe PortD */ PCI_INT(0x0, 0x15, 0x3, 0x13); /*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 void *smp_write_config_table(void *v) { struct mp_config_table *mc; u32 dword; u8 byte; 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 */ dword = 0; dword = pm_ioread(0x34) & 0xF0; dword |= (pm_ioread(0x35) & 0xFF) << 8; dword |= (pm_ioread(0x36) & 0xFF) << 16; dword |= (pm_ioread(0x37) & 0xFF) << 24; smp_write_ioapic(mc, apicid_sb800, 0x11, dword); for (byte = 0x0; byte < sizeof(intr_data); byte ++) { outb(byte | 0x80, 0xC00); outb(intr_data[byte], 0xC01); } /* I/O Ints: Type Polarity Trigger Bus ID IRQ APIC ID PIN# */ #define IO_LOCAL_INT(type, intr, apicid, pin) \ smp_write_intsrc(mc, (type), MP_IRQ_TRIGGER_EDGE | MP_IRQ_POLARITY_HIGH, bus_isa, (intr), (apicid), (pin)); mptable_add_isa_interrupts(mc, bus_isa, apicid_sb800, 0); /* PCI interrupts are level triggered, and are * associated with a specific bus/device/function tuple. */ #if !CONFIG_GENERATE_ACPI_TABLES #define PCI_INT(bus, dev, fn, pin) \ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, (bus), (((dev)<<2)|(fn)), apicid_sb800, (pin)) #else #define PCI_INT(bus, dev, fn, pin) #endif PCI_INT(0x0, 0x14, 0x0, 0x10); /* HD Audio: */ PCI_INT(0x0, 0x14, 0x2, 0x12); PCI_INT(0x0, 0x12, 0x0, intr_data[0x30]); /* USB */ PCI_INT(0x0, 0x12, 0x1, intr_data[0x31]); PCI_INT(0x0, 0x13, 0x0, intr_data[0x32]); PCI_INT(0x0, 0x13, 0x1, intr_data[0x33]); PCI_INT(0x0, 0x16, 0x0, intr_data[0x34]); PCI_INT(0x0, 0x16, 0x1, intr_data[0x35]); /* sata */ PCI_INT(0x0, 0x11, 0x0, intr_data[0x41]); /* on board NIC & Slot PCIE. */ /* PCI_INT(bus_rs780[0x1], 0x5, 0x0, 0x12); */ /* PCI_INT(bus_rs780[0x1], 0x5, 0x1, 0x13); */ PCI_INT(bus_rs780[0x2], 0x0, 0x0, 0x12); /* Dev 2, external GFX */ /* PCI_INT(bus_rs780[0x3], 0x0, 0x0, 0x13); */ PCI_INT(bus_rs780[0x4], 0x0, 0x0, 0x10); /* configuration B doesnt need dev 5,6,7 */ /* * PCI_INT(bus_rs780[0x5], 0x0, 0x0, 0x11); * PCI_INT(bus_rs780[0x6], 0x0, 0x0, 0x12); * PCI_INT(bus_rs780[0x7], 0x0, 0x0, 0x13); */ PCI_INT(bus_rs780[0x9], 0x0, 0x0, 0x11); PCI_INT(bus_rs780[0xA], 0x0, 0x0, 0x12); /* NIC */ /* PCI slots */ /* PCI_SLOT 0. */ PCI_INT(bus_sb800[1], 0x5, 0x0, 0x14); PCI_INT(bus_sb800[1], 0x5, 0x1, 0x15); PCI_INT(bus_sb800[1], 0x5, 0x2, 0x16); PCI_INT(bus_sb800[1], 0x5, 0x3, 0x17); /* PCI_SLOT 1. */ PCI_INT(bus_sb800[1], 0x6, 0x0, 0x15); PCI_INT(bus_sb800[1], 0x6, 0x1, 0x16); PCI_INT(bus_sb800[1], 0x6, 0x2, 0x17); PCI_INT(bus_sb800[1], 0x6, 0x3, 0x14); /* PCI_SLOT 2. */ PCI_INT(bus_sb800[1], 0x7, 0x0, 0x16); PCI_INT(bus_sb800[1], 0x7, 0x1, 0x17); PCI_INT(bus_sb800[1], 0x7, 0x2, 0x14); PCI_INT(bus_sb800[1], 0x7, 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); }
static void sm_init(device_t dev) { u8 byte; u32 ioapic_base; printk(BIOS_INFO, "sm_init().\n"); ioapic_base = 0xFEC00000;//pci_read_config32(dev, 0x74) & (0xffffffe0); /* some like mem resource, but does not have enable bit */ /* Don't rename APIC ID */ /* TODO: We should call setup_ioapic() here. But kernel hangs if cpu is K8. * We need to check out why and change back. */ clear_ioapic(ioapic_base); //setup_ioapic(ioapic_base, 0); /* enable serial irq */ byte = pm_ioread(0x54); byte |= 1 << 7; /* enable serial irq function */ byte &= ~(0xF << 2); byte |= 4 << 2; /* set NumSerIrqBits=4 */ pm_iowrite(0x54, byte); pm_iowrite(0x00, 0x0E); pm_iowrite(0x0B, 0x02); /* 2.11 IO Trap Settings */ abcfg_reg(0x10090, 1 << 16, 1 << 16); /* 4.1 ab index */ //pci_write_config32(dev, 0xF0, AB_INDX); pm_iowrite(0xE0, AB_INDX & 0xFF); pm_iowrite(0xE1, (AB_INDX >> 8) & 0xFF); pm_iowrite(0xE2, (AB_INDX >> 16) & 0xFF); pm_iowrite(0xE3, (AB_INDX >> 24) & 0xFF); /* Initialize the real time clock */ rtc_init(0); byte = pm_ioread(0x8); byte |= 1 << 2 | 1 << 4; pm_iowrite(0x08, byte); byte = pm_ioread(0x9); byte |= 1 << 0; pm_iowrite(0x09, byte); abcfg_reg(0x10060, (BIT31), BIT31); abcfg_reg(0x1009C, (BIT4 + BIT5), BIT4 + BIT5); abcfg_reg(0x9C, (BIT2 + BIT3 + BIT4 + BIT5 + BIT6 + BIT7), BIT2 + BIT3 + BIT4 + BIT5 + BIT6 + BIT7); abcfg_reg(0x90, (BIT21 + BIT22 + BIT23), BIT21 + BIT22 + BIT23); abcfg_reg(0xF0, (BIT6 + BIT5), BIT6 + BIT5); abcfg_reg(0x10090, (BIT9 + BIT10 + BIT11 + BIT12), BIT9 + BIT10 + BIT11 + BIT12); abcfg_reg(0x58, (BIT10), BIT10); abcfg_reg(0xF0, (BIT3 + BIT4), BIT3 + BIT4); abcfg_reg(0x54, (BIT1), BIT1); // axindxc_reg(0x02, BIT9, BIT9); axindxc_reg(0x10, BIT9, BIT9); /* 4.2 Enabling Upstream DMA Access */ axcfg_reg(0x04, 1 << 2, 1 << 2); /* 4.3 Enabling PCIB Prefetch Settings */ abcfg_reg(0x10060, 1 << 20, 1 << 20); abcfg_reg(0x10064, 1 << 20, 1 << 20); /* 4.4 Enabling OHCI Prefetch for Performance Enhancement, A12 */ abcfg_reg(0x80, 1 << 0, 1<< 0); /* 4.5 B-Link Client's Credit Variable Settings for the Downstream Arbitration Equation */ /* 4.6 Enabling Additional Address Bits Checking in Downstream */ abcfg_reg(0x9c, 1 << 0, 1 << 0); //abcfg_reg(0x9c, 3 << 0, 3 << 0); //A11 /* 4.7 Set B-Link Prefetch Mode */ abcfg_reg(0x80, 3 << 17, 3 << 17); // RPR Enabled SMI ordering enhancement. ABCFG 0x90[21] // RPR USB Delay A-Link Express L1 State. ABCFG 0x90[17] abcfg_reg(0x90, 1 << 17 | 1 << 21, 1 << 17 | 1 << 21); /* 4.8 Enabling Detection of Upstream Interrupts */ abcfg_reg(0x94, 1 << 20 | 0x7FFFF, 1 << 20 | 0x00FEE); /* 4.9: Enabling Downstream Posted Transactions to Pass Non-Posted * Transactions for the K8 Platform (for All Revisions) */ abcfg_reg(0x10090, 1 << 8, 1 << 8); /* 4.10:Programming Cycle Delay for AB and BIF Clock Gating */ /* 4.11:Enabling AB Int_Arbiter Enhancement (for All Revisions) */ abcfg_reg(0x10054, 0xFFFF0000, 0x01040000); abcfg_reg(0x54, 0xFF << 16, 4 << 16); abcfg_reg(0x54, 1 << 24, 0 << 24); abcfg_reg(0x54, 1 << 26, 1 << 26); abcfg_reg(0x98, 0xFFFFFF00, 0x00004700); /* 4.12: Enabling AB and BIF Clock Gating */ abcfg_reg(0x10054, 0x0000FFFF, 0x07FF); /* 4.13:Enabling Requester ID for upstream traffic. */ abcfg_reg(0x98, 3 << 16, 3 << 16); abcfg_reg(0x50, 1 << 2, 0 << 2); /* 5.2 Enabling GPP Port A/B/C/D */ //abcfg_reg(0xC0, 0xF << 4, 0xF << 4); /* Enable SCI as irq9. */ outb(0x10, 0xC00); outb(0x9, 0xC01); /* Enabled IRQ input */ outb(0x9, 0xC00); outb(0xF7, 0xC01); abcfg_reg(0x90, 0xFFFFFFFF, 0x00F80040); abcfg_reg(0xA0, 0xFFFFFFFF, 0x00000000); abcfg_reg(0xA4, 0xFFFFFFFF, 0x00000000); abcfg_reg(0xC0, 0xFFFFFFFF, 0x0000F014); abcfg_reg(0x98, 0xFFFFFFFF, 0X01034700); }
/* * 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 */ rtc_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); }
/* * 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); }
/* * 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); */ }