2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
6 * Copyright (C) 2004, 06 by Ralf Baechle (ralf@linux-mips.org)
9 #include <linux/types.h>
10 #include <linux/pci.h>
11 #include <linux/mv643xx.h>
13 #include <linux/init.h>
15 #include <asm/marvell.h>
18 * We assume the address ranges have already been setup appropriately by
19 * the firmware. PMON in case of the Ocelot C does that.
21 static struct resource mv_pci_io_mem0_resource
= {
22 .name
= "MV64340 PCI0 IO MEM",
23 .flags
= IORESOURCE_IO
26 static struct resource mv_pci_mem0_resource
= {
27 .name
= "MV64340 PCI0 MEM",
28 .flags
= IORESOURCE_MEM
31 static struct mv_pci_controller mv_bus0_controller
= {
33 .pci_ops
= &mv_pci_ops
,
34 .mem_resource
= &mv_pci_mem0_resource
,
35 .io_resource
= &mv_pci_io_mem0_resource
,
37 .config_addr
= MV64340_PCI_0_CONFIG_ADDR
,
38 .config_vreg
= MV64340_PCI_0_CONFIG_DATA_VIRTUAL_REG
,
41 static uint32_t mv_io_base
, mv_io_size
;
43 static void mv64340_pci0_init(void)
45 uint32_t mem0_base
, mem0_size
;
46 uint32_t io_base
, io_size
;
48 io_base
= MV_READ(MV64340_PCI_0_IO_BASE_ADDR
) << 16;
49 io_size
= (MV_READ(MV64340_PCI_0_IO_SIZE
) + 1) << 16;
50 mem0_base
= MV_READ(MV64340_PCI_0_MEMORY0_BASE_ADDR
) << 16;
51 mem0_size
= (MV_READ(MV64340_PCI_0_MEMORY0_SIZE
) + 1) << 16;
53 mv_pci_io_mem0_resource
.start
= 0;
54 mv_pci_io_mem0_resource
.end
= io_size
- 1;
55 mv_pci_mem0_resource
.start
= mem0_base
;
56 mv_pci_mem0_resource
.end
= mem0_base
+ mem0_size
- 1;
57 mv_bus0_controller
.pcic
.mem_offset
= mem0_base
;
58 mv_bus0_controller
.pcic
.io_offset
= 0;
60 ioport_resource
.end
= io_size
- 1;
62 register_pci_controller(&mv_bus0_controller
.pcic
);
68 static struct resource mv_pci_io_mem1_resource
= {
69 .name
= "MV64340 PCI1 IO MEM",
70 .flags
= IORESOURCE_IO
73 static struct resource mv_pci_mem1_resource
= {
74 .name
= "MV64340 PCI1 MEM",
75 .flags
= IORESOURCE_MEM
78 static struct mv_pci_controller mv_bus1_controller
= {
80 .pci_ops
= &mv_pci_ops
,
81 .mem_resource
= &mv_pci_mem1_resource
,
82 .io_resource
= &mv_pci_io_mem1_resource
,
84 .config_addr
= MV64340_PCI_1_CONFIG_ADDR
,
85 .config_vreg
= MV64340_PCI_1_CONFIG_DATA_VIRTUAL_REG
,
88 static __init
void mv64340_pci1_init(void)
90 uint32_t mem0_base
, mem0_size
;
91 uint32_t io_base
, io_size
;
93 io_base
= MV_READ(MV64340_PCI_1_IO_BASE_ADDR
) << 16;
94 io_size
= (MV_READ(MV64340_PCI_1_IO_SIZE
) + 1) << 16;
95 mem0_base
= MV_READ(MV64340_PCI_1_MEMORY0_BASE_ADDR
) << 16;
96 mem0_size
= (MV_READ(MV64340_PCI_1_MEMORY0_SIZE
) + 1) << 16;
99 * Here we assume the I/O window of second bus to be contiguous with
100 * the first. A gap is no problem but would waste address space for
101 * remapping the port space.
103 mv_pci_io_mem1_resource
.start
= mv_io_size
;
104 mv_pci_io_mem1_resource
.end
= mv_io_size
+ io_size
- 1;
105 mv_pci_mem1_resource
.start
= mem0_base
;
106 mv_pci_mem1_resource
.end
= mem0_base
+ mem0_size
- 1;
107 mv_bus1_controller
.pcic
.mem_offset
= mem0_base
;
108 mv_bus1_controller
.pcic
.io_offset
= 0;
110 ioport_resource
.end
= io_base
+ io_size
-mv_io_base
- 1;
112 register_pci_controller(&mv_bus1_controller
.pcic
);
114 mv_io_size
= io_base
+ io_size
- mv_io_base
;
117 static __init
int __init
ocelot_c_pci_init(void)
119 unsigned long io_v_base
;
122 enable
= ~MV_READ(MV64340_BASE_ADDR_ENABLE
);
125 * We require at least one enabled I/O or PCI memory window or we
126 * will ignore this PCI bus. We ignore PCI windows 1, 2 and 3.
128 if (enable
& (0x01 << 9) || enable
& (0x01 << 10))
131 if (enable
& (0x01 << 14) || enable
& (0x01 << 15))
135 io_v_base
= (unsigned long) ioremap(mv_io_base
, mv_io_size
);
137 panic("Could not ioremap I/O port range");
139 set_io_port_base(io_v_base
);
145 arch_initcall(ocelot_c_pci_init
);