From f31df54bf1958b9e5253ec17dc7ad6e8778db7bc Mon Sep 17 00:00:00 2001 From: Li-Ta Lo Date: Thu, 12 Apr 2001 10:46:43 +0000 Subject: [PATCH] fix RTC and 8254 problem --- src/northsouthbridge/sis/630/southbridge.c | 64 ++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/src/northsouthbridge/sis/630/southbridge.c b/src/northsouthbridge/sis/630/southbridge.c index f0c884bfa7..f19d3bd675 100644 --- a/src/northsouthbridge/sis/630/southbridge.c +++ b/src/northsouthbridge/sis/630/southbridge.c @@ -121,10 +121,17 @@ apc_fixup(void) regval = inb(0x71); outb(regval | 0x80, 0x71); +#ifndef SIS630S /* Select Programmable LED0 and EEPROM Data Out for GPIO8 and GPIO3 */ outb(0x02, 0x70); regval = inb(0x71); outb(regval | 0x19, 0x71); +#else /* SIS630S */ + /* Select Programmable MDC/RXCLK and RXEXR for GPIO[9:8] and GPIO3 */ + outb(0x02, 0x70); + regval = inb(0x71); + outb(regval | 0x09, 0x71); +#endif /* select Keyboard/Mouse function for GPIO Pin [14:10] */ outb(0x02, 0x70); @@ -137,6 +144,61 @@ apc_fixup(void) } } +/* timer0_fixup: Fix up the Timer 0 of 8254 Programmable Timer + * + * The timer 0 is used to generate the 18.2 Hz, IRQ 0 timer event and used by system + * to update date/time. + * + * FixME: Should be program timer 1 for DRAM refresh too ?? + */ +static void +timer0_fixup(void) +{ + /* select Timer 0, 16 Bit Access, Mode 3, Binary */ + outb_p(0x43, 0x36); + + /* Load LSB, 0x00 */ + outb_p(0x40, 0x00); + + /* Load MSB, 0x00 */ + outb_p(0x40, 0x00); +} + +/* rtc_fixup: Fix up the Real Time Clock + * + * The Real Time Clock updates the day/time information in the CMOS RAM every second. + * The clock diveder has to be programmed correctly or the RTC will update the CMOS + * in incorrect time interval (i.e. more or less then 1Sec in "wall clock"). + * + * FixME: Where does the CMOS stroe Y2K information and how does Linux handle it ?? + */ +static void +rtc_fixup(void) +{ + volatile u8 dummy; + struct pci_dev *isa_bridge; + + isa_bridge = pci_find_device(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503, + (void *)NULL); + if (isa_bridge != NULL) { + /* Register 0x48, Enable internal RTC */ + pci_read_config_byte(isa_bridge, 0x48, ®val); + pci_write_config_byte(isa_bridge, 0x48, regval | 0x10); + } + + /* Select Normal Colok Divider, 978 us interrupt */ + outb_p(0x0A, 0x70); + outb_p(0x26, 0x71); + + /* Select 24 HR time */ + outb_p(0x0B, 0x70); + outb_p(0x26, 0x71); + + /* Clear Checksum Error */ + outb_p(0x0D, 0x70); + dummy = inb_p(0x71); +} + static void acpi_fixup(void) { @@ -227,6 +289,8 @@ final_southbridge_fixup() } #endif /* OLD_KERNEL_HACK */ + timer0_fixup(); + rtc_fixup(); apc_fixup(); serial_irq_fixedup(); acpi_fixup();