2 * This program is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU General Public License
4 * as published by the Free Software Foundation; either version 2
5 * of the License, or (at your option) any later version.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 #include <linux/types.h>
18 #include <linux/pci.h>
19 #include <linux/kernel.h>
20 #include <linux/init.h>
22 #include <linux/spinlock.h>
23 #include <linux/delay.h>
24 #include <linux/irq.h>
25 #include <asm/paccess.h>
26 #include <asm/irq_cpu.h>
30 #define AR531X_MEM_BASE 0x80800000UL
31 #define AR531X_MEM_SIZE 0x00ffffffUL
32 #define AR531X_IO_SIZE 0x00007fffUL
33 #define IDSEL_SHIFT 13
35 static spinlock_t ar531x_pci_lock
= SPIN_LOCK_UNLOCKED
;
38 static int config_access(int busno
, int dev
, int func
, int where
, int size
, u32 ptr
, int write
)
40 u32 address
; /* Address to read from */
44 if ((busno
!= 0) || ((dev
!= 0) && (dev
!= 3)) || (func
> 2))
47 spin_lock_irqsave(&ar531x_pci_lock
, flags
);
49 /* Select Configuration access */
50 reg
= sysRegRead(AR5315_PCI_MISC_CONFIG
);
51 reg
|= AR5315_PCIMISC_CFG_SEL
;
52 sysRegWrite(AR5315_PCI_MISC_CONFIG
, reg
);
53 (void)sysRegRead(AR5315_PCI_MISC_CONFIG
);
55 address
= (u32
)cfgaddr
+ (1 << (IDSEL_SHIFT
+ dev
)) + (func
<< 8) + where
;
64 ret
= put_dbe(ptr
, (u8
*) address
);
66 ret
= put_dbe(ptr
, (u16
*) address
);
68 ret
= put_dbe(ptr
, (u32
*) address
);
71 ret
= get_dbe(*((u32
*)ptr
), (u8
*) address
);
73 ret
= get_dbe(*((u32
*)ptr
), (u16
*) address
);
75 ret
= get_dbe(*((u32
*)ptr
), (u32
*) address
);
78 /* Select Memory access */
79 reg
= sysRegRead(AR5315_PCI_MISC_CONFIG
);
80 reg
&= ~AR5315_PCIMISC_CFG_SEL
;
81 sysRegWrite(AR5315_PCI_MISC_CONFIG
, reg
);
82 (void)sysRegRead(AR5315_PCI_MISC_CONFIG
);
84 spin_unlock_irqrestore(&ar531x_pci_lock
, flags
);
87 *((u32
*)ptr
) = 0xffffffff;
88 return PCIBIOS_DEVICE_NOT_FOUND
;
91 return PCIBIOS_SUCCESSFUL
;
94 static int ar531x_pci_read(struct pci_bus
*bus
, unsigned int devfn
, int where
, int size
, u32
* value
)
96 return config_access(bus
->number
, PCI_SLOT(devfn
), PCI_FUNC(devfn
), where
, size
, (u32
) value
, 0);
99 static int ar531x_pci_write(struct pci_bus
*bus
, unsigned int devfn
, int where
, int size
, u32 value
)
101 return config_access(bus
->number
, PCI_SLOT(devfn
), PCI_FUNC(devfn
), where
, size
, value
, 1);
104 struct pci_ops ar531x_pci_ops
= {
105 .read
= ar531x_pci_read
,
106 .write
= ar531x_pci_write
,
109 static struct resource ar531x_mem_resource
= {
110 .name
= "AR531x PCI MEM",
111 .start
= AR531X_MEM_BASE
,
112 .end
= AR531X_MEM_BASE
+ AR531X_MEM_SIZE
- AR531X_IO_SIZE
- 1 + 0x4000000,
113 .flags
= IORESOURCE_MEM
,
116 static struct resource ar531x_io_resource
= {
117 .name
= "AR531x PCI I/O",
118 .start
= AR531X_MEM_BASE
+ AR531X_MEM_SIZE
- AR531X_IO_SIZE
,
119 .end
= AR531X_MEM_BASE
+ AR531X_MEM_SIZE
- 1,
120 .flags
= IORESOURCE_IO
,
123 struct pci_controller ar531x_pci_controller
= {
124 .pci_ops
= &ar531x_pci_ops
,
125 .mem_resource
= &ar531x_mem_resource
,
126 .io_resource
= &ar531x_io_resource
,
127 .mem_offset
= 0x00000000UL
,
128 .io_offset
= 0x00000000UL
,
131 int pcibios_map_irq(const struct pci_dev
*dev
, u8 slot
, u8 pin
)
133 return AR5315_IRQ_LCBUS_PCI
;
136 int pcibios_plat_dev_init(struct pci_dev
*dev
)
140 pci_write_config_byte(dev
, PCI_INTERRUPT_LINE
, 5);
141 pci_write_config_word(dev
, 0x40, 0);
143 /* Clear any pending Abort or external Interrupts
144 * and enable interrupt processing */
145 reg
= sysRegRead(AR5315_PCI_INTEN_REG
);
146 reg
&= ~AR5315_PCI_INT_ENABLE
;
147 sysRegWrite(AR5315_PCI_INTEN_REG
, reg
);
149 reg
= sysRegRead(AR5315_PCI_INT_STATUS
);
150 reg
|= (AR5315_PCI_ABORT_INT
| AR5315_PCI_EXT_INT
);
151 sysRegWrite(AR5315_PCI_INT_STATUS
, reg
);
153 reg
= sysRegRead(AR5315_PCI_INT_MASK
);
154 reg
|= (AR5315_PCI_EXT_INT
| AR5315_PCI_ABORT_INT
);
155 sysRegWrite(AR5315_PCI_INT_MASK
, reg
);
157 reg
= sysRegRead(AR5315_PCI_INTEN_REG
);
158 reg
|= AR5315_PCI_INT_ENABLE
;
159 sysRegWrite(AR5315_PCI_INTEN_REG
, reg
);
164 static void ar5315_pci_fixup(struct pci_dev
*dev
)
166 struct pci_bus
*bus
= dev
->bus
;
168 if ((PCI_SLOT(dev
->devfn
) != 3) || (PCI_FUNC(dev
->devfn
) != 0) || (bus
->number
!= 0))
171 #define _DEV bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)
172 printk("PCI: fixing up device %d,%d,%d\n", _DEV
);
174 config_access(_DEV
, PCI_BASE_ADDRESS_0
, 4, HOST_PCI_MBAR0
, 1);
175 config_access(_DEV
, PCI_BASE_ADDRESS_1
, 4, HOST_PCI_MBAR1
, 1);
176 config_access(_DEV
, PCI_BASE_ADDRESS_2
, 4, HOST_PCI_MBAR2
, 1);
177 config_access(_DEV
, PCI_COMMAND
, 4,
178 PCI_COMMAND_MEMORY
|PCI_COMMAND_MASTER
|PCI_COMMAND_SPECIAL
|
179 PCI_COMMAND_INVALIDATE
|PCI_COMMAND_PARITY
|PCI_COMMAND_SERR
|
180 PCI_COMMAND_FAST_BACK
, 1);
183 DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID
, PCI_ANY_ID
, ar5315_pci_fixup
);
185 int __init
ar5315_pci_init(void)
189 printk("AR531x PCI init... \n");
191 cfgaddr
= (u32
) ioremap_nocache(0x80000000, 1*1024*1024); /* Remap PCI config space */
192 ar531x_pci_controller
.io_map_base
=
193 (unsigned long) ioremap_nocache(AR531X_MEM_BASE
+ AR531X_MEM_SIZE
, AR531X_IO_SIZE
);
194 set_io_port_base(ar531x_pci_controller
.io_map_base
); /* PCI I/O space */
196 reg
= sysRegRead(AR5315_RESET
);
197 sysRegWrite(AR5315_RESET
, reg
| AR5315_RESET_PCIDMA
);
201 sysRegWrite(AR5315_RESET
, reg
& ~AR5315_RESET_PCIDMA
);
202 sysRegRead(AR5315_RESET
); /* read after */
206 reg
= sysRegRead(AR5315_ENDIAN_CTL
);
207 reg
|= AR5315_CONFIG_PCIAHB
| AR5315_CONFIG_PCIAHB_BRIDGE
;
209 sysRegWrite(AR5315_ENDIAN_CTL
, reg
);
211 reg
= sysRegRead(AR5315_PCICLK
);
213 sysRegWrite(AR5315_PCICLK
, reg
);
215 reg
= sysRegRead(AR5315_AHB_ARB_CTL
);
217 sysRegWrite(AR5315_AHB_ARB_CTL
, reg
);
219 reg
= sysRegRead(AR5315_IF_CTL
);
220 reg
&= ~(IF_PCI_CLK_MASK
| IF_MASK
);
221 reg
|= (IF_PCI
| IF_PCI_HOST
| IF_PCI_INTR
| (IF_PCI_CLK_OUTPUT_CLK
<< IF_PCI_CLK_SHIFT
));
223 sysRegWrite(AR5315_IF_CTL
, reg
);
225 /* Reset the PCI bus by setting bits 5-4 in PCI_MCFG */
226 reg
= sysRegRead(AR5315_PCI_MISC_CONFIG
);
227 reg
&= ~(AR5315_PCIMISC_RST_MODE
);
228 reg
|= AR5315_PCIRST_LOW
;
229 sysRegWrite(AR5315_PCI_MISC_CONFIG
, reg
);
231 /* wait for 100 ms */
234 /* Bring the PCI out of reset */
235 reg
= sysRegRead(AR5315_PCI_MISC_CONFIG
);
236 reg
&= ~(AR5315_PCIMISC_RST_MODE
);
237 reg
|= (AR5315_PCIRST_HIGH
| AR5315_PCICACHE_DIS
| 0x8);
238 sysRegWrite(AR5315_PCI_MISC_CONFIG
, reg
);
240 sysRegWrite(AR5315_PCI_UNCACHE_CFG
,
241 0x1E | /* 1GB uncached */
242 (1 << 5) | /* Enable uncached */
243 (0x2 << 30) /* Base: 0x80000000 */
245 (void)sysRegRead(AR5315_PCI_UNCACHE_CFG
); /* flush */
249 /* dirty hack - anyone with a datasheet that knows the memory map ? */
250 ioport_resource
.start
= 0x10000000;
251 ioport_resource
.end
= 0xffffffff;
252 iomem_resource
.start
= 0x10000000;
253 iomem_resource
.end
= 0xffffffff;
255 register_pci_controller(&ar531x_pci_controller
);
261 arch_initcall(ar5315_pci_init
);