2 * Support for Gemini PCI Controller
4 * Copyright (C) 2009 Janos Laube <janos.dev@gmail.com>
5 * Copyright (C) 2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
7 * based on SL2312 PCI controller code
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
16 #include <linux/kernel.h>
17 #include <linux/pci.h>
18 #include <linux/irq.h>
19 #include <linux/gpio.h>
21 #include <asm/mach/pci.h>
23 #include <mach/irqs.h>
24 #include <mach/hardware.h>
26 #define GEMINI_PCI_IOSIZE_1M 0x0000
28 #define GEMINI_PCI_PMC 0x40
29 #define GEMINI_PCI_PMCSR 0x44
30 #define GEMINI_PCI_CTRL1 0x48
31 #define GEMINI_PCI_CTRL2 0x4C
32 #define GEMINI_PCI_MEM1_BASE_SIZE 0x50
33 #define GEMINI_PCI_MEM2_BASE_SIZE 0x54
34 #define GEMINI_PCI_MEM3_BASE_SIZE 0x58
36 #define PCI_CTRL2_INTSTS_OFFSET 28
37 #define PCI_CTRL2_INTMASK_OFFSET 22
39 #define GEMINI_PCI_DMA_MASK 0xFFF00000
40 #define GEMINI_PCI_DMA_MEM1_BASE 0x00000000
41 #define GEMINI_PCI_DMA_MEM2_BASE 0x00000000
42 #define GEMINI_PCI_DMA_MEM3_BASE 0x00000000
43 #define GEMINI_PCI_DMA_MEM1_SIZE 7
44 #define GEMINI_PCI_DMA_MEM2_SIZE 6
45 #define GEMINI_PCI_DMA_MEM3_SIZE 6
47 #define PCI_CONF_ENABLE (1 << 31)
48 #define PCI_CONF_WHERE(r) ((r) & 0xFC)
49 #define PCI_CONF_BUS(b) (((b) & 0xFF) << 16)
50 #define PCI_CONF_DEVICE(d) (((d) & 0x1F) << 11)
51 #define PCI_CONF_FUNCTION(f) (((f) & 0x07) << 8)
53 #define PCI_IOSIZE_REG (IO_ADDRESS(GEMINI_PCI_IO_BASE))
54 #define PCI_PROT_REG (IO_ADDRESS(GEMINI_PCI_IO_BASE) + 0x04)
55 #define PCI_CTRL_REG (IO_ADDRESS(GEMINI_PCI_IO_BASE) + 0x08)
56 #define PCI_SOFTRST_REG (IO_ADDRESS(GEMINI_PCI_IO_BASE) + 0x10)
57 #define PCI_CONFIG_REG (IO_ADDRESS(GEMINI_PCI_IO_BASE) + 0x28)
58 #define PCI_DATA_REG (IO_ADDRESS(GEMINI_PCI_IO_BASE) + 0x2C)
61 static DEFINE_SPINLOCK(gemini_pci_lock
);
63 static int gemini_pci_read_config(struct pci_bus
* bus
, unsigned int fn
,
64 int config
, int size
, u32
* value
)
66 unsigned long irq_flags
;
68 spin_lock_irqsave(&gemini_pci_lock
, irq_flags
);
70 __raw_writel(PCI_CONF_BUS(bus
->number
) |
71 PCI_CONF_DEVICE(PCI_SLOT(fn
)) |
72 PCI_CONF_FUNCTION(PCI_FUNC(fn
)) |
73 PCI_CONF_WHERE(config
) |
77 *value
= __raw_readl(PCI_DATA_REG
);
80 *value
= (*value
>> (8 * (config
& 3))) & 0xFF;
82 *value
= (*value
>> (8 * (config
& 3))) & 0xFFFF;
84 spin_unlock_irqrestore(&gemini_pci_lock
, irq_flags
);
87 "[read] slt: %.2d, fnc: %d, cnf: 0x%.2X, val (%d bytes): 0x%.8X\n",
88 PCI_SLOT(fn
), PCI_FUNC(fn
), config
, size
, *value
);
90 return PCIBIOS_SUCCESSFUL
;
93 static int gemini_pci_write_config(struct pci_bus
* bus
, unsigned int fn
,
94 int config
, int size
, u32 value
)
96 unsigned long irq_flags
= 0;
97 int ret
= PCIBIOS_SUCCESSFUL
;
100 "[write] slt: %.2d, fnc: %d, cnf: 0x%.2X, val (%d bytes): 0x%.8X\n",
101 PCI_SLOT(fn
), PCI_FUNC(fn
), config
, size
, value
);
103 spin_lock_irqsave(&gemini_pci_lock
, irq_flags
);
105 __raw_writel(PCI_CONF_BUS(bus
->number
) |
106 PCI_CONF_DEVICE(PCI_SLOT(fn
)) |
107 PCI_CONF_FUNCTION(PCI_FUNC(fn
)) |
108 PCI_CONF_WHERE(config
) |
114 __raw_writel(value
, PCI_DATA_REG
);
117 __raw_writew(value
, PCI_DATA_REG
+ (config
& 3));
120 __raw_writeb(value
, PCI_DATA_REG
+ (config
& 3));
123 ret
= PCIBIOS_BAD_REGISTER_NUMBER
;
126 spin_unlock_irqrestore(&gemini_pci_lock
, irq_flags
);
131 static struct pci_ops gemini_pci_ops
= {
132 .read
= gemini_pci_read_config
,
133 .write
= gemini_pci_write_config
,
136 static struct resource gemini_pci_resource_io
= {
137 .name
= "PCI I/O Space",
138 .start
= GEMINI_PCI_IO_BASE
,
139 .end
= GEMINI_PCI_IO_BASE
+ SZ_1M
- 1,
140 .flags
= IORESOURCE_IO
,
143 static struct resource gemini_pci_resource_mem
= {
144 .name
= "PCI Memory Space",
145 .start
= GEMINI_PCI_MEM_BASE
,
146 .end
= GEMINI_PCI_MEM_BASE
+ SZ_128M
- 1,
147 .flags
= IORESOURCE_MEM
,
150 static int __init
gemini_pci_request_resources(struct pci_sys_data
*sys
)
152 if (request_resource(&ioport_resource
, &gemini_pci_resource_io
))
154 if (request_resource(&iomem_resource
, &gemini_pci_resource_mem
))
157 pci_add_resource(&sys
->resources
, &gemini_pci_resource_io
);
158 pci_add_resource(&sys
->resources
, &gemini_pci_resource_mem
);
163 pr_err("Gemini PCI: request_resource() failed. "
164 "Abort PCI bus enumeration.\n");
168 static int __init
gemini_pci_setup(int nr
, struct pci_sys_data
*sys
)
172 pcibios_min_io
= 0x100;
175 if ((nr
> 0) || gemini_pci_request_resources(sys
))
178 /* setup I/O space to 1MB size */
179 __raw_writel(GEMINI_PCI_IOSIZE_1M
, PCI_IOSIZE_REG
);
181 /* setup hostbridge */
182 cmd
= __raw_readl(PCI_CTRL_REG
);
183 cmd
|= PCI_COMMAND_IO
;
184 cmd
|= PCI_COMMAND_MEMORY
;
185 cmd
|= PCI_COMMAND_MASTER
;
186 __raw_writel(cmd
, PCI_CTRL_REG
);
191 static struct pci_bus
* __init
gemini_pci_scan_bus(int nr
, struct pci_sys_data
* sys
)
193 unsigned int reg
= 0;
194 struct pci_bus
* bus
= 0;
196 bus
= pci_scan_bus(nr
, &gemini_pci_ops
, sys
);
198 dev_dbg(&bus
->dev
, "setting up PCI DMA\n");
199 reg
= (GEMINI_PCI_DMA_MEM1_BASE
& GEMINI_PCI_DMA_MASK
)
200 | (GEMINI_PCI_DMA_MEM1_SIZE
<< 16);
201 gemini_pci_write_config(bus
, 0, GEMINI_PCI_MEM1_BASE_SIZE
, 4, reg
);
202 reg
= (GEMINI_PCI_DMA_MEM2_BASE
& GEMINI_PCI_DMA_MASK
)
203 | (GEMINI_PCI_DMA_MEM2_SIZE
<< 16);
204 gemini_pci_write_config(bus
, 0, GEMINI_PCI_MEM2_BASE_SIZE
, 4, reg
);
205 reg
= (GEMINI_PCI_DMA_MEM3_BASE
& GEMINI_PCI_DMA_MASK
)
206 | (GEMINI_PCI_DMA_MEM3_SIZE
<< 16);
207 gemini_pci_write_config(bus
, 0, GEMINI_PCI_MEM3_BASE_SIZE
, 4, reg
);
213 /* Should work with all boards based on original Storlink EVB */
214 static int __init
gemini_pci_map_irq(const struct pci_dev
*dev
, u8 slot
, u8 pin
)
216 if (slot
< 9 || slot
> 12)
219 return PCI_IRQ_BASE
+ (((slot
- 9) + (pin
- 1)) & 0x3);
222 static struct hw_pci gemini_hw_pci __initdata
= {
224 .setup
= gemini_pci_setup
,
225 .scan
= gemini_pci_scan_bus
,
226 .map_irq
= gemini_pci_map_irq
,
229 /* we need this for muxed PCI interrupts handling */
230 static struct pci_bus bogus_pci_bus
;
232 static void gemini_pci_ack_irq(struct irq_data
*d
)
234 unsigned int irq
= d
->irq
;
237 gemini_pci_read_config(&bogus_pci_bus
, 0, GEMINI_PCI_CTRL2
, 4, ®
);
238 reg
&= ~(0xF << PCI_CTRL2_INTSTS_OFFSET
);
239 reg
|= 1 << (irq
- PCI_IRQ_BASE
+ PCI_CTRL2_INTSTS_OFFSET
);
240 gemini_pci_write_config(&bogus_pci_bus
, 0, GEMINI_PCI_CTRL2
, 4, reg
);
243 static void gemini_pci_mask_irq(struct irq_data
*d
)
245 unsigned int irq
= d
->irq
;
248 gemini_pci_read_config(&bogus_pci_bus
, 0, GEMINI_PCI_CTRL2
, 4, ®
);
249 reg
&= ~((0xF << PCI_CTRL2_INTSTS_OFFSET
)
250 | (1 << (irq
- PCI_IRQ_BASE
+ PCI_CTRL2_INTMASK_OFFSET
)));
251 gemini_pci_write_config(&bogus_pci_bus
, 0, GEMINI_PCI_CTRL2
, 4, reg
);
254 static void gemini_pci_unmask_irq(struct irq_data
*d
)
256 unsigned int irq
= d
->irq
;
259 gemini_pci_read_config(&bogus_pci_bus
, 0, GEMINI_PCI_CTRL2
, 4, ®
);
260 reg
&= ~(0xF << PCI_CTRL2_INTSTS_OFFSET
);
261 reg
|= 1 << (irq
- PCI_IRQ_BASE
+ PCI_CTRL2_INTMASK_OFFSET
);
262 gemini_pci_write_config(&bogus_pci_bus
, 0, GEMINI_PCI_CTRL2
, 4, reg
);
265 static void gemini_pci_irq_handler(struct irq_desc
*desc
)
267 unsigned int pci_irq_no
, irq_stat
, reg
, i
;
269 gemini_pci_read_config(&bogus_pci_bus
, 0, GEMINI_PCI_CTRL2
, 4, ®
);
270 irq_stat
= reg
>> PCI_CTRL2_INTSTS_OFFSET
;
272 for (i
= 0; i
< 4; i
++) {
274 if ((irq_stat
& (1 << i
)) == 0)
277 pci_irq_no
= PCI_IRQ_BASE
+ i
;
279 BUG_ON(!(irq_desc
[pci_irq_no
].handle_irq
));
280 irq_desc
[pci_irq_no
].handle_irq(&irq_desc
[pci_irq_no
]);
284 static struct irq_chip gemini_pci_irq_chip
= {
286 .irq_ack
= gemini_pci_ack_irq
,
287 .irq_mask
= gemini_pci_mask_irq
,
288 .irq_unmask
= gemini_pci_unmask_irq
,
291 static int __init
gemini_pci_init(void)
295 for (i
= 72; i
<= 95; i
++)
296 gpio_request(i
, "PCI");
298 /* initialize our bogus bus */
299 dev_set_name(&bogus_pci_bus
.dev
, "PCI IRQ handler");
300 bogus_pci_bus
.number
= 0;
302 /* mask and clear all interrupts */
303 gemini_pci_write_config(&bogus_pci_bus
, 0, GEMINI_PCI_CTRL2
+ 2, 2,
306 for (i
= PCI_IRQ_BASE
; i
< PCI_IRQ_BASE
+ 4; i
++) {
307 irq_set_chip_and_handler(i
, &gemini_pci_irq_chip
,
311 irq_set_chained_handler(IRQ_PCI
, gemini_pci_irq_handler
);
313 pci_common_init(&gemini_hw_pci
);
318 subsys_initcall(gemini_pci_init
);