3 @@ -379,6 +379,7 @@ config ARCH_GEMINI
5 select ARCH_REQUIRE_GPIOLIB
6 select ARCH_USES_GETTIMEOFFSET
7 + select MIGHT_HAVE_PCI
9 Support for the Cortina Systems Gemini family SoCs
11 --- a/arch/arm/mach-gemini/include/mach/hardware.h
12 +++ b/arch/arm/mach-gemini/include/mach/hardware.h
15 #define IO_ADDRESS(x) ((((x) & 0xFFF00000) >> 4) | ((x) & 0x000FFFFF) | 0xF0000000)
18 + * PCI subsystem macros
20 +#define pcibios_assign_all_busses() 1
23 --- a/arch/arm/mach-gemini/include/mach/irqs.h
24 +++ b/arch/arm/mach-gemini/include/mach/irqs.h
27 #define NORMAL_IRQ_NUM 32
29 -#define GPIO_IRQ_BASE NORMAL_IRQ_NUM
30 +#define PCI_IRQ_BASE NORMAL_IRQ_NUM
31 +#define PCI_IRQ_NUM 4
33 +#define GPIO_IRQ_BASE (NORMAL_IRQ_NUM + PCI_IRQ_NUM)
34 #define GPIO_IRQ_NUM (3 * 32)
36 #define ARCH_TIMER_IRQ IRQ_TIMER2
38 -#define NR_IRQS (NORMAL_IRQ_NUM + GPIO_IRQ_NUM)
39 +#define NR_IRQS (NORMAL_IRQ_NUM + PCI_IRQ_NUM + GPIO_IRQ_NUM)
41 #endif /* __MACH_IRQS_H__ */
42 --- a/arch/arm/mach-gemini/Makefile
43 +++ b/arch/arm/mach-gemini/Makefile
46 obj-y := irq.o mm.o time.o devices.o gpio.o
48 +obj-$(CONFIG_PCI) += pci.o
50 # Board-specific support
51 obj-$(CONFIG_MACH_NAS4220B) += board-nas4220b.o
52 obj-$(CONFIG_MACH_RUT100) += board-rut1xx.o
53 --- a/arch/arm/mach-gemini/mm.c
54 +++ b/arch/arm/mach-gemini/mm.c
55 @@ -59,6 +59,11 @@ static struct map_desc gemini_io_desc[]
59 + .virtual = IO_ADDRESS(GEMINI_PCI_IO_BASE),
60 + .pfn = __phys_to_pfn(GEMINI_PCI_IO_BASE),
64 .virtual = IO_ADDRESS(GEMINI_FLASH_CTRL_BASE),
65 .pfn = __phys_to_pfn(GEMINI_FLASH_CTRL_BASE),
68 +++ b/arch/arm/mach-gemini/pci.c
71 + * Support for Gemini PCI Controller
73 + * Copyright (C) 2009 Janos Laube <janos.dev@gmail.com>
74 + * Copyright (C) 2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
76 + * based on SL2312 PCI controller code
79 + * This program is free software; you can redistribute it and/or modify
80 + * it under the terms of the GNU General Public License as published by
81 + * the Free Software Foundation; either version 2 of the License, or
82 + * (at your option) any later version.
85 +#include <linux/kernel.h>
86 +#include <linux/pci.h>
87 +#include <linux/irq.h>
88 +#include <linux/gpio.h>
90 +#include <asm/mach/pci.h>
92 +#include <mach/irqs.h>
93 +#include <mach/hardware.h>
95 +#define GEMINI_PCI_IOSIZE_1M 0x0000
97 +#define GEMINI_PCI_PMC 0x40
98 +#define GEMINI_PCI_PMCSR 0x44
99 +#define GEMINI_PCI_CTRL1 0x48
100 +#define GEMINI_PCI_CTRL2 0x4C
101 +#define GEMINI_PCI_MEM1_BASE_SIZE 0x50
102 +#define GEMINI_PCI_MEM2_BASE_SIZE 0x54
103 +#define GEMINI_PCI_MEM3_BASE_SIZE 0x58
105 +#define PCI_CTRL2_INTSTS_OFFSET 28
106 +#define PCI_CTRL2_INTMASK_OFFSET 22
108 +#define GEMINI_PCI_DMA_MASK 0xFFF00000
109 +#define GEMINI_PCI_DMA_MEM1_BASE 0x00000000
110 +#define GEMINI_PCI_DMA_MEM2_BASE 0x00000000
111 +#define GEMINI_PCI_DMA_MEM3_BASE 0x00000000
112 +#define GEMINI_PCI_DMA_MEM1_SIZE 7
113 +#define GEMINI_PCI_DMA_MEM2_SIZE 6
114 +#define GEMINI_PCI_DMA_MEM3_SIZE 6
116 +#define PCI_CONF_ENABLE (1 << 31)
117 +#define PCI_CONF_WHERE(r) ((r) & 0xFC)
118 +#define PCI_CONF_BUS(b) (((b) & 0xFF) << 16)
119 +#define PCI_CONF_DEVICE(d) (((d) & 0x1F) << 11)
120 +#define PCI_CONF_FUNCTION(f) (((f) & 0x07) << 8)
122 +#define PCI_IOSIZE_REG (IO_ADDRESS(GEMINI_PCI_IO_BASE))
123 +#define PCI_PROT_REG (IO_ADDRESS(GEMINI_PCI_IO_BASE) + 0x04)
124 +#define PCI_CTRL_REG (IO_ADDRESS(GEMINI_PCI_IO_BASE) + 0x08)
125 +#define PCI_SOFTRST_REG (IO_ADDRESS(GEMINI_PCI_IO_BASE) + 0x10)
126 +#define PCI_CONFIG_REG (IO_ADDRESS(GEMINI_PCI_IO_BASE) + 0x28)
127 +#define PCI_DATA_REG (IO_ADDRESS(GEMINI_PCI_IO_BASE) + 0x2C)
130 +static DEFINE_SPINLOCK(gemini_pci_lock);
132 +static int gemini_pci_read_config(struct pci_bus* bus, unsigned int fn,
133 + int config, int size, u32* value)
135 + unsigned long irq_flags;
137 + spin_lock_irqsave(&gemini_pci_lock, irq_flags);
139 + __raw_writel(PCI_CONF_BUS(bus->number) |
140 + PCI_CONF_DEVICE(PCI_SLOT(fn)) |
141 + PCI_CONF_FUNCTION(PCI_FUNC(fn)) |
142 + PCI_CONF_WHERE(config) |
146 + *value = __raw_readl(PCI_DATA_REG);
149 + *value = (*value >> (8 * (config & 3))) & 0xFF;
150 + else if (size == 2)
151 + *value = (*value >> (8 * (config & 3))) & 0xFFFF;
153 + spin_unlock_irqrestore(&gemini_pci_lock, irq_flags);
156 + "[read] slt: %.2d, fnc: %d, cnf: 0x%.2X, val (%d bytes): 0x%.8X\n",
157 + PCI_SLOT(fn), PCI_FUNC(fn), config, size, *value);
159 + return PCIBIOS_SUCCESSFUL;
162 +static int gemini_pci_write_config(struct pci_bus* bus, unsigned int fn,
163 + int config, int size, u32 value)
165 + unsigned long irq_flags = 0;
166 + int ret = PCIBIOS_SUCCESSFUL;
169 + "[write] slt: %.2d, fnc: %d, cnf: 0x%.2X, val (%d bytes): 0x%.8X\n",
170 + PCI_SLOT(fn), PCI_FUNC(fn), config, size, value);
172 + spin_lock_irqsave(&gemini_pci_lock, irq_flags);
174 + __raw_writel(PCI_CONF_BUS(bus->number) |
175 + PCI_CONF_DEVICE(PCI_SLOT(fn)) |
176 + PCI_CONF_FUNCTION(PCI_FUNC(fn)) |
177 + PCI_CONF_WHERE(config) |
183 + __raw_writel(value, PCI_DATA_REG);
186 + __raw_writew(value, PCI_DATA_REG + (config & 3));
189 + __raw_writeb(value, PCI_DATA_REG + (config & 3));
192 + ret = PCIBIOS_BAD_REGISTER_NUMBER;
195 + spin_unlock_irqrestore(&gemini_pci_lock, irq_flags);
200 +static struct pci_ops gemini_pci_ops = {
201 + .read = gemini_pci_read_config,
202 + .write = gemini_pci_write_config,
205 +static struct resource gemini_pci_resource_io = {
206 + .name = "PCI I/O Space",
207 + .start = IO_ADDRESS(GEMINI_PCI_IO_BASE),
208 + .end = IO_ADDRESS(GEMINI_PCI_IO_BASE) + SZ_1M - 1,
209 + .flags = IORESOURCE_IO,
212 +static struct resource gemini_pci_resource_mem = {
213 + .name = "PCI Memory Space",
214 + .start = GEMINI_PCI_MEM_BASE,
215 + .end = GEMINI_PCI_MEM_BASE + SZ_128M - 1,
216 + .flags = IORESOURCE_MEM,
219 +static int __init gemini_pci_request_resources(struct pci_sys_data *sys)
221 + if (request_resource(&ioport_resource, &gemini_pci_resource_io))
222 + goto bad_resources;
223 + if (request_resource(&iomem_resource, &gemini_pci_resource_mem))
224 + goto bad_resources;
226 + pci_add_resource(&sys->resources, &gemini_pci_resource_io);
227 + pci_add_resource(&sys->resources, &gemini_pci_resource_mem);
232 + pr_err("Gemini PCI: request_resource() failed. "
233 + "Abort PCI bus enumeration.\n");
237 +static int __init gemini_pci_setup(int nr, struct pci_sys_data *sys)
241 + pcibios_min_io = 0x100;
242 + pcibios_min_mem = 0;
244 + if ((nr > 0) || gemini_pci_request_resources(sys))
247 + /* setup I/O space to 1MB size */
248 + __raw_writel(GEMINI_PCI_IOSIZE_1M, PCI_IOSIZE_REG);
250 + /* setup hostbridge */
251 + cmd = __raw_readl(PCI_CTRL_REG);
252 + cmd |= PCI_COMMAND_IO;
253 + cmd |= PCI_COMMAND_MEMORY;
254 + cmd |= PCI_COMMAND_MASTER;
255 + __raw_writel(cmd, PCI_CTRL_REG);
260 +static struct pci_bus* __init gemini_pci_scan_bus(int nr, struct pci_sys_data* sys)
262 + unsigned int reg = 0;
263 + struct pci_bus* bus = 0;
265 + bus = pci_scan_bus(nr, &gemini_pci_ops, sys);
267 + dev_dbg(&bus->dev, "setting up PCI DMA\n");
268 + reg = (GEMINI_PCI_DMA_MEM1_BASE & GEMINI_PCI_DMA_MASK)
269 + | (GEMINI_PCI_DMA_MEM1_SIZE << 16);
270 + gemini_pci_write_config(bus, 0, GEMINI_PCI_MEM1_BASE_SIZE, 4, reg);
271 + reg = (GEMINI_PCI_DMA_MEM2_BASE & GEMINI_PCI_DMA_MASK)
272 + | (GEMINI_PCI_DMA_MEM2_SIZE << 16);
273 + gemini_pci_write_config(bus, 0, GEMINI_PCI_MEM2_BASE_SIZE, 4, reg);
274 + reg = (GEMINI_PCI_DMA_MEM3_BASE & GEMINI_PCI_DMA_MASK)
275 + | (GEMINI_PCI_DMA_MEM3_SIZE << 16);
276 + gemini_pci_write_config(bus, 0, GEMINI_PCI_MEM3_BASE_SIZE, 4, reg);
282 +/* Should work with all boards based on original Storlink EVB */
283 +static int __init gemini_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
285 + if (slot < 9 || slot > 12)
288 + return PCI_IRQ_BASE + (((slot - 9) + (pin - 1)) & 0x3);
291 +static struct hw_pci gemini_hw_pci __initdata = {
292 + .nr_controllers = 1,
293 + .setup = gemini_pci_setup,
294 + .scan = gemini_pci_scan_bus,
295 + .swizzle = pci_std_swizzle,
296 + .map_irq = gemini_pci_map_irq,
299 +/* we need this for muxed PCI interrupts handling */
300 +static struct pci_bus bogus_pci_bus;
302 +static void gemini_pci_ack_irq(struct irq_data *d)
304 + unsigned int irq = d->irq;
307 + gemini_pci_read_config(&bogus_pci_bus, 0, GEMINI_PCI_CTRL2, 4, ®);
308 + reg &= ~(0xF << PCI_CTRL2_INTSTS_OFFSET);
309 + reg |= 1 << (irq - PCI_IRQ_BASE + PCI_CTRL2_INTSTS_OFFSET);
310 + gemini_pci_write_config(&bogus_pci_bus, 0, GEMINI_PCI_CTRL2, 4, reg);
313 +static void gemini_pci_mask_irq(struct irq_data *d)
315 + unsigned int irq = d->irq;
318 + gemini_pci_read_config(&bogus_pci_bus, 0, GEMINI_PCI_CTRL2, 4, ®);
319 + reg &= ~((0xF << PCI_CTRL2_INTSTS_OFFSET)
320 + | (1 << (irq - PCI_IRQ_BASE + PCI_CTRL2_INTMASK_OFFSET)));
321 + gemini_pci_write_config(&bogus_pci_bus, 0, GEMINI_PCI_CTRL2, 4, reg);
324 +static void gemini_pci_unmask_irq(struct irq_data *d)
326 + unsigned int irq = d->irq;
329 + gemini_pci_read_config(&bogus_pci_bus, 0, GEMINI_PCI_CTRL2, 4, ®);
330 + reg &= ~(0xF << PCI_CTRL2_INTSTS_OFFSET);
331 + reg |= 1 << (irq - PCI_IRQ_BASE + PCI_CTRL2_INTMASK_OFFSET);
332 + gemini_pci_write_config(&bogus_pci_bus, 0, GEMINI_PCI_CTRL2, 4, reg);
335 +static void gemini_pci_irq_handler(unsigned int irq, struct irq_desc *desc)
337 + unsigned int pci_irq_no, irq_stat, reg, i;
339 + gemini_pci_read_config(&bogus_pci_bus, 0, GEMINI_PCI_CTRL2, 4, ®);
340 + irq_stat = reg >> PCI_CTRL2_INTSTS_OFFSET;
342 + for (i = 0; i < 4; i++) {
344 + if ((irq_stat & (1 << i)) == 0)
347 + pci_irq_no = PCI_IRQ_BASE + i;
349 + BUG_ON(!(irq_desc[pci_irq_no].handle_irq));
350 + irq_desc[pci_irq_no].handle_irq(pci_irq_no,
351 + &irq_desc[pci_irq_no]);
355 +static struct irq_chip gemini_pci_irq_chip = {
357 + .irq_ack = gemini_pci_ack_irq,
358 + .irq_mask = gemini_pci_mask_irq,
359 + .irq_unmask = gemini_pci_unmask_irq,
362 +static int __init gemini_pci_init(void)
366 + for (i = 72; i <= 95; i++)
367 + gpio_request(i, "PCI");
369 + /* initialize our bogus bus */
370 + dev_set_name(&bogus_pci_bus.dev, "PCI IRQ handler");
371 + bogus_pci_bus.number = 0;
373 + /* mask and clear all interrupts */
374 + gemini_pci_write_config(&bogus_pci_bus, 0, GEMINI_PCI_CTRL2 + 2, 2,
377 + for (i = PCI_IRQ_BASE; i < PCI_IRQ_BASE + 4; i++) {
378 + irq_set_chip_and_handler(i, &gemini_pci_irq_chip,
380 + set_irq_flags(i, IRQF_VALID);
383 + irq_set_chained_handler(IRQ_PCI, gemini_pci_irq_handler);
385 + pci_common_init(&gemini_hw_pci);
390 +subsys_initcall(gemini_pci_init);