arm64: dts: Revert "specify console via command line"
[linux/fpc-iii.git] / arch / mips / pci / ops-loongson3.c
blob2f6ad36bdea69b888955c550cc3a75b4927b7291
1 // SPDX-License-Identifier: GPL-2.0
2 #include <linux/types.h>
3 #include <linux/pci.h>
4 #include <linux/kernel.h>
6 #include <asm/mips-boards/bonito64.h>
8 #include <loongson.h>
10 #define PCI_ACCESS_READ 0
11 #define PCI_ACCESS_WRITE 1
13 #define HT1LO_PCICFG_BASE 0x1a000000
14 #define HT1LO_PCICFG_BASE_TP1 0x1b000000
16 static int loongson3_pci_config_access(unsigned char access_type,
17 struct pci_bus *bus, unsigned int devfn,
18 int where, u32 *data)
20 unsigned char busnum = bus->number;
21 int function = PCI_FUNC(devfn);
22 int device = PCI_SLOT(devfn);
23 int reg = where & ~3;
24 void *addrp;
25 u64 addr;
27 if (where < PCI_CFG_SPACE_SIZE) { /* standard config */
28 addr = (busnum << 16) | (device << 11) | (function << 8) | reg;
29 if (busnum == 0) {
30 if (device > 31)
31 return PCIBIOS_DEVICE_NOT_FOUND;
32 addrp = (void *)TO_UNCAC(HT1LO_PCICFG_BASE | addr);
33 } else {
34 addrp = (void *)TO_UNCAC(HT1LO_PCICFG_BASE_TP1 | addr);
36 } else if (where < PCI_CFG_SPACE_EXP_SIZE) { /* extended config */
37 struct pci_dev *rootdev;
39 rootdev = pci_get_domain_bus_and_slot(0, 0, 0);
40 if (!rootdev)
41 return PCIBIOS_DEVICE_NOT_FOUND;
43 addr = pci_resource_start(rootdev, 3);
44 if (!addr)
45 return PCIBIOS_DEVICE_NOT_FOUND;
47 addr |= busnum << 20 | device << 15 | function << 12 | reg;
48 addrp = (void *)TO_UNCAC(addr);
49 } else {
50 return PCIBIOS_DEVICE_NOT_FOUND;
53 if (access_type == PCI_ACCESS_WRITE)
54 writel(*data, addrp);
55 else {
56 *data = readl(addrp);
57 if (*data == 0xffffffff) {
58 *data = -1;
59 return PCIBIOS_DEVICE_NOT_FOUND;
62 return PCIBIOS_SUCCESSFUL;
65 static int loongson3_pci_pcibios_read(struct pci_bus *bus, unsigned int devfn,
66 int where, int size, u32 *val)
68 u32 data = 0;
69 int ret = loongson3_pci_config_access(PCI_ACCESS_READ,
70 bus, devfn, where, &data);
72 if (ret != PCIBIOS_SUCCESSFUL)
73 return ret;
75 if (size == 1)
76 *val = (data >> ((where & 3) << 3)) & 0xff;
77 else if (size == 2)
78 *val = (data >> ((where & 3) << 3)) & 0xffff;
79 else
80 *val = data;
82 return PCIBIOS_SUCCESSFUL;
85 static int loongson3_pci_pcibios_write(struct pci_bus *bus, unsigned int devfn,
86 int where, int size, u32 val)
88 u32 data = 0;
89 int ret;
91 if (size == 4)
92 data = val;
93 else {
94 ret = loongson3_pci_config_access(PCI_ACCESS_READ,
95 bus, devfn, where, &data);
96 if (ret != PCIBIOS_SUCCESSFUL)
97 return ret;
99 if (size == 1)
100 data = (data & ~(0xff << ((where & 3) << 3))) |
101 (val << ((where & 3) << 3));
102 else if (size == 2)
103 data = (data & ~(0xffff << ((where & 3) << 3))) |
104 (val << ((where & 3) << 3));
107 ret = loongson3_pci_config_access(PCI_ACCESS_WRITE,
108 bus, devfn, where, &data);
110 return ret;
113 struct pci_ops loongson_pci_ops = {
114 .read = loongson3_pci_pcibios_read,
115 .write = loongson3_pci_pcibios_write