Root/target/linux/ifxmips/files/arch/mips/pci/ops-ifxmips.c

1#include <linux/types.h>
2#include <linux/pci.h>
3#include <linux/kernel.h>
4#include <linux/init.h>
5#include <linux/delay.h>
6#include <linux/mm.h>
7#include <asm/addrspace.h>
8#include <linux/vmalloc.h>
9#include <ifxmips.h>
10#include <ifxmips_irq.h>
11#include <ifxmips_ebu.h>
12
13#define IFXMIPS_PCI_CFG_BUSNUM_SHF 16
14#define IFXMIPS_PCI_CFG_DEVNUM_SHF 11
15#define IFXMIPS_PCI_CFG_FUNNUM_SHF 8
16
17#define PCI_ACCESS_READ 0
18#define PCI_ACCESS_WRITE 1
19
20extern u32 ifxmips_pci_mapped_cfg;
21
22static int
23ifxmips_pci_config_access(unsigned char access_type,
24        struct pci_bus *bus, unsigned int devfn, unsigned int where, u32 *data)
25{
26    unsigned long cfg_base;
27    unsigned long flags;
28
29    u32 temp;
30
31    /* IFXMips support slot from 0 to 15 */
32    /* dev_fn 0&0x68 (AD29) is ifxmips itself */
33    if ((bus->number != 0) || ((devfn & 0xf8) > 0x78)
34            || ((devfn & 0xf8) == 0) || ((devfn & 0xf8) == 0x68))
35        return 1;
36
37    spin_lock_irqsave(&ebu_lock, flags);
38
39    cfg_base = ifxmips_pci_mapped_cfg;
40    cfg_base |= (bus->number << IFXMIPS_PCI_CFG_BUSNUM_SHF) | (devfn <<
41            IFXMIPS_PCI_CFG_FUNNUM_SHF) | (where & ~0x3);
42
43    /* Perform access */
44    if (access_type == PCI_ACCESS_WRITE)
45    {
46#ifdef CONFIG_SWAP_IO_SPACE
47        ifxmips_w32(swab32(*data), ((u32*)cfg_base));
48#else
49        ifxmips_w32(*data, ((u32*)cfg_base));
50#endif
51    } else {
52        *data = ifxmips_r32(((u32*)(cfg_base)));
53#ifdef CONFIG_SWAP_IO_SPACE
54        *data = swab32(*data);
55#endif
56    }
57    wmb();
58
59    /* clean possible Master abort */
60    cfg_base = (ifxmips_pci_mapped_cfg | (0x0 << IFXMIPS_PCI_CFG_FUNNUM_SHF)) + 4;
61    temp = ifxmips_r32(((u32*)(cfg_base)));
62#ifdef CONFIG_SWAP_IO_SPACE
63    temp = swab32 (temp);
64#endif
65    cfg_base = (ifxmips_pci_mapped_cfg | (0x68 << IFXMIPS_PCI_CFG_FUNNUM_SHF)) + 4;
66    ifxmips_w32(temp, ((u32*)cfg_base));
67
68    spin_unlock_irqrestore(&ebu_lock, flags);
69
70    if (((*data) == 0xffffffff) && (access_type == PCI_ACCESS_READ))
71        return 1;
72
73    return 0;
74}
75
76int
77ifxmips_pci_read_config_dword(struct pci_bus *bus, unsigned int devfn,
78        int where, int size, u32 * val)
79{
80    u32 data = 0;
81
82    if (ifxmips_pci_config_access(PCI_ACCESS_READ, bus, devfn, where, &data))
83        return PCIBIOS_DEVICE_NOT_FOUND;
84
85    if (size == 1)
86        *val = (data >> ((where & 3) << 3)) & 0xff;
87    else if (size == 2)
88        *val = (data >> ((where & 3) << 3)) & 0xffff;
89    else
90        *val = data;
91
92    return PCIBIOS_SUCCESSFUL;
93}
94
95int
96ifxmips_pci_write_config_dword(struct pci_bus *bus, unsigned int devfn,
97        int where, int size, u32 val)
98{
99    u32 data = 0;
100
101    if (size == 4)
102    {
103        data = val;
104    } else {
105        if (ifxmips_pci_config_access(PCI_ACCESS_READ, bus, devfn, where, &data))
106            return PCIBIOS_DEVICE_NOT_FOUND;
107
108        if (size == 1)
109            data = (data & ~(0xff << ((where & 3) << 3))) |
110                (val << ((where & 3) << 3));
111        else if (size == 2)
112            data = (data & ~(0xffff << ((where & 3) << 3))) |
113                (val << ((where & 3) << 3));
114    }
115
116    if (ifxmips_pci_config_access(PCI_ACCESS_WRITE, bus, devfn, where, &data))
117        return PCIBIOS_DEVICE_NOT_FOUND;
118
119    return PCIBIOS_SUCCESSFUL;
120}
121

Archive Download this file



interactive