171e2f4ddSJiaxun Yang // SPDX-License-Identifier: GPL-2.0-or-later
271e2f4ddSJiaxun Yang /*
371e2f4ddSJiaxun Yang  * read/write operation to the PCI config space of 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  *	the Virtual Support Module(VSM) for virtulizing the PCI
1271e2f4ddSJiaxun Yang  *	configure space are defined in cs5536_modulename.c respectively,
1371e2f4ddSJiaxun Yang  *
1471e2f4ddSJiaxun Yang  *	after this virtulizing, user can access the PCI configure space
1571e2f4ddSJiaxun Yang  *	directly as a normal multi-function PCI device which follows
1671e2f4ddSJiaxun Yang  *	the PCI-2.2 spec.
1771e2f4ddSJiaxun Yang  */
1871e2f4ddSJiaxun Yang 
1971e2f4ddSJiaxun Yang #include <linux/types.h>
2071e2f4ddSJiaxun Yang #include <cs5536/cs5536_pci.h>
2171e2f4ddSJiaxun Yang #include <cs5536/cs5536_vsm.h>
2271e2f4ddSJiaxun Yang 
2371e2f4ddSJiaxun Yang enum {
2471e2f4ddSJiaxun Yang 	CS5536_FUNC_START = -1,
2571e2f4ddSJiaxun Yang 	CS5536_ISA_FUNC,
2671e2f4ddSJiaxun Yang 	reserved_func,
2771e2f4ddSJiaxun Yang 	CS5536_IDE_FUNC,
2871e2f4ddSJiaxun Yang 	CS5536_ACC_FUNC,
2971e2f4ddSJiaxun Yang 	CS5536_OHCI_FUNC,
3071e2f4ddSJiaxun Yang 	CS5536_EHCI_FUNC,
3171e2f4ddSJiaxun Yang 	CS5536_FUNC_END,
3271e2f4ddSJiaxun Yang };
3371e2f4ddSJiaxun Yang 
3471e2f4ddSJiaxun Yang static const cs5536_pci_vsm_write vsm_conf_write[] = {
3571e2f4ddSJiaxun Yang 	[CS5536_ISA_FUNC]	= pci_isa_write_reg,
3671e2f4ddSJiaxun Yang 	[reserved_func]		= NULL,
3771e2f4ddSJiaxun Yang 	[CS5536_IDE_FUNC]	= pci_ide_write_reg,
3871e2f4ddSJiaxun Yang 	[CS5536_ACC_FUNC]	= pci_acc_write_reg,
3971e2f4ddSJiaxun Yang 	[CS5536_OHCI_FUNC]	= pci_ohci_write_reg,
4071e2f4ddSJiaxun Yang 	[CS5536_EHCI_FUNC]	= pci_ehci_write_reg,
4171e2f4ddSJiaxun Yang };
4271e2f4ddSJiaxun Yang 
4371e2f4ddSJiaxun Yang static const cs5536_pci_vsm_read vsm_conf_read[] = {
4471e2f4ddSJiaxun Yang 	[CS5536_ISA_FUNC]	= pci_isa_read_reg,
4571e2f4ddSJiaxun Yang 	[reserved_func]		= NULL,
4671e2f4ddSJiaxun Yang 	[CS5536_IDE_FUNC]	= pci_ide_read_reg,
4771e2f4ddSJiaxun Yang 	[CS5536_ACC_FUNC]	= pci_acc_read_reg,
4871e2f4ddSJiaxun Yang 	[CS5536_OHCI_FUNC]	= pci_ohci_read_reg,
4971e2f4ddSJiaxun Yang 	[CS5536_EHCI_FUNC]	= pci_ehci_read_reg,
5071e2f4ddSJiaxun Yang };
5171e2f4ddSJiaxun Yang 
5271e2f4ddSJiaxun Yang /*
5371e2f4ddSJiaxun Yang  * write to PCI config space and transfer it to MSR write.
5471e2f4ddSJiaxun Yang  */
cs5536_pci_conf_write4(int function,int reg,u32 value)5571e2f4ddSJiaxun Yang void cs5536_pci_conf_write4(int function, int reg, u32 value)
5671e2f4ddSJiaxun Yang {
5771e2f4ddSJiaxun Yang 	if ((function <= CS5536_FUNC_START) || (function >= CS5536_FUNC_END))
5871e2f4ddSJiaxun Yang 		return;
5971e2f4ddSJiaxun Yang 	if ((reg < 0) || (reg > 0x100) || ((reg & 0x03) != 0))
6071e2f4ddSJiaxun Yang 		return;
6171e2f4ddSJiaxun Yang 
6271e2f4ddSJiaxun Yang 	if (vsm_conf_write[function] != NULL)
6371e2f4ddSJiaxun Yang 		vsm_conf_write[function](reg, value);
6471e2f4ddSJiaxun Yang }
6571e2f4ddSJiaxun Yang 
6671e2f4ddSJiaxun Yang /*
6771e2f4ddSJiaxun Yang  * read PCI config space and transfer it to MSR access.
6871e2f4ddSJiaxun Yang  */
cs5536_pci_conf_read4(int function,int reg)6971e2f4ddSJiaxun Yang u32 cs5536_pci_conf_read4(int function, int reg)
7071e2f4ddSJiaxun Yang {
7171e2f4ddSJiaxun Yang 	u32 data = 0;
7271e2f4ddSJiaxun Yang 
7371e2f4ddSJiaxun Yang 	if ((function <= CS5536_FUNC_START) || (function >= CS5536_FUNC_END))
7471e2f4ddSJiaxun Yang 		return 0;
7571e2f4ddSJiaxun Yang 	if ((reg < 0) || ((reg & 0x03) != 0))
7671e2f4ddSJiaxun Yang 		return 0;
7771e2f4ddSJiaxun Yang 	if (reg > 0x100)
7871e2f4ddSJiaxun Yang 		return 0xffffffff;
7971e2f4ddSJiaxun Yang 
8071e2f4ddSJiaxun Yang 	if (vsm_conf_read[function] != NULL)
8171e2f4ddSJiaxun Yang 		data = vsm_conf_read[function](reg);
8271e2f4ddSJiaxun Yang 
8371e2f4ddSJiaxun Yang 	return data;
8471e2f4ddSJiaxun Yang }
85