Merge branch 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mfashe...
[pandora-kernel.git] / arch / arm / mach-pxa / cm-x270-pci.c
1 /*
2  * linux/arch/arm/mach-pxa/cm-x270-pci.c
3  *
4  * PCI bios-type initialisation for PCI machines
5  *
6  * Bits taken from various places.
7  *
8  * Copyright (C) 2007 Compulab, Ltd.
9  * Mike Rapoport <mike@compulab.co.il>
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License version 2 as
13  * published by the Free Software Foundation.
14  */
15
16 #include <linux/kernel.h>
17 #include <linux/pci.h>
18 #include <linux/init.h>
19 #include <linux/device.h>
20 #include <linux/platform_device.h>
21 #include <linux/irq.h>
22
23 #include <asm/mach/pci.h>
24 #include <asm/arch/cm-x270.h>
25 #include <asm/arch/pxa-regs.h>
26 #include <asm/arch/pxa2xx-gpio.h>
27 #include <asm/mach-types.h>
28
29 #include <asm/hardware/it8152.h>
30
31 unsigned long it8152_base_address = CMX270_IT8152_VIRT;
32
33 /*
34  * Only first 64MB of memory can be accessed via PCI.
35  * We use GFP_DMA to allocate safe buffers to do map/unmap.
36  * This is really ugly and we need a better way of specifying
37  * DMA-capable regions of memory.
38  */
39 void __init cmx270_pci_adjust_zones(int node, unsigned long *zone_size,
40         unsigned long *zhole_size)
41 {
42         unsigned int sz = SZ_64M >> PAGE_SHIFT;
43
44         if (machine_is_armcore()) {
45                 pr_info("Adjusting zones for CM-x270\n");
46
47                 /*
48                  * Only adjust if > 64M on current system
49                  */
50                 if (node || (zone_size[0] <= sz))
51                         return;
52
53                 zone_size[1] = zone_size[0] - sz;
54                 zone_size[0] = sz;
55                 zhole_size[1] = zhole_size[0];
56                 zhole_size[0] = 0;
57         }
58 }
59
60 static void cmx270_it8152_irq_demux(unsigned int irq, struct irq_desc *desc)
61 {
62         /* clear our parent irq */
63         GEDR(GPIO_IT8152_IRQ) = GPIO_bit(GPIO_IT8152_IRQ);
64
65         it8152_irq_demux(irq, desc);
66 }
67
68 void __cmx270_pci_init_irq(void)
69 {
70         it8152_init_irq();
71         pxa_gpio_mode(IRQ_TO_GPIO(GPIO_IT8152_IRQ));
72         set_irq_type(IRQ_GPIO(GPIO_IT8152_IRQ), IRQT_RISING);
73
74         set_irq_chained_handler(IRQ_GPIO(GPIO_IT8152_IRQ),
75                                 cmx270_it8152_irq_demux);
76 }
77
78 #ifdef CONFIG_PM
79 static unsigned long sleep_save_ite[10];
80
81 void __cmx270_pci_suspend(void)
82 {
83         /* save ITE state */
84         sleep_save_ite[0] = __raw_readl(IT8152_INTC_PDCNIMR);
85         sleep_save_ite[1] = __raw_readl(IT8152_INTC_LPCNIMR);
86         sleep_save_ite[2] = __raw_readl(IT8152_INTC_LPNIAR);
87
88         /* Clear ITE IRQ's */
89         __raw_writel((0), IT8152_INTC_PDCNIRR);
90         __raw_writel((0), IT8152_INTC_LPCNIRR);
91 }
92
93 void __cmx270_pci_resume(void)
94 {
95         /* restore IT8152 state */
96         __raw_writel((sleep_save_ite[0]), IT8152_INTC_PDCNIMR);
97         __raw_writel((sleep_save_ite[1]), IT8152_INTC_LPCNIMR);
98         __raw_writel((sleep_save_ite[2]), IT8152_INTC_LPNIAR);
99 }
100 #else
101 void cmx270_pci_suspend(void) {}
102 void cmx270_pci_resume(void) {}
103 #endif
104
105 /* PCI IRQ mapping*/
106 static int __init cmx270_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
107 {
108         int irq;
109
110         dev_dbg(&dev->dev, "%s: slot=%x, pin=%x\n", __func__, slot, pin);
111
112         irq = it8152_pci_map_irq(dev, slot, pin);
113         if (irq)
114                 return irq;
115
116         /*
117           Here comes the ugly part. The routing is baseboard specific,
118           but defining a platform for each possible base of CM-x270 is
119           unrealistic. Here we keep mapping for ATXBase and SB-x270.
120         */
121         /* ATXBASE PCI slot */
122         if (slot == 7)
123                 return IT8152_PCI_INTA;
124
125         /* ATXBase/SB-x270 CardBus */
126         if (slot == 8 || slot == 0)
127                 return IT8152_PCI_INTB;
128
129         /* ATXBase Ethernet */
130         if (slot == 9)
131                 return IT8152_PCI_INTA;
132
133         /* SB-x270 Ethernet */
134         if (slot == 16)
135                 return IT8152_PCI_INTA;
136
137         /* PC104+ interrupt routing */
138         if ((slot == 17) || (slot == 19))
139                 return IT8152_PCI_INTA;
140         if ((slot == 18) || (slot == 20))
141                 return IT8152_PCI_INTB;
142
143         return(0);
144 }
145
146 static void cmx270_pci_preinit(void)
147 {
148         pr_info("Initializing CM-X270 PCI subsystem\n");
149
150         __raw_writel(0x800, IT8152_PCI_CFG_ADDR);
151         if (__raw_readl(IT8152_PCI_CFG_DATA) == 0x81521283) {
152                 pr_info("PCI Bridge found.\n");
153
154                 /* set PCI I/O base at 0 */
155                 writel(0x848, IT8152_PCI_CFG_ADDR);
156                 writel(0, IT8152_PCI_CFG_DATA);
157
158                 /* set PCI memory base at 0 */
159                 writel(0x840, IT8152_PCI_CFG_ADDR);
160                 writel(0, IT8152_PCI_CFG_DATA);
161
162                 writel(0x20, IT8152_GPIO_GPDR);
163
164                 /* CardBus Controller on ATXbase baseboard */
165                 writel(0x4000, IT8152_PCI_CFG_ADDR);
166                 if (readl(IT8152_PCI_CFG_DATA) == 0xAC51104C) {
167                         pr_info("CardBus Bridge found.\n");
168
169                         /* Configure socket 0 */
170                         writel(0x408C, IT8152_PCI_CFG_ADDR);
171                         writel(0x1022, IT8152_PCI_CFG_DATA);
172
173                         writel(0x4080, IT8152_PCI_CFG_ADDR);
174                         writel(0x3844d060, IT8152_PCI_CFG_DATA);
175
176                         writel(0x4090, IT8152_PCI_CFG_ADDR);
177                         writel(((readl(IT8152_PCI_CFG_DATA) & 0xffff) |
178                                 0x60440000),
179                                IT8152_PCI_CFG_DATA);
180
181                         writel(0x4018, IT8152_PCI_CFG_ADDR);
182                         writel(0xb0000000, IT8152_PCI_CFG_DATA);
183
184                         /* Configure socket 1 */
185                         writel(0x418C, IT8152_PCI_CFG_ADDR);
186                         writel(0x1022, IT8152_PCI_CFG_DATA);
187
188                         writel(0x4180, IT8152_PCI_CFG_ADDR);
189                         writel(0x3844d060, IT8152_PCI_CFG_DATA);
190
191                         writel(0x4190, IT8152_PCI_CFG_ADDR);
192                         writel(((readl(IT8152_PCI_CFG_DATA) & 0xffff) |
193                                 0x60440000),
194                                IT8152_PCI_CFG_DATA);
195
196                         writel(0x4118, IT8152_PCI_CFG_ADDR);
197                         writel(0xb0000000, IT8152_PCI_CFG_DATA);
198                 }
199         }
200 }
201
202 static struct hw_pci cmx270_pci __initdata = {
203         .swizzle        = pci_std_swizzle,
204         .map_irq        = cmx270_pci_map_irq,
205         .nr_controllers = 1,
206         .setup          = it8152_pci_setup,
207         .scan           = it8152_pci_scan_bus,
208         .preinit        = cmx270_pci_preinit,
209 };
210
211 static int __init cmx270_init_pci(void)
212 {
213         if (machine_is_armcore())
214                 pci_common_init(&cmx270_pci);
215
216         return 0;
217 }
218
219 subsys_initcall(cmx270_init_pci);