>From d34ce4df75cd3b101c909d5d3d3a6651a3f64656 Mon Sep 17 00:00:00 2001 From: Wu Zhangjin <wuzhangjin@xxxxxxxxx> Date: Sat, 16 May 2009 03:21:19 +0800 Subject: [PATCH 14/30] loongson: add basic fuloong(2f) support fuloong(2e) have an VIA686B south bridge, but fuloong(2f) have an AMD CS5536 south bridge. --- arch/mips/Makefile | 1 + .../mips/include/asm/mach-loongson/cs5536/cs5536.h | 576 +++++ .../include/asm/mach-loongson/cs5536/cs5536_pci.h | 181 ++ arch/mips/include/asm/mach-loongson/cs5536/mfgpt.h | 15 + .../mips/include/asm/mach-loongson/cs5536/pcireg.h | 485 ++++ arch/mips/include/asm/mach-loongson/machine.h | 30 + arch/mips/loongson/Kconfig | 28 + arch/mips/loongson/Makefile | 6 + arch/mips/loongson/common/Makefile | 6 + arch/mips/loongson/common/bonito-irq.c | 5 + arch/mips/loongson/common/cs5536_vsm.c | 2321 ++++++++++++++++++++ arch/mips/loongson/common/mem.c | 1 + arch/mips/loongson/fuloong-2f/Makefile | 5 + arch/mips/loongson/fuloong-2f/irq.c | 57 + arch/mips/loongson/fuloong-2f/reset.c | 75 + arch/mips/pci/Makefile | 3 +- arch/mips/pci/fixup-fuloong2f.c | 189 ++ arch/mips/pci/ops-fuloong2e.c | 159 -- arch/mips/pci/ops-loongson2.c | 210 ++ 19 files changed, 4193 insertions(+), 160 deletions(-) create mode 100644 arch/mips/include/asm/mach-loongson/cs5536/cs5536.h create mode 100644 arch/mips/include/asm/mach-loongson/cs5536/cs5536_pci.h create mode 100644 arch/mips/include/asm/mach-loongson/cs5536/mfgpt.h create mode 100644 arch/mips/include/asm/mach-loongson/cs5536/pcireg.h create mode 100644 arch/mips/loongson/common/cs5536_vsm.c create mode 100644 arch/mips/loongson/fuloong-2f/Makefile create mode 100644 arch/mips/loongson/fuloong-2f/irq.c create mode 100644 arch/mips/loongson/fuloong-2f/reset.c create mode 100644 arch/mips/pci/fixup-fuloong2f.c delete mode 100644 arch/mips/pci/ops-fuloong2e.c create mode 100644 arch/mips/pci/ops-loongson2.c diff --git a/arch/mips/Makefile b/arch/mips/Makefile index 6cbfc22..abf16c1 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -310,6 +310,7 @@ core-$(CONFIG_LOONGSON_SYSTEMS) +=arch/mips/loongson/ cflags-$(CONFIG_LOONGSON_SYSTEMS) += -I $(srctree)/arch/mips/include/asm/mach-loongson \ -mno-branch-likely load-$(CONFIG_LEMOTE_FULOONG2E) +=0xffffffff80100000 +load-$(CONFIG_LEMOTE_FULOONG2F) +=0xffffffff80200000 # # MIPS Malta board diff --git a/arch/mips/include/asm/mach-loongson/cs5536/cs5536.h b/arch/mips/include/asm/mach-loongson/cs5536/cs5536.h new file mode 100644 index 0000000..502b464 --- /dev/null +++ b/arch/mips/include/asm/mach-loongson/cs5536/cs5536.h @@ -0,0 +1,576 @@ +/* + * The include file of cs5536 sourthbridge define which is used in the pmon only. + * you can modify it or change it, please set the modify time and steps. + * + * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology + * Author : jlliu <liujl@xxxxxxxxxx> + */ + +#ifndef _CS5536_H +#define _CS5536_H + +extern void _rdmsr(u32 msr, u32 * hi, u32 * lo); +extern void _wrmsr(u32 msr, u32 hi, u32 lo); + +/*************************************************************************/ + +/* + * basic define + */ +#define PCI_IO_BASE_VA mips_io_port_base + +/* + * MSR module base + */ +#define CS5536_SB_MSR_BASE (0x00000000) +#define CS5536_GLIU_MSR_BASE (0x10000000) +#define CS5536_ILLEGAL_MSR_BASE (0x20000000) +#define CS5536_USB_MSR_BASE (0x40000000) +#define CS5536_IDE_MSR_BASE (0x60000000) +#define CS5536_DIVIL_MSR_BASE (0x80000000) +#define CS5536_ACC_MSR_BASE (0xa0000000) +#define CS5536_UNUSED_MSR_BASE (0xc0000000) +#define CS5536_GLCP_MSR_BASE (0xe0000000) + +#define SB_MSR_REG(offset) (CS5536_SB_MSR_BASE | offset) +#define GLIU_MSR_REG(offset) (CS5536_GLIU_MSR_BASE | offset) +#define ILLEGAL_MSR_REG(offset) (CS5536_ILLEGAL_MSR_BASE| offset) +#define USB_MSR_REG(offset) (CS5536_USB_MSR_BASE | offset) +#define IDE_MSR_REG(offset) (CS5536_IDE_MSR_BASE | offset) +#define DIVIL_MSR_REG(offset) (CS5536_DIVIL_MSR_BASE | offset) +#define ACC_MSR_REG(offset) (CS5536_ACC_MSR_BASE | offset) +#define UNUSED_MSR_REG(offset) (CS5536_UNUSED_MSR_BASE | offset) +#define GLCP_MSR_REG(offset) (CS5536_GLCP_MSR_BASE | offset) + +/* + * BAR SPACE OF VIRTUAL PCI : range for pci probe use, length is the actual size. + */ +/* IO space for all DIVIL modules */ +#define CS5536_IRQ_RANGE 0xffffffe0 /* USERD FOR PCI PROBE */ +#define CS5536_IRQ_LENGTH 0x20 /* THE REGS ACTUAL LENGTH */ +#define CS5536_SMB_RANGE 0xfffffff8 +#define CS5536_SMB_LENGTH 0x08 +#define CS5536_GPIO_RANGE 0xffffff00 +#define CS5536_GPIO_LENGTH 0x100 +#define CS5536_MFGPT_RANGE 0xffffffc0 +#define CS5536_MFGPT_LENGTH 0x40 +#define CS5536_ACPI_RANGE 0xffffffe0 +#define CS5536_ACPI_LENGTH 0x20 +#define CS5536_PMS_RANGE 0xffffff80 +#define CS5536_PMS_LENGTH 0x80 +/* MEM space for 4KB nand flash; IO space for 16B nor flash. */ +#ifdef CS5536_USE_NOR_FLASH +#define CS5536_FLSH0_RANGE 0xfffffff0 +#define CS5536_FLSH0_LENGTH 0x10 +#define CS5536_FLSH1_RANGE 0xfffffff0 +#define CS5536_FLSH1_LENGTH 0x10 +#define CS5536_FLSH2_RANGE 0xfffffff0 +#define CS5536_FLSH2_LENGTH 0x10 +#define CS5536_FLSH3_RANGE 0xfffffff0 +#define CS5536_FLSH3_LENGTH 0x10 +#else +#define CS5536_FLSH0_RANGE 0xfffff000 +#define CS5536_FLSH0_LENGTH 0x1000 +#define CS5536_FLSH1_RANGE 0xfffff000 +#define CS5536_FLSH1_LENGTH 0x1000 +#define CS5536_FLSH2_RANGE 0xfffff000 +#define CS5536_FLSH2_LENGTH 0x1000 +#define CS5536_FLSH3_RANGE 0xfffff000 +#define CS5536_FLSH3_LENGTH 0x1000 +#endif +/* IO space for IDE */ +#define CS5536_IDE_RANGE 0xfffffff0 +#define CS5536_IDE_LENGTH 0x10 +/* IO space for ACC */ +#define CS5536_ACC_RANGE 0xffffff80 +#define CS5536_ACC_LENGTH 0x80 +/* MEM space for ALL USB modules */ +/* #define CS5536_OHCI_RANGE 0xfffffff0 */ +#define CS5536_OHCI_RANGE 0xfffff000 +#define CS5536_OHCI_LENGTH 0x1000 +/* #define CS5536_EHCI_RANGE 0xfffffff0 */ +#define CS5536_EHCI_RANGE 0xfffff000 +#define CS5536_EHCI_LENGTH 0x1000 +#define CS5536_UDC_RANGE 0xffffe000 +#define CS5536_UDC_LENGTH 0x2000 +#define CS5536_OTG_RANGE 0xfffff000 +#define CS5536_OTG_LENGTH 0x1000 + +/* + * PCI MSR ACCESS + */ +#define PCI_MSR_CTRL 0xF0 +#define PCI_MSR_ADDR 0xF4 +#define PCI_MSR_DATA_LO 0xF8 +#define PCI_MSR_DATA_HI 0xFC + +/******************************* MSR *********************************************/ + +/* + * GLIU STANDARD MSR + */ +#define GLIU_CAP 0x00 +#define GLIU_CONFIG 0x01 +#define GLIU_SMI 0x02 +#define GLIU_ERROR 0x03 +#define GLIU_PM 0x04 +#define GLIU_DIAG 0x05 + +/* + * GLIU SPEC. MSR + */ +#define GLIU_P2D_BM0 0x20 +#define GLIU_P2D_BM1 0x21 +#define GLIU_P2D_BM2 0x22 +#define GLIU_P2D_BMK0 0x23 +#define GLIU_P2D_BMK1 0x24 +#define GLIU_P2D_BM3 0x25 +#define GLIU_P2D_BM4 0x26 +#define GLIU_COH 0x80 +#define GLIU_PAE 0x81 +#define GLIU_ARB 0x82 +#define GLIU_ASMI 0x83 +#define GLIU_AERR 0x84 +#define GLIU_DEBUG 0x85 +#define GLIU_PHY_CAP 0x86 +#define GLIU_NOUT_RESP 0x87 +#define GLIU_NOUT_WDATA 0x88 +#define GLIU_WHOAMI 0x8B +#define GLIU_SLV_DIS 0x8C +#define GLIU_IOD_BM0 0xE0 +#define GLIU_IOD_BM1 0xE1 +#define GLIU_IOD_BM2 0xE2 +#define GLIU_IOD_BM3 0xE3 +#define GLIU_IOD_BM4 0xE4 +#define GLIU_IOD_BM5 0xE5 +#define GLIU_IOD_BM6 0xE6 +#define GLIU_IOD_BM7 0xE7 +#define GLIU_IOD_BM8 0xE8 +#define GLIU_IOD_BM9 0xE9 +#define GLIU_IOD_SC0 0xEA +#define GLIU_IOD_SC1 0xEB +#define GLIU_IOD_SC2 0xEC +#define GLIU_IOD_SC3 0xED +#define GLIU_IOD_SC4 0xEE +#define GLIU_IOD_SC5 0xEF +#define GLIU_IOD_SC6 0xF0 +#define GLIU_IOD_SC7 0xF1 + +/* + * SB STANDARD + */ +#define SB_CAP 0x00 +#define SB_CONFIG 0x01 +#define SB_SMI 0x02 +#define SB_ERROR 0x03 +#define SB_MAR_ERR_EN 0x00000001 +#define SB_TAR_ERR_EN 0x00000002 +#define SB_RSVD_BIT1 0x00000004 +#define SB_EXCEP_ERR_EN 0x00000008 +#define SB_SYSE_ERR_EN 0x00000010 +#define SB_PARE_ERR_EN 0x00000020 +#define SB_TAS_ERR_EN 0x00000040 +#define SB_MAR_ERR_FLAG 0x00010000 +#define SB_TAR_ERR_FLAG 0x00020000 +#define SB_RSVD_BIT2 0x00040000 +#define SB_EXCEP_ERR_FLAG 0x00080000 +#define SB_SYSE_ERR_FLAG 0x00100000 +#define SB_PARE_ERR_FLAG 0x00200000 +#define SB_TAS_ERR_FLAG 0x00400000 +#define SB_PM 0x04 +#define SB_DIAG 0x05 + +/* + * SB SPEC. + */ +#define SB_CTRL 0x10 +#define SB_R0 0x20 +#define SB_R1 0x21 +#define SB_R2 0x22 +#define SB_R3 0x23 +#define SB_R4 0x24 +#define SB_R5 0x25 +#define SB_R6 0x26 +#define SB_R7 0x27 +#define SB_R8 0x28 +#define SB_R9 0x29 +#define SB_R10 0x2A +#define SB_R11 0x2B +#define SB_R12 0x2C +#define SB_R13 0x2D +#define SB_R14 0x2E +#define SB_R15 0x2F + +/* + * GLCP STANDARD + */ +#define GLCP_CAP 0x00 +#define GLCP_CONFIG 0x01 +#define GLCP_SMI 0x02 +#define GLCP_ERROR 0x03 +#define GLCP_PM 0x04 +#define GLCP_DIAG 0x05 + +/* + * GLCP SPEC. + */ +#define GLCP_CLK_DIS_DELAY 0x08 +#define GLCP_PM_CLK_DISABLE 0x09 +#define GLCP_GLB_PM 0x0B +#define GLCP_DBG_OUT 0x0C +#define GLCP_RSVD1 0x0D +#define GLCP_SOFT_COM 0x0E +#define SOFT_BAR_SMB_FLAG 0x00000001 +#define SOFT_BAR_GPIO_FLAG 0x00000002 +#define SOFT_BAR_MFGPT_FLAG 0x00000004 +#define SOFT_BAR_IRQ_FLAG 0x00000008 +#define SOFT_BAR_PMS_FLAG 0x00000010 +#define SOFT_BAR_ACPI_FLAG 0x00000020 +#define SOFT_BAR_FLSH0_FLAG 0x00000040 +#define SOFT_BAR_FLSH1_FLAG 0x00000080 +#define SOFT_BAR_FLSH2_FLAG 0x00000100 +#define SOFT_BAR_FLSH3_FLAG 0x00000200 +#define SOFT_BAR_IDE_FLAG 0x00000400 +#define SOFT_BAR_ACC_FLAG 0x00000800 +#define SOFT_BAR_OHCI_FLAG 0x00001000 +#define SOFT_BAR_EHCI_FLAG 0x00002000 +#define SOFT_BAR_UDC_FLAG 0x00004000 +#define SOFT_BAR_OTG_FLAG 0x00008000 +#define GLCP_RSVD2 0x0F +#define GLCP_CLK_OFF 0x10 +#define GLCP_CLK_ACTIVE 0x11 +#define GLCP_CLK_DISABLE 0x12 +#define GLCP_CLK4ACK 0x13 +#define GLCP_SYS_RST 0x14 +#define GLCP_RSVD3 0x15 +#define GLCP_DBG_CLK_CTRL 0x16 +#define GLCP_CHIP_REV_ID 0x17 + +/* + * DIVIL STANDARD + */ +#define DIVIL_CAP 0x00 +#define DIVIL_CONFIG 0x01 +#define DIVIL_SMI 0x02 +#define DIVIL_ERROR 0x03 +#define DIVIL_PM 0x04 +#define DIVIL_DIAG 0x05 + +/* + * DIVIL SPEC. + */ +#define DIVIL_LBAR_IRQ 0x08 +#define DIVIL_LBAR_KEL 0x09 +#define DIVIL_LBAR_SMB 0x0B +#define DIVIL_LBAR_GPIO 0x0C +#define DIVIL_LBAR_MFGPT 0x0D +#define DIVIL_LBAR_ACPI 0x0E +#define DIVIL_LBAR_PMS 0x0F +#define DIVIL_LBAR_FLSH0 0x10 +#define DIVIL_LBAR_FLSH1 0x11 +#define DIVIL_LBAR_FLSH2 0x12 +#define DIVIL_LBAR_FLSH3 0x13 +#define DIVIL_LEG_IO 0x14 +#define DIVIL_BALL_OPTS 0x15 +#define DIVIL_SOFT_IRQ 0x16 +#define DIVIL_SOFT_RESET 0x17 +/* NOR FLASH */ +#define NORF_CTRL 0x18 +#define NORF_T01 0x19 +#define NORF_T23 0x1A +/* NAND FLASH */ +#define NANDF_DATA 0x1B +#define NANDF_CTRL 0x1C +#define NANDF_RSVD 0x1D +/* KEL Keyboard Emulation Logic */ +#define KEL_CTRL 0x1F +/* PIC */ +#define PIC_YSEL_LOW 0x20 +#define PIC_YSEL_LOW_USB_SHIFT 8 +#define PIC_YSEL_LOW_ACC_SHIFT 16 +#define PIC_YSEL_LOW_FLASH_SHIFT 24 +#define PIC_YSEL_HIGH 0x21 +#define PIC_ZSEL_LOW 0x22 +#define PIC_ZSEL_HIGH 0x23 +#define PIC_IRQM_PRIM 0x24 +#define PIC_IRQM_LPC 0x25 +#define PIC_XIRR_STS_LOW 0x26 +#define PIC_XIRR_STS_HIGH 0x27 +#define PCI_SHDW 0x34 +/* MFGPT */ +#define MFGPT_IRQ 0x28 +#define MFGPT_NR 0x29 +#define MFGPT_RSVD 0x2A +#define MFGPT_SETUP 0x2B +/* FLOPPY */ +#define FLPY_3F2_SHDW 0x30 +#define FLPY_3F7_SHDW 0x31 +#define FLPY_372_SHDW 0x32 +#define FLPY_377_SHDW 0x33 +/* PIT */ +#define PIT_SHDW 0x36 +#define PIT_CNTRL 0x37 +/* UART */ +#define UART1_MOD 0x38 +#define UART1_DONG 0x39 +#define UART1_CONF 0x3A +#define UART1_RSVD 0x3B +#define UART2_MOD 0x3C +#define UART2_DONG 0x3D +#define UART2_CONF 0x3E +#define UART2_RSVD 0x3F +/* DMA */ +#define DIVIL_AC_DMA 0x1E +#define DMA_MAP 0x40 +#define DMA_SHDW_CH0 0x41 +#define DMA_SHDW_CH1 0x42 +#define DMA_SHDW_CH2 0x43 +#define DMA_SHDW_CH3 0x44 +#define DMA_SHDW_CH4 0x45 +#define DMA_SHDW_CH5 0x46 +#define DMA_SHDW_CH6 0x47 +#define DMA_SHDW_CH7 0x48 +#define DMA_MSK_SHDW 0x49 +/* LPC */ +#define LPC_EADDR 0x4C +#define LPC_ESTAT 0x4D +#define LPC_SIRQ 0x4E +#define LPC_RSVD 0x4F +/* PMC */ +#define PMC_LTMR 0x50 +#define PMC_RSVD 0x51 +/* RTC */ +#define RTC_RAM_LOCK 0x54 +#define RTC_DOMA_OFFSET 0x55 +#define RTC_MONA_OFFSET 0x56 +#define RTC_CEN_OFFSET 0x57 + +/* + * IDE STANDARD + */ +#define IDE_CAP 0x00 +#define IDE_CONFIG 0x01 +#define IDE_SMI 0x02 +#define IDE_ERROR 0x03 +#define IDE_PM 0x04 +#define IDE_DIAG 0x05 + +/* + * IDE SPEC. + */ +#define IDE_IO_BAR 0x08 +#define IDE_CFG 0x10 +#define IDE_DTC 0x12 +#define IDE_CAST 0x13 +#define IDE_ETC 0x14 +#define IDE_INTERNAL_PM 0x15 + +/* + * ACC STANDARD + */ +#define ACC_CAP 0x00 +#define ACC_CONFIG 0x01 +#define ACC_SMI 0x02 +#define ACC_ERROR 0x03 +#define ACC_PM 0x04 +#define ACC_DIAG 0x05 + +/* + * USB STANDARD + */ +#define USB_CAP 0x00 +#define USB_CONFIG 0x01 +#define USB_SMI 0x02 +#define USB_ERROR 0x03 +#define USB_PM 0x04 +#define USB_DIAG 0x05 + +/* + * USB SPEC. + */ +#define USB_OHCI 0x08 +#define USB_EHCI 0x09 +#define USB_UDC 0x0A +#define USB_OTG 0x0B + +/********************************** NATIVE ****************************************/ +/* IDE NATIVE registers */ +#define IDE_BM_CMD 0x00 +#define IDE_BM_STS 0x02 +#define IDE_BM_PRD 0x04 + +/* OHCI native registers */ +#define OHCI_REVISION 0x00 +#define OHCI_CONTROL 0x04 +#define OHCI_COMMAND_STATUS 0x08 +#define OHCI_INT_STATUS 0x0C +#define OHCI_INT_ENABLE 0x10 +#define OHCI_INT_DISABLE 0x14 +#define OHCI_HCCA 0x18 +#define OHCI_PERI_CUR_ED 0x1C +#define OHCI_CTRL_HEAD_ED 0x20 +#define OHCI_CTRL_CUR_ED 0x24 +#define OHCI_BULK_HEAD_ED 0x28 +#define OHCI_BULK_CUR_ED 0x2C +#define OHCI_DONE_HEAD 0x30 +#define OHCI_FM_INTERVAL 0x34 +#define OHCI_FM_REMAINING 0x38 +#define OHCI_FM_NUMBER 0x3C +#define OHCI_PERI_START 0x40 +#define OHCI_LS_THRESHOLD 0x44 +#define OHCI_RH_DESCRIPTORA 0x48 +#define OHCI_RH_DESCRIPTORB 0x4C +#define OHCI_RH_STATUS 0x50 +#define OHCI_RH_PORT_STATUS1 0x54 +#define OHCI_RH_PORT_STATUS2 0x58 +#define OHCI_RH_PORT_STATUS3 0x5C +#define OHCI_RH_PORT_STATUS4 0x60 + +/* KEL : MEM SPACE; REG :32BITS WIDTH */ +#define KEL_HCE_CTRL 0x100 +#define KEL_HCE_IN 0x104 +#define KEL_HCE_OUT 0x108 +#define KEL_HCE_STS 0x10C +#define KEL_PORTA 0x92 /* 8bits */ +/* PIC : I/O SPACE; REG : 8BITS */ +#define PIC_ICW1_MASTER 0x20 +#define PIC_ICW1_SLAVE 0xA0 +#define PIC_ICW2_MASTER 0x21 +#define PIC_ICW2_SLAVE 0xA1 +#define PIC_ICW3_MASTER 0x21 +#define PIC_ICW3_SLAVE 0xA1 +#define PIC_ICW4_MASTER 0x21 +#define PIC_ICW4_SLAVE 0xA1 +#define PIC_OCW1_MASTER 0x21 +#define PIC_OCW1_SLAVE 0xA1 +#define PIC_OCW2_MASTER 0x20 +#define PIC_OCW2_SLAVE 0xA0 +#define PIC_OCW3_MASTER 0x20 +#define PIC_OCW3_SLAVE 0xA0 +#define PIC_IRR_MASTER 0x20 +#define PIC_IRR_SLAVE 0xA0 +#define PIC_ISR_MASTER 0x20 +#define PIC_ISR_SLAVE 0xA0 +#define PIC_INT_SEL1 0x4D0 +#define PIC_INT_SEL2 0x4D1 +/* GPIO : I/O SPACE; REG : 32BITS */ +#define GPIOL_OUT_VAL 0x00 +#define GPIOL_OUT_EN 0x04 +#define GPIOL_OUT_OD_EN 0x08 +#define GPIOL_OUT_INVRT_EN 0x0c +#define GPIOL_OUT_AUX1_SEL 0x10 +#define GPIOL_OUT_AUX2_SEL 0x14 +#define GPIOL_PU_EN 0x18 +#define GPIOL_PD_EN 0x1c +#define GPIOL_IN_EN 0x20 +#define GPIOL_IN_INVRT_EN 0x24 +#define GPIOL_IN_FLTR_EN 0x28 +#define GPIOL_IN_EVNTCNT_EN 0x2c +#define GPIOL_IN_READBACK 0x30 +#define GPIOL_IN_AUX1_SEL 0x34 +#define GPIOL_EVNT_EN 0x38 +#define GPIOL_LOCK_EN 0x3c +#define GPIOL_IN_POSEDGE_EN 0x40 +#define GPIOL_IN_NEGEDGE_EN 0x44 +#define GPIOL_IN_POSEDGE_STS 0x48 +#define GPIOL_IN_NEGEDGE_STS 0x4c +#define GPIOH_OUT_VAL 0x80 +#define GPIOH_OUT_EN 0x84 +#define GPIOH_OUT_OD_EN 0x88 +#define GPIOH_OUT_INVRT_EN 0x8c +#define GPIOH_OUT_AUX1_SEL 0x90 +#define GPIOH_OUT_AUX2_SEL 0x94 +#define GPIOH_PU_EN 0x98 +#define GPIOH_PD_EN 0x9c +#define GPIOH_IN_EN 0xA0 +#define GPIOH_IN_INVRT_EN 0xA4 +#define GPIOH_IN_FLTR_EN 0xA8 +#define GPIOH_IN_EVNTCNT_EN 0xAc +#define GPIOH_IN_READBACK 0xB0 +#define GPIOH_IN_AUX1_SEL 0xB4 +#define GPIOH_EVNT_EN 0xB8 +#define GPIOH_LOCK_EN 0xBc +#define GPIOH_IN_POSEDGE_EN 0xC0 +#define GPIOH_IN_NEGEDGE_EN 0xC4 +#define GPIOH_IN_POSEDGE_STS 0xC8 +#define GPIOH_IN_NEGEDGE_STS 0xCC +/* SMB : I/O SPACE, REG : 8BITS WIDTH */ +#define SMB_SDA 0x00 +#define SMB_STS 0x01 +#define SMB_STS_SLVSTP (1 << 7) +#define SMB_STS_SDAST (1 << 6) +#define SMB_STS_BER (1 << 5) +#define SMB_STS_NEGACK (1 << 4) +#define SMB_STS_STASTR (1 << 3) +#define SMB_STS_NMATCH (1 << 2) +#define SMB_STS_MASTER (1 << 1) +#define SMB_STS_XMIT (1 << 0) +#define SMB_CTRL_STS 0x02 +#define SMB_CSTS_TGSTL (1 << 5) +#define SMB_CSTS_TSDA (1 << 4) +#define SMB_CSTS_GCMTCH (1 << 3) +#define SMB_CSTS_MATCH (1 << 2) +#define SMB_CSTS_BB (1 << 1) +#define SMB_CSTS_BUSY (1 << 0) +#define SMB_CTRL1 0x03 +#define SMB_CTRL1_STASTRE (1 << 7) +#define SMB_CTRL1_NMINTE (1 << 6) +#define SMB_CTRL1_GCMEN (1 << 5) +#define SMB_CTRL1_ACK (1 << 4) +#define SMB_CTRL1_RSVD (1 << 3) +#define SMB_CTRL1_INTEN (1 << 2) +#define SMB_CTRL1_STOP (1 << 1) +#define SMB_CTRL1_START (1 << 0) +#define SMB_ADDR 0x04 +#define SMB_ADDR_SAEN (1 << 7) +#define SMB_CONTROLLER_ADDR (0xef << 0) +#define SMB_CTRL2 0x05 +#define SMB_FREQ (0x20 << 1) /* (0x7f << 1) */ +#define SMB_ENABLE (0x01 << 0) +#define SMB_CTRL3 0x06 + +/*********************************** LEGACY I/O *******************************/ + +/* + * LEGACY I/O SPACE BASE + */ +#define CS5536_LEGACY_BASE_ADDR (PCI_IO_BASE_VA | 0x0000) + +/* + * IDE LEGACY REG : legacy IO address is 0x170~0x177 and 0x376 (0x1f0~0x1f7 and 0x3f6) + * all registers are 16bits except the IDE_LEGACY_DATA reg + * some registers are read only and the + */ +#define PRI_IDE_LEGACY_REG(offset) (CS5536_LEGACY_BASE_ADDR | 0x1f0 | offset) +#define SEC_IDE_LEGACY_REG(offset) (CS5536_LEGACY_BASE_ADDR | 0x170 | offset) + +#define IDE_LEGACY_DATA 0x00 /* RW */ +#define IDE_LEGACY_ERROR 0x01 /* RO */ +#define IDE_LEGACY_FEATURE 0x01 /* WO */ +#define IDE_LEGACY_SECTOR_COUNT 0x02 /* RW */ +#define IDE_LEGACY_SECTOR_NUM 0x03 /* RW */ +#define IDE_LEGACY_CYL_LO 0x04 /* RW */ +#define IDE_LEGACY_CYL_HI 0x05 /* RW */ +#define IDE_LEGACY_HEAD 0x06 /* RW */ +#define IDE_LEGACY_HEAD_DRV (1 << 4) +#define IDE_LEGACY_HEAD_LBA (1 << 6) +#define IDE_LEGACY_HEAD_IBM (1 << 7 | 1 << 5) +#define IDE_LEGACY_STATUS 0x07 /* RO */ +#define IDE_LEGACY_STATUS_ERR (1 << 0) +#define IDE_LEGACY_STATUS_IDX (1 << 1) +#define IDE_LEGACY_STATUS_CORR (1 << 2) +#define IDE_LEGACY_STATUS_DRQ (1 << 3) +#define IDE_LEGACY_STATUS_DSC (1 << 4) +#define IDE_LEGACY_STATUS_DWF (1 << 5) +#define IDE_LEGACY_STATUS_DRDY (1 << 6) +#define IDE_LEGACY_STATUS_BUSY (1 << 7) +#define IDE_LEGACY_COMMAND 0x07 /* WO */ +#define IDE_LEGACY_ASTATUS 0x206 /* RO */ +#define IDE_LEGACY_CTRL 0x206 /* WO */ +#define IDE_LEGACY_CTRL_IDS 0x02 +#define IDE_LEGACY_CTRL_RST 0x04 +#define IDE_LEGACY_CTRL_4BIT 0x08 + +/**********************************************************************************/ + +#endif /* _CS5536_H */ diff --git a/arch/mips/include/asm/mach-loongson/cs5536/cs5536_pci.h b/arch/mips/include/asm/mach-loongson/cs5536/cs5536_pci.h new file mode 100644 index 0000000..e60a824 --- /dev/null +++ b/arch/mips/include/asm/mach-loongson/cs5536/cs5536_pci.h @@ -0,0 +1,181 @@ +/* + * the definition file of cs5536 Virtual Support Module(VSM). + * pci configuration space can be accessed through the VSM, so + * there is no need the MSR read/write now, except the spec. MSR + * registers which are not implemented yet. + * + * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology + * Author : jlliu, liujl@xxxxxxxxxx + */ + +#ifndef _CS5536_PCI_H +#define _CS5536_PCI_H + +#define PCI_OPS_CS5536_IDSEL 14 +extern void cs5536_pci_conf_write4(int function, int reg, u32 value); +extern u32 cs5536_pci_conf_read4(int function, int reg); + +/* +#define TEST_CS5536_USE_FLASH +#ifdef TEST_CS5536_USE_FLASH +#define TEST_CS5536_USE_NOR_FLASH +#endif +*/ +#define TEST_CS5536_USE_EHCI +#define TEST_CS5536_USE_UDC +#define TEST_CS5536_USE_OTG + +#define PCI_SPECIAL_SHUTDOWN 1 +#define CS5536_FLASH_INTR 6 +#define CS5536_ACC_INTR 9 +#define CS5536_IDE_INTR 14 +#define CS5536_USB_INTR 11 +#define CS5536_UART1_INTR 4 +#define CS5536_UART2_INTR 3 + +/************************* PCI BUS DEVICE FUNCTION ********************/ + +/* + * PCI bus device function + */ +#define PCI_BUS_CS5536 0 +#define PCI_IDSEL_CS5536 14 +#define PCI_CFG_BASE 0x02000000 + +#define CS5536_ISA_FUNC 0 +#define CS5536_FLASH_FUNC 1 +#define CS5536_IDE_FUNC 2 +#define CS5536_ACC_FUNC 3 +#define CS5536_OHCI_FUNC 4 +#define CS5536_EHCI_FUNC 5 +#define CS5536_UDC_FUNC 6 +#define CS5536_OTG_FUNC 7 +#define CS5536_FUNC_START 0 +#define CS5536_FUNC_END 7 +#define CS5536_FUNC_COUNT (CS5536_FUNC_END - CS5536_FUNC_START + 1) + +/***************************** STANDARD PCI-2.2 EXPANSION ***********************/ + +/* + * PCI configuration space + * we have to virtualize the PCI configure space head, so we should + * define the necessary IDs and some others. + */ +/* VENDOR ID */ +#define CS5536_VENDOR_ID 0x1022 + +/* DEVICE ID */ +#define CS5536_ISA_DEVICE_ID 0x2090 +#define CS5536_FLASH_DEVICE_ID 0x2091 +#define CS5536_IDE_DEVICE_ID 0x209a +#define CS5536_ACC_DEVICE_ID 0x2093 +#define CS5536_OHCI_DEVICE_ID 0x2094 +#define CS5536_EHCI_DEVICE_ID 0x2095 +#define CS5536_UDC_DEVICE_ID 0x2096 +#define CS5536_OTG_DEVICE_ID 0x2097 + +/* CLASS CODE : CLASS SUB-CLASS INTERFACE */ +#define CS5536_ISA_CLASS_CODE 0x060100 +#define CS5536_FLASH_CLASS_CODE 0x050100 +#define CS5536_IDE_CLASS_CODE 0x010180 +#define CS5536_ACC_CLASS_CODE 0x040100 +#define CS5536_OHCI_CLASS_CODE 0x0C0310 +#define CS5536_EHCI_CLASS_CODE 0x0C0320 +#define CS5536_UDC_CLASS_CODE 0x0C03FE +#define CS5536_OTG_CLASS_CODE 0x0C0380 + +/* BHLC : BIST HEADER-TYPE LATENCY-TIMER CACHE-LINE-SIZE */ +#define PCI_NONE_BIST 0x00 //RO not implemented yet. +#define PCI_BRIDGE_HEADER_TYPE 0x80 //RO +#define PCI_NORMAL_HEADER_TYPE 0x00 +#define PCI_NORMAL_LATENCY_TIMER 0x00 +#define PCI_NORMAL_CACHE_LINE_SIZE 0x08 //RW + +/* BAR */ +#define PCI_BAR0_REG 0x10 +#define PCI_BAR1_REG 0x14 +#define PCI_BAR2_REG 0x18 +#define PCI_BAR3_REG 0x1c +#define PCI_BAR4_REG 0x20 +#define PCI_BAR5_REG 0x24 +#define PCI_BAR_COUNT 6 +#define PCI_BAR_RANGE_MASK 0xFFFFFFFF + +/* CARDBUS CIS POINTER */ +#define PCI_CARDBUS_CIS_POINTER 0x00000000 + +/* SUBSYSTEM VENDOR ID */ +#define CS5536_SUB_VENDOR_ID CS5536_VENDOR_ID + +/* SUBSYSTEM ID */ +#define CS5536_ISA_SUB_ID CS5536_ISA_DEVICE_ID +#define CS5536_FLASH_SUB_ID CS5536_FLASH_DEVICE_ID +#define CS5536_IDE_SUB_ID CS5536_IDE_DEVICE_ID +#define CS5536_ACC_SUB_ID CS5536_ACC_DEVICE_ID +#define CS5536_OHCI_SUB_ID CS5536_OHCI_DEVICE_ID +#define CS5536_EHCI_SUB_ID CS5536_EHCI_DEVICE_ID +#define CS5536_UDC_SUB_ID CS5536_UDC_DEVICE_ID +#define CS5536_OTG_SUB_ID CS5536_OTG_DEVICE_ID + +/* EXPANSION ROM BAR */ +#define PCI_EXPANSION_ROM_BAR 0x00000000 + +/* CAPABILITIES POINTER */ +#define PCI_CAPLIST_POINTER 0x00000000 +#define PCI_CAPLIST_USB_POINTER 0x40 +/* INTERRUPT */ +#define PCI_MAX_LATENCY 0x40 +#define PCI_MIN_GRANT 0x00 +#define PCI_DEFAULT_PIN 0x01 + +/**************************** EXPANSION PCI REG **************************************/ + +/* + * ISA EXPANSION + */ +#define PCI_UART1_INT_REG 0x50 +#define PCI_UART2_INT_REG 0x54 +#define PCI_ISA_FIXUP_REG 0x58 + +/* + * FLASH EXPANSION + */ +#define PCI_FLASH_INT_REG 0x50 +#define PCI_NOR_FLASH_CTRL_REG 0x40 +#define PCI_NOR_FLASH_T01_REG 0x44 +#define PCI_NOR_FLASH_T23_REG 0x48 +#define PCI_NAND_FLASH_TDATA_REG 0x60 +#define PCI_NAND_FLASH_TCTRL_REG 0x64 +#define PCI_NAND_FLASH_RSVD_REG 0x68 +#define PCI_FLASH_SELECT_REG 0x70 + +/* + * IDE EXPANSION + */ +#define PCI_IDE_CFG_REG 0x40 +#define CS5536_IDE_FLASH_SIGNATURE 0xDEADBEEF +#define PCI_IDE_DTC_REG 0x48 +#define PCI_IDE_CAST_REG 0x4C +#define PCI_IDE_ETC_REG 0x50 +#define PCI_IDE_PM_REG 0x54 +#define PCI_IDE_INT_REG 0x60 + +/* + * ACC EXPANSION + */ +#define PCI_ACC_INT_REG 0x50 + +/* + * OHCI EXPANSION : INTTERUPT IS IMPLEMENTED BY THE OHCI + */ +#define PCI_OHCI_PM_REG 0x40 +#define PCI_OHCI_INT_REG 0x50 + +/* + * EHCI EXPANSION + */ +#define PCI_EHCI_LEGSMIEN_REG 0x50 +#define PCI_EHCI_LEGSMISTS_REG 0x54 +#define PCI_EHCI_FLADJ_REG 0x60 + +#endif /* _CS5536_PCI_H_ */ diff --git a/arch/mips/include/asm/mach-loongson/cs5536/mfgpt.h b/arch/mips/include/asm/mach-loongson/cs5536/mfgpt.h new file mode 100644 index 0000000..c435389 --- /dev/null +++ b/arch/mips/include/asm/mach-loongson/cs5536/mfgpt.h @@ -0,0 +1,15 @@ +/* + * cs5536 mfgpt header file + */ + +#ifndef _CS5536_MFGPT_H +#define _CS5536_MFGPT_H + +#include <cs5536/cs5536.h> + +#define MFGPT_BASE mfgpt_base +#define MFGPT0_CMP2 (MFGPT_BASE + 2) +#define MFGPT0_CNT (MFGPT_BASE + 4) +#define MFGPT0_SETUP (MFGPT_BASE + 6) + +#endif /*!_CS5536_MFGPT_H */ diff --git a/arch/mips/include/asm/mach-loongson/cs5536/pcireg.h b/arch/mips/include/asm/mach-loongson/cs5536/pcireg.h new file mode 100644 index 0000000..aa823d3 --- /dev/null +++ b/arch/mips/include/asm/mach-loongson/cs5536/pcireg.h @@ -0,0 +1,485 @@ +/* + * Copyright (c) 2001, 2006 www.ict.ac.cn. + * Copyright (c) 2006, 2008 www.lemote.com.cn. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the named License, + * or any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _DEV_PCI_PCIREG_H_ +#define _DEV_PCI_PCIREG_H_ + + +/* + * Standardized PCI configuration information + * + * XXX This is not complete. + */ + +/* + * Device identification register; contains a vendor ID and a device ID. + */ +#define PCI_ID_REG 0x00 + +typedef u_int16_t pci_vendor_id_t; +typedef u_int16_t pci_product_id_t; + +#define PCI_VENDOR_SHIFT 0 +#define PCI_VENDOR_MASK 0xffff +#define PCI_VENDOR(id) \ + (((id) >> PCI_VENDOR_SHIFT) & PCI_VENDOR_MASK) + +#define PCI_PRODUCT_SHIFT 16 +#define PCI_PRODUCT_MASK 0xffff +#define PCI_PRODUCT(id) \ + (((id) >> PCI_PRODUCT_SHIFT) & PCI_PRODUCT_MASK) + +/* + * Command and status register. + */ +#define PCI_COMMAND_STATUS_REG 0x04 + +#define PCI_COMMAND_IO_ENABLE 0x00000001 +#define PCI_COMMAND_MEM_ENABLE 0x00000002 +#define PCI_COMMAND_MASTER_ENABLE 0x00000004 +#define PCI_COMMAND_SPECIAL_ENABLE 0x00000008 +#define PCI_COMMAND_INVALIDATE_ENABLE 0x00000010 +#define PCI_COMMAND_PALETTE_ENABLE 0x00000020 +#define PCI_COMMAND_PARITY_ENABLE 0x00000040 +#define PCI_COMMAND_STEPPING_ENABLE 0x00000080 +#define PCI_COMMAND_SERR_ENABLE 0x00000100 +#define PCI_COMMAND_BACKTOBACK_ENABLE 0x00000200 + +#define PCI_STATUS_CAPLIST_SUPPORT 0x00100000 +#define PCI_STATUS_66MHZ_SUPPORT 0x00200000 +#define PCI_STATUS_UDF_SUPPORT 0x00400000 +#define PCI_STATUS_BACKTOBACK_SUPPORT 0x00800000 +#define PCI_STATUS_PARITY_ERROR 0x01000000 +#define PCI_STATUS_DEVSEL_FAST 0x00000000 +#define PCI_STATUS_DEVSEL_MEDIUM 0x02000000 +#define PCI_STATUS_DEVSEL_SLOW 0x04000000 +#define PCI_STATUS_DEVSEL_MASK 0x06000000 +#define PCI_STATUS_TARGET_TARGET_ABORT 0x08000000 +#define PCI_STATUS_MASTER_TARGET_ABORT 0x10000000 +#define PCI_STATUS_MASTER_ABORT 0x20000000 +#define PCI_STATUS_SPECIAL_ERROR 0x40000000 +#define PCI_STATUS_PARITY_DETECT 0x80000000 + +/* + * PCI Class and Revision Register; defines type and revision of device. + */ +#define PCI_CLASS_REG 0x08 + +typedef u_int8_t pci_class_t; +typedef u_int8_t pci_subclass_t; +typedef u_int8_t pci_interface_t; +typedef u_int8_t pci_revision_t; + +#define PCI_CLASS_SHIFT 24 +#define PCI_CLASS_MASK 0xff +#define PCI_CLASS(cr) \ + (((cr) >> PCI_CLASS_SHIFT) & PCI_CLASS_MASK) + +#define PCI_SUBCLASS_SHIFT 16 +#define PCI_SUBCLASS_MASK 0xff +#define PCI_SUBCLASS(cr) \ + (((cr) >> PCI_SUBCLASS_SHIFT) & PCI_SUBCLASS_MASK) + +#define PCI_ISCLASS(what, class, subclass) \ + (((what) & 0xffff0000) == (class << 24 | subclass << 16)) + +#define PCI_INTERFACE_SHIFT 8 +#define PCI_INTERFACE_MASK 0xff +#define PCI_INTERFACE(cr) \ + (((cr) >> PCI_INTERFACE_SHIFT) & PCI_INTERFACE_MASK) + +#define PCI_REVISION_SHIFT 0 +#define PCI_REVISION_MASK 0xff +#define PCI_REVISION(cr) \ + (((cr) >> PCI_REVISION_SHIFT) & PCI_REVISION_MASK) + +/* base classes */ +#define PCI_CLASS_PREHISTORIC 0x00 +#define PCI_CLASS_MASS_STORAGE 0x01 +#define PCI_CLASS_NETWORK 0x02 +#define PCI_CLASS_DISPLAY 0x03 +#define PCI_CLASS_MULTIMEDIA 0x04 +#define PCI_CLASS_MEMORY 0x05 +#define PCI_CLASS_BRIDGE 0x06 +#define PCI_CLASS_COMMUNICATIONS 0x07 +#define PCI_CLASS_SYSTEM 0x08 +#define PCI_CLASS_INPUT 0x09 +#define PCI_CLASS_DOCK 0x0a +#define PCI_CLASS_PROCESSOR 0x0b +#define PCI_CLASS_SERIALBUS 0x0c +#define PCI_CLASS_WIRELESS 0x0d +#define PCI_CLASS_I2O 0x0e +#define PCI_CLASS_SATCOM 0x0f +#define PCI_CLASS_CRYPTO 0x10 +#define PCI_CLASS_DASP 0x11 +#define PCI_CLASS_UNDEFINED 0xff + +/* 0x00 prehistoric subclasses */ +#define PCI_SUBCLASS_PREHISTORIC_MISC 0x00 +#define PCI_SUBCLASS_PREHISTORIC_VGA 0x01 + +/* 0x01 mass storage subclasses */ +#define PCI_SUBCLASS_MASS_STORAGE_SCSI 0x00 +#define PCI_SUBCLASS_MASS_STORAGE_IDE 0x01 +#define PCI_SUBCLASS_MASS_STORAGE_FLOPPY 0x02 +#define PCI_SUBCLASS_MASS_STORAGE_IPI 0x03 +#define PCI_SUBCLASS_MASS_STORAGE_RAID 0x04 +#define PCI_SUBCLASS_MASS_STORAGE_ATA 0x05 +#define PCI_SUBCLASS_MASS_STORAGE_MISC 0x80 + +/* 0x02 network subclasses */ +#define PCI_SUBCLASS_NETWORK_ETHERNET 0x00 +#define PCI_SUBCLASS_NETWORK_TOKENRING 0x01 +#define PCI_SUBCLASS_NETWORK_FDDI 0x02 +#define PCI_SUBCLASS_NETWORK_ATM 0x03 +#define PCI_SUBCLASS_NETWORK_ISDN 0x04 +#define PCI_SUBCLASS_NETWORK_WORLDFIP 0x05 +#define PCI_SUBCLASS_NETWORK_PCIMGMULTICOMP 0x06 +#define PCI_SUBCLASS_NETWORK_MISC 0x80 + +/* 0x03 display subclasses */ +#define PCI_SUBCLASS_DISPLAY_VGA 0x00 +#define PCI_SUBCLASS_DISPLAY_XGA 0x01 +#define PCI_SUBCLASS_DISPLAY_3D 0x02 +#define PCI_SUBCLASS_DISPLAY_MISC 0x80 + +/* 0x04 multimedia subclasses */ +#define PCI_SUBCLASS_MULTIMEDIA_VIDEO 0x00 +#define PCI_SUBCLASS_MULTIMEDIA_AUDIO 0x01 +#define PCI_SUBCLASS_MULTIMEDIA_TELEPHONY 0x02 +#define PCI_SUBCLASS_MULTIMEDIA_MISC 0x80 + +/* 0x05 memory subclasses */ +#define PCI_SUBCLASS_MEMORY_RAM 0x00 +#define PCI_SUBCLASS_MEMORY_FLASH 0x01 +#define PCI_SUBCLASS_MEMORY_MISC 0x80 + +/* 0x06 bridge subclasses */ +#define PCI_SUBCLASS_BRIDGE_HOST 0x00 +#define PCI_SUBCLASS_BRIDGE_ISA 0x01 +#define PCI_SUBCLASS_BRIDGE_EISA 0x02 +#define PCI_SUBCLASS_BRIDGE_MC 0x03 +#define PCI_SUBCLASS_BRIDGE_PCI 0x04 +#define PCI_SUBCLASS_BRIDGE_PCMCIA 0x05 +#define PCI_SUBCLASS_BRIDGE_NUBUS 0x06 +#define PCI_SUBCLASS_BRIDGE_CARDBUS 0x07 +#define PCI_SUBCLASS_BRIDGE_RACEWAY 0x08 +#define PCI_SUBCLASS_BRIDGE_STPCI 0x09 +#define PCI_SUBCLASS_BRIDGE_INFINIBAND 0x0a +#define PCI_SUBCLASS_BRIDGE_MISC 0x80 + +/* 0x07 communications subclasses */ +#define PCI_SUBCLASS_COMMUNICATIONS_SERIAL 0x00 +#define PCI_SUBCLASS_COMMUNICATIONS_PARALLEL 0x01 +#define PCI_SUBCLASS_COMMUNICATIONS_MPSERIAL 0x02 +#define PCI_SUBCLASS_COMMUNICATIONS_MODEM 0x03 +#define PCI_SUBCLASS_COMMUNICATIONS_MISC 0x80 + +/* 0x08 system subclasses */ +#define PCI_SUBCLASS_SYSTEM_PIC 0x00 +#define PCI_SUBCLASS_SYSTEM_DMA 0x01 +#define PCI_SUBCLASS_SYSTEM_TIMER 0x02 +#define PCI_SUBCLASS_SYSTEM_RTC 0x03 +#define PCI_SUBCLASS_SYSTEM_PCIHOTPLUG 0x04 +#define PCI_SUBCLASS_SYSTEM_MISC 0x80 + +/* 0x09 input subclasses */ +#define PCI_SUBCLASS_INPUT_KEYBOARD 0x00 +#define PCI_SUBCLASS_INPUT_DIGITIZER 0x01 +#define PCI_SUBCLASS_INPUT_MOUSE 0x02 +#define PCI_SUBCLASS_INPUT_SCANNER 0x03 +#define PCI_SUBCLASS_INPUT_GAMEPORT 0x04 +#define PCI_SUBCLASS_INPUT_MISC 0x80 + +/* 0x0a dock subclasses */ +#define PCI_SUBCLASS_DOCK_GENERIC 0x00 +#define PCI_SUBCLASS_DOCK_MISC 0x80 + +/* 0x0b processor subclasses */ +#define PCI_SUBCLASS_PROCESSOR_386 0x00 +#define PCI_SUBCLASS_PROCESSOR_486 0x01 +#define PCI_SUBCLASS_PROCESSOR_PENTIUM 0x02 +#define PCI_SUBCLASS_PROCESSOR_ALPHA 0x10 +#define PCI_SUBCLASS_PROCESSOR_POWERPC 0x20 +#define PCI_SUBCLASS_PROCESSOR_MIPS 0x30 +#define PCI_SUBCLASS_PROCESSOR_COPROC 0x40 + +/* 0x0c serial bus subclasses */ +#define PCI_SUBCLASS_SERIALBUS_FIREWIRE 0x00 +#define PCI_SUBCLASS_SERIALBUS_ACCESS 0x01 +#define PCI_SUBCLASS_SERIALBUS_SSA 0x02 +#define PCI_SUBCLASS_SERIALBUS_USB 0x03 +#define PCI_SUBCLASS_SERIALBUS_FIBER 0x04 +#define PCI_SUBCLASS_SERIALBUS_SMBUS 0x05 +#define PCI_SUBCLASS_SERIALBUS_INFINIBAND 0x06 +#define PCI_SUBCLASS_SERIALBUS_IPMI 0x07 +#define PCI_SUBCLASS_SERIALBUS_SERCOS 0x08 +#define PCI_SUBCLASS_SERIALBUS_CANBUS 0x09 + +/* 0x0d wireless subclasses */ +#define PCI_SUBCLASS_WIRELESS_IRDA 0x00 +#define PCI_SUBCLASS_WIRELESS_CONSUMERIR 0x01 +#define PCI_SUBCLASS_WIRELESS_RF 0x10 +#define PCI_SUBCLASS_WIRELESS_MISC 0x80 + +/* 0x0e I2O (Intelligent I/O) subclasses */ +#define PCI_SUBCLASS_I2O_STANDARD 0x00 + +/* 0x0f satellite communication subclasses */ +/* PCI_SUBCLASS_SATCOM_??? 0x00 / * XXX ??? */ +#define PCI_SUBCLASS_SATCOM_TV 0x01 +#define PCI_SUBCLASS_SATCOM_AUDIO 0x02 +#define PCI_SUBCLASS_SATCOM_VOICE 0x03 +#define PCI_SUBCLASS_SATCOM_DATA 0x04 + +/* 0x10 encryption/decryption subclasses */ +#define PCI_SUBCLASS_CRYPTO_NETCOMP 0x00 +#define PCI_SUBCLASS_CRYPTO_ENTERTAINMENT 0x10 +#define PCI_SUBCLASS_CRYPTO_MISC 0x80 + +/* 0x11 data acquisition and signal processing subclasses */ +#define PCI_SUBCLASS_DASP_DPIO 0x00 +#define PCI_SUBCLASS_DASP_TIMEFREQ 0x01 +#define PCI_SUBCLASS_DASP_MISC 0x80 + +/* + * PCI BIST/Header Type/Latency Timer/Cache Line Size Register. + */ +#define PCI_BHLC_REG 0x0c + +#define PCI_BIST_SHIFT 24 +#define PCI_BIST_MASK 0xff +#define PCI_BIST(bhlcr) \ + (((bhlcr) >> PCI_BIST_SHIFT) & PCI_BIST_MASK) + +#define PCI_HDRTYPE_SHIFT 16 +#define PCI_HDRTYPE_MASK 0xff +#define PCI_HDRTYPE(bhlcr) \ + (((bhlcr) >> PCI_HDRTYPE_SHIFT) & PCI_HDRTYPE_MASK) + +#define PCI_HDRTYPE_TYPE(bhlcr) \ + (PCI_HDRTYPE(bhlcr) & 0x7f) +#define PCI_HDRTYPE_MULTIFN(bhlcr) \ + ((PCI_HDRTYPE(bhlcr) & 0x80) != 0) + +#define PCI_LATTIMER_SHIFT 8 +#define PCI_LATTIMER_MASK 0xff +#define PCI_LATTIMER(bhlcr) \ + (((bhlcr) >> PCI_LATTIMER_SHIFT) & PCI_LATTIMER_MASK) + +#define PCI_CACHELINE_SHIFT 0 +#define PCI_CACHELINE_MASK 0xff +#define PCI_CACHELINE(bhlcr) \ + (((bhlcr) >> PCI_CACHELINE_SHIFT) & PCI_CACHELINE_MASK) + +/* config registers for header type 0 devices */ + +#define PCI_MAPS 0x10 +#define PCI_CARDBUSCIS 0x28 +#define PCI_SUBVEND_0 0x2c +#define PCI_SUBDEV_0 0x2e +#define PCI_INTLINE 0x3c +#define PCI_INTPIN 0x3d +#define PCI_MINGNT 0x3e +#define PCI_MAXLAT 0x3f + +/* config registers for header type 1 devices */ + +#define PCI_SECSTAT_1 0 /**/ + +#define PCI_PRIBUS_1 0x18 +#define PCI_SECBUS_1 0x19 +#define PCI_SUBBUS_1 0x1a +#define PCI_SECLAT_1 0x1b + +#define PCI_IOBASEL_1 0x1c +#define PCI_IOLIMITL_1 0x1d +#define PCI_IOBASEH_1 0x30 /**/ +#define PCI_IOLIMITH_1 0x32 /**/ + +#define PCI_MEMBASE_1 0x20 +#define PCI_MEMLIMIT_1 0x22 + +#define PCI_PMBASEL_1 0x24 +#define PCI_PMLIMITL_1 0x26 +#define PCI_PMBASEH_1 0 /**/ +#define PCI_PMLIMITH_1 0 /**/ + +#define PCI_BRIDGECTL_1 0 /**/ + +#define PCI_SUBVEND_1 0x34 +#define PCI_SUBDEV_1 0x36 + +/* config registers for header type 2 devices */ + +#define PCI_SECSTAT_2 0x16 + +#define PCI_PRIBUS_2 0x18 +#define PCI_SECBUS_2 0x19 +#define PCI_SUBBUS_2 0x1a +#define PCI_SECLAT_2 0x1b + +#define PCI_MEMBASE0_2 0x1c +#define PCI_MEMLIMIT0_2 0x20 +#define PCI_MEMBASE1_2 0x24 +#define PCI_MEMLIMIT1_2 0x28 +#define PCI_IOBASE0_2 0x2c +#define PCI_IOLIMIT0_2 0x30 +#define PCI_IOBASE1_2 0x34 +#define PCI_IOLIMIT1_2 0x38 + +#define PCI_BRIDGECTL_2 0x3e + +#define PCI_SUBVEND_2 0x40 +#define PCI_SUBDEV_2 0x42 + +#define PCI_PCCARDIF_2 0x44 + +/* + * Mapping registers + */ +#define PCI_MAPREG_START 0x10 +#define PCI_MAPREG_END 0x28 +#define PCI_MAPREG_ROM 0x30 +#define PCI_MAPREG_PPB_END 0x18 +#define PCI_MAPREG_PCB_END 0x14 + +#define PCI_MAPREG_TYPE(mr) \ + ((mr) & PCI_MAPREG_TYPE_MASK) +#define PCI_MAPREG_TYPE_MASK 0x00000001 + +#define PCI_MAPREG_TYPE_MEM 0x00000000 +#define PCI_MAPREG_TYPE_IO 0x00000001 +#define PCI_MAPREG_TYPE_ROM 0x00000001 + +#define PCI_MAPREG_MEM_TYPE(mr) \ + ((mr) & PCI_MAPREG_MEM_TYPE_MASK) +#define PCI_MAPREG_MEM_TYPE_MASK 0x00000006 + +#define PCI_MAPREG_MEM_TYPE_32BIT 0x00000000 +#define PCI_MAPREG_MEM_TYPE_32BIT_1M 0x00000002 +#define PCI_MAPREG_MEM_TYPE_64BIT 0x00000004 + +#define PCI_MAPREG_MEM_CACHEABLE(mr) \ + (((mr) & PCI_MAPREG_MEM_CACHEABLE_MASK) != 0) +#define PCI_MAPREG_MEM_CACHEABLE_MASK 0x00000008 + +#define PCI_MAPREG_MEM_PREFETCHABLE(mr) \ + (((mr) & PCI_MAPREG_MEM_PREFETCHABLE_MASK) != 0) +#define PCI_MAPREG_MEM_PREFETCHABLE_MASK 0x00000008 + +#define PCI_MAPREG_MEM_ADDR(mr) \ + ((mr) & PCI_MAPREG_MEM_ADDR_MASK) +#define PCI_MAPREG_MEM_SIZE(mr) \ + (PCI_MAPREG_MEM_ADDR(mr) & -PCI_MAPREG_MEM_ADDR(mr)) +#define PCI_MAPREG_MEM_ADDR_MASK 0xfffffff0 + +#define PCI_MAPREG_MEM64_ADDR(mr) \ + ((mr) & PCI_MAPREG_MEM64_ADDR_MASK) +#define PCI_MAPREG_MEM64_SIZE(mr) \ + (PCI_MAPREG_MEM64_ADDR(mr) & -PCI_MAPREG_MEM64_ADDR(mr)) +#define PCI_MAPREG_MEM64_ADDR_MASK 0xfffffffffffffff0 + +#define PCI_MAPREG_IO_ADDR(mr) \ + ((mr) & PCI_MAPREG_IO_ADDR_MASK) +#define PCI_MAPREG_IO_SIZE(mr) \ + (PCI_MAPREG_IO_ADDR(mr) & -PCI_MAPREG_IO_ADDR(mr)) +#define PCI_MAPREG_IO_ADDR_MASK 0xfffffffe + +#define PCI_MAPREG_ROM_ADDR(mr) \ + ((mr) & PCI_MAPREG_ROM_ADDR_MASK) +#define PCI_MAPREG_ROM_SIZE(mr) \ + (PCI_MAPREG_ROM_ADDR(mr) & -PCI_MAPREG_ROM_ADDR(mr)) +#define PCI_MAPREG_ROM_ADDR_MASK 0xfffff800 + +/* + * Cardbus CIS pointer (PCI rev. 2.1) + */ +#define PCI_CARDBUS_CIS_REG 0x28 + +/* + * Subsystem identification register; contains a vendor ID and a device ID. + * Types/macros for PCI_ID_REG apply. + * (PCI rev. 2.1) + */ +#define PCI_SUBSYS_ID_REG 0x2c + +/* + * capabilities link list (PCI rev. 2.2) + */ +#define PCI_CAPLISTPTR_REG 0x34 +#define PCI_CAPLIST_PTR(cpr) ((cpr) & 0xff) +#define PCI_CAPLIST_NEXT(cr) (((cr) >> 8) & 0xff) +#define PCI_CAPLIST_CAP(cr) ((cr) & 0xff) + +#define PCI_CAP_REESSERVED 0x00 +#define PCI_CAP_PWRMGMT 0x01 +#define PCI_CAP_AGP 0x02 +#define PCI_CAP_VPD 0x03 +#define PCI_CAP_SLOTID 0x04 +#define PCI_CAP_MBI 0x05 +#define PCI_CAP_CPCI_HOTSWAP 0x06 +#define PCI_CAP_PCIX 0x07 +#define PCI_CAP_LDT 0x08 +#define PCI_CAP_VENDSPEC 0x09 +#define PCI_CAP_DEBUGPORT 0x0a +#define PCI_CAP_CPCI_RSRCCTL 0x0b +#define PCI_CAP_HOTPLUG 0x0c + +/* + * Power Management Control Status Register; access via capability pointer. + */ +#define PCI_PMCSR_STATE_MASK 0x03 +#define PCI_PMCSR_STATE_D0 0x00 +#define PCI_PMCSR_STATE_D1 0x01 +#define PCI_PMCSR_STATE_D2 0x02 +#define PCI_PMCSR_STATE_D3 0x03 + +/* + * Interrupt Configuration Register; contains interrupt pin and line. + */ +#define PCI_INTERRUPT_REG 0x3c + +typedef u_int8_t pci_intr_pin_t; +typedef u_int8_t pci_intr_line_t; + +#define PCI_INTERRUPT_PIN_SHIFT 8 +#define PCI_INTERRUPT_PIN_MASK 0xff +#define PCI_INTERRUPT_PIN(icr) \ + (((icr) >> PCI_INTERRUPT_PIN_SHIFT) & PCI_INTERRUPT_PIN_MASK) + +#define PCI_INTERRUPT_LINE_SHIFT 0 +#define PCI_INTERRUPT_LINE_MASK 0xff +#define PCI_INTERRUPT_LINE(icr) \ + (((icr) >> PCI_INTERRUPT_LINE_SHIFT) & PCI_INTERRUPT_LINE_MASK) + +#define PCI_MIN_GNT_SHIFT 16 +#define PCI_MIN_GNT_MASK 0xff +#define PCI_MIN_GNT(icr) \ + (((icr) >> PCI_MIN_GNT_SHIFT) & PCI_MIN_GNT_MASK) + +#define PCI_MAX_LAT_SHIFT 24 +#define PCI_MAX_LAT_MASK 0xff +#define PCI_MAX_LAT(icr) \ + (((icr) >> PCI_MAX_LAT_SHIFT) & PCI_MAX_LAT_MASK) + +#define PCI_INTERRUPT_PIN_NONE 0x00 +#define PCI_INTERRUPT_PIN_A 0x01 +#define PCI_INTERRUPT_PIN_B 0x02 +#define PCI_INTERRUPT_PIN_C 0x03 +#define PCI_INTERRUPT_PIN_D 0x04 +#define PCI_INTERRUPT_PIN_MAX 0x04 + +#endif /* _DEV_PCI_PCIREG_H_ */ diff --git a/arch/mips/include/asm/mach-loongson/machine.h b/arch/mips/include/asm/mach-loongson/machine.h index 3614619..577b86c 100644 --- a/arch/mips/include/asm/mach-loongson/machine.h +++ b/arch/mips/include/asm/mach-loongson/machine.h @@ -13,6 +13,8 @@ #ifndef __MACHINE_H #define __MACHINE_H +#ifdef CONFIG_LEMOTE_FULOONG2E + #define MACH_NAME "lemote-fuloong(2e)" #define LOONGSON_UART_BASE 0x1fd003f8 @@ -23,5 +25,33 @@ #define LOONGSON_TIMER_IRQ (MIPS_CPU_IRQ_BASE + 7) #define LOONGSON_DMATIMEOUT_IRQ (LOONGSON_IRQ_BASE + 10) +#else /* CONFIG_LEMOTE_FULOONG2F */ + +#define MACH_NAME "lemote-fuloong(2f)" + +#define LOONGSON_UART_BASE 0x1fd002f8 + +#define LOONGSON_TIMER_IRQ (MIPS_CPU_IRQ_BASE + 7) /* cpu timer */ +#define LOONGSON_PERFCNT_IRQ (MIPS_CPU_IRQ_BASE + 6) /* cpu perf counter */ +#define LOONGSON_NORTH_BRIDGE_IRQ (MIPS_CPU_IRQ_BASE + 6) /* bonito */ +#define LOONGSON_UART_IRQ (MIPS_CPU_IRQ_BASE + 3) /* cpu serial port */ +#define LOONGSON_SOUTH_BRIDGE_IRQ (MIPS_CPU_IRQ_BASE + 2) /* i8259 */ + +#define LOONGSON_INT_BIT_GPIO1 (1 << 1) +#define LOONGSON_INT_BIT_GPIO2 (1 << 2) +#define LOONGSON_INT_BIT_GPIO3 (1 << 3) +#define LOONGSON_INT_BIT_PCI_INTA (1 << 4) +#define LOONGSON_INT_BIT_PCI_INTB (1 << 5) +#define LOONGSON_INT_BIT_PCI_INTC (1 << 6) +#define LOONGSON_INT_BIT_PCI_INTD (1 << 7) +#define LOONGSON_INT_BIT_PCI_PERR (1 << 8) +#define LOONGSON_INT_BIT_PCI_SERR (1 << 9) +#define LOONGSON_INT_BIT_DDR (1 << 10) +#define LOONGSON_INT_BIT_INT0 (1 << 11) +#define LOONGSON_INT_BIT_INT1 (1 << 12) +#define LOONGSON_INT_BIT_INT2 (1 << 13) +#define LOONGSON_INT_BIT_INT3 (1 << 14) + +#endif #endif /* ! __MACHINE_H */ diff --git a/arch/mips/loongson/Kconfig b/arch/mips/loongson/Kconfig index 9ae71a5..42a5309 100644 --- a/arch/mips/loongson/Kconfig +++ b/arch/mips/loongson/Kconfig @@ -27,4 +27,32 @@ config LEMOTE_FULOONG2E Lemote Fulong mini-PC board based on the Chinese Loongson-2E CPU and an FPGA northbridge +config LEMOTE_FULOONG2F + bool "Lemote Fuloong(2f) mini-PC" + select ARCH_SPARSEMEM_ENABLE + select CEVT_R4K + select CSRC_R4K + select SYS_HAS_CPU_LOONGSON2F + select DMA_NONCOHERENT + select BOOT_ELF32 + select BOARD_SCACHE + select HW_HAS_PCI + select I8259 + select ISA + select IRQ_CPU + select SYS_SUPPORTS_32BIT_KERNEL + select SYS_SUPPORTS_64BIT_KERNEL + select SYS_SUPPORTS_LITTLE_ENDIAN + select SYS_SUPPORTS_HIGHMEM + select SYS_HAS_EARLY_PRINTK + select GENERIC_HARDIRQS_NO__DO_IRQ + select GENERIC_ISA_DMA_SUPPORT_BROKEN + select CPU_HAS_WB + select CS5536 + help + Lemote Fulong mini-PC board based on the Chinese Loongson-2F CPU + endchoice + +config CS5536 + bool diff --git a/arch/mips/loongson/Makefile b/arch/mips/loongson/Makefile index cc9f1c8..e9b8a81 100644 --- a/arch/mips/loongson/Makefile +++ b/arch/mips/loongson/Makefile @@ -9,3 +9,9 @@ obj-$(CONFIG_LOONGSON_SYSTEMS) += common/ # obj-$(CONFIG_LEMOTE_FULOONG2E) += fuloong-2e/ + +# +# Lemote Fuloong mini-PC (Loongson 2F-based) +# + +obj-$(CONFIG_LEMOTE_FULOONG2F) += fuloong-2f/ diff --git a/arch/mips/loongson/common/Makefile b/arch/mips/loongson/common/Makefile index cda3d77..869adb5 100644 --- a/arch/mips/loongson/common/Makefile +++ b/arch/mips/loongson/common/Makefile @@ -17,4 +17,10 @@ obj-$(CONFIG_EARLY_PRINTK) += early_printk.o # obj-$(CONFIG_RTC_DRV_CMOS) += rtc.o +# +# Enable CS5536 Virtual Support Module(VSM) for virtulize the PCI configure +# space +# +obj-$(CONFIG_CS5536) += cs5536_vsm.o + EXTRA_CFLAGS += -Werror diff --git a/arch/mips/loongson/common/bonito-irq.c b/arch/mips/loongson/common/bonito-irq.c index 61f473d..d5a5ae8 100644 --- a/arch/mips/loongson/common/bonito-irq.c +++ b/arch/mips/loongson/common/bonito-irq.c @@ -53,10 +53,13 @@ static struct irq_chip bonito_irq_type = { .unmask = bonito_irq_enable, }; +/* there is no need to handle dma timeout in loongson-2f base machines */ +#ifdef CONFIG_CPU_LOONGSON2E static struct irqaction dma_timeout_irqaction = { .handler = no_action, .name = "dma_timeout", }; +#endif void bonito_irq_init(void) { @@ -66,5 +69,7 @@ void bonito_irq_init(void) set_irq_chip_and_handler(i, &bonito_irq_type, handle_level_irq); } +#ifdef CONFIG_CPU_LOONGSON2E setup_irq(LOONGSON_DMATIMEOUT_IRQ, &dma_timeout_irqaction); +#endif } diff --git a/arch/mips/loongson/common/cs5536_vsm.c b/arch/mips/loongson/common/cs5536_vsm.c new file mode 100644 index 0000000..727b871 --- /dev/null +++ b/arch/mips/loongson/common/cs5536_vsm.c @@ -0,0 +1,2321 @@ +/* + * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology + * Author : jlliu, liujl@xxxxxxxxxx + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * the Virtual Support Module(VSM) for virtulize the PCI configure + * space. so user can access the PCI configure space directly as + * a normal multi-function PCI device which following the PCI-2.2 spec. + */ +#include <linux/types.h> + +#include <cs5536/cs5536.h> +#include <cs5536/cs5536_pci.h> +#include <cs5536/pcireg.h> + +/* internal used functions */ + +/* + * enable/disable the divil module bar space. + * + * For all the DIVIL module LBAR, you should control the DIVIL LBAR reg + * and the RCONFx(0~5) reg to use the modules. + */ +static void divil_lbar_enable_disable(int enable) +{ + u32 hi, lo; + + /* + * The DIVIL IRQ is not used yet. and make the RCONF0 reserved. + */ + + _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_SMB), &hi, &lo); + if (enable) + hi |= 0x01; + else + hi &= ~0x01; + _wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_SMB), hi, lo); + + _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_GPIO), &hi, &lo); + if (enable) + hi |= 0x01; + else + hi &= ~0x01; + _wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_GPIO), hi, lo); + + _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_MFGPT), &hi, &lo); + if (enable) + hi |= 0x01; + else + hi &= ~0x01; + _wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_MFGPT), hi, lo); + + _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_PMS), &hi, &lo); + if (enable) + hi |= 0x01; + else + hi &= ~0x01; + _wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_PMS), hi, lo); + + _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_ACPI), &hi, &lo); + if (enable) + hi |= 0x01; + else + hi &= ~0x01; + _wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_ACPI), hi, lo); + + /* + * RCONF0 is reserved to the DIVIL IRQ mdoule + */ +#if 0 + _rdmsr(SB_MSR_REG(SB_R1), &hi, &lo); + if (enable) + lo |= 0x01; + else + lo &= ~0x01; + _wrmsr(SB_MSR_REG(SB_R1), hi, lo); + + _rdmsr(SB_MSR_REG(SB_R2), &hi, &lo); + if (enable) + lo |= 0x01; + else + lo &= ~0x01; + _wrmsr(SB_MSR_REG(SB_R2), hi, lo); + + _rdmsr(SB_MSR_REG(SB_R3), &hi, &lo); + if (enable) + lo |= 0x01; + else + lo &= ~0x01; + _wrmsr(SB_MSR_REG(SB_R3), hi, lo); + + _rdmsr(SB_MSR_REG(SB_R4), &hi, &lo); + if (enable) + lo |= 0x01; + else + lo &= ~0x01; + _wrmsr(SB_MSR_REG(SB_R4), hi, lo); + + _rdmsr(SB_MSR_REG(SB_R5), &hi, &lo); + if (enable) + lo |= 0x01; + else + lo &= ~0x01; + _wrmsr(SB_MSR_REG(SB_R5), hi, lo); +#endif + return; +} + +#ifdef TEST_CS5536_USE_FLASH +/* + * enable or disable the region of flashs(NOR or NAND) + * + * the same as the DIVIL other modules above, two groups of regs should be modified + * here to control the region. DIVIL flash LBAR and the RCONFx(6~9 reserved). + */ +static void flash_lbar_enable_disable(int enable) +{ + u32 hi, lo; + + _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH0), &hi, &lo); + if (enable) + hi |= 0x01; + else + hi &= ~0x01; + _wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH0), hi, lo); + + _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH1), &hi, &lo); + if (enable) + hi |= 0x01; + else + hi &= ~0x01; + _wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH1), hi, lo); + + _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH2), &hi, &lo); + if (enable) + hi |= 0x01; + else + hi &= ~0x01; + _wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH2), hi, lo); + + _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH3), &hi, &lo); + if (enable) + hi |= 0x01; + else + hi &= ~0x01; + _wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH3), hi, lo); + + _rdmsr(SB_MSR_REG(SB_R6), &hi, &lo); + if (enable) + lo |= 0x01; + else + lo &= ~0x01; + _wrmsr(SB_MSR_REG(SB_R6), hi, lo); + + _rdmsr(SB_MSR_REG(SB_R7), &hi, &lo); + if (enable) + lo |= 0x01; + else + lo &= ~0x01; + _wrmsr(SB_MSR_REG(SB_R7), hi, lo); + + _rdmsr(SB_MSR_REG(SB_R8), &hi, &lo); + if (enable) + lo |= 0x01; + else + lo &= ~0x01; + _wrmsr(SB_MSR_REG(SB_R8), hi, lo); + + _rdmsr(SB_MSR_REG(SB_R9), &hi, &lo); + if (enable) + lo |= 0x01; + else + lo &= ~0x01; + _wrmsr(SB_MSR_REG(SB_R9), hi, lo); + + return; +} +#endif + +/* cs5536 modules */ + +/* + * isa_write : isa write transfering. + * WE assume that the ISA is not the BUS MASTER.!!! + */ +/* FAST BACK TO BACK '1' for BUS MASTER '0' for BUS SALVE */ +/* COMMAND : + * bit0 : IO SPACE ENABLE + * bit1 : MEMORY SPACE ENABLE(ignore) + * bit2 : BUS MASTER ENABLE(ignore) + * bit3 : SPECIAL CYCLE(ignore)? default is ignored. + * bit4 : MEMORY WRITE and INVALIDATE(ignore) + * bit5 : VGA PALETTE(ignore) + * bit6 : PARITY ERROR(ignore)? : default is ignored. + * bit7 : WAIT CYCLE CONTROL(ignore) + * bit8 : SYSTEM ERROR(ignore) + * bit9 : FAST BACK TO BACK(ignore) + * bit10-bit15 : RESERVED + * STATUS : + * bit0-bit3 : RESERVED + * bit4 : CAPABILITY LIST(ignore) + * bit5 : 66MHZ CAPABLE + * bit6 : RESERVED + * bit7 : FAST BACK TO BACK(ignore) + * bit8 : DATA PARITY ERROR DETECED(ignore) + * bit9-bit10 : DEVSEL TIMING(ALL MEDIUM) + * bit11: SIGNALED TARGET ABORT + * bit12: RECEIVED TARGET ABORT + * bit13: RECEIVED MASTER ABORT + * bit14: SIGNALED SYSTEM ERROR + * bit15: DETECTED PARITY ERROR + */ +static void pci_isa_write_reg(int reg, u32 value) +{ + u32 hi, lo; + u32 temp; + + switch (reg) { + case PCI_COMMAND_STATUS_REG: + /* command */ + if (value & PCI_COMMAND_IO_ENABLE) { + divil_lbar_enable_disable(1); + } else { + divil_lbar_enable_disable(0); + } +#if 0 + /* PER response enable or disable. */ + if (value & PCI_COMMAND_PARITY_ENABLE) { + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + lo |= SB_PARE_ERR_EN; + _wrmsr(SB_MSR_REG(SB_ERROR), hi, lo); + } else { + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + lo &= ~SB_PARE_ERR_EN; + _wrmsr(SB_MSR_REG(SB_ERROR), hi, lo); + } +#endif + /* status */ + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + temp = lo & 0x0000ffff; + if ((value & PCI_STATUS_TARGET_TARGET_ABORT) && + (lo & SB_TAS_ERR_EN)) { + temp |= SB_TAS_ERR_FLAG; + } + if ((value & PCI_STATUS_MASTER_TARGET_ABORT) && + (lo & SB_TAR_ERR_EN)) { + temp |= SB_TAR_ERR_FLAG; + } + if ((value & PCI_STATUS_MASTER_ABORT) + && (lo & SB_MAR_ERR_EN)) { + temp |= SB_MAR_ERR_FLAG; + } + if ((value & PCI_STATUS_PARITY_DETECT) + && (lo & SB_PARE_ERR_EN)) { + temp |= SB_PARE_ERR_FLAG; + } + lo = temp; + _wrmsr(SB_MSR_REG(SB_ERROR), hi, lo); + break; + case PCI_BHLC_REG: + value &= 0x0000ff00; + _rdmsr(SB_MSR_REG(SB_CTRL), &hi, &lo); + hi &= 0xffffff00; + hi |= (value >> 8); + _wrmsr(SB_MSR_REG(SB_CTRL), hi, lo); + break; + case PCI_BAR0_REG: + if (value == PCI_BAR_RANGE_MASK) { + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo |= SOFT_BAR_SMB_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + } else if (value & 0x01) { + /* SMB NATIVE IO space has 8bytes */ + hi = 0x0000f001; + lo = value & 0x0000fff8; + _wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_SMB), hi, lo); + + /* RCONFx is 4bytes in units for IO space. */ + hi = ((value & 0x000ffffc) << 12) | + ((CS5536_SMB_LENGTH - 4) << 12) | 0x01; + lo = ((value & 0x000ffffc) << 12) | 0x01; + _wrmsr(SB_MSR_REG(SB_R0), hi, lo); + } + break; + case PCI_BAR1_REG: + if (value == PCI_BAR_RANGE_MASK) { + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo |= SOFT_BAR_GPIO_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + } else if (value & 0x01) { + /* GPIO NATIVE reg is 256bytes */ + hi = 0x0000f001; + lo = value & 0x0000ff00; + _wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_GPIO), hi, lo); + + /* RCONFx is 4bytes in units for IO space */ + hi = ((value & 0x000ffffc) << 12) | + ((CS5536_GPIO_LENGTH - 4) + << 12) | 0x01; + lo = ((value & 0x000ffffc) << 12) | 0x01; + _wrmsr(SB_MSR_REG(SB_R1), hi, lo); + } + break; + case PCI_BAR2_REG: + if (value == PCI_BAR_RANGE_MASK) { + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo |= SOFT_BAR_MFGPT_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + } else if (value & 0x01) { + /* MFGPT NATIVE reg is 64bytes */ + hi = 0x0000f001; + lo = value & 0x0000ffc0; + _wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_MFGPT), hi, lo); + + /* RCONFx is 4bytes in units for IO space */ + hi = ((value & 0x000ffffc) << 12) | + ((CS5536_MFGPT_LENGTH - 4) + << 12) | 0x01; + lo = ((value & 0x000ffffc) << 12) | 0x01; + _wrmsr(SB_MSR_REG(SB_R2), hi, lo); + } + break; + case PCI_BAR3_REG: + if (value == PCI_BAR_RANGE_MASK) { + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo |= SOFT_BAR_IRQ_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + } else if (value & 0x01) { + /* IRQ NATIVE reg is 32bytes */ + hi = 0x0000f001; + lo = value & 0x0000ffc0; + _wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_IRQ), hi, lo); + + /* RCONFx is 4bytes in units for IO space */ + hi = ((value & 0x000ffffc) << 12) | + ((CS5536_IRQ_LENGTH - 4) << 12) | 0x01; + lo = ((value & 0x000ffffc) << 12) | 0x01; + _wrmsr(SB_MSR_REG(SB_R3), hi, lo); + } + break; + case PCI_BAR4_REG: + if (value == PCI_BAR_RANGE_MASK) { + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo |= SOFT_BAR_PMS_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + } else if (value & 0x01) { + /* PMS NATIVE reg is 128bytes */ + hi = 0x0000f001; + lo = value & 0x0000ff80; + _wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_PMS), hi, lo); + + /* RCONFx is 4bytes in units for IO space. */ + hi = ((value & 0x000ffffc) << 12) | + ((CS5536_PMS_LENGTH - 4) << 12) | 0x01; + lo = ((value & 0x000ffffc) << 12) | 0x01; + _wrmsr(SB_MSR_REG(SB_R4), hi, lo); + } + break; + case PCI_BAR5_REG: + if (value == PCI_BAR_RANGE_MASK) { + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo |= SOFT_BAR_ACPI_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + } else if (value & 0x01) { + /* ACPI NATIVE reg is 32bytes */ + hi = 0x0000f001; + lo = value & 0x0000ffe0; + _wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_ACPI), hi, lo); + + /* RCONFx is 4bytes in units for IO space. */ + hi = ((value & 0x000ffffc) << 12) | + ((CS5536_ACPI_LENGTH - 4) + << 12) | 0x01; + lo = ((value & 0x000ffffc) << 12) | 0x01; + _wrmsr(SB_MSR_REG(SB_R5), hi, lo); + } + break; + case PCI_UART1_INT_REG: + if (value) { + /* enable uart1 interrupt in PIC */ + _rdmsr(DIVIL_MSR_REG(PIC_YSEL_HIGH), &hi, &lo); + lo &= ~(0xf << 24); + lo |= (CS5536_UART1_INTR << 24); + _wrmsr(DIVIL_MSR_REG(PIC_YSEL_HIGH), hi, lo); + } else { + /* disable uart1 interrupt in PIC */ + _rdmsr(DIVIL_MSR_REG(PIC_YSEL_HIGH), &hi, &lo); + lo &= ~(0xf << 24); + _wrmsr(DIVIL_MSR_REG(PIC_YSEL_HIGH), hi, lo); + } + break; + case PCI_UART2_INT_REG: + if (value) { + /* enable uart2 interrupt in PIC */ + _rdmsr(DIVIL_MSR_REG(PIC_YSEL_HIGH), &hi, &lo); + lo &= ~(0xf << 28); + lo |= (CS5536_UART2_INTR << 28); + _wrmsr(DIVIL_MSR_REG(PIC_YSEL_HIGH), hi, lo); + } else { + /* disable uart2 interrupt in PIC */ + _rdmsr(DIVIL_MSR_REG(PIC_YSEL_HIGH), &hi, &lo); + lo &= ~(0xf << 28); + _wrmsr(DIVIL_MSR_REG(PIC_YSEL_HIGH), hi, lo); + } + break; + case PCI_ISA_FIXUP_REG: + if (value) { + /* enable the TARGET ABORT/MASTER ABORT etc. */ + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + lo |= 0x00000063; + _wrmsr(SB_MSR_REG(SB_ERROR), hi, lo); + } + + default: + /* ALL OTHER PCI CONFIG SPACE HEADER IS NOT IMPLEMENTED. */ + break; + } + + return; +} + +/* + * isa_read : isa read transfering. + * we assume that the ISA is not the BUS MASTER. + */ + + /* COMMAND : + * bit0 : IO SPACE ENABLE + * bit1 : MEMORY SPACE ENABLE(ignore) + * bit2 : BUS MASTER ENABLE(ignore) + * bit3 : SPECIAL CYCLE(ignore)? default is ignored. + * bit4 : MEMORY WRITE and INVALIDATE(ignore) + * bit5 : VGA PALETTE(ignore) + * bit6 : PARITY ERROR(ignore)? : default is ignored. + * bit7 : WAIT CYCLE CONTROL(ignore) + * bit8 : SYSTEM ERROR(ignore) + * bit9 : FAST BACK TO BACK(ignore) + * bit10-bit15 : RESERVED + * STATUS : + * bit0-bit3 : RESERVED + * bit4 : CAPABILITY LIST(ignore) + * bit5 : 66MHZ CAPABLE + * bit6 : RESERVED + * bit7 : FAST BACK TO BACK(ignore) + * bit8 : DATA PARITY ERROR DETECED(ignore)? + * bit9-bit10 : DEVSEL TIMING(ALL MEDIUM) + * bit11: SIGNALED TARGET ABORT + * bit12: RECEIVED TARGET ABORT + * bit13: RECEIVED MASTER ABORT + * bit14: SIGNALED SYSTEM ERROR + * bit15: DETECTED PARITY ERROR(?) + */ + +static u32 pci_isa_read_reg(int reg) +{ + u32 conf_data; + u32 hi, lo; + + switch (reg) { + case PCI_ID_REG: + conf_data = (CS5536_ISA_DEVICE_ID << 16 | CS5536_VENDOR_ID); + break; + case PCI_COMMAND_STATUS_REG: + conf_data = 0; + /* command */ + /* we just check the first LBAR for the IO enable bit, */ + /* maybe we should changed later. */ + _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_SMB), &hi, &lo); + if (hi & 0x01) { + conf_data |= PCI_COMMAND_IO_ENABLE; + } + /* conf_data |= PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE | PCI_COMMAND_MASTER_ENABLE; */ +#if 0 + conf_data |= PCI_COMMAND_SPECIAL_ENABLE; +#endif +#if 0 + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + if (lo & SB_PARE_ERR_EN) { + conf_data |= PCI_COMMAND_PARITY_ENABLE; + } else { + conf_data &= ~PCI_COMMAND_PARITY_ENABLE; + } +#endif + /* status */ + conf_data |= PCI_STATUS_66MHZ_SUPPORT; + conf_data |= PCI_STATUS_DEVSEL_MEDIUM; +#if 1 + conf_data |= PCI_STATUS_BACKTOBACK_SUPPORT; +#endif + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + if (lo & SB_TAS_ERR_FLAG) + conf_data |= PCI_STATUS_TARGET_TARGET_ABORT; + if (lo & SB_TAR_ERR_FLAG) + conf_data |= PCI_STATUS_MASTER_TARGET_ABORT; + if (lo & SB_MAR_ERR_FLAG) + conf_data |= PCI_STATUS_MASTER_ABORT; + if (lo & SB_PARE_ERR_FLAG) + conf_data |= PCI_STATUS_PARITY_DETECT; + break; + case PCI_CLASS_REG: + _rdmsr(GLCP_MSR_REG(GLCP_CHIP_REV_ID), &hi, &lo); + conf_data = lo & 0x000000ff; + conf_data |= (CS5536_ISA_CLASS_CODE << 8); + break; + case PCI_BHLC_REG: + _rdmsr(SB_MSR_REG(SB_CTRL), &hi, &lo); + hi &= 0x000000f8; + conf_data = + (PCI_NONE_BIST << 24) | (PCI_BRIDGE_HEADER_TYPE << 16) + | (hi << 8) | PCI_NORMAL_CACHE_LINE_SIZE; + break; + /* + * we only use the LBAR of DIVIL, no RCONF used. + * all of them are IO space. + */ + case PCI_BAR0_REG: + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + if (lo & SOFT_BAR_SMB_FLAG) { + conf_data = CS5536_SMB_RANGE | PCI_MAPREG_TYPE_IO; + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo &= ~SOFT_BAR_SMB_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + } else { + _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_SMB), &hi, &lo); + conf_data = lo & 0x0000fff8; + conf_data |= 0x01; + conf_data &= ~0x02; + } + break; + case PCI_BAR1_REG: + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + if (lo & SOFT_BAR_GPIO_FLAG) { + conf_data = CS5536_GPIO_RANGE | PCI_MAPREG_TYPE_IO; + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo &= ~SOFT_BAR_GPIO_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + } else { + _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_GPIO), &hi, &lo); + conf_data = lo & 0x0000ff00; + conf_data |= 0x01; + conf_data &= ~0x02; + } + break; + case PCI_BAR2_REG: + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + if (lo & SOFT_BAR_MFGPT_FLAG) { + conf_data = CS5536_MFGPT_RANGE | PCI_MAPREG_TYPE_IO; + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo &= ~SOFT_BAR_MFGPT_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + } else { + _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_MFGPT), &hi, &lo); + conf_data = lo & 0x0000ffc0; + conf_data |= 0x01; + conf_data &= ~0x02; + } + break; +#if 1 + case PCI_BAR3_REG: + conf_data = 0; + break; +#else + case PCI_BAR3_REG: + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + if (lo & SOFT_BAR_IRQ_FLAG) { + conf_data = CS5536_IRQ_RANGE | PCI_MAPREG_TYPE_IO; + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo &= ~SOFT_BAR_IRQ_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + } else { + _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_IRQ), &hi, &lo); + conf_data = lo & 0x0000ffc0; + conf_data |= 0x01; + conf_data &= ~0x02; + } + break; +#endif + case PCI_BAR4_REG: + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + if (lo & SOFT_BAR_PMS_FLAG) { + conf_data = CS5536_PMS_RANGE | PCI_MAPREG_TYPE_IO; + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo &= ~SOFT_BAR_PMS_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + } else { + _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_PMS), &hi, &lo); + conf_data = lo & 0x0000ff80; + conf_data |= 0x01; + conf_data &= ~0x02; + } + break; + case PCI_BAR5_REG: + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + if (lo & SOFT_BAR_ACPI_FLAG) { + conf_data = CS5536_ACPI_RANGE | PCI_MAPREG_TYPE_IO; + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo &= ~SOFT_BAR_ACPI_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + } else { + _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_ACPI), &hi, &lo); + conf_data = lo & 0x0000ffe0; + conf_data |= 0x01; + conf_data &= ~0x02; + } + break; + case PCI_CARDBUS_CIS_REG: + conf_data = PCI_CARDBUS_CIS_POINTER; + break; + case PCI_SUBSYS_ID_REG: + conf_data = (CS5536_ISA_SUB_ID << 16) | CS5536_SUB_VENDOR_ID; + break; + case PCI_MAPREG_ROM: + conf_data = PCI_EXPANSION_ROM_BAR; + break; + case PCI_CAPLISTPTR_REG: + conf_data = PCI_CAPLIST_POINTER; + break; + case PCI_INTERRUPT_REG: + conf_data = + (PCI_MAX_LATENCY << 24) | (PCI_MIN_GRANT << 16) | + (0x00 << 8) | 0x00; + break; + default: + conf_data = 0; + break; + } + + return conf_data; +} + +#ifdef TEST_CS5536_USE_FLASH + +#ifndef TEST_CS5536_USE_NOR_FLASH /* for nand flash */ +static void pci_flash_write_reg(int reg, u32 value) +{ + u32 hi, lo; + + switch (reg) { + case PCI_COMMAND_STATUS_REG: + /* command */ + if (value & PCI_COMMAND_MEM_ENABLE) { + flash_lbar_enable_disable(1); + } else { + flash_lbar_enable_disable(0); + } + /* status */ + if (value & PCI_STATUS_PARITY_ERROR) { + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + if (lo & SB_PARE_ERR_FLAG) { + lo = (lo & 0x0000ffff) | SB_PARE_ERR_FLAG; + _wrmsr(SB_MSR_REG(SB_ERROR), hi, lo); + } + } + break; + case PCI_BAR0_REG: + if (value == PCI_BAR_RANGE_MASK) { + /* make the flag for reading the bar length. */ + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo |= SOFT_BAR_FLSH0_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + } else if ((value & 0x01) == 0x00) { + /* mem space nand flash native reg base addr */ + hi = 0xfffff007; + lo = value & 0xfffff000; + _wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH0), hi, lo); + + /* RCONFx is 4KB in units for mem space. */ + hi = ((value & 0xfffff000) << 12) | + ((CS5536_FLSH0_LENGTH & 0xfffff000) - + (1 << 12)) | 0x00; + lo = ((value & 0xfffff000) << 12) | 0x01; + _wrmsr(SB_MSR_REG(SB_R6), hi, lo); + } + break; + case PCI_BAR1_REG: + if (value == PCI_BAR_RANGE_MASK) { + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo |= SOFT_BAR_FLSH1_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + } else if ((value & 0x01) == 0x00) { + /* mem space nand flash native reg base addr */ + hi = 0xfffff007; + lo = value & 0xfffff000; + _wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH1), hi, lo); + + /* RCONFx is 4KB in units for mem space. */ + hi = ((value & 0xfffff000) << 12) | + ((CS5536_FLSH1_LENGTH & 0xfffff000) - + (1 << 12)) | 0x00; + lo = ((value & 0xfffff000) << 12) | 0x01; + _wrmsr(SB_MSR_REG(SB_R7), hi, lo); + } + break; + case PCI_BAR2_REG: + if (value == PCI_BAR_RANGE_MASK) { + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo |= SOFT_BAR_FLSH2_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + } else if ((value & 0x01) == 0x00) { + /* mem space nand flash native reg base addr */ + hi = 0xfffff007; + lo = value & 0xfffff000; + _wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH2), hi, lo); + + /* RCONFx is 4KB in units for mem space. */ + hi = ((value & 0xfffff000) << 12) | + ((CS5536_FLSH2_LENGTH & 0xfffff000) - + (1 << 12)) | 0x00; + lo = ((value & 0xfffff000) << 12) | 0x01; + _wrmsr(SB_MSR_REG(SB_R8), hi, lo); + } + break; + case PCI_BAR3_REG: + if (value == PCI_BAR_RANGE_MASK) { + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo |= SOFT_BAR_FLSH3_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + } else if ((value & 0x01) == 0x00) { + /* mem space nand flash native reg base addr */ + hi = 0xfffff007; + lo = value & 0xfffff000; + _wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH3), hi, lo); + + /* RCONFx is 4KB in units for mem space. */ + hi = ((value & 0xfffff000) << 12) | + ((CS5536_FLSH3_LENGTH & 0xfffff000) - + (1 << 12)) | 0x00; + lo = ((value & 0xfffff000) << 12) | 0x01; + _wrmsr(SB_MSR_REG(SB_R9), hi, lo); + } + break; + case PCI_FLASH_INT_REG: + if (value) { + /* enable all the flash interrupt in PIC */ + _rdmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), &hi, &lo); + lo &= ~(0xf << PIC_YSEL_LOW_FLASH_SHIFT); + lo |= (CS5536_FLASH_INTR << PIC_YSEL_LOW_FLASH_SHIFT); + _wrmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), hi, lo); + } else { + /* disable all the flash interrupt in PIC */ + _rdmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), &hi, &lo); + lo &= ~(0xf << PIC_YSEL_LOW_FLASH_SHIFT); + _wrmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), hi, lo); + } + break; + case PCI_NAND_FLASH_TDATA_REG: + hi = 0; + lo = value; + _wrmsr(DIVIL_MSR_REG(NANDF_DATA), hi, lo); + break; + case PCI_NAND_FLASH_TCTRL_REG: + hi = 0; + lo = value & 0x00000fff; + _wrmsr(DIVIL_MSR_REG(NANDF_CTRL), hi, lo); + break; + case PCI_NAND_FLASH_RSVD_REG: + hi = 0; + lo = value; + _wrmsr(DIVIL_MSR_REG(NANDF_RSVD), hi, lo); + break; + case PCI_FLASH_SELECT_REG: + if (value == CS5536_IDE_FLASH_SIGNATURE) { + _rdmsr(DIVIL_MSR_REG(DIVIL_BALL_OPTS), &hi, &lo); + lo &= ~0x01; + _wrmsr(DIVIL_MSR_REG(DIVIL_BALL_OPTS), hi, lo); + } + break; + default: + break; + } + + return; +} + +static u32 pci_flash_read_reg(int reg) +{ + u32 conf_data; + u32 hi, lo; + + switch (reg) { + case PCI_ID_REG: + conf_data = (CS5536_FLASH_DEVICE_ID << 16 | CS5536_VENDOR_ID); + break; + case PCI_COMMAND_STATUS_REG: + conf_data = 0; + /* command */ + /* we just read one lbar for returning. */ + _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH0), &hi, &lo); + if (hi & 0x01) + conf_data |= PCI_COMMAND_MEM_ENABLE; + /* STATUS */ + conf_data |= PCI_STATUS_66MHZ_SUPPORT; + conf_data |= PCI_STATUS_BACKTOBACK_SUPPORT; + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + if (lo & SB_PARE_ERR_FLAG) + conf_data |= PCI_STATUS_PARITY_ERROR; + conf_data |= PCI_STATUS_DEVSEL_MEDIUM; + break; + case PCI_CLASS_REG: + _rdmsr(DIVIL_MSR_REG(DIVIL_CAP), &hi, &lo); + conf_data = lo & 0x000000ff; + conf_data |= (CS5536_FLASH_CLASS_CODE << 8); + break; + case PCI_BHLC_REG: + conf_data = + (PCI_NONE_BIST << 24) | (PCI_NORMAL_HEADER_TYPE << 16) + | (PCI_NORMAL_LATENCY_TIMER << 8) | + PCI_NORMAL_CACHE_LINE_SIZE; + break; + case PCI_BAR0_REG: + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + if (lo & SOFT_BAR_FLSH0_FLAG) { + conf_data = CS5536_FLSH0_RANGE | PCI_MAPREG_TYPE_MEM; + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo &= ~SOFT_BAR_FLSH0_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + } else { + _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH0), &hi, &lo); + conf_data = lo; + conf_data &= ~0x0f; + } + break; + case PCI_BAR1_REG: + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + if (lo & SOFT_BAR_FLSH1_FLAG) { + conf_data = CS5536_FLSH1_RANGE | PCI_MAPREG_TYPE_MEM; + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo &= ~SOFT_BAR_FLSH1_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + } else { + _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH1), &hi, &lo); + conf_data = lo; + conf_data &= ~0x0f; + } + break; + case PCI_BAR2_REG: + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + if (lo & SOFT_BAR_FLSH2_FLAG) { + conf_data = CS5536_FLSH2_RANGE | PCI_MAPREG_TYPE_MEM; + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo &= ~SOFT_BAR_FLSH2_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + } else { + _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH2), &hi, &lo); + conf_data = lo; + conf_data &= ~0x0f; + } + break; + case PCI_BAR3_REG: + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + if (lo & SOFT_BAR_FLSH3_FLAG) { + conf_data = CS5536_FLSH3_RANGE | PCI_MAPREG_TYPE_MEM; + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo &= ~SOFT_BAR_FLSH3_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + } else { + _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH3), &hi, &lo); + conf_data = lo; + conf_data &= ~0x0f; + } + break; + case PCI_CARDBUS_CIS_REG: + conf_data = PCI_CARDBUS_CIS_POINTER; + break; + case PCI_SUBSYS_ID_REG: + conf_data = (CS5536_FLASH_SUB_ID << 16) | CS5536_SUB_VENDOR_ID; + break; + case PCI_MAPREG_ROM: + conf_data = PCI_EXPANSION_ROM_BAR; + break; + case PCI_CAPLISTPTR_REG: + conf_data = PCI_CAPLIST_POINTER; + break; + case PCI_INTERRUPT_REG: + conf_data = + (PCI_MAX_LATENCY << 24) | (PCI_MIN_GRANT << 16) | + (PCI_DEFAULT_PIN << 8) | (CS5536_FLASH_INTR); + break; + case PCI_NAND_FLASH_TDATA_REG: + _rdmsr(DIVIL_MSR_REG(NANDF_DATA), &hi, &lo); + conf_data = lo; + break; + case PCI_NAND_FLASH_TCTRL_REG: + _rdmsr(DIVIL_MSR_REG(NANDF_CTRL), &hi, &lo); + conf_data = lo & 0x00000fff; + break; + case PCI_NAND_FLASH_RSVD_REG: + _rdmsr(DIVIL_MSR_REG(NANDF_RSVD), &hi, &lo); + conf_data = lo; + break; + case PCI_FLASH_SELECT_REG: + _rdmsr(DIVIL_MSR_REG(DIVIL_BALL_OPTS), &hi, &lo); + conf_data = lo & 0x01; + break; + + } + return 0; +} + +#else /* nor flash */ + +static void pci_flash_write_reg(int reg, u32 value) +{ + u32 hi, lo; + + switch (reg) { + case PCI_COMMAND_STATUS_REG: + /* command */ + if (value & PCI_COMMAND_IO_ENABLE) { + flash_lbar_enable_disable(1); + } else { + flash_lbar_enable_disable(0); + } + /* status */ + if (value & PCI_STATUS_PARITY_ERROR) { + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + if (lo & SB_PARE_ERR_FLAG) { + lo = (lo & 0x0000ffff) | SB_PARE_ERR_FLAG; + _wrmsr(SB_MSR_REG(SB_ERROR), hi, lo); + } + } + break; + case PCI_BAR0_REG: + if (value == PCI_BAR_RANGE_MASK) { + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo |= SOFT_BAR_FLSH0_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + } else if (value & 0x01) { + /* IO space of 16bytes nor flash */ + hi = 0x0000fff1; + lo = value & 0x0000fff0; + _wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH0), hi, lo); + + /* RCONFx used for 16bytes reserved. */ + hi = ((value & 0x000ffffc) << 12) | + ((CS5536_FLSH0_LENGTH - 4) + << 12) | 0x01; + lo = ((value & 0x000ffffc) << 12) | 0x01; + _wrmsr(SB_MSR_REG(SB_R6), hi, lo); + } + break; + case PCI_BAR1_REG: + if (value == PCI_BAR_RANGE_MASK) { + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo |= SOFT_BAR_FLSH1_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + } else if (value & 0x01) { + /* IO space of 16bytes nor flash */ + hi = 0x0000fff1; + lo = value & 0x0000fff0; + _wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH1), hi, lo); + + /* RCONFx used for 16bytes reserved. */ + hi = ((value & 0x000ffffc) << 12) | + ((CS5536_FLSH1_LENGTH - 4) + << 12) | 0x01; + lo = ((value & 0x000ffffc) << 12) | 0x01; + _wrmsr(SB_MSR_REG(SB_R7), hi, lo); + } + break; + case PCI_BAR2_REG: + if (value == PCI_BAR_RANGE_MASK) { + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo |= SOFT_BAR_FLSH2_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + } else if (value & 0x01) { + hi = 0x0000fff1; + lo = value & 0x0000fff0; + _wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH2), hi, lo); + + hi = ((value & 0x000ffffc) << 12) | + ((CS5536_FLSH2_LENGTH - 4) + << 12) | 0x01; + lo = ((value & 0x000ffffc) << 12) | 0x01; + _wrmsr(SB_MSR_REG(SB_R8), hi, lo); + } + break; + case PCI_BAR3_REG: + if (value == PCI_BAR_RANGE_MASK) { + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo |= SOFT_BAR_FLSH3_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + } else if (value & 0x01) { + /* 16bytes for nor flash */ + hi = 0x0000fff1; + lo = value & 0x0000fff0; + _wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH3), hi, lo); + + /* 16bytes of IO space of RCONFx region. */ + hi = ((value & 0x000ffffc) << 12) | + ((CS5536_FLSH3_LENGTH - 4) + << 12) | 0x01; + lo = ((value & 0x000ffffc) << 12) | 0x01; + _wrmsr(SB_MSR_REG(SB_R9), hi, lo); + } + break; + + case PCI_INTERRUPT_REG: + conf_data = + (PCI_MAX_LATENCY << 24) | (PCI_MIN_GRANT << 16) | + (PCI_DEFAULT_PIN << 8) | (CS5536_FLASH_INTR); + break; + case PCI_FLASH_INT_REG: + if (value) { + /* enable all the flash interrupt in PIC */ + _rdmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), &hi, &lo); + lo &= ~(0xf << PIC_YSEL_LOW_FLASH_SHIFT); + lo |= (CS5536_FLASH_INTR << PIC_YSEL_LOW_FLASH_SHIFT); + _wrmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), hi, lo); + } else { + /* disable all the flash interrupt in PIC */ + _rdmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), &hi, &lo); + lo &= ~(0xf << PIC_YSEL_LOW_FLASH_SHIFT); + _wrmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), hi, lo); + } + break; + case PCI_NOR_FLASH_CTRL_REG: + hi = 0; + lo = value & 0x000000ff; + _wrmsr(DIVIL_MSR_REG(NORF_CTRL), hi, lo); + break; + case PCI_NOR_FLASH_T01_REG: + hi = 0; + lo = value; + _wrmsr(DIVIL_MSR_REG(NORF_T01), hi, lo); + break; + case PCI_NOR_FLASH_T23_REG: + hi = 0; + lo = value; + _wrmsr(DIVIL_MSR_REG(NORF_T23), hi, lo); + break; + case PCI_FLASH_SELECT_REG: + if (value == CS5536_IDE_FLASH_SIGNATURE) { + _rdmsr(DIVIL_MSR_REG(DIVIL_BALL_OPTS), &hi, &lo); + lo &= ~0x01; + _wrmsr(DIVIL_MSR_REG(DIVIL_BALL_OPTS), hi, lo); + } + break; + + default: + break; + } + + return; +} + +static u32 pci_flash_read_reg(int reg) +{ + u32 conf_data; + u32 hi, lo; + + switch (reg) { + case PCI_ID_REG: + conf_data = (CS5536_FLASH_DEVICE_ID << 16 | CS5536_VENDOR_ID); + break; + case PCI_COMMAND_STATUS_REG: + conf_data = 0; + /* command */ + /* we just check one flash bar for returning. */ + _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH0), &hi, &lo); + if (hi & 0x01) + conf_data |= PCI_COMMAND_IO_ENABLE; + /* STATUS */ + conf_data |= PCI_STATUS_66MHZ_SUPPORT; + conf_data |= PCI_STATUS_BACKTOBACK_SUPPORT; + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + if (lo & SB_PARE_ERR_FLAG) + conf_data |= PCI_STATUS_PARITY_ERROR; + conf_data |= PCI_STATUS_DEVSEL_MEDIUM; + break; + case PCI_CLASS_REG: + _rdmsr(DIVIL_MSR_REG(DIVIL_CAP), &hi, &lo); + conf_data = lo & 0x000000ff; + conf_data |= (CS5536_FLASH_CLASS_CODE << 8); + break; + case PCI_BHLC_REG: + conf_data = + (PCI_NONE_BIST << 24) | (PCI_NORMAL_HEADER_TYPE << 16) + | (PCI_NORMAL_LATENCY_TIMER << 8) | + PCI_NORMAL_CACHE_LINE_SIZE; + break; + case PCI_BAR0_REG: + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + if (lo & SOFT_BAR_FLSH0_FLAG) { + conf_data = CS5536_FLSH0_RANGE | PCI_MAPREG_TYPE_IO; + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo &= ~SOFT_BAR_FLSH0_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + } else { + _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH0), &hi, &lo); + conf_data = lo & 0x0000ffff; + conf_data |= 0x01; + conf_data &= ~0x02; + } + break; + case PCI_BAR1_REG: + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + if (lo & SOFT_BAR_FLSH1_FLAG) { + conf_data = CS5536_FLSH1_RANGE | PCI_MAPREG_TYPE_IO; + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo &= ~SOFT_BAR_FLSH1_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + } else { + _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH1), &hi, &lo); + conf_data = lo & 0x0000ffff; + conf_data |= 0x01; + conf_data &= ~0x02; + } + break; + case PCI_BAR2_REG: + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + if (lo & SOFT_BAR_FLSH2_FLAG) { + conf_data = CS5536_FLSH2_RANGE | PCI_MAPREG_TYPE_IO; + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo &= ~SOFT_BAR_FLSH2_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + } else { + _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH2), &hi, &lo); + conf_data = lo & 0x0000ffff; + conf_data |= 0x01; + conf_data &= ~0x02; + } + break; + case PCI_BAR3_REG: + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + if (lo & SOFT_BAR_FLSH3_FLAG) { + conf_data = CS5536_FLSH3_RANGE | PCI_MAPREG_TYPE_IO; + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo &= ~SOFT_BAR_FLSH3_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + } else { + _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH3), &hi, &lo); + conf_data = lo & 0x0000ffff; + conf_data |= 0x01; + conf_data &= ~0x02; + } + break; + case PCI_CARDBUS_CIS_REG: + conf_data = PCI_CARDBUS_CIS_POINTER; + break; + case PCI_SUBSYS_ID_REG: + conf_data = (CS5536_FLASH_SUB_ID << 16) | CS5536_SUB_VENDOR_ID; + break; + case PCI_MAPREG_ROM: + conf_data = PCI_EXPANSION_ROM_BAR; + break; + case PCI_CAPLISTPTR_REG: + conf_data = PCI_CAPLIST_POINTER; + break; + case PCI_INTERRUPT_REG: + conf_data = + (PCI_MAX_LATENCY << 24) | (PCI_MIN_GRANT << 16) | + (PCI_DEFAULT_PIN << 8) | (CS5536_FLASH_INTR); + break; + case PCI_NOR_FLASH_CTRL_REG: + _rdmsr(DIVIL_MSR_REG(NORF_CTRL), &hi, &lo); + conf_data = lo & 0x000000ff; + break; + case PCI_NOR_FLASH_T01_REG: + _rdmsr(DIVIL_MSR_REG(NORF_T01), &hi, &lo); + conf_data = lo; + break; + case PCI_NOR_FLASH_T23_REG: + _rdmsr(DIVIL_MSR_REG(NORF_T23), &hi, &lo); + conf_data = lo; + break; + default: + conf_data = 0; + break; + } + return conf_data; +} +#endif /* TEST_CS5536_USE_NOR_FLASH */ + +#else /* TEST_CS5536_USE_FLASH */ + +static void pci_flash_write_reg(int reg, u32 value) +{ + return; +} + +static u32 pci_flash_read_reg(int reg) +{ + return 0xffffffff; +} + +#endif /* TEST_CS5536_USE_FLASH */ + +/* + * ide_write : ide write transfering + */ +static void pci_ide_write_reg(int reg, u32 value) +{ + u32 hi, lo; + + switch (reg) { + case PCI_COMMAND_STATUS_REG: + /* command */ + if (value & PCI_COMMAND_MASTER_ENABLE) { + _rdmsr(GLIU_MSR_REG(GLIU_PAE), &hi, &lo); + lo |= (0x03 << 4); + _wrmsr(GLIU_MSR_REG(GLIU_PAE), hi, lo); + } else { + _rdmsr(GLIU_MSR_REG(GLIU_PAE), &hi, &lo); + lo &= ~(0x03 << 4); + _wrmsr(GLIU_MSR_REG(GLIU_PAE), hi, lo); + } + /* status */ + if (value & PCI_STATUS_PARITY_ERROR) { + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + if (lo & SB_PARE_ERR_FLAG) { + lo = (lo & 0x0000ffff) | SB_PARE_ERR_FLAG; + _wrmsr(SB_MSR_REG(SB_ERROR), hi, lo); + } + } + break; + case PCI_BHLC_REG: + value &= 0x0000ff00; + _rdmsr(SB_MSR_REG(SB_CTRL), &hi, &lo); + hi &= 0xffffff00; + hi |= (value >> 8); + _wrmsr(SB_MSR_REG(SB_CTRL), hi, lo); + break; + case PCI_BAR4_REG: + if (value == PCI_BAR_RANGE_MASK) { + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo |= SOFT_BAR_IDE_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + } else if (value & 0x01) { + hi = 0x00000000; + /* lo = ((value & 0x0fffffff) << 4) | 0x001; */ + lo = (value & 0xfffffff0) | 0x1; + _wrmsr(IDE_MSR_REG(IDE_IO_BAR), hi, lo); + + value &= 0xfffffffc; + hi = 0x60000000 | ((value & 0x000ff000) >> 12); + lo = 0x000ffff0 | ((value & 0x00000fff) << 20); + _wrmsr(GLIU_MSR_REG(GLIU_IOD_BM2), hi, lo); + } + break; + case PCI_IDE_CFG_REG: + if (value == CS5536_IDE_FLASH_SIGNATURE) { + _rdmsr(DIVIL_MSR_REG(DIVIL_BALL_OPTS), &hi, &lo); + lo |= 0x01; + _wrmsr(DIVIL_MSR_REG(DIVIL_BALL_OPTS), hi, lo); + } else { + hi = 0; + lo = value; + _wrmsr(IDE_MSR_REG(IDE_CFG), hi, lo); + } + break; + case PCI_IDE_DTC_REG: + hi = 0; + lo = value; + _wrmsr(IDE_MSR_REG(IDE_DTC), hi, lo); + break; + case PCI_IDE_CAST_REG: + hi = 0; + lo = value; + _wrmsr(IDE_MSR_REG(IDE_CAST), hi, lo); + break; + case PCI_IDE_ETC_REG: + hi = 0; + lo = value; + _wrmsr(IDE_MSR_REG(IDE_ETC), hi, lo); + break; + case PCI_IDE_PM_REG: + hi = 0; + lo = value; + _wrmsr(IDE_MSR_REG(IDE_INTERNAL_PM), hi, lo); + break; + default: + break; + } + + return; +} + +/* + * ide_read : ide read tranfering. + */ +static u32 pci_ide_read_reg(int reg) +{ + u32 conf_data; + u32 hi, lo; + + switch (reg) { + case PCI_ID_REG: + conf_data = (CS5536_IDE_DEVICE_ID << 16 | CS5536_VENDOR_ID); + break; + case PCI_COMMAND_STATUS_REG: + conf_data = 0; + /* command */ + _rdmsr(IDE_MSR_REG(IDE_IO_BAR), &hi, &lo); + if (lo & 0xfffffff0) + conf_data |= PCI_COMMAND_IO_ENABLE; + _rdmsr(GLIU_MSR_REG(GLIU_PAE), &hi, &lo); + if ((lo & 0x30) == 0x30) + conf_data |= PCI_COMMAND_MASTER_ENABLE; + /* conf_data |= PCI_COMMAND_BACKTOBACK_ENABLE??? HOW TO GET.. */ + /* STATUS */ + conf_data |= PCI_STATUS_66MHZ_SUPPORT; + conf_data |= PCI_STATUS_BACKTOBACK_SUPPORT; + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + if (lo & SB_PARE_ERR_FLAG) + conf_data |= PCI_STATUS_PARITY_ERROR; + conf_data |= PCI_STATUS_DEVSEL_MEDIUM; + break; + case PCI_CLASS_REG: + _rdmsr(IDE_MSR_REG(IDE_CAP), &hi, &lo); + conf_data = lo & 0x000000ff; + conf_data |= (CS5536_IDE_CLASS_CODE << 8); + break; + case PCI_BHLC_REG: + _rdmsr(SB_MSR_REG(SB_CTRL), &hi, &lo); + hi &= 0x000000f8; + conf_data = + (PCI_NONE_BIST << 24) | (PCI_NORMAL_HEADER_TYPE << 16) + | (hi << 8) | PCI_NORMAL_CACHE_LINE_SIZE; + break; + case PCI_BAR0_REG: + conf_data = 0x00000000; + break; + case PCI_BAR1_REG: + conf_data = 0x00000000; + break; + case PCI_BAR2_REG: + conf_data = 0x00000000; + break; + case PCI_BAR3_REG: + conf_data = 0x00000000; + break; + case PCI_BAR4_REG: + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + if (lo & SOFT_BAR_IDE_FLAG) { + conf_data = CS5536_IDE_RANGE | PCI_MAPREG_TYPE_IO; + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo &= ~SOFT_BAR_IDE_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + } else { + _rdmsr(IDE_MSR_REG(IDE_IO_BAR), &hi, &lo); + /* conf_data = lo >> 4; */ + conf_data = lo & 0xfffffff0; + conf_data |= 0x01; + conf_data &= ~0x02; + } + break; + case PCI_BAR5_REG: + conf_data = 0x00000000; + break; + case PCI_CARDBUS_CIS_REG: + conf_data = PCI_CARDBUS_CIS_POINTER; + break; + case PCI_SUBSYS_ID_REG: + conf_data = (CS5536_IDE_SUB_ID << 16) | CS5536_SUB_VENDOR_ID; + break; + case PCI_MAPREG_ROM: + conf_data = PCI_EXPANSION_ROM_BAR; + break; + case PCI_CAPLISTPTR_REG: + conf_data = PCI_CAPLIST_POINTER; + break; + case PCI_INTERRUPT_REG: + conf_data = + (PCI_MAX_LATENCY << 24) | (PCI_MIN_GRANT << 16) | + (PCI_DEFAULT_PIN << 8) | (CS5536_IDE_INTR); + break; + case PCI_IDE_CFG_REG: + _rdmsr(IDE_MSR_REG(IDE_CFG), &hi, &lo); + conf_data = lo; + break; + case PCI_IDE_DTC_REG: + _rdmsr(IDE_MSR_REG(IDE_DTC), &hi, &lo); + conf_data = lo; + break; + case PCI_IDE_CAST_REG: + _rdmsr(IDE_MSR_REG(IDE_CAST), &hi, &lo); + conf_data = lo; + break; + case PCI_IDE_ETC_REG: + _rdmsr(IDE_MSR_REG(IDE_ETC), &hi, &lo); + conf_data = lo; + case PCI_IDE_PM_REG: + _rdmsr(IDE_MSR_REG(IDE_INTERNAL_PM), &hi, &lo); + conf_data = lo; + break; + + default: + conf_data = 0; + break; + } + + return conf_data; +} + +static void pci_acc_write_reg(int reg, u32 value) +{ + u32 hi, lo; + + switch (reg) { + case PCI_COMMAND_STATUS_REG: + /* command */ + if (value & PCI_COMMAND_MASTER_ENABLE) { + _rdmsr(GLIU_MSR_REG(GLIU_PAE), &hi, &lo); + lo |= (0x03 << 8); + _wrmsr(GLIU_MSR_REG(GLIU_PAE), hi, lo); + } else { + _rdmsr(GLIU_MSR_REG(GLIU_PAE), &hi, &lo); + lo &= ~(0x03 << 8); + _wrmsr(GLIU_MSR_REG(GLIU_PAE), hi, lo); + } + /* status */ + if (value & PCI_STATUS_PARITY_ERROR) { + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + if (lo & SB_PARE_ERR_FLAG) { + lo = (lo & 0x0000ffff) | SB_PARE_ERR_FLAG; + _wrmsr(SB_MSR_REG(SB_ERROR), hi, lo); + } + } + break; + case PCI_BAR0_REG: + if (value == PCI_BAR_RANGE_MASK) { + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo |= SOFT_BAR_ACC_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + } else if (value & 0x01) { + value &= 0xfffffffc; + hi = 0xA0000000 | ((value & 0x000ff000) >> 12); + lo = 0x000fff80 | ((value & 0x00000fff) << 20); + _wrmsr(GLIU_MSR_REG(GLIU_IOD_BM1), hi, lo); + } + break; + case PCI_ACC_INT_REG: + if (value) { + /* enable all the acc interrupt in PIC */ + _rdmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), &hi, &lo); + lo &= ~(0xf << PIC_YSEL_LOW_ACC_SHIFT); + lo |= (CS5536_ACC_INTR << PIC_YSEL_LOW_ACC_SHIFT); + _wrmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), hi, lo); + } else { + /* disable all the usb interrupt in PIC */ + _rdmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), &hi, &lo); + lo &= ~(0xf << PIC_YSEL_LOW_ACC_SHIFT); + _wrmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), hi, lo); + } + break; + default: + break; + } + + return; +} + +static u32 pci_acc_read_reg(int reg) +{ + u32 hi, lo; + u32 conf_data; + + switch (reg) { + case PCI_ID_REG: + conf_data = (CS5536_ACC_DEVICE_ID << 16 | CS5536_VENDOR_ID); + break; + case PCI_COMMAND_STATUS_REG: + + conf_data = 0; + /* command */ + _rdmsr(GLIU_MSR_REG(GLIU_IOD_BM1), &hi, &lo); + if (((lo & 0xfff00000) || (hi & 0x000000ff)) + && ((hi & 0xf0000000) == 0xa0000000)) + conf_data |= PCI_COMMAND_IO_ENABLE; + _rdmsr(GLIU_MSR_REG(GLIU_PAE), &hi, &lo); + if ((lo & 0x300) == 0x300) + conf_data |= PCI_COMMAND_MASTER_ENABLE; + /* conf_data |= PCI_COMMAND_BACKTOBACK_ENABLE??? HOW TO GET.. */ + /* STATUS */ + conf_data |= PCI_STATUS_66MHZ_SUPPORT; + conf_data |= PCI_STATUS_BACKTOBACK_SUPPORT; + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + if (lo & SB_PARE_ERR_FLAG) + conf_data |= PCI_STATUS_PARITY_ERROR; + conf_data |= PCI_STATUS_DEVSEL_MEDIUM; + break; + case PCI_CLASS_REG: + _rdmsr(ACC_MSR_REG(ACC_CAP), &hi, &lo); + conf_data = lo & 0x000000ff; + conf_data |= (CS5536_ACC_CLASS_CODE << 8); + break; + case PCI_BHLC_REG: + conf_data = + (PCI_NONE_BIST << 24) | (PCI_NORMAL_HEADER_TYPE << 16) + | (PCI_NORMAL_LATENCY_TIMER << 8) | + PCI_NORMAL_CACHE_LINE_SIZE; + break; + case PCI_BAR0_REG: + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + if (lo & SOFT_BAR_ACC_FLAG) { + conf_data = CS5536_ACC_RANGE | PCI_MAPREG_TYPE_IO; + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo &= ~SOFT_BAR_ACC_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + } else { + _rdmsr(GLIU_MSR_REG(GLIU_IOD_BM1), &hi, &lo); + conf_data = (hi & 0x000000ff) << 12; + conf_data |= (lo & 0xfff00000) >> 20; + conf_data |= 0x01; + conf_data &= ~0x02; + } + break; + case PCI_BAR1_REG: + conf_data = 0x000000; + break; + case PCI_BAR2_REG: + conf_data = 0x000000; + break; + case PCI_BAR3_REG: + conf_data = 0x000000; + break; + case PCI_BAR4_REG: + conf_data = 0x000000; + break; + case PCI_BAR5_REG: + conf_data = 0x000000; + break; + case PCI_CARDBUS_CIS_REG: + conf_data = PCI_CARDBUS_CIS_POINTER; + break; + case PCI_SUBSYS_ID_REG: + conf_data = (CS5536_ACC_SUB_ID << 16) | CS5536_SUB_VENDOR_ID; + break; + case PCI_MAPREG_ROM: + conf_data = PCI_EXPANSION_ROM_BAR; + break; + case PCI_CAPLISTPTR_REG: + conf_data = PCI_CAPLIST_USB_POINTER; + break; + case PCI_INTERRUPT_REG: + conf_data = + (PCI_MAX_LATENCY << 24) | (PCI_MIN_GRANT << 16) | + (PCI_DEFAULT_PIN << 8) | (CS5536_ACC_INTR); + break; + default: + conf_data = 0; + break; + } + + return conf_data; +} + +/* + * ohci_write : ohci write tranfering. + */ +static void pci_ohci_write_reg(int reg, u32 value) +{ + u32 hi, lo; + + switch (reg) { + case PCI_COMMAND_STATUS_REG: + /* command */ + if (value & PCI_COMMAND_MASTER_ENABLE) { + _rdmsr(USB_MSR_REG(USB_OHCI), &hi, &lo); + hi |= (1 << 2); + _wrmsr(USB_MSR_REG(USB_OHCI), hi, lo); + } else { + _rdmsr(USB_MSR_REG(USB_OHCI), &hi, &lo); + hi &= ~(1 << 2); + _wrmsr(USB_MSR_REG(USB_OHCI), hi, lo); + } + if (value & PCI_COMMAND_MEM_ENABLE) { + _rdmsr(USB_MSR_REG(USB_OHCI), &hi, &lo); + hi |= (1 << 1); + _wrmsr(USB_MSR_REG(USB_OHCI), hi, lo); + } else { + _rdmsr(USB_MSR_REG(USB_OHCI), &hi, &lo); + hi &= ~(1 << 1); + _wrmsr(USB_MSR_REG(USB_OHCI), hi, lo); + } + /* status */ + if (value & PCI_STATUS_PARITY_ERROR) { + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + if (lo & SB_PARE_ERR_FLAG) { + lo = (lo & 0x0000ffff) | SB_PARE_ERR_FLAG; + _wrmsr(SB_MSR_REG(SB_ERROR), hi, lo); + } + } + break; + case PCI_BAR0_REG: + if (value == PCI_BAR_RANGE_MASK) { + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo |= SOFT_BAR_OHCI_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + } else if ((value & 0x01) == 0x00) { + _rdmsr(USB_MSR_REG(USB_OHCI), &hi, &lo); + /* lo = (value & 0xffffff00) << 8; */ + lo = value; + _wrmsr(USB_MSR_REG(USB_OHCI), hi, lo); + + value &= 0xfffffff0; + hi = 0x40000000 | ((value & 0xff000000) >> 24); + lo = 0x000fffff | ((value & 0x00fff000) << 8); + _wrmsr(GLIU_MSR_REG(GLIU_P2D_BM3), hi, lo); + } + break; + case PCI_INTERRUPT_REG: + value &= 0x000000ff; + break; + case PCI_OHCI_PM_REG: + break; + case PCI_OHCI_INT_REG: + if (value) { + /* enable all the usb interrupt in PIC */ + _rdmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), &hi, &lo); + lo &= ~(0xf << 8); + lo |= (CS5536_USB_INTR << 8); + _wrmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), hi, lo); + } else { + /* disable all the usb interrupt in PIC */ + _rdmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), &hi, &lo); + lo &= ~(0xf << 8); + _wrmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), hi, lo); + } + break; + default: + break; + } + + return; +} + +/* + * ohci_read : ohci read transfering. + */ +static u32 pci_ohci_read_reg(int reg) +{ + u32 conf_data; + u32 hi, lo; + + switch (reg) { + case PCI_ID_REG: + conf_data = (CS5536_OHCI_DEVICE_ID << 16 | CS5536_VENDOR_ID); + break; + case PCI_COMMAND_STATUS_REG: + conf_data = 0; + /* command */ + _rdmsr(USB_MSR_REG(USB_OHCI), &hi, &lo); + if (hi & 0x04) + conf_data |= PCI_COMMAND_MASTER_ENABLE; + if (hi & 0x02) + conf_data |= PCI_COMMAND_MEM_ENABLE; + /* status */ + conf_data |= PCI_STATUS_66MHZ_SUPPORT; + conf_data |= PCI_STATUS_BACKTOBACK_SUPPORT; + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + if (lo & SB_PARE_ERR_FLAG) + conf_data |= PCI_STATUS_PARITY_ERROR; + conf_data |= PCI_STATUS_DEVSEL_MEDIUM; + break; + case PCI_CLASS_REG: + _rdmsr(USB_MSR_REG(USB_CAP), &hi, &lo); + conf_data = lo & 0x000000ff; + conf_data |= (CS5536_OHCI_CLASS_CODE << 8); + break; + case PCI_BHLC_REG: + conf_data = + (PCI_NONE_BIST << 24) | (PCI_NORMAL_HEADER_TYPE << 16) + | (0x00 << 8) + | PCI_NORMAL_CACHE_LINE_SIZE; + break; + case PCI_BAR0_REG: + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + if (lo & SOFT_BAR_OHCI_FLAG) { + conf_data = CS5536_OHCI_RANGE | PCI_MAPREG_TYPE_MEM; + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo &= ~SOFT_BAR_OHCI_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + } else { + _rdmsr(USB_MSR_REG(USB_OHCI), &hi, &lo); + /* conf_data = lo >> 8; */ + conf_data = lo & 0xffffff00; + conf_data &= ~0x0000000f; /* 32bit mem */ + } + break; + case PCI_BAR1_REG: + conf_data = 0x000000; + break; + case PCI_BAR2_REG: + conf_data = 0x000000; + break; + case PCI_BAR3_REG: + conf_data = 0x000000; + break; + case PCI_BAR4_REG: + conf_data = 0x000000; + break; + case PCI_BAR5_REG: + conf_data = 0x000000; + break; + case PCI_CARDBUS_CIS_REG: + conf_data = PCI_CARDBUS_CIS_POINTER; + break; + case PCI_SUBSYS_ID_REG: + conf_data = (CS5536_OHCI_SUB_ID << 16) | CS5536_SUB_VENDOR_ID; + break; + case PCI_MAPREG_ROM: + conf_data = PCI_EXPANSION_ROM_BAR; + break; + case PCI_CAPLISTPTR_REG: + conf_data = PCI_CAPLIST_USB_POINTER; + break; + case PCI_INTERRUPT_REG: + conf_data = + (PCI_MAX_LATENCY << 24) | (PCI_MIN_GRANT << 16) | + (PCI_DEFAULT_PIN << 8) | (CS5536_USB_INTR); + break; + case PCI_OHCI_PM_REG: + conf_data = 0; + break; + case PCI_OHCI_INT_REG: + _rdmsr(DIVIL_MSR_REG(0x20), &hi, &lo); + if ((lo & 0x00000f00) == 11) + conf_data = 1; + else + conf_data = 0; + break; + default: + conf_data = 0; + break; + } + + return conf_data; +} + +#ifdef TEST_CS5536_USE_EHCI +static void pci_ehci_write_reg(int reg, u32 value) +{ + u32 hi, lo; + + switch (reg) { + case PCI_COMMAND_STATUS_REG: + /* command */ + if (value & PCI_COMMAND_MASTER_ENABLE) { + _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo); + hi |= (1 << 2); + _wrmsr(USB_MSR_REG(USB_EHCI), hi, lo); + } else { + _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo); + hi &= ~(1 << 2); + _wrmsr(USB_MSR_REG(USB_EHCI), hi, lo); + } + if (value & PCI_COMMAND_MEM_ENABLE) { + _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo); + hi |= (1 << 1); + _wrmsr(USB_MSR_REG(USB_EHCI), hi, lo); + } else { + _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo); + hi &= ~(1 << 1); + _wrmsr(USB_MSR_REG(USB_EHCI), hi, lo); + } + /* status */ + if (value & PCI_STATUS_PARITY_ERROR) { + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + if (lo & SB_PARE_ERR_FLAG) { + lo = (lo & 0x0000ffff) | SB_PARE_ERR_FLAG; + _wrmsr(SB_MSR_REG(SB_ERROR), hi, lo); + } + } + break; + case PCI_BAR0_REG: + if (value == PCI_BAR_RANGE_MASK) { + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo |= SOFT_BAR_EHCI_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + } else if ((value & 0x01) == 0x00) { + _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo); + lo = value; + _wrmsr(USB_MSR_REG(USB_EHCI), hi, lo); + + value &= 0xfffffff0; + hi = 0x40000000 | ((value & 0xff000000) >> 24); + lo = 0x000fffff | ((value & 0x00fff000) << 8); + _wrmsr(GLIU_MSR_REG(GLIU_P2D_BM4), hi, lo); + } + break; + case PCI_EHCI_LEGSMIEN_REG: + _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo); + hi &= 0x003f0000; + hi |= (value & 0x3f) << 16; + _wrmsr(USB_MSR_REG(USB_EHCI), hi, lo); + break; + case PCI_EHCI_FLADJ_REG: + _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo); + hi &= ~0x00003f00; + hi |= value & 0x00003f00; + _wrmsr(USB_MSR_REG(USB_EHCI), hi, lo); + break; + default: + break; + } + + return; +} + +static u32 pci_ehci_read_reg(int reg) +{ + u32 conf_data; + u32 hi, lo; + + switch (reg) { + case PCI_ID_REG: + conf_data = (CS5536_EHCI_DEVICE_ID << 16 | CS5536_VENDOR_ID); + break; + case PCI_COMMAND_STATUS_REG: + conf_data = 0; + /* command */ + _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo); + if (hi & 0x04) + conf_data |= PCI_COMMAND_MASTER_ENABLE; + if (hi & 0x02) + conf_data |= PCI_COMMAND_MEM_ENABLE; + /* status */ + conf_data |= PCI_STATUS_66MHZ_SUPPORT; + conf_data |= PCI_STATUS_BACKTOBACK_SUPPORT; + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + if (lo & SB_PARE_ERR_FLAG) + conf_data |= PCI_STATUS_PARITY_ERROR; + conf_data |= PCI_STATUS_DEVSEL_MEDIUM; + break; + case PCI_CLASS_REG: + _rdmsr(USB_MSR_REG(USB_CAP), &hi, &lo); + conf_data = lo & 0x000000ff; + conf_data |= (CS5536_EHCI_CLASS_CODE << 8); + break; + case PCI_BHLC_REG: + conf_data = + (PCI_NONE_BIST << 24) | (PCI_NORMAL_HEADER_TYPE << 16) + | (PCI_NORMAL_LATENCY_TIMER << 8) | + PCI_NORMAL_CACHE_LINE_SIZE; + break; + case PCI_BAR0_REG: + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + if (lo & SOFT_BAR_EHCI_FLAG) { + conf_data = CS5536_EHCI_RANGE | PCI_MAPREG_TYPE_MEM; + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo &= ~SOFT_BAR_EHCI_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + } else { + _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo); + conf_data = lo & 0xfffff000; + } + break; + case PCI_BAR1_REG: + conf_data = 0x000000; + break; + case PCI_BAR2_REG: + conf_data = 0x000000; + break; + case PCI_BAR3_REG: + conf_data = 0x000000; + break; + case PCI_BAR4_REG: + conf_data = 0x000000; + break; + case PCI_BAR5_REG: + conf_data = 0x000000; + break; + case PCI_CARDBUS_CIS_REG: + conf_data = PCI_CARDBUS_CIS_POINTER; + break; + case PCI_SUBSYS_ID_REG: + conf_data = (CS5536_EHCI_SUB_ID << 16) | CS5536_SUB_VENDOR_ID; + break; + case PCI_MAPREG_ROM: + conf_data = PCI_EXPANSION_ROM_BAR; + break; + case PCI_CAPLISTPTR_REG: + conf_data = PCI_CAPLIST_USB_POINTER; + break; + case PCI_INTERRUPT_REG: + conf_data = + (PCI_MAX_LATENCY << 24) | (PCI_MIN_GRANT << 16) | + (PCI_DEFAULT_PIN << 8) | (CS5536_USB_INTR); + break; + case PCI_EHCI_LEGSMIEN_REG: + _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo); + conf_data = (hi & 0x003f0000) >> 16; + break; + case PCI_EHCI_LEGSMISTS_REG: + _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo); + conf_data = (hi & 0x3f000000) >> 24; + break; + case PCI_EHCI_FLADJ_REG: + _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo); + conf_data = hi & 0x00003f00; + break; + default: + conf_data = 0; + break; + } + + return conf_data; +} +#else +static void pci_ehci_write_reg(int reg, u32 value) +{ + return; +} + +static u32 pci_ehci_read_reg(int reg) +{ + return 0xffffffff; +} + +#endif + +#ifdef TEST_CS5536_USE_UDC +static void pci_udc_write_reg(int reg, u32 value) +{ + u32 hi, lo; + + switch (reg) { + case PCI_COMMAND_STATUS_REG: + /* command */ + if (value & PCI_COMMAND_MASTER_ENABLE) { + _rdmsr(USB_MSR_REG(USB_UDC), &hi, &lo); + hi |= (1 << 2); + _wrmsr(USB_MSR_REG(USB_UDC), hi, lo); + } else { + _rdmsr(USB_MSR_REG(USB_UDC), &hi, &lo); + hi &= ~(1 << 2); + _wrmsr(USB_MSR_REG(USB_UDC), hi, lo); + } + if (value & PCI_COMMAND_MEM_ENABLE) { + _rdmsr(USB_MSR_REG(USB_UDC), &hi, &lo); + hi |= (1 << 1); + _wrmsr(USB_MSR_REG(USB_UDC), hi, lo); + } else { + _rdmsr(USB_MSR_REG(USB_UDC), &hi, &lo); + hi &= ~(1 << 1); + _wrmsr(USB_MSR_REG(USB_UDC), hi, lo); + } + /* status */ + if (value & PCI_STATUS_PARITY_ERROR) { + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + if (lo & SB_PARE_ERR_FLAG) { + lo = (lo & 0x0000ffff) | SB_PARE_ERR_FLAG; + _wrmsr(SB_MSR_REG(SB_ERROR), hi, lo); + } + } + break; + case PCI_BAR0_REG: + if (value == PCI_BAR_RANGE_MASK) { + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo |= SOFT_BAR_UDC_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + } else if ((value & 0x01) == 0x00) { + _rdmsr(USB_MSR_REG(USB_UDC), &hi, &lo); + lo = value; + _wrmsr(USB_MSR_REG(USB_UDC), hi, lo); + + value &= 0xfffffff0; + hi = 0x40000000 | ((value & 0xff000000) >> 24); + lo = 0x000fffff | ((value & 0x00fff000) << 8); + _wrmsr(GLIU_MSR_REG(GLIU_P2D_BM0), hi, lo); + } + break; + default: + break; + } + + return; +} + +static u32 pci_udc_read_reg(int reg) +{ + u32 conf_data; + u32 hi, lo; + + switch (reg) { + case PCI_ID_REG: + conf_data = (CS5536_UDC_DEVICE_ID << 16 | CS5536_VENDOR_ID); + break; + case PCI_COMMAND_STATUS_REG: + conf_data = 0; + /* command */ + _rdmsr(USB_MSR_REG(USB_UDC), &hi, &lo); + if (hi & 0x04) + conf_data |= PCI_COMMAND_MASTER_ENABLE; + if (hi & 0x02) + conf_data |= PCI_COMMAND_MEM_ENABLE; + /* status */ + conf_data |= PCI_STATUS_66MHZ_SUPPORT; + conf_data |= PCI_STATUS_BACKTOBACK_SUPPORT; + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + if (lo & SB_PARE_ERR_FLAG) + conf_data |= PCI_STATUS_PARITY_ERROR; + conf_data |= PCI_STATUS_DEVSEL_MEDIUM; + break; + case PCI_CLASS_REG: + _rdmsr(USB_MSR_REG(USB_CAP), &hi, &lo); + conf_data = lo & 0x000000ff; + conf_data |= (CS5536_UDC_CLASS_CODE << 8); + break; + case PCI_BHLC_REG: + conf_data = + (PCI_NONE_BIST << 24) | (PCI_NORMAL_HEADER_TYPE << 16) + | (0x00 << 8) + | PCI_NORMAL_CACHE_LINE_SIZE; + break; + case PCI_BAR0_REG: + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + if (lo & SOFT_BAR_UDC_FLAG) { + conf_data = CS5536_UDC_RANGE | PCI_MAPREG_TYPE_MEM; + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo &= ~SOFT_BAR_UDC_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + } else { + _rdmsr(USB_MSR_REG(USB_UDC), &hi, &lo); + conf_data = lo & 0xfffff000; + conf_data &= ~0x0000000f; /* 32bit mem */ + } + break; + case PCI_BAR1_REG: + conf_data = 0x000000; + break; + case PCI_BAR2_REG: + conf_data = 0x000000; + break; + case PCI_BAR3_REG: + conf_data = 0x000000; + break; + case PCI_BAR4_REG: + conf_data = 0x000000; + break; + case PCI_BAR5_REG: + conf_data = 0x000000; + break; + case PCI_CARDBUS_CIS_REG: + conf_data = PCI_CARDBUS_CIS_POINTER; + break; + case PCI_SUBSYS_ID_REG: + conf_data = (CS5536_UDC_SUB_ID << 16) | CS5536_SUB_VENDOR_ID; + break; + case PCI_MAPREG_ROM: + conf_data = PCI_EXPANSION_ROM_BAR; + break; + case PCI_CAPLISTPTR_REG: + conf_data = PCI_CAPLIST_USB_POINTER; + break; + case PCI_INTERRUPT_REG: + conf_data = + (PCI_MAX_LATENCY << 24) | (PCI_MIN_GRANT << 16) | + (PCI_DEFAULT_PIN << 8) | (CS5536_USB_INTR); + break; + default: + conf_data = 0; + break; + } + + return conf_data; +} + +#else /* TEST_CS5536_USE_UDC */ + +static void pci_udc_write_reg(int reg, u32 value) +{ + return; +} + +static u32 pci_udc_read_reg(int reg) +{ + return 0xffffffff; +} + +#endif /* TEST_CS5536_USE_UDC */ + +#ifdef TEST_CS5536_USE_OTG +static void pci_otg_write_reg(int reg, u32 value) +{ + u32 hi, lo; + + switch (reg) { + case PCI_COMMAND_STATUS_REG: + /* command */ + if (value & PCI_COMMAND_MEM_ENABLE) { + _rdmsr(USB_MSR_REG(USB_OTG), &hi, &lo); + hi |= (1 << 1); + _wrmsr(USB_MSR_REG(USB_OTG), hi, lo); + } else { + _rdmsr(USB_MSR_REG(USB_OTG), &hi, &lo); + hi &= ~(1 << 1); + _wrmsr(USB_MSR_REG(USB_OTG), hi, lo); + } + /* status */ + if (value & PCI_STATUS_PARITY_ERROR) { + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + if (lo & SB_PARE_ERR_FLAG) { + lo = (lo & 0x0000ffff) | SB_PARE_ERR_FLAG; + _wrmsr(SB_MSR_REG(SB_ERROR), hi, lo); + } + } + break; + case PCI_BAR0_REG: + if (value == PCI_BAR_RANGE_MASK) { + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo |= SOFT_BAR_OTG_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + } else if ((value & 0x01) == 0x00) { + _rdmsr(USB_MSR_REG(USB_OTG), &hi, &lo); + lo = value & 0xffffff00; + _wrmsr(USB_MSR_REG(USB_OTG), hi, lo); + + value &= 0xfffffff0; + hi = 0x40000000 | ((value & 0xff000000) >> 24); + lo = 0x000fffff | ((value & 0x00fff000) << 8); + _wrmsr(GLIU_MSR_REG(GLIU_P2D_BM1), hi, lo); + } + break; + default: + break; + } + + return; +} + +static u32 pci_otg_read_reg(int reg) +{ + u32 conf_data; + u32 hi, lo; + + switch (reg) { + case PCI_ID_REG: + conf_data = (CS5536_OTG_DEVICE_ID << 16 | CS5536_VENDOR_ID); + break; + case PCI_COMMAND_STATUS_REG: + conf_data = 0; + /* command */ + _rdmsr(USB_MSR_REG(USB_OTG), &hi, &lo); + if (hi & 0x02) + conf_data |= PCI_COMMAND_MEM_ENABLE; + /* status */ + conf_data |= PCI_STATUS_66MHZ_SUPPORT; + conf_data |= PCI_STATUS_BACKTOBACK_SUPPORT; + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + if (lo & SB_PARE_ERR_FLAG) + conf_data |= PCI_STATUS_PARITY_ERROR; + conf_data |= PCI_STATUS_DEVSEL_MEDIUM; + break; + case PCI_CLASS_REG: + _rdmsr(USB_MSR_REG(USB_CAP), &hi, &lo); + conf_data = lo & 0x000000ff; + conf_data |= (CS5536_OTG_CLASS_CODE << 8); + break; + case PCI_BHLC_REG: + conf_data = + (PCI_NONE_BIST << 24) | (PCI_NORMAL_HEADER_TYPE << 16) + | (0x00 << 8) + | PCI_NORMAL_CACHE_LINE_SIZE; + break; + case PCI_BAR0_REG: + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + if (lo & SOFT_BAR_OTG_FLAG) { + conf_data = CS5536_OTG_RANGE | PCI_MAPREG_TYPE_MEM; + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo &= ~SOFT_BAR_OTG_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + } else { + _rdmsr(USB_MSR_REG(USB_OTG), &hi, &lo); + conf_data = lo & 0xffffff00; + conf_data &= ~0x0000000f; + } + break; + case PCI_BAR1_REG: + conf_data = 0x000000; + break; + case PCI_BAR2_REG: + conf_data = 0x000000; + break; + case PCI_BAR3_REG: + conf_data = 0x000000; + break; + case PCI_BAR4_REG: + conf_data = 0x000000; + break; + case PCI_BAR5_REG: + conf_data = 0x000000; + break; + case PCI_CARDBUS_CIS_REG: + conf_data = PCI_CARDBUS_CIS_POINTER; + break; + case PCI_SUBSYS_ID_REG: + conf_data = (CS5536_OTG_SUB_ID << 16) | CS5536_SUB_VENDOR_ID; + break; + case PCI_MAPREG_ROM: + conf_data = PCI_EXPANSION_ROM_BAR; + break; + case PCI_CAPLISTPTR_REG: + conf_data = PCI_CAPLIST_USB_POINTER; + break; + case PCI_INTERRUPT_REG: + conf_data = + (PCI_MAX_LATENCY << 24) | (PCI_MIN_GRANT << 16) | + (PCI_DEFAULT_PIN << 8) | (CS5536_USB_INTR); + break; + default: + conf_data = 0; + break; + } + + return conf_data; +} + +#else /* TEST_CS5536_USE_OTG */ + +static void pci_otg_write_reg(int reg, u32 value) +{ + return; +} + +static u32 pci_otg_read_reg(int reg) +{ + return 0xffffffff; +} + +#endif /* TEST_CS5536_USE_OTG */ + +/* read/write to PCI config space and transfer it to MSR write */ + +/* + * write to PCI config space and transfer it to MSR write. + */ +void cs5536_pci_conf_write4(int function, int reg, u32 value) +{ + /* some basic checking. */ + if ((function < CS5536_FUNC_START) || (function > CS5536_FUNC_END)) { + return; + } + if ((reg < 0) || (reg > 0x100) || ((reg & 0x03) != 0)) { + return; + } + + switch (function) { + case CS5536_ISA_FUNC: + pci_isa_write_reg(reg, value); + break; + case CS5536_FLASH_FUNC: + pci_flash_write_reg(reg, value); + break; + case CS5536_IDE_FUNC: + pci_ide_write_reg(reg, value); + break; + case CS5536_ACC_FUNC: + pci_acc_write_reg(reg, value); + break; + case CS5536_OHCI_FUNC: + pci_ohci_write_reg(reg, value); + break; + case CS5536_EHCI_FUNC: + pci_ehci_write_reg(reg, value); + break; + case CS5536_UDC_FUNC: + pci_udc_write_reg(reg, value); + break; + case CS5536_OTG_FUNC: + pci_otg_write_reg(reg, value); + break; + default: + break; + } + return; +} + +/* + * read PCI config space and transfer it to MSR access. + */ +u32 cs5536_pci_conf_read4(int function, int reg) +{ + u32 data = 0; + + /* some basic checking. */ + if ((function < CS5536_FUNC_START) || (function > CS5536_FUNC_END)) { + return 0; + } + if ((reg < 0) || ((reg & 0x03) != 0)) { + return 0; + } + if (reg > 0x100) + return 0xffffffff; + + switch (function) { + case CS5536_ISA_FUNC: + data = pci_isa_read_reg(reg); + break; + case CS5536_FLASH_FUNC: + data = pci_flash_read_reg(reg); + break; + case CS5536_IDE_FUNC: + data = pci_ide_read_reg(reg); + break; + case CS5536_ACC_FUNC: + data = pci_acc_read_reg(reg); + break; + case CS5536_OHCI_FUNC: + data = pci_ohci_read_reg(reg); + break; + case CS5536_EHCI_FUNC: + data = pci_ehci_read_reg(reg); + break; + case CS5536_UDC_FUNC: + data = pci_udc_read_reg(reg); + break; + case CS5536_OTG_FUNC: + data = pci_otg_read_reg(reg); + break; + default: + break; + } + return data; +} diff --git a/arch/mips/loongson/common/mem.c b/arch/mips/loongson/common/mem.c index 85de2dc..059d43f 100644 --- a/arch/mips/loongson/common/mem.c +++ b/arch/mips/loongson/common/mem.c @@ -11,6 +11,7 @@ #include <asm/bootinfo.h> +#include <loongson.h> #include <mem.h> extern unsigned int memsize, highmemsize; diff --git a/arch/mips/loongson/fuloong-2f/Makefile b/arch/mips/loongson/fuloong-2f/Makefile new file mode 100644 index 0000000..010b86c --- /dev/null +++ b/arch/mips/loongson/fuloong-2f/Makefile @@ -0,0 +1,5 @@ +# +# Makefile for fuloong-2f +# + +obj-y += irq.o reset.o diff --git a/arch/mips/loongson/fuloong-2f/irq.c b/arch/mips/loongson/fuloong-2f/irq.c new file mode 100644 index 0000000..94a4def --- /dev/null +++ b/arch/mips/loongson/fuloong-2f/irq.c @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology + * Author: Fuxin Zhang, zhangfx@xxxxxxxxxx + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include <linux/interrupt.h> + +#include <loongson.h> +#include <machine.h> + +inline int mach_i8259_irq(void) +{ + int irq, isr, imr; + + irq = -1; + + if ((LOONGSON_INTISR & LOONGSON_INTEN) & LOONGSON_INT_BIT_INT0) { + imr = inb(0x21) | (inb(0xa1) << 8); + isr = inb(0x20) | (inb(0xa0) << 8); + isr &= ~0x4; /* irq2 for cascade */ + isr &= ~imr; + irq = ffs(isr) - 1; + } + + return irq; +} + +extern void bonito_irqdispatch(void); +extern void i8259_irqdispatch(void); + +inline void mach_irq_dispatch(unsigned int pending) +{ + if (pending & CAUSEF_IP7) { + do_IRQ( LOONGSON_TIMER_IRQ ); + } else if (pending & CAUSEF_IP6) { /* North Bridge, Performance counter */ + do_IRQ( LOONGSON_PERFCNT_IRQ ); + bonito_irqdispatch(); + } else if (pending & CAUSEF_IP3) { /* CPU UART */ + do_IRQ( LOONGSON_UART_IRQ ); + } else if (pending & CAUSEF_IP2) { /* South Bridge */ + i8259_irqdispatch(); + } else { + spurious_interrupt(); + } +} + +void __init set_irq_trigger_mode(void) +{ + /* setup cs5536 as high level trigger */ + LOONGSON_INTPOL = LOONGSON_INT_BIT_INT0 | LOONGSON_INT_BIT_INT1; + LOONGSON_INTEDGE &= ~(LOONGSON_INT_BIT_INT0 | LOONGSON_INT_BIT_INT1); +} diff --git a/arch/mips/loongson/fuloong-2f/reset.c b/arch/mips/loongson/fuloong-2f/reset.c new file mode 100644 index 0000000..19a0941 --- /dev/null +++ b/arch/mips/loongson/fuloong-2f/reset.c @@ -0,0 +1,75 @@ +/* Board-specific reboot/shutdown routines + * + * Copyright (c) 2009 Philippe Vachon <philippe@xxxxxxxxx> + * + * Copyright (C) 2009 Lemote Inc. & Insititute of Computing Technology + * Author: Wu Zhangjin, wuzj@xxxxxxxxxx + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include <linux/io.h> +#include <linux/delay.h> +#include <linux/types.h> + +#include <loongson.h> + +/* cs5536 is the south bridge used by fuloong2f mini PC */ +#include <cs5536/cs5536.h> + +void inline mach_prepare_reboot(void) +{ + /* + * reset cpu to full speed, this is needed when enabling cpu frequency + * scalling + */ + LOONGSON_CHIPCFG0 |= 0x7; + + /* send a reset signal to south bridge. + * anyone of the following two methods works well. + * + * NOTE: if enable "Power Management" in kernel, rtl8169 will not reset + * normally with this reset operation and it will not work in PMON, but + * you can tyep halt command and then reboot, seems the hardware reset + * logic not work normally. + */ +#if 0 + { + u32 hi, lo; + _rdmsr(GLCP_MSR_REG(GLCP_SYS_RST), &hi, &lo); + lo |= 0x00000001; + _wrmsr(GLCP_MSR_REG(GLCP_SYS_RST), hi, lo); + } +#else + { + u32 hi, lo; + _rdmsr(DIVIL_MSR_REG(DIVIL_SOFT_RESET), &hi, &lo); + lo |= 0x00000001; + _wrmsr(DIVIL_MSR_REG(DIVIL_SOFT_RESET), hi, lo); + } +#endif +} + +void inline mach_prepare_shutdown(void) +{ + u32 hi, lo, val; + phys_addr_t gpio_base; + + _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_GPIO), &hi, &lo); + + gpio_base = mips_io_port_base | (lo & 0xff00); + + /* make cs5536 gpio13 output enable */ + val = (readl((u32 *) (gpio_base + GPIOL_OUT_EN)) & ~(1 << (16 + 13))) + | (1 << 13); + writel(val, (u32 *) (gpio_base + GPIOL_OUT_EN)); + mmiowb(); + /* make cs5536 gpio13 output low level voltage. */ + val = (readl((u32 *) (gpio_base + GPIOL_OUT_VAL)) & ~(1 << (13))) + | (1 << (16 + 13)); + writel(val, (u32 *) (gpio_base + GPIOL_OUT_VAL)); + mmiowb(); +} diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile index a0cc238..b96ed14 100644 --- a/arch/mips/pci/Makefile +++ b/arch/mips/pci/Makefile @@ -26,7 +26,8 @@ obj-$(CONFIG_MIPS_COBALT) += fixup-cobalt.o obj-$(CONFIG_SOC_AU1500) += fixup-au1000.o ops-au1000.o obj-$(CONFIG_SOC_AU1550) += fixup-au1000.o ops-au1000.o obj-$(CONFIG_SOC_PNX8550) += fixup-pnx8550.o ops-pnx8550.o -obj-$(CONFIG_LEMOTE_FULOONG2E) += fixup-fuloong2e.o ops-fuloong2e.o +obj-$(CONFIG_LEMOTE_FULOONG2E) += fixup-fuloong2e.o ops-loongson2.o +obj-$(CONFIG_LEMOTE_FULOONG2F) += fixup-fuloong2f.o ops-loongson2.o obj-$(CONFIG_MIPS_MALTA) += fixup-malta.o obj-$(CONFIG_PMC_MSP7120_GW) += fixup-pmcmsp.o ops-pmcmsp.o obj-$(CONFIG_PMC_MSP7120_EVAL) += fixup-pmcmsp.o ops-pmcmsp.o diff --git a/arch/mips/pci/fixup-fuloong2f.c b/arch/mips/pci/fixup-fuloong2f.c new file mode 100644 index 0000000..8118e91 --- /dev/null +++ b/arch/mips/pci/fixup-fuloong2f.c @@ -0,0 +1,189 @@ +/* + * Copyright (C) 2008 Lemote Technology + * Copyright (C) 2004 ICT CAS + * Author: Li xiaoyu, lixy@xxxxxxxxx + * + * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology + * Author: Fuxin Zhang, zhangfx@xxxxxxxxxx + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include <linux/init.h> +#include <linux/pci.h> + +#include <loongson.h> +#include <cs5536/cs5536.h> + +/* + * PCI interrupt pins + * + * These should not be changed, or you should consider loongson2f interrupt register and + * your pci card dispatch + */ +#define PCIA 4 +#define PCIB 5 +#define PCIC 6 +#define PCID 7 + +/* all the pci device has the PCIA pin, check the datasheet. */ +static char irq_tab[][5] __initdata = { + /* INTA INTB INTC INTD */ + {0, 0, 0, 0, 0}, /* 11: Unused */ + {0, 0, 0, 0, 0}, /* 12: Unused */ + {0, 0, 0, 0, 0}, /* 13: Unused */ + {0, 0, 0, 0, 0}, /* 14: Unused */ + {0, 0, 0, 0, 0}, /* 15: Unused */ + {0, 0, 0, 0, 0}, /* 16: Unused */ + {0, PCIA, 0, 0, 0}, /* 17: RTL8110-0 */ + {0, PCIB, 0, 0, 0}, /* 18: RTL8110-1 */ + {0, PCIC, 0, 0, 0}, /* 19: SiI3114 */ + {0, PCID, 0, 0, 0}, /* 20: 3-ports nec usb */ + {0, PCIA, PCIB, PCIC, PCID}, /* 21: PCI-SLOT */ + {0, 0, 0, 0, 0}, /* 22: Unused */ + {0, 0, 0, 0, 0}, /* 23: Unused */ + {0, 0, 0, 0, 0}, /* 24: Unused */ + {0, 0, 0, 0, 0}, /* 25: Unused */ + {0, 0, 0, 0, 0}, /* 26: Unused */ + {0, 0, 0, 0, 0}, /* 27: Unused */ +}; + +int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + int virq; + + if ((PCI_SLOT(dev->devfn) != (14)) && (PCI_SLOT(dev->devfn) < 32)) { + virq = irq_tab[slot][pin]; + printk("slot: %d, pin: %d, irq: %d\n", slot, pin, + virq + LOONGSON_IRQ_BASE); + if (virq != 0) + return (LOONGSON_IRQ_BASE + virq); + else + return 0; + } else if (PCI_SLOT(dev->devfn) == 14) { /* cs5536 */ + switch (PCI_FUNC(dev->devfn)) { + case 2: + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 14); + return 14; /* for IDE */ + case 3: + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 9); + return 9; /* for AUDIO */ + case 4: /* for OHCI */ + case 5: /* for EHCI */ + case 6: /* for UDC */ + case 7: /* for OTG */ + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 11); + return 11; + } + return dev->irq; + } else { + printk(" strange pci slot number.\n"); + return 0; + } +} + +/* Do platform specific device initialization at pci_enable_device() time */ +int pcibios_plat_dev_init(struct pci_dev *dev) +{ + return 0; +} + +/* CS5536 SPEC. fixup */ +static void __init loongson_cs5536_isa_fixup(struct pci_dev *pdev) +{ + /* the uart1 and uart2 interrupt in PIC is enabled as default */ + pci_write_config_dword(pdev, 0x50, 1); + pci_write_config_dword(pdev, 0x54, 1); + /* enable the pci MASTER ABORT/ TARGET ABORT etc. */ + /* pci_write_config_dword(pdev, 0x58, 1); */ + return; +} + +static void __init loongson_cs5536_ide_fixup(struct pci_dev *pdev) +{ + /* setting the mutex pin as IDE function */ + /* the IDE interrupt in PIC is enabled as default */ + pci_write_config_dword(pdev, 0x40, 0xDEADBEEF); + return; +} + +static void __init loongson_cs5536_acc_fixup(struct pci_dev *pdev) +{ + u8 val; + + /* enable the AUDIO interrupt in PIC */ + pci_write_config_dword(pdev, 0x50, 1); + +#if 1 + pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &val); + printk("cs5536 acc latency %x\n", val); + pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xc0); +#endif + return; +} + +static void __init loongson_cs5536_ohci_fixup(struct pci_dev *pdev) +{ + /* enable the OHCI interrupt in PIC */ + /* THE OHCI, EHCI, UDC, OTG are shared with interrupt in PIC */ + pci_write_config_dword(pdev, 0x50, 1); + return; +} + +static void __init loongson_cs5536_ehci_fixup(struct pci_dev *pdev) +{ + u32 hi, lo; + + /* Serial short detect enable */ + _rdmsr(USB_MSR_REG(USB_CONFIG), &hi, &lo); + _wrmsr(USB_MSR_REG(USB_CONFIG), (1 << 1) | (1 << 2) | (1 << 3), lo); + +#if 0 + { + u32 bar; + void __iomem *base; + + /* Write to clear diag register */ + _rdmsr(USB_MSR_REG(USB_DIAG), &hi, &lo); + _wrmsr(USB_MSR_REG(USB_DIAG), hi, lo); + + pci_read_config_dword(pdev, 0x10, &bar); + base = ioremap_nocache(bar, 0x100); + + /* Make HCCAPARMS writable */ + writel(readl(base + 0xA0) | (1 << 1), (base + 0xA0)); + + /* EECP=50h, IST=01h, ASPC=1h */ + writel(0x00000012, base + 0x08); + iounmap(base); + } +#endif + + /* setting the USB2.0 micro frame length */ + pci_write_config_dword(pdev, 0x60, 0x2000); + return; +} + +static void __init loongson_nec_fixup(struct pci_dev *pdev) +{ + unsigned int val; + + pci_read_config_dword(pdev, 0xe0, &val); + /* Only 2 port be used */ + pci_write_config_dword(pdev, 0xe0, (val & ~3) | 0x2); +} + +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA, + loongson_cs5536_isa_fixup); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_OHC, + loongson_cs5536_ohci_fixup); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_EHC, + loongson_cs5536_ehci_fixup); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_AUDIO, + loongson_cs5536_acc_fixup); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_IDE, + loongson_cs5536_ide_fixup); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_USB, + loongson_nec_fixup); diff --git a/arch/mips/pci/ops-fuloong2e.c b/arch/mips/pci/ops-fuloong2e.c deleted file mode 100644 index dbcc1eb..0000000 --- a/arch/mips/pci/ops-fuloong2e.c +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright (C) 1999, 2000, 2004 MIPS Technologies, Inc. - * All rights reserved. - * Authors: Carsten Langgaard <carstenl@xxxxxxxx> - * Maciej W. Rozycki <macro@xxxxxxxx> - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * MIPS boards specific PCI support. - */ -#include <linux/types.h> -#include <linux/pci.h> -#include <linux/kernel.h> -#include <linux/init.h> - -#include <loongson.h> - -#define PCI_ACCESS_READ 0 -#define PCI_ACCESS_WRITE 1 - -#define CFG_SPACE_REG(offset) (void *)CKSEG1ADDR(LOONGSON_PCICFG_BASE | (offset)) -#define ID_SEL_BEGIN 11 -#define MAX_DEV_NUM (31 - ID_SEL_BEGIN) - - -static int loongson_pcibios_config_access(unsigned char access_type, - struct pci_bus *bus, - unsigned int devfn, int where, - u32 * data) -{ - u32 busnum = bus->number; - u32 addr, type; - u32 dummy; - void *addrp; - int device = PCI_SLOT(devfn); - int function = PCI_FUNC(devfn); - int reg = where & ~3; - - if (busnum == 0) { - /* Type 0 configuration for onboard PCI bus */ - if (device > MAX_DEV_NUM) - return -1; - - addr = (1 << (device + ID_SEL_BEGIN)) | (function << 8) | reg; - type = 0; - } else { - /* Type 1 configuration for offboard PCI bus */ - addr = (busnum << 16) | (device << 11) | (function << 8) | reg; - type = 0x10000; - } - - /* Clear aborts */ - LOONGSON_PCICMD |= LOONGSON_PCICMD_MABORT_CLR | LOONGSON_PCICMD_MTABORT_CLR; - - LOONGSON_PCIMAP_CFG = (addr >> 16) | type; - - /* Flush Bonito register block */ - dummy = LOONGSON_PCIMAP_CFG; - mmiowb(); - - addrp = CFG_SPACE_REG(addr & 0xffff); - if (access_type == PCI_ACCESS_WRITE) { - writel(cpu_to_le32(*data), addrp); - } else { - *data = le32_to_cpu(readl(addrp)); - } - - /* Detect Master/Target abort */ - if (LOONGSON_PCICMD & (LOONGSON_PCICMD_MABORT_CLR | - LOONGSON_PCICMD_MTABORT_CLR)) { - /* Error occurred */ - - /* Clear bits */ - LOONGSON_PCICMD |= (LOONGSON_PCICMD_MABORT_CLR | - LOONGSON_PCICMD_MTABORT_CLR); - - return -1; - } - - return 0; - -} - - -/* - * We can't address 8 and 16 bit words directly. Instead we have to - * read/write a 32bit word and mask/modify the data we actually want. - */ -static int loongson_pcibios_read(struct pci_bus *bus, unsigned int devfn, - int where, int size, u32 * val) -{ - u32 data = 0; - - if ((size == 2) && (where & 1)) - return PCIBIOS_BAD_REGISTER_NUMBER; - else if ((size == 4) && (where & 3)) - return PCIBIOS_BAD_REGISTER_NUMBER; - - if (loongson_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, where, - &data)) - return -1; - - if (size == 1) - *val = (data >> ((where & 3) << 3)) & 0xff; - else if (size == 2) - *val = (data >> ((where & 3) << 3)) & 0xffff; - else - *val = data; - - return PCIBIOS_SUCCESSFUL; -} - -static int loongson_pcibios_write(struct pci_bus *bus, unsigned int devfn, - int where, int size, u32 val) -{ - u32 data = 0; - - if ((size == 2) && (where & 1)) - return PCIBIOS_BAD_REGISTER_NUMBER; - else if ((size == 4) && (where & 3)) - return PCIBIOS_BAD_REGISTER_NUMBER; - - if (size == 4) - data = val; - else { - if (loongson_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, - where, &data)) - return -1; - - if (size == 1) - data = (data & ~(0xff << ((where & 3) << 3))) | - (val << ((where & 3) << 3)); - else if (size == 2) - data = (data & ~(0xffff << ((where & 3) << 3))) | - (val << ((where & 3) << 3)); - } - - if (loongson_pcibios_config_access(PCI_ACCESS_WRITE, bus, devfn, where, - &data)) - return -1; - - return PCIBIOS_SUCCESSFUL; -} - -struct pci_ops loongson_pci_ops = { - .read = loongson_pcibios_read, - .write = loongson_pcibios_write -}; diff --git a/arch/mips/pci/ops-loongson2.c b/arch/mips/pci/ops-loongson2.c new file mode 100644 index 0000000..a391307 --- /dev/null +++ b/arch/mips/pci/ops-loongson2.c @@ -0,0 +1,210 @@ +/* + * Copyright (C) 1999, 2000, 2004 MIPS Technologies, Inc. + * All rights reserved. + * Authors: Carsten Langgaard <carstenl@xxxxxxxx> + * Maciej W. Rozycki <macro@xxxxxxxx> + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * MIPS boards specific PCI support. + */ +#include <linux/types.h> +#include <linux/pci.h> +#include <linux/kernel.h> +#include <linux/init.h> + +#include <loongson.h> + +#ifdef CONFIG_CS5536 +#include <cs5536/cs5536_pci.h> +#endif + +#define PCI_ACCESS_READ 0 +#define PCI_ACCESS_WRITE 1 + +#define CFG_SPACE_REG(offset) (void *)CKSEG1ADDR(LOONGSON_PCICFG_BASE | (offset)) +#define ID_SEL_BEGIN 11 +#define MAX_DEV_NUM (31 - ID_SEL_BEGIN) + + +static int loongson_pcibios_config_access(unsigned char access_type, + struct pci_bus *bus, + unsigned int devfn, int where, + u32 * data) +{ + u32 busnum = bus->number; + u32 addr, type; + u32 dummy; + void *addrp; + int device = PCI_SLOT(devfn); + int function = PCI_FUNC(devfn); + int reg = where & ~3; + + if (busnum == 0) { + /* board-specific parts, currently, only fuloong2f,yeeloong2f use CS5536, + fuloong2e use via686b */ +#ifdef CONFIG_CS5536 + /* + * CS5536 PCI ACCESS ROUTINE, Note the functions circle call: + * loongson_pcibios_config_access()--->cs5536_pci_conf_read/write4()---> + * _rdmsr/_wrmsr()--->loongson_pcibios_read/write() + */ + if ((PCI_OPS_CS5536_IDSEL == device) && (reg < 0xF0)) { + switch (access_type) { + case PCI_ACCESS_READ: + *data = cs5536_pci_conf_read4(function, reg); + break; + case PCI_ACCESS_WRITE: + cs5536_pci_conf_write4(function, reg, *data); + break; + } + return 0; + } +#endif + /* Type 0 configuration for onboard PCI bus */ + if (device > MAX_DEV_NUM) + return -1; + + addr = (1 << (device + ID_SEL_BEGIN)) | (function << 8) | reg; + type = 0; + } else { + /* Type 1 configuration for offboard PCI bus */ + addr = (busnum << 16) | (device << 11) | (function << 8) | reg; + type = 0x10000; + } + + /* Clear aborts */ + LOONGSON_PCICMD |= LOONGSON_PCICMD_MABORT_CLR | LOONGSON_PCICMD_MTABORT_CLR; + + LOONGSON_PCIMAP_CFG = (addr >> 16) | type; + + /* Flush Bonito register block */ + dummy = LOONGSON_PCIMAP_CFG; + mmiowb(); + + addrp = CFG_SPACE_REG(addr & 0xffff); + if (access_type == PCI_ACCESS_WRITE) { + writel(cpu_to_le32(*data), addrp); + } else { + *data = le32_to_cpu(readl(addrp)); + } + + /* Detect Master/Target abort */ + if (LOONGSON_PCICMD & (LOONGSON_PCICMD_MABORT_CLR | + LOONGSON_PCICMD_MTABORT_CLR)) { + /* Error occurred */ + + /* Clear bits */ + LOONGSON_PCICMD |= (LOONGSON_PCICMD_MABORT_CLR | + LOONGSON_PCICMD_MTABORT_CLR); + + return -1; + } + + return 0; + +} + + +/* + * We can't address 8 and 16 bit words directly. Instead we have to + * read/write a 32bit word and mask/modify the data we actually want. + */ +static int loongson_pcibios_read(struct pci_bus *bus, unsigned int devfn, + int where, int size, u32 * val) +{ + u32 data = 0; + + if ((size == 2) && (where & 1)) + return PCIBIOS_BAD_REGISTER_NUMBER; + else if ((size == 4) && (where & 3)) + return PCIBIOS_BAD_REGISTER_NUMBER; + + if (loongson_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, where, + &data)) + return -1; + + if (size == 1) + *val = (data >> ((where & 3) << 3)) & 0xff; + else if (size == 2) + *val = (data >> ((where & 3) << 3)) & 0xffff; + else + *val = data; + + return PCIBIOS_SUCCESSFUL; +} + +static int loongson_pcibios_write(struct pci_bus *bus, unsigned int devfn, + int where, int size, u32 val) +{ + u32 data = 0; + + if ((size == 2) && (where & 1)) + return PCIBIOS_BAD_REGISTER_NUMBER; + else if ((size == 4) && (where & 3)) + return PCIBIOS_BAD_REGISTER_NUMBER; + + if (size == 4) + data = val; + else { + if (loongson_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, + where, &data)) + return -1; + + if (size == 1) + data = (data & ~(0xff << ((where & 3) << 3))) | + (val << ((where & 3) << 3)); + else if (size == 2) + data = (data & ~(0xffff << ((where & 3) << 3))) | + (val << ((where & 3) << 3)); + } + + if (loongson_pcibios_config_access(PCI_ACCESS_WRITE, bus, devfn, where, + &data)) + return -1; + + return PCIBIOS_SUCCESSFUL; +} + +struct pci_ops loongson_pci_ops = { + .read = loongson_pcibios_read, + .write = loongson_pcibios_write +}; + +#ifdef CONFIG_CS5536 +void _rdmsr(u32 msr, u32 * hi, u32 * lo) +{ + struct pci_bus bus = { + .number = 0 + }; + u32 devfn = PCI_DEVFN(PCI_OPS_CS5536_IDSEL, 0); + loongson_pcibios_write(&bus, devfn, 0xf4, 4, msr); + loongson_pcibios_read(&bus, devfn, 0xf8, 4, lo); + loongson_pcibios_read(&bus, devfn, 0xfc, 4, hi); +} + +void _wrmsr(u32 msr, u32 hi, u32 lo) +{ + struct pci_bus bus = { + .number = 0 + }; + u32 devfn = PCI_DEVFN(PCI_OPS_CS5536_IDSEL, 0); + loongson_pcibios_write(&bus, devfn, 0xf4, 4, msr); + loongson_pcibios_write(&bus, devfn, 0xf8, 4, lo); + loongson_pcibios_write(&bus, devfn, 0xfc, 4, hi); +} + +EXPORT_SYMBOL(_rdmsr); +EXPORT_SYMBOL(_wrmsr); +#endif -- 1.6.2.1