xref: /linux/arch/mips/loongson2ef/common/cs5536/cs5536_isa.c (revision 1ac731c529cd4d6adbce134754b51ff7d822b145)
171e2f4ddSJiaxun Yang // SPDX-License-Identifier: GPL-2.0-or-later
271e2f4ddSJiaxun Yang /*
371e2f4ddSJiaxun Yang  * the ISA Virtual Support Module of AMD CS5536
471e2f4ddSJiaxun Yang  *
571e2f4ddSJiaxun Yang  * Copyright (C) 2007 Lemote, Inc.
671e2f4ddSJiaxun Yang  * Author : jlliu, liujl@lemote.com
771e2f4ddSJiaxun Yang  *
871e2f4ddSJiaxun Yang  * Copyright (C) 2009 Lemote, Inc.
971e2f4ddSJiaxun Yang  * Author: Wu Zhangjin, wuzhangjin@gmail.com
1071e2f4ddSJiaxun Yang  */
1171e2f4ddSJiaxun Yang 
1271e2f4ddSJiaxun Yang #include <linux/pci.h>
1371e2f4ddSJiaxun Yang #include <cs5536/cs5536.h>
1471e2f4ddSJiaxun Yang #include <cs5536/cs5536_pci.h>
1571e2f4ddSJiaxun Yang 
1671e2f4ddSJiaxun Yang /* common variables for PCI_ISA_READ/WRITE_BAR */
1771e2f4ddSJiaxun Yang static const u32 divil_msr_reg[6] = {
1871e2f4ddSJiaxun Yang 	DIVIL_MSR_REG(DIVIL_LBAR_SMB), DIVIL_MSR_REG(DIVIL_LBAR_GPIO),
1971e2f4ddSJiaxun Yang 	DIVIL_MSR_REG(DIVIL_LBAR_MFGPT), DIVIL_MSR_REG(DIVIL_LBAR_IRQ),
2071e2f4ddSJiaxun Yang 	DIVIL_MSR_REG(DIVIL_LBAR_PMS), DIVIL_MSR_REG(DIVIL_LBAR_ACPI),
2171e2f4ddSJiaxun Yang };
2271e2f4ddSJiaxun Yang 
2371e2f4ddSJiaxun Yang static const u32 soft_bar_flag[6] = {
2471e2f4ddSJiaxun Yang 	SOFT_BAR_SMB_FLAG, SOFT_BAR_GPIO_FLAG, SOFT_BAR_MFGPT_FLAG,
2571e2f4ddSJiaxun Yang 	SOFT_BAR_IRQ_FLAG, SOFT_BAR_PMS_FLAG, SOFT_BAR_ACPI_FLAG,
2671e2f4ddSJiaxun Yang };
2771e2f4ddSJiaxun Yang 
2871e2f4ddSJiaxun Yang static const u32 sb_msr_reg[6] = {
2971e2f4ddSJiaxun Yang 	SB_MSR_REG(SB_R0), SB_MSR_REG(SB_R1), SB_MSR_REG(SB_R2),
3071e2f4ddSJiaxun Yang 	SB_MSR_REG(SB_R3), SB_MSR_REG(SB_R4), SB_MSR_REG(SB_R5),
3171e2f4ddSJiaxun Yang };
3271e2f4ddSJiaxun Yang 
3371e2f4ddSJiaxun Yang static const u32 bar_space_range[6] = {
3471e2f4ddSJiaxun Yang 	CS5536_SMB_RANGE, CS5536_GPIO_RANGE, CS5536_MFGPT_RANGE,
3571e2f4ddSJiaxun Yang 	CS5536_IRQ_RANGE, CS5536_PMS_RANGE, CS5536_ACPI_RANGE,
3671e2f4ddSJiaxun Yang };
3771e2f4ddSJiaxun Yang 
3871e2f4ddSJiaxun Yang static const int bar_space_len[6] = {
3971e2f4ddSJiaxun Yang 	CS5536_SMB_LENGTH, CS5536_GPIO_LENGTH, CS5536_MFGPT_LENGTH,
4071e2f4ddSJiaxun Yang 	CS5536_IRQ_LENGTH, CS5536_PMS_LENGTH, CS5536_ACPI_LENGTH,
4171e2f4ddSJiaxun Yang };
4271e2f4ddSJiaxun Yang 
4371e2f4ddSJiaxun Yang /*
4471e2f4ddSJiaxun Yang  * enable the divil module bar space.
4571e2f4ddSJiaxun Yang  *
4671e2f4ddSJiaxun Yang  * For all the DIVIL module LBAR, you should control the DIVIL LBAR reg
4771e2f4ddSJiaxun Yang  * and the RCONFx(0~5) reg to use the modules.
4871e2f4ddSJiaxun Yang  */
divil_lbar_enable(void)4971e2f4ddSJiaxun Yang static void divil_lbar_enable(void)
5071e2f4ddSJiaxun Yang {
5171e2f4ddSJiaxun Yang 	u32 hi, lo;
5271e2f4ddSJiaxun Yang 	int offset;
5371e2f4ddSJiaxun Yang 
5471e2f4ddSJiaxun Yang 	/*
5571e2f4ddSJiaxun Yang 	 * The DIVIL IRQ is not used yet. and make the RCONF0 reserved.
5671e2f4ddSJiaxun Yang 	 */
5771e2f4ddSJiaxun Yang 
5871e2f4ddSJiaxun Yang 	for (offset = DIVIL_LBAR_SMB; offset <= DIVIL_LBAR_PMS; offset++) {
5971e2f4ddSJiaxun Yang 		_rdmsr(DIVIL_MSR_REG(offset), &hi, &lo);
6071e2f4ddSJiaxun Yang 		hi |= 0x01;
6171e2f4ddSJiaxun Yang 		_wrmsr(DIVIL_MSR_REG(offset), hi, lo);
6271e2f4ddSJiaxun Yang 	}
6371e2f4ddSJiaxun Yang }
6471e2f4ddSJiaxun Yang 
6571e2f4ddSJiaxun Yang /*
6671e2f4ddSJiaxun Yang  * disable the divil module bar space.
6771e2f4ddSJiaxun Yang  */
divil_lbar_disable(void)6871e2f4ddSJiaxun Yang static void divil_lbar_disable(void)
6971e2f4ddSJiaxun Yang {
7071e2f4ddSJiaxun Yang 	u32 hi, lo;
7171e2f4ddSJiaxun Yang 	int offset;
7271e2f4ddSJiaxun Yang 
7371e2f4ddSJiaxun Yang 	for (offset = DIVIL_LBAR_SMB; offset <= DIVIL_LBAR_PMS; offset++) {
7471e2f4ddSJiaxun Yang 		_rdmsr(DIVIL_MSR_REG(offset), &hi, &lo);
7571e2f4ddSJiaxun Yang 		hi &= ~0x01;
7671e2f4ddSJiaxun Yang 		_wrmsr(DIVIL_MSR_REG(offset), hi, lo);
7771e2f4ddSJiaxun Yang 	}
7871e2f4ddSJiaxun Yang }
7971e2f4ddSJiaxun Yang 
8071e2f4ddSJiaxun Yang /*
8171e2f4ddSJiaxun Yang  * BAR write: write value to the n BAR
8271e2f4ddSJiaxun Yang  */
8371e2f4ddSJiaxun Yang 
pci_isa_write_bar(int n,u32 value)8471e2f4ddSJiaxun Yang void pci_isa_write_bar(int n, u32 value)
8571e2f4ddSJiaxun Yang {
8671e2f4ddSJiaxun Yang 	u32 hi = 0, lo = value;
8771e2f4ddSJiaxun Yang 
8871e2f4ddSJiaxun Yang 	if (value == PCI_BAR_RANGE_MASK) {
8971e2f4ddSJiaxun Yang 		_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
9071e2f4ddSJiaxun Yang 		lo |= soft_bar_flag[n];
9171e2f4ddSJiaxun Yang 		_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
9271e2f4ddSJiaxun Yang 	} else if (value & 0x01) {
9371e2f4ddSJiaxun Yang 		/* NATIVE reg */
9471e2f4ddSJiaxun Yang 		hi = 0x0000f001;
9571e2f4ddSJiaxun Yang 		lo &= bar_space_range[n];
9671e2f4ddSJiaxun Yang 		_wrmsr(divil_msr_reg[n], hi, lo);
9771e2f4ddSJiaxun Yang 
9871e2f4ddSJiaxun Yang 		/* RCONFx is 4bytes in units for I/O space */
9971e2f4ddSJiaxun Yang 		hi = ((value & 0x000ffffc) << 12) |
10071e2f4ddSJiaxun Yang 		    ((bar_space_len[n] - 4) << 12) | 0x01;
10171e2f4ddSJiaxun Yang 		lo = ((value & 0x000ffffc) << 12) | 0x01;
10271e2f4ddSJiaxun Yang 		_wrmsr(sb_msr_reg[n], hi, lo);
10371e2f4ddSJiaxun Yang 	}
10471e2f4ddSJiaxun Yang }
10571e2f4ddSJiaxun Yang 
10671e2f4ddSJiaxun Yang /*
10771e2f4ddSJiaxun Yang  * BAR read: read the n BAR
10871e2f4ddSJiaxun Yang  */
10971e2f4ddSJiaxun Yang 
pci_isa_read_bar(int n)11071e2f4ddSJiaxun Yang u32 pci_isa_read_bar(int n)
11171e2f4ddSJiaxun Yang {
11271e2f4ddSJiaxun Yang 	u32 conf_data = 0;
11371e2f4ddSJiaxun Yang 	u32 hi, lo;
11471e2f4ddSJiaxun Yang 
11571e2f4ddSJiaxun Yang 	_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
11671e2f4ddSJiaxun Yang 	if (lo & soft_bar_flag[n]) {
11771e2f4ddSJiaxun Yang 		conf_data = bar_space_range[n] | PCI_BASE_ADDRESS_SPACE_IO;
11871e2f4ddSJiaxun Yang 		lo &= ~soft_bar_flag[n];
11971e2f4ddSJiaxun Yang 		_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
12071e2f4ddSJiaxun Yang 	} else {
12171e2f4ddSJiaxun Yang 		_rdmsr(divil_msr_reg[n], &hi, &lo);
12271e2f4ddSJiaxun Yang 		conf_data = lo & bar_space_range[n];
12371e2f4ddSJiaxun Yang 		conf_data |= 0x01;
12471e2f4ddSJiaxun Yang 		conf_data &= ~0x02;
12571e2f4ddSJiaxun Yang 	}
12671e2f4ddSJiaxun Yang 	return conf_data;
12771e2f4ddSJiaxun Yang }
12871e2f4ddSJiaxun Yang 
12971e2f4ddSJiaxun Yang /*
13071e2f4ddSJiaxun Yang  * isa_write: ISA write transfer
13171e2f4ddSJiaxun Yang  *
13271e2f4ddSJiaxun Yang  * We assume that this is not a bus master transfer.
13371e2f4ddSJiaxun Yang  */
pci_isa_write_reg(int reg,u32 value)13471e2f4ddSJiaxun Yang void pci_isa_write_reg(int reg, u32 value)
13571e2f4ddSJiaxun Yang {
13671e2f4ddSJiaxun Yang 	u32 hi = 0, lo = value;
13771e2f4ddSJiaxun Yang 	u32 temp;
13871e2f4ddSJiaxun Yang 
13971e2f4ddSJiaxun Yang 	switch (reg) {
14071e2f4ddSJiaxun Yang 	case PCI_COMMAND:
14171e2f4ddSJiaxun Yang 		if (value & PCI_COMMAND_IO)
14271e2f4ddSJiaxun Yang 			divil_lbar_enable();
14371e2f4ddSJiaxun Yang 		else
14471e2f4ddSJiaxun Yang 			divil_lbar_disable();
14571e2f4ddSJiaxun Yang 		break;
14671e2f4ddSJiaxun Yang 	case PCI_STATUS:
14771e2f4ddSJiaxun Yang 		_rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
14871e2f4ddSJiaxun Yang 		temp = lo & 0x0000ffff;
14971e2f4ddSJiaxun Yang 		if ((value & PCI_STATUS_SIG_TARGET_ABORT) &&
15071e2f4ddSJiaxun Yang 		    (lo & SB_TAS_ERR_EN))
15171e2f4ddSJiaxun Yang 			temp |= SB_TAS_ERR_FLAG;
15271e2f4ddSJiaxun Yang 
15371e2f4ddSJiaxun Yang 		if ((value & PCI_STATUS_REC_TARGET_ABORT) &&
15471e2f4ddSJiaxun Yang 		    (lo & SB_TAR_ERR_EN))
15571e2f4ddSJiaxun Yang 			temp |= SB_TAR_ERR_FLAG;
15671e2f4ddSJiaxun Yang 
15771e2f4ddSJiaxun Yang 		if ((value & PCI_STATUS_REC_MASTER_ABORT)
15871e2f4ddSJiaxun Yang 		    && (lo & SB_MAR_ERR_EN))
15971e2f4ddSJiaxun Yang 			temp |= SB_MAR_ERR_FLAG;
16071e2f4ddSJiaxun Yang 
16171e2f4ddSJiaxun Yang 		if ((value & PCI_STATUS_DETECTED_PARITY)
16271e2f4ddSJiaxun Yang 		    && (lo & SB_PARE_ERR_EN))
16371e2f4ddSJiaxun Yang 			temp |= SB_PARE_ERR_FLAG;
16471e2f4ddSJiaxun Yang 
16571e2f4ddSJiaxun Yang 		lo = temp;
16671e2f4ddSJiaxun Yang 		_wrmsr(SB_MSR_REG(SB_ERROR), hi, lo);
16771e2f4ddSJiaxun Yang 		break;
16871e2f4ddSJiaxun Yang 	case PCI_CACHE_LINE_SIZE:
16971e2f4ddSJiaxun Yang 		value &= 0x0000ff00;
17071e2f4ddSJiaxun Yang 		_rdmsr(SB_MSR_REG(SB_CTRL), &hi, &lo);
17171e2f4ddSJiaxun Yang 		hi &= 0xffffff00;
17271e2f4ddSJiaxun Yang 		hi |= (value >> 8);
17371e2f4ddSJiaxun Yang 		_wrmsr(SB_MSR_REG(SB_CTRL), hi, lo);
17471e2f4ddSJiaxun Yang 		break;
17571e2f4ddSJiaxun Yang 	case PCI_BAR0_REG:
17671e2f4ddSJiaxun Yang 		pci_isa_write_bar(0, value);
17771e2f4ddSJiaxun Yang 		break;
17871e2f4ddSJiaxun Yang 	case PCI_BAR1_REG:
17971e2f4ddSJiaxun Yang 		pci_isa_write_bar(1, value);
18071e2f4ddSJiaxun Yang 		break;
18171e2f4ddSJiaxun Yang 	case PCI_BAR2_REG:
18271e2f4ddSJiaxun Yang 		pci_isa_write_bar(2, value);
18371e2f4ddSJiaxun Yang 		break;
18471e2f4ddSJiaxun Yang 	case PCI_BAR3_REG:
18571e2f4ddSJiaxun Yang 		pci_isa_write_bar(3, value);
18671e2f4ddSJiaxun Yang 		break;
18771e2f4ddSJiaxun Yang 	case PCI_BAR4_REG:
18871e2f4ddSJiaxun Yang 		pci_isa_write_bar(4, value);
18971e2f4ddSJiaxun Yang 		break;
19071e2f4ddSJiaxun Yang 	case PCI_BAR5_REG:
19171e2f4ddSJiaxun Yang 		pci_isa_write_bar(5, value);
19271e2f4ddSJiaxun Yang 		break;
19371e2f4ddSJiaxun Yang 	case PCI_UART1_INT_REG:
19471e2f4ddSJiaxun Yang 		_rdmsr(DIVIL_MSR_REG(PIC_YSEL_HIGH), &hi, &lo);
19571e2f4ddSJiaxun Yang 		/* disable uart1 interrupt in PIC */
19671e2f4ddSJiaxun Yang 		lo &= ~(0xf << 24);
19771e2f4ddSJiaxun Yang 		if (value)	/* enable uart1 interrupt in PIC */
19871e2f4ddSJiaxun Yang 			lo |= (CS5536_UART1_INTR << 24);
19971e2f4ddSJiaxun Yang 		_wrmsr(DIVIL_MSR_REG(PIC_YSEL_HIGH), hi, lo);
20071e2f4ddSJiaxun Yang 		break;
20171e2f4ddSJiaxun Yang 	case PCI_UART2_INT_REG:
20271e2f4ddSJiaxun Yang 		_rdmsr(DIVIL_MSR_REG(PIC_YSEL_HIGH), &hi, &lo);
20371e2f4ddSJiaxun Yang 		/* disable uart2 interrupt in PIC */
20471e2f4ddSJiaxun Yang 		lo &= ~(0xf << 28);
20571e2f4ddSJiaxun Yang 		if (value)	/* enable uart2 interrupt in PIC */
20671e2f4ddSJiaxun Yang 			lo |= (CS5536_UART2_INTR << 28);
20771e2f4ddSJiaxun Yang 		_wrmsr(DIVIL_MSR_REG(PIC_YSEL_HIGH), hi, lo);
20871e2f4ddSJiaxun Yang 		break;
20971e2f4ddSJiaxun Yang 	case PCI_ISA_FIXUP_REG:
21071e2f4ddSJiaxun Yang 		if (value) {
21171e2f4ddSJiaxun Yang 			/* enable the TARGET ABORT/MASTER ABORT etc. */
21271e2f4ddSJiaxun Yang 			_rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
21371e2f4ddSJiaxun Yang 			lo |= 0x00000063;
21471e2f4ddSJiaxun Yang 			_wrmsr(SB_MSR_REG(SB_ERROR), hi, lo);
21571e2f4ddSJiaxun Yang 		}
216*f0e7c06fSJiaxun Yang 		break;
21771e2f4ddSJiaxun Yang 	default:
21871e2f4ddSJiaxun Yang 		/* ALL OTHER PCI CONFIG SPACE HEADER IS NOT IMPLEMENTED. */
21971e2f4ddSJiaxun Yang 		break;
22071e2f4ddSJiaxun Yang 	}
22171e2f4ddSJiaxun Yang }
22271e2f4ddSJiaxun Yang 
22371e2f4ddSJiaxun Yang /*
22471e2f4ddSJiaxun Yang  * isa_read: ISA read transfers
22571e2f4ddSJiaxun Yang  *
22671e2f4ddSJiaxun Yang  * We assume that this is not a bus master transfer.
22771e2f4ddSJiaxun Yang  */
pci_isa_read_reg(int reg)22871e2f4ddSJiaxun Yang u32 pci_isa_read_reg(int reg)
22971e2f4ddSJiaxun Yang {
23071e2f4ddSJiaxun Yang 	u32 conf_data = 0;
23171e2f4ddSJiaxun Yang 	u32 hi, lo;
23271e2f4ddSJiaxun Yang 
23371e2f4ddSJiaxun Yang 	switch (reg) {
23471e2f4ddSJiaxun Yang 	case PCI_VENDOR_ID:
23571e2f4ddSJiaxun Yang 		conf_data =
23671e2f4ddSJiaxun Yang 		    CFG_PCI_VENDOR_ID(CS5536_ISA_DEVICE_ID, CS5536_VENDOR_ID);
23771e2f4ddSJiaxun Yang 		break;
23871e2f4ddSJiaxun Yang 	case PCI_COMMAND:
23971e2f4ddSJiaxun Yang 		/* we just check the first LBAR for the IO enable bit, */
24071e2f4ddSJiaxun Yang 		/* maybe we should changed later. */
24171e2f4ddSJiaxun Yang 		_rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_SMB), &hi, &lo);
24271e2f4ddSJiaxun Yang 		if (hi & 0x01)
24371e2f4ddSJiaxun Yang 			conf_data |= PCI_COMMAND_IO;
24471e2f4ddSJiaxun Yang 		break;
24571e2f4ddSJiaxun Yang 	case PCI_STATUS:
24671e2f4ddSJiaxun Yang 		conf_data |= PCI_STATUS_66MHZ;
24771e2f4ddSJiaxun Yang 		conf_data |= PCI_STATUS_DEVSEL_MEDIUM;
24871e2f4ddSJiaxun Yang 		conf_data |= PCI_STATUS_FAST_BACK;
24971e2f4ddSJiaxun Yang 
25071e2f4ddSJiaxun Yang 		_rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
25171e2f4ddSJiaxun Yang 		if (lo & SB_TAS_ERR_FLAG)
25271e2f4ddSJiaxun Yang 			conf_data |= PCI_STATUS_SIG_TARGET_ABORT;
25371e2f4ddSJiaxun Yang 		if (lo & SB_TAR_ERR_FLAG)
25471e2f4ddSJiaxun Yang 			conf_data |= PCI_STATUS_REC_TARGET_ABORT;
25571e2f4ddSJiaxun Yang 		if (lo & SB_MAR_ERR_FLAG)
25671e2f4ddSJiaxun Yang 			conf_data |= PCI_STATUS_REC_MASTER_ABORT;
25771e2f4ddSJiaxun Yang 		if (lo & SB_PARE_ERR_FLAG)
25871e2f4ddSJiaxun Yang 			conf_data |= PCI_STATUS_DETECTED_PARITY;
25971e2f4ddSJiaxun Yang 		break;
26071e2f4ddSJiaxun Yang 	case PCI_CLASS_REVISION:
26171e2f4ddSJiaxun Yang 		_rdmsr(GLCP_MSR_REG(GLCP_CHIP_REV_ID), &hi, &lo);
26271e2f4ddSJiaxun Yang 		conf_data = lo & 0x000000ff;
26371e2f4ddSJiaxun Yang 		conf_data |= (CS5536_ISA_CLASS_CODE << 8);
26471e2f4ddSJiaxun Yang 		break;
26571e2f4ddSJiaxun Yang 	case PCI_CACHE_LINE_SIZE:
26671e2f4ddSJiaxun Yang 		_rdmsr(SB_MSR_REG(SB_CTRL), &hi, &lo);
26771e2f4ddSJiaxun Yang 		hi &= 0x000000f8;
26871e2f4ddSJiaxun Yang 		conf_data = CFG_PCI_CACHE_LINE_SIZE(PCI_BRIDGE_HEADER_TYPE, hi);
26971e2f4ddSJiaxun Yang 		break;
27071e2f4ddSJiaxun Yang 		/*
27171e2f4ddSJiaxun Yang 		 * we only use the LBAR of DIVIL, no RCONF used.
27271e2f4ddSJiaxun Yang 		 * all of them are IO space.
27371e2f4ddSJiaxun Yang 		 */
27471e2f4ddSJiaxun Yang 	case PCI_BAR0_REG:
27571e2f4ddSJiaxun Yang 		return pci_isa_read_bar(0);
27671e2f4ddSJiaxun Yang 		break;
27771e2f4ddSJiaxun Yang 	case PCI_BAR1_REG:
27871e2f4ddSJiaxun Yang 		return pci_isa_read_bar(1);
27971e2f4ddSJiaxun Yang 		break;
28071e2f4ddSJiaxun Yang 	case PCI_BAR2_REG:
28171e2f4ddSJiaxun Yang 		return pci_isa_read_bar(2);
28271e2f4ddSJiaxun Yang 		break;
28371e2f4ddSJiaxun Yang 	case PCI_BAR3_REG:
28471e2f4ddSJiaxun Yang 		break;
28571e2f4ddSJiaxun Yang 	case PCI_BAR4_REG:
28671e2f4ddSJiaxun Yang 		return pci_isa_read_bar(4);
28771e2f4ddSJiaxun Yang 		break;
28871e2f4ddSJiaxun Yang 	case PCI_BAR5_REG:
28971e2f4ddSJiaxun Yang 		return pci_isa_read_bar(5);
29071e2f4ddSJiaxun Yang 		break;
29171e2f4ddSJiaxun Yang 	case PCI_CARDBUS_CIS:
29271e2f4ddSJiaxun Yang 		conf_data = PCI_CARDBUS_CIS_POINTER;
29371e2f4ddSJiaxun Yang 		break;
29471e2f4ddSJiaxun Yang 	case PCI_SUBSYSTEM_VENDOR_ID:
29571e2f4ddSJiaxun Yang 		conf_data =
29671e2f4ddSJiaxun Yang 		    CFG_PCI_VENDOR_ID(CS5536_ISA_SUB_ID, CS5536_SUB_VENDOR_ID);
29771e2f4ddSJiaxun Yang 		break;
29871e2f4ddSJiaxun Yang 	case PCI_ROM_ADDRESS:
29971e2f4ddSJiaxun Yang 		conf_data = PCI_EXPANSION_ROM_BAR;
30071e2f4ddSJiaxun Yang 		break;
30171e2f4ddSJiaxun Yang 	case PCI_CAPABILITY_LIST:
30271e2f4ddSJiaxun Yang 		conf_data = PCI_CAPLIST_POINTER;
30371e2f4ddSJiaxun Yang 		break;
30471e2f4ddSJiaxun Yang 	case PCI_INTERRUPT_LINE:
30571e2f4ddSJiaxun Yang 		/* no interrupt used here */
30671e2f4ddSJiaxun Yang 		conf_data = CFG_PCI_INTERRUPT_LINE(0x00, 0x00);
30771e2f4ddSJiaxun Yang 		break;
30871e2f4ddSJiaxun Yang 	default:
30971e2f4ddSJiaxun Yang 		break;
31071e2f4ddSJiaxun Yang 	}
31171e2f4ddSJiaxun Yang 
31271e2f4ddSJiaxun Yang 	return conf_data;
31371e2f4ddSJiaxun Yang }
31471e2f4ddSJiaxun Yang 
31571e2f4ddSJiaxun Yang /*
31671e2f4ddSJiaxun Yang  * The mfgpt timer interrupt is running early, so we must keep the south bridge
31771e2f4ddSJiaxun Yang  * mmio always enabled. Otherwise we may race with the PCI configuration which
31871e2f4ddSJiaxun Yang  * may temporarily disable it. When that happens and the timer interrupt fires,
31971e2f4ddSJiaxun Yang  * we are not able to clear it and the system will hang.
32071e2f4ddSJiaxun Yang  */
cs5536_isa_mmio_always_on(struct pci_dev * dev)32171e2f4ddSJiaxun Yang static void cs5536_isa_mmio_always_on(struct pci_dev *dev)
32271e2f4ddSJiaxun Yang {
32371e2f4ddSJiaxun Yang 	dev->mmio_always_on = 1;
32471e2f4ddSJiaxun Yang }
32571e2f4ddSJiaxun Yang DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA,
32671e2f4ddSJiaxun Yang 	PCI_CLASS_BRIDGE_ISA, 8, cs5536_isa_mmio_always_on);
327