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 by Ralf Baechle
9 #include <linux/types.h>
10 #include <linux/pci.h>
11 #include <asm/mv64340.h>
12 #include <asm/pci_channel.h>
14 #include <linux/init.h>
17 * We assume the address ranges have already been setup appropriately by
18 * the firmware. PMON in case of the Ocelot C does that.
20 static struct resource mv_pci_io_mem0_resource = {
21 .name = "MV64340 PCI0 IO MEM",
22 .flags = IORESOURCE_IO
25 static struct resource mv_pci_mem0_resource = {
26 .name = "MV64340 PCI0 MEM",
27 .flags = IORESOURCE_MEM
30 static struct mv_pci_controller mv_bus0_controller = {
32 .pci_ops = &mv_pci_ops,
33 .mem_resource = &mv_pci_mem0_resource,
34 .io_resource = &mv_pci_io_mem0_resource,
36 .config_addr = MV64340_PCI_0_CONFIG_ADDR,
37 .config_vreg = MV64340_PCI_0_CONFIG_DATA_VIRTUAL_REG,
40 static uint32_t mv_io_base, mv_io_size;
42 static void mv64340_pci0_init(void)
44 uint32_t mem0_base, mem0_size;
45 uint32_t io_base, io_size;
47 io_base = MV_READ(MV64340_PCI_0_IO_BASE_ADDR) << 16;
48 io_size = (MV_READ(MV64340_PCI_0_IO_SIZE) + 1) << 16;
49 mem0_base = MV_READ(MV64340_PCI_0_MEMORY0_BASE_ADDR) << 16;
50 mem0_size = (MV_READ(MV64340_PCI_0_MEMORY0_SIZE) + 1) << 16;
52 mv_pci_io_mem0_resource.start = 0;
53 mv_pci_io_mem0_resource.end = io_size - 1;
54 mv_pci_mem0_resource.start = mem0_base;
55 mv_pci_mem0_resource.end = mem0_base + mem0_size - 1;
56 mv_bus0_controller.pcic.mem_offset = mem0_base;
57 mv_bus0_controller.pcic.io_offset = 0;
59 ioport_resource.end = io_size - 1;
61 register_pci_controller(&mv_bus0_controller.pcic);
67 static struct resource mv_pci_io_mem1_resource = {
68 .name = "MV64340 PCI1 IO MEM",
69 .flags = IORESOURCE_IO
72 static struct resource mv_pci_mem1_resource = {
73 .name = "MV64340 PCI1 MEM",
74 .flags = IORESOURCE_MEM
77 static struct mv_pci_controller mv_bus1_controller = {
79 .pci_ops = &mv_pci_ops,
80 .mem_resource = &mv_pci_mem1_resource,
81 .io_resource = &mv_pci_io_mem1_resource,
83 .config_addr = MV64340_PCI_1_CONFIG_ADDR,
84 .config_vreg = MV64340_PCI_1_CONFIG_DATA_VIRTUAL_REG,
87 static __init void mv64340_pci1_init(void)
89 uint32_t mem0_base, mem0_size;
90 uint32_t io_base, io_size;
92 io_base = MV_READ(MV64340_PCI_1_IO_BASE_ADDR) << 16;
93 io_size = (MV_READ(MV64340_PCI_1_IO_SIZE) + 1) << 16;
94 mem0_base = MV_READ(MV64340_PCI_1_MEMORY0_BASE_ADDR) << 16;
95 mem0_size = (MV_READ(MV64340_PCI_1_MEMORY0_SIZE) + 1) << 16;
98 * Here we assume the I/O window of second bus to be contiguous with
99 * the first. A gap is no problem but would waste address space for
100 * remapping the port space.
102 mv_pci_io_mem1_resource.start = mv_io_size;
103 mv_pci_io_mem1_resource.end = mv_io_size + io_size - 1;
104 mv_pci_mem1_resource.start = mem0_base;
105 mv_pci_mem1_resource.end = mem0_base + mem0_size - 1;
106 mv_bus1_controller.pcic.mem_offset = mem0_base;
107 mv_bus1_controller.pcic.io_offset = 0;
109 ioport_resource.end = io_base + io_size -mv_io_base - 1;
111 register_pci_controller(&mv_bus1_controller.pcic);
113 mv_io_size = io_base + io_size - mv_io_base;
116 static __init int __init ocelot_c_pci_init(void)
118 unsigned long io_v_base;
121 enable = ~MV_READ(MV64340_BASE_ADDR_ENABLE);
124 * We require at least one enabled I/O or PCI memory window or we
125 * will ignore this PCI bus. We ignore PCI windows 1, 2 and 3.
127 if (enable & (0x01 << 9) || enable & (0x01 << 10))
130 if (enable & (0x01 << 14) || enable & (0x01 << 15))
134 io_v_base = (unsigned long) ioremap(mv_io_base, mv_io_size);
136 panic("Could not ioremap I/O port range");
138 set_io_port_base(io_v_base);
144 arch_initcall(ocelot_c_pci_init);