Linux Audio

Check our new training course

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