diff --git a/src/northsouthbridge/sis/550/ipl.S b/src/northsouthbridge/sis/550/ipl.S index 1228af61be..a8e72ae6d2 100644 --- a/src/northsouthbridge/sis/550/ipl.S +++ b/src/northsouthbridge/sis/550/ipl.S @@ -32,11 +32,14 @@ #include "ipl.h" #define SIS550_BUG +.code16 + +#ifdef STD_FLASH +.org 0xfe00 +#endif #undef SIZE_ALL #define REALLY_COMPACT - -.code16 sis630spd_start: cli # Disables the maskable @@ -61,7 +64,7 @@ lpc_init_complete: #ifdef SIZE_ALL xorw %bx, %bx # clear %fs, %fs is used as "bitmap" of - movw %bx, %fs # install DIMM slot + movw %bx, %fs # installed DIMM slot #endif /* SIZE_ALL */ spd_sizing_start: @@ -211,87 +214,23 @@ init_sdram: jmp init_sdram init_complete: - sis630ipl_start: /* O.K. we have DRAM now, so set up STACK for CALL/RET */ movw $DOC_STACK_SEG, %ax movw %ax, %ss movw $SPL_RAM_SEG, %ax movw %ax, %es + xorw %sp, %sp # clear %sp - xorl %esp, %esp # clear %sp - xorw %dx, %dx # clear %dx, start of RAM - movw $0x800, %si # point %si to CDSN Data area - movw $0x1000, %di # point %di to CDSN Control area - movw $DOC_SPL_START_PAGE, %bp # start page of LinuxBIOS - - movb $0x84, %al # Reset DOC Millennium - call doc_reset - - movb $0x85, %al # Turn into Normal Mode - call doc_reset - -read_next_page: - movw $0x1000, %di # point %di to CDSN Control area - -flash_command: - movb $0x03, 0x04(%di) # start command cycle - movb $0x00, (%si) # issue flash command Read00 - call doc_cycle_end - - movw %bp, %bx # %bp is current page number - - -flash_address: -#ifndef SIS550_BUG - shll $0x08, %ebx - movb $0x01, %cl # this one is DANGEROUS but I am - # sure the upper 3 bytes == 0x00 - - movb $0x05, 0x04(%di) # start address cycle -0: - movb %bl, (%si) # write address to CDSNIO - shrw $0x08, %bx # shift next address byte - loop 0b - -#else /* SIS550_BUG */ - - movb $0x05, 0x04(%di) # start address cycle - - movb $0x00, (%si) - movw %bp, %bx - movb %bl, (%si) - movb $0x00, (%si) +#ifdef STD_FLASH +#include "rom/std_flash.inc" +#else /* !STD_FLASH */ +#if defined(USE_DOC_MIL) || defined(USE_DOC_2000_TSOP) +# include "rom/doc_mil.inc" +#else defined(USE_DOC_MIL_PLUS) +# include "rom/doc_mil_plus.inc" #endif - - call doc_cycle_end - -wait_for_flash_ready: - /* delay by reding NOP register before polling the FLASH READY bit, - this is inlined to save a call/ret pair */ -doc_delay: - movb $0x04, %cl # this one is DANGEROUS but I am - # sure the upper 3 bytes == 0x00 -0: - movb 0x20(%di), %al # read DOC NOP retisger - loop 0b # four times - - testb $0x80, 0x04(%di) # is flash ready ? - jz wait_for_flash_ready - - movb 0x1d(%di), %al # init read pipeline - - movw $0x100, %cx # 1 page = 512 bytes - movw $0x800, %si # point %si to CDSN Data area - movw %dx, %di # restore saved current destination - rep - movsw - - movw %di, %dx # save current destination - incw %bp # increse current page number - cmpw $(DOC_SPL_START_PAGE + DOC_SPL_SIZE_IN_PAGE), %bp - # moved enough data ?? - jl read_next_page # no, read next page +#endif /* STD_FLASH */ sis630ipl_end: jmp spl_vector # jump to SPL vector @@ -326,7 +265,7 @@ write_common: read_spd: /* Input: AH = 05h, AL = byte number of SPD to be read. Output: BL = The value of specified SPD byte. */ - movb $0x05, %ah + movb $0x05, %ah # set SMB Command == byte address CALL_BP(sis_set_smbus) movw $0x0312, %ax # Start, R/W byte Data @@ -347,7 +286,7 @@ read_spd_fail: sis_get_smbus: /* Input: AH - register index. - Output: AL - register value. */ + Output: BL - register value. */ addb %ah, %dl # read SMBus byte 0 inb %dx, %al movb %al, %bl # return result in BL @@ -364,18 +303,6 @@ sis_set_smbus: outb %al, %dx RET_BP # End of sis_set_smbus -doc_reset: - /* Input: AL = value write to DOC_CONTROL register - Clobberd: CX */ - movb %al, 0x02(%di) # write DoC Control retister - movb %al, 0x02(%di) # twice - ret # End of doc_reset - -doc_cycle_end: - movb $0x00, 0x1e(%di) # flush write pepeline - movb $0x01, 0x04(%di) # end command cycle - ret - sdram_type_bank_1: # Column Number 8 9 10 11 Row Number .byte 0b0000, 0b0100, 0b1000, 0xff # 11 @@ -420,15 +347,31 @@ pci_init_table: .word 0x5201 # Refresh Cycle Enable .word 0x0000 /* Null, End of table */ - .org 0x01f0 +#ifdef STD_FLASH + .org 0xfff0 +reset_vector: + .byte 0xea # jmp to f000:fe00, where IPL + .word 0xfe00, 0xf000 # starts in Standard Flash +#else /* !STD_FLASH i.e. DoC Mil */ +#if defined(USE_DOC_MIL) + .org 0x1f0 +#elif defined(USE_DOC_2000_TSOP) || defined(USE_DOC_MIL_PLUS) + .org 0x3f0 +#endif reset_vector: .byte 0xea # jmp to fe00:0000, where IPL .word 0x0000, DOC_WIN_SEG # starts in DoC +#endif /* STD_FLASH */ spl_vector: .byte 0xea # jmp to 8000:0000, where SPL .word 0x0000, SPL_RAM_SEG # (LinuxBIOS) starts in RAM - .org 0x01ff +#if defined(USE_DOC_MIL) + .org 0x1ff +#elif defined(USE_DOC_2000_TSOP) || defined(USE_DOC_MIL_PLUS) + .org 0x3ff +#endif + end: hlt diff --git a/src/northsouthbridge/sis/550/southbridge.c b/src/northsouthbridge/sis/550/southbridge.c index ffe6bce94b..2906227b52 100644 --- a/src/northsouthbridge/sis/550/southbridge.c +++ b/src/northsouthbridge/sis/550/southbridge.c @@ -16,14 +16,107 @@ static char rcsid[] = #include #include #include -#include +#include + +#include + +#define BYTE sizeof(u8) +#define WORD sizeof(u16) +#define DBLE sizeof(u32) +#define IDE_REG_EXTENDED_OFFSET (0x200u) +#define IDE_REG_SECTOR_COUNT(base) ((base) + 2u) +#define IDE_REG_CONTROL(base) ((base) + IDE_REG_EXTENDED_OFFSET + 6u) +#define IDE_BASE1 (0x1F0u) /* primary controller */ +#define ASIZE(x) (sizeof(x)/sizeof((x)[0])) + +typedef struct { + u8 size; + u8 regno; + u32 andval; + u32 orval; +} initreg_t; + +static const initreg_t ide_init[] = { + /* + * BUS(0), DEVICE(0), FUNCTION(1): IDE Interface. Bridge + */ + /* SIZE REG AND-MASK OR-MASK */ + { WORD, 0x04, 0x00, 0x0007 }, /* Command Register. sets mem+ */ + { WORD, 0x06, 0x00, 0x3000 }, /* Status reg, clear aborts. */ + { WORD, 0x09, 0x0A, 0x00 }, /* Programming interface = Compatible mode. */ + { BYTE, 0x0D, 0x00, 0x10 }, /* Latency Timer */ + /* We let the pci enumerator assign these. */ + // { DBLE, 0x10, 0x0, 0x1F1 }, /* Primary channel base addr. */ + // { DBLE, 0x14, 0x0, 0x3F5 }, /* Primary channel control base addr. */ + // { DBLE, 0x18, 0x0, 0x171 }, /* Secondary channel base addr. */ + // { DBLE, 0x1C, 0x0, 0x375 }, /* Secondary channel control base addr. */ + // { DBLE, 0x20, 0x0, 0x4001 }, /* Control register base addr. */ + { WORD, 0x2C, 0x00, 0x1039 }, /* Subsystem vendor ID. */ + { WORD, 0x2E, 0x00, 0x5513 }, /* Subsystem ID. */ + { BYTE, 0x3c, 0x00, 0x0e }, /* reserved don't do this, sets irq 14 */ + { BYTE, 0x40, 0x00, 0x01 }, /* Primary master data recovery time. 1 PCICLK */ + { BYTE, 0x41, 0x00, 0xb3 }, /* Primary master data active time. UDMA Mode 2 */ + { BYTE, 0x42, 0x00, 0x00 }, /* Primary slave data recovery time. */ + { BYTE, 0x43, 0x00, 0x00 }, /* Primary slave data active time. */ + { BYTE, 0x44, 0x00, 0x00 }, /* Secondary master data recovery time. */ + { BYTE, 0x45, 0x00, 0x00 }, /* Secondary master data active time. */ + { BYTE, 0x46, 0x00, 0x00 }, /* Secondary slave data recovery time. */ + { BYTE, 0x47, 0x00, 0x00 }, /* Secondary slave data active time. */ + { BYTE, 0x48, 0x00, 0x05 }, /* Read/Write FIFO Threshold = 1/4 */ + { BYTE, 0x4A, 0x40, 0xe2 }, /* Enable Bus Master, Fast postwrite, IDE 0 */ + { BYTE, 0x4B, 0x00, 0x11 }, /* Enable Postwrite and Prefech for IDE0, Master */ + { WORD, 0x4C, 0x00, 0x0200 }, /* Prefetch count of primary. */ + { WORD, 0x4E, 0x00, 0x0200 }, /* Prefetch count of secondary. */ + { BYTE, 0x52, 0xFF, 0x14 } /* Miscelaneous control (Only Doc). */ +}; + +void ide_fixup(void) +{ + volatile int delay; + struct pci_dev *dev = pci_find_device(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_5513, + (void *) NULL); + int i; + u8 val8; + u16 val16; + u32 val32; + + int initlen = ASIZE(ide_init); + const initreg_t * inittab = ide_init; + + printk_info ("Entering the initregs process\n"); + + for (i = 0; i < initlen; ++i) { + u16 regno = inittab[i].regno; + switch (inittab[i].size) { + case BYTE: + pci_read_config_byte(dev, regno, &val8); + val8 = (val8 & inittab[i].andval) | inittab[i].orval; + pci_write_config_byte(dev, regno, val8); + break; + case WORD: + pci_read_config_word(dev, regno, &val16); + val16 = (val16 & inittab[i].andval) | inittab[i].orval; + pci_write_config_word(dev, regno, val16); + break; + case DBLE: + pci_read_config_dword(dev, regno, &val32); + val32 = (val32 & inittab[i].andval) | inittab[i].orval; + break; + + default: + outb_p(0xEE,0x80); + while(1); + break; + } + } +} void keyboard_on() { u8 regval; struct pci_dev *pcidev; - - /* turn on sis550 keyboard/mouse controller */ + void pc_keyboard_init(void); + /* turn on sis630 keyboard/mouse controller */ pcidev = pci_find_device(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503, (void *)NULL); if (pcidev != NULL) { /* Register 0x47, Keyboard Controller */ @@ -175,6 +268,7 @@ final_southbridge_fixup() serial_irq_fixedup(); acpi_fixup(); + ide_fixup(); /* Delay transaction, experimental */ south_fixup(); diff --git a/src/northsouthbridge/sis/630/ipl.S b/src/northsouthbridge/sis/630/ipl.S index 2fa997000f..cfcc59edfb 100644 --- a/src/northsouthbridge/sis/630/ipl.S +++ b/src/northsouthbridge/sis/630/ipl.S @@ -53,7 +53,7 @@ sis630spd_start: movw $0x7550, %ax # Store ACPI Base Address. CALL_SP(write_lpc_register) # (for use of SMBus) - movw $0x5501, %ax # Mode# enable, this bit + movw $0x5501, %ax # MDOE# enable, this bit CALL_SP(write_pci_register) # should be set before sizing. #ifdef SIZE_ALL @@ -214,88 +214,17 @@ sis630ipl_start: movw %ax, %ss movw $SPL_RAM_SEG, %ax movw %ax, %es + xorw %sp, %sp # clear %sp #ifdef STD_FLASH - movw $0xf000, %ax - movw %ax, %ds - xorw %sp, %sp # clear %sp - xorw %si, %si - xorw %di, %di - movw $0xffff, %cx - rep - movsb - - movw $DOC_WIN_SEG, %ax - movw %ax, %ds +#include "rom/std_flash.inc" #else /* !STD_FLASH */ - movw $sis950_init_table, %si # unlock SiS 950 LPC - movw $0x05, %cx # select Clock Selection - movw $0x2e, %dx # and Flash ROM I/F - rep - outsb - movb $0xfd, %al # enable write, CLKIN = 24 MHZ - outb %al, $0x2f - - xorw %sp, %sp # clear %sp - xorw %dx, %dx # clear %dx, start of RAM - movw $0x800, %si # point %si to CDSN Data area - movw $0x1000, %di # point %di to CDSN Control area - movw $DOC_SPL_START_PAGE, %bp # start page of LinuxBIOS - - movb $0x84, %al # Reset DOC Millennium - call doc_reset - - movb $0x85, %al # Turn into Normal Mode - call doc_reset - -read_next_page: - movw $0x1000, %di # point %di to CDSN Control area - -flash_command: - movb $0x03, 0x04(%di) # start command cycle - movb $0x00, (%si) # issue flash command Read00 - call doc_cycle_end - - movw %bp, %bx # %bp is current page number - -flash_address: - shll $0x08, %ebx - movb $0x03, %cl # this one is DANGEROUS but I am - # sure the upper 3 bytes == 0x00 - - movb $0x05, 0x04(%di) # start address cycle -0: - movb %bl, (%si) # write address to CDSNIO - shrw $0x08, %bx # shift next address byte - loop 0b - - call doc_cycle_end - -wait_for_flash_ready: - /* delay by reding NOP register before polling the FLASH READY bit, - this is inlined to save a call/ret pair */ -doc_delay: - movb $0x04, %cl # this one is DANGEROUS but I am - # sure the upper 3 bytes == 0x00 -0: - movb 0x20(%di), %al # read DOC NOP retisger - loop 0b # four times - - testb $0x80, 0x04(%di) # is flash ready ? - jz wait_for_flash_ready - - movb 0x1d(%di), %al # init read pipeline - movw $0x100, %cx # 1 page = 512 bytes - movw $0x800, %si # point %si to CDSN Data area - movw %dx, %di # restore saved current destination - rep - movsw - - movw %di, %dx # save current destination - incw %bp # increse current page number - cmpw $(DOC_SPL_START_PAGE + DOC_SPL_SIZE_IN_PAGE), %bp - # moved enough data ?? - jl read_next_page # no, read next page +#include "unlock_flash.inc" +#if defined(USE_DOC_MIL) || defined(USE_DOC_2000_TSOP) +# include "rom/doc_mil.inc" +#else defined(USE_DOC_MIL_PLUS) +# include "rom/doc_mil_plus.inc" +#endif #endif /* STD_FLASH */ sis630ipl_end: @@ -369,18 +298,6 @@ sis_set_smbus: outb %al, %dx RET_BP # End of sis_set_smbus -doc_reset: - /* Input: AL = value write to DOC_CONTROL register - Clobberd: CX */ - movb %al, 0x02(%di) # write DoC Control retister - movb %al, 0x02(%di) # twice - ret # End of doc_reset - -doc_cycle_end: - movb $0x00, 0x1e(%di) # flush write pepeline - movb $0x01, 0x04(%di) # end command cycle - ret - sdram_type_bank_1: # Column Number 8 9 10 11 Row Number .byte 0b0000, 0b0100, 0b1000, 0xff # 11 @@ -412,7 +329,11 @@ reset_vector: .byte 0xea # jmp to f000:fe00, where IPL .word 0xfe00, 0xf000 # starts in Standard Flash #else /* !STD_FLASH i.e. DoC Mil */ +#if defined(USE_DOC_MIL) .org 0x1f0 +#elif defined(USE_DOC_2000_TSOP) || defined(USE_DOC_MIL_PLUS) + .org 0x3f0 +#endif reset_vector: .byte 0xea # jmp to fe00:0000, where IPL .word 0x0000, DOC_WIN_SEG # starts in DoC diff --git a/src/northsouthbridge/sis/630/southbridge.c b/src/northsouthbridge/sis/630/southbridge.c index e3ec568d28..f35d5fc3b9 100644 --- a/src/northsouthbridge/sis/630/southbridge.c +++ b/src/northsouthbridge/sis/630/southbridge.c @@ -20,10 +20,6 @@ static char rcsid[] = #include -/* - * Something in the pci enumerator appears to be hosing - * values in the ide pci space. This is a temp workaround. - */ #define BYTE sizeof(u8) #define WORD sizeof(u16) #define DBLE sizeof(u32) @@ -33,101 +29,88 @@ static char rcsid[] = #define IDE_BASE1 (0x1F0u) /* primary controller */ #define ASIZE(x) (sizeof(x)/sizeof((x)[0])) - -void ide_fixup(void) { - volatile int delay; - struct pci_dev *dev = pci_find_device(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_5513, (void *)NULL); - int i; - u8 val8; - u16 val16; - u32 val32; - typedef struct { - u8 size; - u8 regno; - u32 andval; - u32 orval; + u8 size; + u8 regno; + u32 andval; + u32 orval; } initreg_t; - static const initreg_t ide_init[] = { - /* - * BUS(0), DEVICE(0), FUNCTION(1): IDE Interface. Bridge - */ - /*SIZE REG AND-MASK OR-MASK */ - { WORD, 0x04, 0x0, 0x0007 }, /* Command Register. sets mem+ */ - { WORD, 0x06, 0x0, 0x3000 }, /* Status reg, clear aborts. */ - { WORD, 0x09, 0x0A, 0x00 }, /* Programming interface = Compatible mode. */ - { BYTE, 0x0D, 0x0, 0x10 }, /* Latency Timer */ - /* We let the pci enumerator assign these. */ - // { DBLE, 0x10, 0x0, 0x1F1 }, /* Primary channel base addr. */ - // { DBLE, 0x14, 0x0, 0x3F5 }, /* Primary channel control base addr. */ - // { DBLE, 0x18, 0x0, 0x171 }, /* Secondary channel base addr. */ - // { DBLE, 0x1C, 0x0, 0x375 }, /* Secondary channel control base addr. */ - // { DBLE, 0x20, 0x0, 0x4001 }, /* Control register base addr. */ - { WORD, 0x2C, 0x0, 0x1039 }, /* Subsystem vendor ID. */ - { WORD, 0x2E, 0x0, 0x5513 }, /* Subsystem ID. */ - { BYTE, 0x3c, 0x0, 0x0e }, /* reserved don't do this, sets irq 14 */ - { BYTE, 0x40, 0x00, 0x01 }, /* Primary master data recovery time. */ - { BYTE, 0x41, 0x00, 0xb3 }, /* Primary master data active time. UDMA */ - { BYTE, 0x42, 0x00, 0x00 }, /* Primary slave data recovery time. */ - { BYTE, 0x43, 0x00, 0x00 }, /* Primary slave data active time. */ - { BYTE, 0x44, 0x00, 0x00 }, /* Secondary master data recovery time. */ - { BYTE, 0x45, 0x00, 0x00 }, /* Secondary master data active time. */ - { BYTE, 0x46, 0x00, 0x00 }, /* Secondary slave data recovery time. */ - { BYTE, 0x47, 0x00, 0x00 }, /* Secondary slave data active time. */ - { BYTE, 0x48, 0x00, 0x05 }, /* Ide status */ - { BYTE, 0x4A, 0x40, 0xe6 }, /* Ide general control 0 was 0x62 */ - { BYTE, 0x4B, 0x00, 0x11 }, /* Ide general control 1 */ - { WORD, 0x4C, 0x00, 0x0200}, /* prefetch of primary. */ - { WORD, 0x4E, 0x00, 0x0200} /* prefetch of secondary. */ - //{ BYTE, 0x48, 0x00, 0x33 }, /* Ide status */ - //{ BYTE, 0x4A, 0x00, 0xe2 }, /* Ide general control 0 was 0x62 */ - //{ BYTE, 0x4B, 0x00, 0x00 } /* Ide general control 1 */ - /* The following register has recommended setting of 0x41 in 630 programming guide, - * But no documentation in the manual. It looks identical to the same register in the - * 530. - */ - , - { BYTE, 0x52, 0xFF, 0x14 } /* Miscelaneous control (Only Doc). */ - }; - int initlen=ASIZE(ide_init); - const initreg_t * inittab = ide_init; +static const initreg_t ide_init[] = { + /* + * BUS(0), DEVICE(0), FUNCTION(1): IDE Interface. Bridge + */ + /* SIZE REG AND-MASK OR-MASK */ + { WORD, 0x04, 0x00, 0x0007 }, /* Command Register. sets mem+ */ + { WORD, 0x06, 0x00, 0x3000 }, /* Status reg, clear aborts. */ + { WORD, 0x09, 0x0A, 0x00 }, /* Programming interface = Compatible mode. */ + { BYTE, 0x0D, 0x00, 0x10 }, /* Latency Timer */ + /* We let the pci enumerator assign these. */ + // { DBLE, 0x10, 0x0, 0x1F1 }, /* Primary channel base addr. */ + // { DBLE, 0x14, 0x0, 0x3F5 }, /* Primary channel control base addr. */ + // { DBLE, 0x18, 0x0, 0x171 }, /* Secondary channel base addr. */ + // { DBLE, 0x1C, 0x0, 0x375 }, /* Secondary channel control base addr. */ + // { DBLE, 0x20, 0x0, 0x4001 }, /* Control register base addr. */ + { WORD, 0x2C, 0x00, 0x1039 }, /* Subsystem vendor ID. */ + { WORD, 0x2E, 0x00, 0x5513 }, /* Subsystem ID. */ + { BYTE, 0x3c, 0x00, 0x0e }, /* reserved don't do this, sets irq 14 */ + { BYTE, 0x40, 0x00, 0x01 }, /* Primary master data recovery time. 1 PCICLK */ + { BYTE, 0x41, 0x00, 0xb3 }, /* Primary master data active time. UDMA Mode 2 */ + { BYTE, 0x42, 0x00, 0x00 }, /* Primary slave data recovery time. */ + { BYTE, 0x43, 0x00, 0x00 }, /* Primary slave data active time. */ + { BYTE, 0x44, 0x00, 0x00 }, /* Secondary master data recovery time. */ + { BYTE, 0x45, 0x00, 0x00 }, /* Secondary master data active time. */ + { BYTE, 0x46, 0x00, 0x00 }, /* Secondary slave data recovery time. */ + { BYTE, 0x47, 0x00, 0x00 }, /* Secondary slave data active time. */ + { BYTE, 0x48, 0x00, 0x05 }, /* Read/Write FIFO Threshold = 1/4 */ + { BYTE, 0x4A, 0x40, 0xe2 }, /* Enable Bus Master, Fast postwrite, IDE 0 */ + { BYTE, 0x4B, 0x00, 0x11 }, /* Enable Postwrite and Prefech for IDE0, Master */ + { WORD, 0x4C, 0x00, 0x0200 }, /* Prefetch count of primary. */ + { WORD, 0x4E, 0x00, 0x0200 }, /* Prefetch count of secondary. */ + { BYTE, 0x52, 0xFF, 0x14 } /* Miscelaneous control (Only Doc). */ +}; +void ide_fixup(void) +{ + volatile int delay; + struct pci_dev *dev = pci_find_device(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_5513, + (void *) NULL); + int i; + u8 val8; + u16 val16; + u32 val32; + int initlen = ASIZE(ide_init); + const initreg_t * inittab = ide_init; - printk_info ("Entering the initregs process\n"); - - for (i = 0; i < initlen; ++i) { - u16 regno = inittab[i].regno; - switch (inittab[i].size) { - case BYTE: - pci_read_config_byte(dev, regno, &val8); - val8 = (val8 & inittab[i].andval) | inittab[i].orval; - pci_write_config_byte(dev, regno, val8); - break; - case WORD: - pci_read_config_word(dev, regno, &val16); - val16 = (val16 & inittab[i].andval) | inittab[i].orval; - pci_write_config_word(dev, regno, val16); - break; - case DBLE: - pci_read_config_dword(dev, regno, &val32); - val32 = (val32 & inittab[i].andval) | inittab[i].orval; - break; - - default: - outb_p(0xEE,0x80); - while(1); - break; - } - } - - + printk_info ("Entering the initregs process\n"); + for (i = 0; i < initlen; ++i) { + u16 regno = inittab[i].regno; + switch (inittab[i].size) { + case BYTE: + pci_read_config_byte(dev, regno, &val8); + val8 = (val8 & inittab[i].andval) | inittab[i].orval; + pci_write_config_byte(dev, regno, val8); + break; + case WORD: + pci_read_config_word(dev, regno, &val16); + val16 = (val16 & inittab[i].andval) | inittab[i].orval; + pci_write_config_word(dev, regno, val16); + break; + case DBLE: + pci_read_config_dword(dev, regno, &val32); + val32 = (val32 & inittab[i].andval) | inittab[i].orval; + break; + + default: + outb_p(0xEE,0x80); + while(1); + break; + } + } } - - void keyboard_on() { u8 regval; @@ -145,7 +128,6 @@ void keyboard_on() pc_keyboard_init(); } - void nvram_on() { struct pci_dev *pcidev; diff --git a/src/northsouthbridge/sis/730/ipl.S b/src/northsouthbridge/sis/730/ipl.S index 1f9e38f11b..7772cfaf2f 100644 --- a/src/northsouthbridge/sis/730/ipl.S +++ b/src/northsouthbridge/sis/730/ipl.S @@ -117,11 +117,11 @@ check_row_column: jl no_sdram #endif /* SAFTY_CHECK */ -#if 1 +#if 0 subb $0x0b, %ch # row = row - 11 shlb $0x02, %ch # row * 4 - addb %ch, %cl # column + row *4 + addb %ch, %cl # column + row * 4 movzbw %cl, %bx # Get the SDRAM type. addw %bx, %si # sdram_type_bank[column + row * 4] @@ -214,88 +214,17 @@ sis730ipl_start: movw %ax, %ss movw $SPL_RAM_SEG, %ax movw %ax, %es + xorw %sp, %sp # clear %sp #ifdef STD_FLASH - movw $0xf000, %ax - movw %ax, %ds - xorw %sp, %sp # clear %sp - xorw %si, %si - xorw %di, %di - movw $0xffff, %cx - rep - movsb - - movw $DOC_WIN_SEG, %ax - movw %ax, %ds +#include "rom/std_flash.inc" #else /* !STD_FLASH */ - movw $sis950_init_table, %si # unlock SiS 950 LPC - movw $0x05, %cx # select Clock Selection - movw $0x2e, %dx # and Flash ROM I/F - rep - outsb - movb $0xfd, %al # enable write, CLKIN = 24 MHZ - outb %al, $0x2f - - xorw %sp, %sp # clear %sp - xorw %dx, %dx # clear %dx, start of RAM - movw $0x800, %si # point %si to CDSN Data area - movw $0x1000, %di # point %di to CDSN Control area - movw $DOC_SPL_START_PAGE, %bp # start page of LinuxBIOS - - movb $0x84, %al # Reset DOC Millennium - call doc_reset - - movb $0x85, %al # Turn into Normal Mode - call doc_reset - -read_next_page: - movw $0x1000, %di # point %di to CDSN Control area - -flash_command: - movb $0x03, 0x04(%di) # start command cycle - movb $0x00, (%si) # issue flash command Read00 - call doc_cycle_end - - movw %bp, %bx # %bp is current page number - -flash_address: - shll $0x08, %ebx - movb $0x03, %cl # this one is DANGEROUS but I am - # sure the upper 3 bytes == 0x00 - - movb $0x05, 0x04(%di) # start address cycle -0: - movb %bl, (%si) # write address to CDSNIO - shrw $0x08, %bx # shift next address byte - loop 0b - - call doc_cycle_end - -wait_for_flash_ready: - /* delay by reding NOP register before polling the FLASH READY bit, - this is inlined to save a call/ret pair */ -doc_delay: - movb $0x04, %cl # this one is DANGEROUS but I am - # sure the upper 3 bytes == 0x00 -0: - movb 0x20(%di), %al # read DOC NOP retisger - loop 0b # four times - - testb $0x80, 0x04(%di) # is flash ready ? - jz wait_for_flash_ready - - movb 0x1d(%di), %al # init read pipeline - movw $0x100, %cx # 1 page = 512 bytes - movw $0x800, %si # point %si to CDSN Data area - movw %dx, %di # restore saved current destination - rep - movsw - - movw %di, %dx # save current destination - incw %bp # increse current page number - cmpw $(DOC_SPL_START_PAGE + DOC_SPL_SIZE_IN_PAGE), %bp - # moved enough data ?? - jl read_next_page # no, read next page +#include "unlock_flash.inc" +#if defined(USE_DOC_MIL) || defined(USE_DOC_2000_TSOP) +# include "rom/doc_mil.inc" +#else defined(USE_DOC_MIL_PLUS) +# include "rom/doc_mil_plus.inc" +#endif #endif /* STD_FLASH */ sis730ipl_end: @@ -331,7 +260,7 @@ write_common: read_spd: /* Input: AH = 05h, AL = byte number of SPD to be read. Output: BL = The value of specified SPD byte. */ - movb $0x05, %ah + movb $0x05, %ah # set SMB Command == byte address CALL_BP(sis_set_smbus) movw $0x0312, %ax # Start, R/W byte Data @@ -352,7 +281,7 @@ read_spd_fail: sis_get_smbus: /* Input: AH - register index. - Output: AL - register value. */ + Output: BL - register value. */ addb %ah, %dl # read SMBus byte 0 inb %dx, %al movb %al, %bl # return result in BL @@ -369,18 +298,6 @@ sis_set_smbus: outb %al, %dx RET_BP # End of sis_set_smbus -doc_reset: - /* Input: AL = value write to DOC_CONTROL register - Clobberd: CX */ - movb %al, 0x02(%di) # write DoC Control retister - movb %al, 0x02(%di) # twice - ret # End of doc_reset - -doc_cycle_end: - movb $0x00, 0x1e(%di) # flush write pepeline - movb $0x01, 0x04(%di) # end command cycle - ret - sdram_type_bank_1: # Column Number 8 9 10 11 Row Number .byte 0b0000, 0b0100, 0b1000, 0xff # 11 @@ -420,7 +337,11 @@ reset_vector: .byte 0xea # jmp to f000:fe00, where IPL .word 0xfe00, 0xf000 # starts in Standard Flash #else /* !STD_FLASH i.e. DoC Mil */ +#if defined(USE_DOC_MIL) .org 0x1f0 +#elif defined(USE_DOC_2000_TSOP) || defined(USE_DOC_MIL_PLUS) + .org 0x3f0 +#endif reset_vector: .byte 0xea # jmp to fe00:0000, where IPL .word 0x0000, DOC_WIN_SEG # starts in DoC diff --git a/src/northsouthbridge/sis/730/southbridge.c b/src/northsouthbridge/sis/730/southbridge.c index 8ad6d6cc13..ba6be75058 100644 --- a/src/northsouthbridge/sis/730/southbridge.c +++ b/src/northsouthbridge/sis/730/southbridge.c @@ -18,6 +18,99 @@ static char rcsid[] = #include #include +#include + +#define BYTE sizeof(u8) +#define WORD sizeof(u16) +#define DBLE sizeof(u32) +#define IDE_REG_EXTENDED_OFFSET (0x200u) +#define IDE_REG_SECTOR_COUNT(base) ((base) + 2u) +#define IDE_REG_CONTROL(base) ((base) + IDE_REG_EXTENDED_OFFSET + 6u) +#define IDE_BASE1 (0x1F0u) /* primary controller */ +#define ASIZE(x) (sizeof(x)/sizeof((x)[0])) + +typedef struct { + u8 size; + u8 regno; + u32 andval; + u32 orval; +} initreg_t; + +static const initreg_t ide_init[] = { + /* + * BUS(0), DEVICE(0), FUNCTION(1): IDE Interface. Bridge + */ + /* SIZE REG AND-MASK OR-MASK */ + { WORD, 0x04, 0x00, 0x0007 }, /* Command Register. sets mem+ */ + { WORD, 0x06, 0x00, 0x3000 }, /* Status reg, clear aborts. */ + { WORD, 0x09, 0x0A, 0x00 }, /* Programming interface = Compatible mode. */ + { BYTE, 0x0D, 0x00, 0x10 }, /* Latency Timer */ + /* We let the pci enumerator assign these. */ + // { DBLE, 0x10, 0x0, 0x1F1 }, /* Primary channel base addr. */ + // { DBLE, 0x14, 0x0, 0x3F5 }, /* Primary channel control base addr. */ + // { DBLE, 0x18, 0x0, 0x171 }, /* Secondary channel base addr. */ + // { DBLE, 0x1C, 0x0, 0x375 }, /* Secondary channel control base addr. */ + // { DBLE, 0x20, 0x0, 0x4001 }, /* Control register base addr. */ + { WORD, 0x2C, 0x00, 0x1039 }, /* Subsystem vendor ID. */ + { WORD, 0x2E, 0x00, 0x5513 }, /* Subsystem ID. */ + { BYTE, 0x3c, 0x00, 0x0e }, /* reserved don't do this, sets irq 14 */ + { BYTE, 0x40, 0x00, 0x01 }, /* Primary master data recovery time. 1 PCICLK */ + { BYTE, 0x41, 0x00, 0xb3 }, /* Primary master data active time. UDMA Mode 2 */ + { BYTE, 0x42, 0x00, 0x00 }, /* Primary slave data recovery time. */ + { BYTE, 0x43, 0x00, 0x00 }, /* Primary slave data active time. */ + { BYTE, 0x44, 0x00, 0x00 }, /* Secondary master data recovery time. */ + { BYTE, 0x45, 0x00, 0x00 }, /* Secondary master data active time. */ + { BYTE, 0x46, 0x00, 0x00 }, /* Secondary slave data recovery time. */ + { BYTE, 0x47, 0x00, 0x00 }, /* Secondary slave data active time. */ + { BYTE, 0x48, 0x00, 0x05 }, /* Read/Write FIFO Threshold = 1/4 */ + { BYTE, 0x4A, 0x40, 0xe2 }, /* Enable Bus Master, Fast postwrite, IDE 0 */ + { BYTE, 0x4B, 0x00, 0x11 }, /* Enable Postwrite and Prefech for IDE0, Master */ + { WORD, 0x4C, 0x00, 0x0200 }, /* Prefetch count of primary. */ + { WORD, 0x4E, 0x00, 0x0200 }, /* Prefetch count of secondary. */ + { BYTE, 0x52, 0xFF, 0x14 } /* Miscelaneous control (Only Doc). */ +}; + +void ide_fixup(void) +{ + volatile int delay; + struct pci_dev *dev = pci_find_device(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_5513, + (void *) NULL); + int i; + u8 val8; + u16 val16; + u32 val32; + + int initlen = ASIZE(ide_init); + const initreg_t * inittab = ide_init; + + printk_info ("Entering the initregs process\n"); + + for (i = 0; i < initlen; ++i) { + u16 regno = inittab[i].regno; + switch (inittab[i].size) { + case BYTE: + pci_read_config_byte(dev, regno, &val8); + val8 = (val8 & inittab[i].andval) | inittab[i].orval; + pci_write_config_byte(dev, regno, val8); + break; + case WORD: + pci_read_config_word(dev, regno, &val16); + val16 = (val16 & inittab[i].andval) | inittab[i].orval; + pci_write_config_word(dev, regno, val16); + break; + case DBLE: + pci_read_config_dword(dev, regno, &val32); + val32 = (val32 & inittab[i].andval) | inittab[i].orval; + break; + + default: + outb_p(0xEE,0x80); + while(1); + break; + } + } +} + void keyboard_on() { u8 regval; @@ -282,6 +375,7 @@ final_southbridge_fixup() apc_fixup(); serial_irq_fixedup(); acpi_fixup(); + ide_fixup(); printk_debug("Southbridge fixup done for SIS 503\n"); }