From: Wu Zhangjin <wuzhangjin@gmail.com>
To: linux-mips@linux-mips.org, Ralf Baechle <ralf@linux-mips.org>
Cc: Arnaud Patard <apatard@mandriva.com>,
loongson-dev@googlegroups.com, zhangfx@lemote.com,
yanh@lemote.com, Philippe Vachon <philippe@cowpig.ca>,
Zhang Le <r0bertz@gentoo.org>, Erwan Lerale <erwan@thiscow.com>
Subject: [PATCH 14/30] loongson: add basic fuloong(2f) support
Date: Sat, 16 May 2009 06:11:43 +0800 [thread overview]
Message-ID: <1242425503.10164.155.camel@falcon> (raw)
>From d34ce4df75cd3b101c909d5d3d3a6651a3f64656 Mon Sep 17 00:00:00 2001
From: Wu Zhangjin <wuzhangjin@gmail.com>
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@lemote.com>
+ */
+
+#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@lemote.com
+ */
+
+#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@lemote.com
+ *
+ * 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@lemote.com
+ *
+ * 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@cowpig.ca>
+ *
+ * Copyright (C) 2009 Lemote Inc. & Insititute of Computing Technology
+ * Author: Wu Zhangjin, wuzj@lemote.com
+ *
+ * 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@ict.ac.cn
+ *
+ * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology
+ * Author: Fuxin Zhang, zhangfx@lemote.com
+ *
+ * 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@mips.com>
- * Maciej W. Rozycki <macro@mips.com>
- *
- * 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@mips.com>
+ * Maciej W. Rozycki <macro@mips.com>
+ *
+ * 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
WARNING: multiple messages have this Message-ID (diff)
From: Wu Zhangjin <wuzhangjin@gmail.com>
To: linux-mips@linux-mips.org, Ralf Baechle <ralf@linux-mips.org>
Cc: Arnaud Patard <apatard@mandriva.com>,
loongson-dev@googlegroups.com, zhangfx@lemote.com,
yanh@lemote.com, Philippe Vachon <philippe@cowpig.ca>,
Zhang Le <r0bertz@gentoo.org>, Erwan Lerale <erwan@thiscow.com>
Subject: [PATCH 14/30] loongson: add basic fuloong(2f) support
Date: Sat, 16 May 2009 06:11:43 +0800 [thread overview]
Message-ID: <1242425503.10164.155.camel@falcon> (raw)
Message-ID: <20090515221143.GmjQYqinASejcjCfC4NtIOayiwu3Q-iqRfHD-x6Zlhw@z> (raw)
From d34ce4df75cd3b101c909d5d3d3a6651a3f64656 Mon Sep 17 00:00:00 2001
From: Wu Zhangjin <wuzhangjin@gmail.com>
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@lemote.com>
+ */
+
+#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@lemote.com
+ */
+
+#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@lemote.com
+ *
+ * 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@lemote.com
+ *
+ * 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@cowpig.ca>
+ *
+ * Copyright (C) 2009 Lemote Inc. & Insititute of Computing Technology
+ * Author: Wu Zhangjin, wuzj@lemote.com
+ *
+ * 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@ict.ac.cn
+ *
+ * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology
+ * Author: Fuxin Zhang, zhangfx@lemote.com
+ *
+ * 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@mips.com>
- * Maciej W. Rozycki <macro@mips.com>
- *
- * 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@mips.com>
+ * Maciej W. Rozycki <macro@mips.com>
+ *
+ * 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
next reply other threads:[~2009-05-15 22:12 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-05-15 22:11 Wu Zhangjin [this message]
2009-05-15 22:11 ` [PATCH 14/30] loongson: add basic fuloong(2f) support Wu Zhangjin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1242425503.10164.155.camel@falcon \
--to=wuzhangjin@gmail.com \
--cc=apatard@mandriva.com \
--cc=erwan@thiscow.com \
--cc=linux-mips@linux-mips.org \
--cc=loongson-dev@googlegroups.com \
--cc=philippe@cowpig.ca \
--cc=r0bertz@gentoo.org \
--cc=ralf@linux-mips.org \
--cc=yanh@lemote.com \
--cc=zhangfx@lemote.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.