2 * Generic SH7786 PCI-Express operations.
4 * Copyright (C) 2009 Paul Mundt
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License v2. See the file "COPYING" in the main directory of this archive
10 #include <linux/kernel.h>
11 #include <linux/init.h>
12 #include <linux/pci.h>
14 #include <linux/spinlock.h>
15 #include "pcie-sh7786.h"
22 static DEFINE_SPINLOCK(sh7786_pcie_lock
);
24 static int sh7786_pcie_config_access(unsigned char access_type
,
25 struct pci_bus
*bus
, unsigned int devfn
, int where
, u32
*data
)
27 struct pci_channel
*chan
= bus
->sysdata
;
30 dev
= PCI_SLOT(devfn
);
31 func
= PCI_FUNC(devfn
);
33 if (bus
->number
> 255 || dev
> 31 || func
> 7)
34 return PCIBIOS_FUNC_NOT_SUPPORTED
;
36 return PCIBIOS_DEVICE_NOT_FOUND
;
38 /* Set the PIO address */
39 pci_write_reg(chan
, (bus
->number
<< 24) | (dev
<< 19) |
40 (func
<< 16) | (where
& ~3), SH4A_PCIEPAR
);
42 /* Enable the configuration access */
43 pci_write_reg(chan
, (1 << 31), SH4A_PCIEPCTLR
);
45 if (access_type
== PCI_ACCESS_READ
)
46 *data
= pci_read_reg(chan
, SH4A_PCIEPDR
);
48 pci_write_reg(chan
, *data
, SH4A_PCIEPDR
);
50 /* Check for master and target aborts */
51 if (pci_read_reg(chan
, SH4A_PCIEPCICONF1
) & ((1 << 29) | (1 << 28)))
52 return PCIBIOS_DEVICE_NOT_FOUND
;
54 return PCIBIOS_SUCCESSFUL
;
57 static int sh7786_pcie_read(struct pci_bus
*bus
, unsigned int devfn
,
58 int where
, int size
, u32
*val
)
64 if ((size
== 2) && (where
& 1))
65 return PCIBIOS_BAD_REGISTER_NUMBER
;
66 else if ((size
== 4) && (where
& 3))
67 return PCIBIOS_BAD_REGISTER_NUMBER
;
69 spin_lock_irqsave(&sh7786_pcie_lock
, flags
);
70 ret
= sh7786_pcie_config_access(PCI_ACCESS_READ
, bus
,
72 if (ret
!= PCIBIOS_SUCCESSFUL
)
76 *val
= (data
>> ((where
& 3) << 3)) & 0xff;
78 *val
= (data
>> ((where
& 2) << 3)) & 0xffff;
82 dev_dbg(&bus
->dev
, "pcie-config-read: bus=%3d devfn=0x%04x "
83 "where=0x%04x size=%d val=0x%08lx\n", bus
->number
,
84 devfn
, where
, size
, (unsigned long)*val
);
87 spin_unlock_irqrestore(&sh7786_pcie_lock
, flags
);
91 static int sh7786_pcie_write(struct pci_bus
*bus
, unsigned int devfn
,
92 int where
, int size
, u32 val
)
98 if ((size
== 2) && (where
& 1))
99 return PCIBIOS_BAD_REGISTER_NUMBER
;
100 else if ((size
== 4) && (where
& 3))
101 return PCIBIOS_BAD_REGISTER_NUMBER
;
103 spin_lock_irqsave(&sh7786_pcie_lock
, flags
);
104 ret
= sh7786_pcie_config_access(PCI_ACCESS_READ
, bus
,
105 devfn
, where
, &data
);
106 if (ret
!= PCIBIOS_SUCCESSFUL
)
109 dev_dbg(&bus
->dev
, "pcie-config-write: bus=%3d devfn=0x%04x "
110 "where=0x%04x size=%d val=%08lx\n", bus
->number
,
111 devfn
, where
, size
, (unsigned long)val
);
114 shift
= (where
& 3) << 3;
115 data
&= ~(0xff << shift
);
116 data
|= ((val
& 0xff) << shift
);
117 } else if (size
== 2) {
118 shift
= (where
& 2) << 3;
119 data
&= ~(0xffff << shift
);
120 data
|= ((val
& 0xffff) << shift
);
124 ret
= sh7786_pcie_config_access(PCI_ACCESS_WRITE
, bus
,
125 devfn
, where
, &data
);
127 spin_unlock_irqrestore(&sh7786_pcie_lock
, flags
);
131 struct pci_ops sh7786_pci_ops
= {
132 .read
= sh7786_pcie_read
,
133 .write
= sh7786_pcie_write
,