Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
  1#include <linux/types.h>
  2#include <linux/pci.h>
  3#include <linux/kernel.h>
  4
  5#include <asm/mips-boards/bonito64.h>
  6
  7#include <loongson.h>
  8
  9#define PCI_ACCESS_READ  0
 10#define PCI_ACCESS_WRITE 1
 11
 12#define HT1LO_PCICFG_BASE      0x1a000000
 13#define HT1LO_PCICFG_BASE_TP1  0x1b000000
 14
 15static int loongson3_pci_config_access(unsigned char access_type,
 16		struct pci_bus *bus, unsigned int devfn,
 17		int where, u32 *data)
 18{
 19	unsigned char busnum = bus->number;
 20	u_int64_t addr, type;
 21	void *addrp;
 22	int device = PCI_SLOT(devfn);
 23	int function = PCI_FUNC(devfn);
 24	int reg = where & ~3;
 25
 26	addr = (busnum << 16) | (device << 11) | (function << 8) | reg;
 27	if (busnum == 0) {
 28		if (device > 31)
 29			return PCIBIOS_DEVICE_NOT_FOUND;
 30		addrp = (void *)(TO_UNCAC(HT1LO_PCICFG_BASE) | (addr & 0xffff));
 31		type = 0;
 32
 33	} else {
 34		addrp = (void *)(TO_UNCAC(HT1LO_PCICFG_BASE_TP1) | (addr));
 35		type = 0x10000;
 36	}
 37
 38	if (access_type == PCI_ACCESS_WRITE)
 39		writel(*data, addrp);
 40	else {
 41		*data = readl(addrp);
 42		if (*data == 0xffffffff) {
 43			*data = -1;
 44			return PCIBIOS_DEVICE_NOT_FOUND;
 45		}
 46	}
 47	return PCIBIOS_SUCCESSFUL;
 48}
 49
 50static int loongson3_pci_pcibios_read(struct pci_bus *bus, unsigned int devfn,
 51				 int where, int size, u32 *val)
 52{
 53	u32 data = 0;
 54	int ret = loongson3_pci_config_access(PCI_ACCESS_READ,
 55			bus, devfn, where, &data);
 56
 57	if (ret != PCIBIOS_SUCCESSFUL)
 58		return ret;
 59
 60	if (size == 1)
 61		*val = (data >> ((where & 3) << 3)) & 0xff;
 62	else if (size == 2)
 63		*val = (data >> ((where & 3) << 3)) & 0xffff;
 64	else
 65		*val = data;
 66
 67	return PCIBIOS_SUCCESSFUL;
 68}
 69
 70static int loongson3_pci_pcibios_write(struct pci_bus *bus, unsigned int devfn,
 71				  int where, int size, u32 val)
 72{
 73	u32 data = 0;
 74	int ret;
 75
 76	if (size == 4)
 77		data = val;
 78	else {
 79		ret = loongson3_pci_config_access(PCI_ACCESS_READ,
 80				bus, devfn, where, &data);
 81		if (ret != PCIBIOS_SUCCESSFUL)
 82			return ret;
 83
 84		if (size == 1)
 85			data = (data & ~(0xff << ((where & 3) << 3))) |
 86			    (val << ((where & 3) << 3));
 87		else if (size == 2)
 88			data = (data & ~(0xffff << ((where & 3) << 3))) |
 89			    (val << ((where & 3) << 3));
 90	}
 91
 92	ret = loongson3_pci_config_access(PCI_ACCESS_WRITE,
 93			bus, devfn, where, &data);
 94
 95	return ret;
 96}
 97
 98struct pci_ops loongson_pci_ops = {
 99	.read = loongson3_pci_pcibios_read,
100	.write = loongson3_pci_pcibios_write
101};