diff options
Diffstat (limited to 'arch/arm/mach-mv78xx0/pcie.c')
-rw-r--r-- | arch/arm/mach-mv78xx0/pcie.c | 110 |
1 files changed, 33 insertions, 77 deletions
diff --git a/arch/arm/mach-mv78xx0/pcie.c b/arch/arm/mach-mv78xx0/pcie.c index 2e56e86b6d68..26a059b4f472 100644 --- a/arch/arm/mach-mv78xx0/pcie.c +++ b/arch/arm/mach-mv78xx0/pcie.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <asm/mach/pci.h> | 15 | #include <asm/mach/pci.h> |
16 | #include <plat/pcie.h> | 16 | #include <plat/pcie.h> |
17 | #include <plat/addr-map.h> | 17 | #include <plat/addr-map.h> |
18 | #include <mach/mv78xx0.h> | ||
18 | #include "common.h" | 19 | #include "common.h" |
19 | 20 | ||
20 | struct pcie_port { | 21 | struct pcie_port { |
@@ -23,16 +24,13 @@ struct pcie_port { | |||
23 | u8 root_bus_nr; | 24 | u8 root_bus_nr; |
24 | void __iomem *base; | 25 | void __iomem *base; |
25 | spinlock_t conf_lock; | 26 | spinlock_t conf_lock; |
26 | char io_space_name[16]; | ||
27 | char mem_space_name[16]; | 27 | char mem_space_name[16]; |
28 | struct resource res[2]; | 28 | struct resource res; |
29 | }; | 29 | }; |
30 | 30 | ||
31 | static struct pcie_port pcie_port[8]; | 31 | static struct pcie_port pcie_port[8]; |
32 | static int num_pcie_ports; | 32 | static int num_pcie_ports; |
33 | static struct resource pcie_io_space; | 33 | static struct resource pcie_io_space; |
34 | static struct resource pcie_mem_space; | ||
35 | |||
36 | 34 | ||
37 | void __init mv78xx0_pcie_id(u32 *dev, u32 *rev) | 35 | void __init mv78xx0_pcie_id(u32 *dev, u32 *rev) |
38 | { | 36 | { |
@@ -40,102 +38,59 @@ void __init mv78xx0_pcie_id(u32 *dev, u32 *rev) | |||
40 | *rev = orion_pcie_rev((void __iomem *)PCIE00_VIRT_BASE); | 38 | *rev = orion_pcie_rev((void __iomem *)PCIE00_VIRT_BASE); |
41 | } | 39 | } |
42 | 40 | ||
41 | u32 pcie_port_size[8] = { | ||
42 | 0, | ||
43 | 0x30000000, | ||
44 | 0x10000000, | ||
45 | 0x10000000, | ||
46 | 0x08000000, | ||
47 | 0x08000000, | ||
48 | 0x08000000, | ||
49 | 0x04000000, | ||
50 | }; | ||
51 | |||
43 | static void __init mv78xx0_pcie_preinit(void) | 52 | static void __init mv78xx0_pcie_preinit(void) |
44 | { | 53 | { |
45 | int i; | 54 | int i; |
46 | u32 size_each; | 55 | u32 size_each; |
47 | u32 start; | 56 | u32 start; |
48 | int win; | 57 | int win = 0; |
49 | 58 | ||
50 | pcie_io_space.name = "PCIe I/O Space"; | 59 | pcie_io_space.name = "PCIe I/O Space"; |
51 | pcie_io_space.start = MV78XX0_PCIE_IO_PHYS_BASE(0); | 60 | pcie_io_space.start = MV78XX0_PCIE_IO_PHYS_BASE(0); |
52 | pcie_io_space.end = | 61 | pcie_io_space.end = |
53 | MV78XX0_PCIE_IO_PHYS_BASE(0) + MV78XX0_PCIE_IO_SIZE * 8 - 1; | 62 | MV78XX0_PCIE_IO_PHYS_BASE(0) + MV78XX0_PCIE_IO_SIZE * 8 - 1; |
54 | pcie_io_space.flags = IORESOURCE_IO; | 63 | pcie_io_space.flags = IORESOURCE_MEM; |
55 | if (request_resource(&iomem_resource, &pcie_io_space)) | 64 | if (request_resource(&iomem_resource, &pcie_io_space)) |
56 | panic("can't allocate PCIe I/O space"); | 65 | panic("can't allocate PCIe I/O space"); |
57 | 66 | ||
58 | pcie_mem_space.name = "PCIe MEM Space"; | 67 | if (num_pcie_ports > 7) |
59 | pcie_mem_space.start = MV78XX0_PCIE_MEM_PHYS_BASE; | 68 | panic("invalid number of PCIe ports"); |
60 | pcie_mem_space.end = | 69 | |
61 | MV78XX0_PCIE_MEM_PHYS_BASE + MV78XX0_PCIE_MEM_SIZE - 1; | 70 | size_each = pcie_port_size[num_pcie_ports]; |
62 | pcie_mem_space.flags = IORESOURCE_MEM; | ||
63 | if (request_resource(&iomem_resource, &pcie_mem_space)) | ||
64 | panic("can't allocate PCIe MEM space"); | ||
65 | 71 | ||
72 | start = MV78XX0_PCIE_MEM_PHYS_BASE; | ||
66 | for (i = 0; i < num_pcie_ports; i++) { | 73 | for (i = 0; i < num_pcie_ports; i++) { |
67 | struct pcie_port *pp = pcie_port + i; | 74 | struct pcie_port *pp = pcie_port + i; |
68 | 75 | ||
69 | snprintf(pp->io_space_name, sizeof(pp->io_space_name), | ||
70 | "PCIe %d.%d I/O", pp->maj, pp->min); | ||
71 | pp->io_space_name[sizeof(pp->io_space_name) - 1] = 0; | ||
72 | pp->res[0].name = pp->io_space_name; | ||
73 | pp->res[0].start = MV78XX0_PCIE_IO_PHYS_BASE(i); | ||
74 | pp->res[0].end = pp->res[0].start + MV78XX0_PCIE_IO_SIZE - 1; | ||
75 | pp->res[0].flags = IORESOURCE_IO; | ||
76 | |||
77 | snprintf(pp->mem_space_name, sizeof(pp->mem_space_name), | 76 | snprintf(pp->mem_space_name, sizeof(pp->mem_space_name), |
78 | "PCIe %d.%d MEM", pp->maj, pp->min); | 77 | "PCIe %d.%d MEM", pp->maj, pp->min); |
79 | pp->mem_space_name[sizeof(pp->mem_space_name) - 1] = 0; | 78 | pp->mem_space_name[sizeof(pp->mem_space_name) - 1] = 0; |
80 | pp->res[1].name = pp->mem_space_name; | 79 | pp->res.name = pp->mem_space_name; |
81 | pp->res[1].flags = IORESOURCE_MEM; | 80 | pp->res.flags = IORESOURCE_MEM; |
82 | } | 81 | pp->res.start = start; |
83 | 82 | pp->res.end = start + size_each - 1; | |
84 | switch (num_pcie_ports) { | ||
85 | case 0: | ||
86 | size_each = 0; | ||
87 | break; | ||
88 | |||
89 | case 1: | ||
90 | size_each = 0x30000000; | ||
91 | break; | ||
92 | |||
93 | case 2 ... 3: | ||
94 | size_each = 0x10000000; | ||
95 | break; | ||
96 | |||
97 | case 4 ... 6: | ||
98 | size_each = 0x08000000; | ||
99 | break; | ||
100 | |||
101 | case 7: | ||
102 | size_each = 0x04000000; | ||
103 | break; | ||
104 | |||
105 | default: | ||
106 | panic("invalid number of PCIe ports"); | ||
107 | } | ||
108 | |||
109 | start = MV78XX0_PCIE_MEM_PHYS_BASE; | ||
110 | for (i = 0; i < num_pcie_ports; i++) { | ||
111 | struct pcie_port *pp = pcie_port + i; | ||
112 | |||
113 | pp->res[1].start = start; | ||
114 | pp->res[1].end = start + size_each - 1; | ||
115 | start += size_each; | 83 | start += size_each; |
116 | } | ||
117 | |||
118 | for (i = 0; i < num_pcie_ports; i++) { | ||
119 | struct pcie_port *pp = pcie_port + i; | ||
120 | 84 | ||
121 | if (request_resource(&pcie_io_space, &pp->res[0])) | 85 | if (request_resource(&iomem_resource, &pp->res)) |
122 | panic("can't allocate PCIe I/O sub-space"); | ||
123 | |||
124 | if (request_resource(&pcie_mem_space, &pp->res[1])) | ||
125 | panic("can't allocate PCIe MEM sub-space"); | 86 | panic("can't allocate PCIe MEM sub-space"); |
126 | } | ||
127 | 87 | ||
128 | win = 0; | 88 | mv78xx0_setup_pcie_mem_win(win + i + 8, pp->res.start, |
129 | for (i = 0; i < num_pcie_ports; i++) { | 89 | resource_size(&pp->res), |
130 | struct pcie_port *pp = pcie_port + i; | 90 | pp->maj, pp->min); |
131 | 91 | ||
132 | mv78xx0_setup_pcie_io_win(win++, pp->res[0].start, | 92 | mv78xx0_setup_pcie_io_win(win + i, i * SZ_64K, SZ_64K, |
133 | resource_size(&pp->res[0]), | ||
134 | pp->maj, pp->min); | 93 | pp->maj, pp->min); |
135 | |||
136 | mv78xx0_setup_pcie_mem_win(win++, pp->res[1].start, | ||
137 | resource_size(&pp->res[1]), | ||
138 | pp->maj, pp->min); | ||
139 | } | 94 | } |
140 | } | 95 | } |
141 | 96 | ||
@@ -156,8 +111,9 @@ static int __init mv78xx0_pcie_setup(int nr, struct pci_sys_data *sys) | |||
156 | orion_pcie_set_local_bus_nr(pp->base, sys->busnr); | 111 | orion_pcie_set_local_bus_nr(pp->base, sys->busnr); |
157 | orion_pcie_setup(pp->base); | 112 | orion_pcie_setup(pp->base); |
158 | 113 | ||
159 | pci_add_resource_offset(&sys->resources, &pp->res[0], sys->io_offset); | 114 | pci_ioremap_io(nr * SZ_64K, MV78XX0_PCIE_IO_PHYS_BASE(nr)); |
160 | pci_add_resource_offset(&sys->resources, &pp->res[1], sys->mem_offset); | 115 | |
116 | pci_add_resource_offset(&sys->resources, &pp->res, sys->mem_offset); | ||
161 | 117 | ||
162 | return 1; | 118 | return 1; |
163 | } | 119 | } |
@@ -281,7 +237,7 @@ static void __init add_pcie_port(int maj, int min, unsigned long base) | |||
281 | pp->root_bus_nr = -1; | 237 | pp->root_bus_nr = -1; |
282 | pp->base = (void __iomem *)base; | 238 | pp->base = (void __iomem *)base; |
283 | spin_lock_init(&pp->conf_lock); | 239 | spin_lock_init(&pp->conf_lock); |
284 | memset(pp->res, 0, sizeof(pp->res)); | 240 | memset(&pp->res, 0, sizeof(pp->res)); |
285 | } else { | 241 | } else { |
286 | printk("link down, ignoring\n"); | 242 | printk("link down, ignoring\n"); |
287 | } | 243 | } |