summaryrefslogtreecommitdiffstats
path: root/meta/recipes-kernel/linux/linux-2.6.23/cm-x270/0004-cm-x270-it8152.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-kernel/linux/linux-2.6.23/cm-x270/0004-cm-x270-it8152.patch')
-rw-r--r--meta/recipes-kernel/linux/linux-2.6.23/cm-x270/0004-cm-x270-it8152.patch496
1 files changed, 496 insertions, 0 deletions
diff --git a/meta/recipes-kernel/linux/linux-2.6.23/cm-x270/0004-cm-x270-it8152.patch b/meta/recipes-kernel/linux/linux-2.6.23/cm-x270/0004-cm-x270-it8152.patch
new file mode 100644
index 0000000000..274eaf24d8
--- /dev/null
+++ b/meta/recipes-kernel/linux/linux-2.6.23/cm-x270/0004-cm-x270-it8152.patch
@@ -0,0 +1,496 @@
1From 1306abec905df1ff5cf2b1d91ac0d94d18d96c5b Mon Sep 17 00:00:00 2001
2From: Cliff Brake <cbrake@happy.dev.bec-systems.com>
3Date: Fri, 20 Jul 2007 19:00:07 -0400
4Subject: [PATCH] cm-x270-it8152
5
6---
7 arch/arm/common/Makefile | 1 +
8 arch/arm/common/it8152.c | 272 +++++++++++++++++++++++++++++++++++++
9 arch/arm/kernel/bios32.c | 28 ++++-
10 include/asm-arm/hardware/it8152.h | 104 ++++++++++++++
11 include/asm-arm/pci.h | 7 +
12 include/linux/pci_ids.h | 1 +
13 6 files changed, 410 insertions(+), 3 deletions(-)
14 create mode 100644 arch/arm/common/it8152.c
15 create mode 100644 include/asm-arm/hardware/it8152.h
16
17diff --git a/arch/arm/common/Makefile b/arch/arm/common/Makefile
18index e1289a2..3d0b9fa 100644
19--- a/arch/arm/common/Makefile
20+++ b/arch/arm/common/Makefile
21@@ -17,3 +17,4 @@ obj-$(CONFIG_SHARPSL_PM) += sharpsl_pm.o
22 obj-$(CONFIG_SHARP_SCOOP) += scoop.o
23 obj-$(CONFIG_ARCH_IXP2000) += uengine.o
24 obj-$(CONFIG_ARCH_IXP23XX) += uengine.o
25+obj-$(CONFIG_PCI_HOST_ITE8152) += it8152.o
26diff --git a/arch/arm/common/it8152.c b/arch/arm/common/it8152.c
27new file mode 100644
28index 0000000..8563610
29--- /dev/null
30+++ b/arch/arm/common/it8152.c
31@@ -0,0 +1,272 @@
32+/*
33+ * arch/arm/common/it8152.c: PCI functions for IT8152
34+ *
35+ * Compulab Ltd, 2002-2006
36+ *
37+ * The DMA bouncing is taken from arch/arm/mach-ixp4xx/common-pci.c
38+ * (see this file for respective copyrights)
39+ *
40+ * This program is free software; you can redistribute it and/or modify
41+ * it under the terms of the GNU General Public License version 2 as
42+ * published by the Free Software Foundation.
43+ */
44+
45+#include <linux/sched.h>
46+#include <linux/kernel.h>
47+#include <linux/pci.h>
48+#include <linux/ptrace.h>
49+#include <linux/interrupt.h>
50+#include <linux/mm.h>
51+#include <linux/slab.h>
52+#include <linux/init.h>
53+#include <linux/ioport.h>
54+#include <asm/mach/map.h>
55+
56+
57+#include <asm/io.h>
58+#include <asm/irq.h>
59+#include <asm/system.h>
60+#include <asm/mach/pci.h>
61+#include <asm/hardware/it8152.h>
62+
63+#define MAX_SLOTS 21
64+
65+static unsigned long
66+it8152_pci_dev_base_address(struct pci_bus *bus, unsigned int devfn)
67+{
68+ unsigned long addr = 0;
69+
70+ if (bus->number == 0) {
71+ if (devfn < PCI_DEVFN(MAX_SLOTS, 0))
72+ addr = (devfn << 8);
73+ } else
74+ addr = (bus->number << 16) | (devfn << 8);
75+
76+ return addr;
77+}
78+
79+static int
80+it8152_pci_read_config(struct pci_bus *bus, unsigned int devfn, int where,
81+ int size, u32 *value)
82+{
83+ unsigned long addr = it8152_pci_dev_base_address(bus, devfn);
84+ u32 v;
85+ int shift;
86+
87+#ifdef CONFIG_MACH_ARMCORE
88+ if(devfn!=0) IT8152_GPIO_GPLR=0x00;
89+#endif
90+ shift = (where & 3);
91+
92+ IT8152_PCI_CFG_ADDR = (addr + where);
93+ v = (IT8152_PCI_CFG_DATA >> (8 * (shift)));
94+
95+ *value = v;
96+
97+#ifdef CONFIG_MACH_ARMCORE
98+ if(devfn!=0) IT8152_GPIO_GPLR=0x20;
99+#endif
100+
101+ return PCIBIOS_SUCCESSFUL;
102+}
103+
104+
105+static int
106+it8152_pci_write_config(struct pci_bus *bus, unsigned int devfn, int where,
107+ int size, u32 value)
108+{
109+ unsigned long addr = it8152_pci_dev_base_address(bus, devfn);
110+ u32 v, vtemp, mask=0;
111+ int shift;
112+
113+#ifdef CONFIG_MACH_ARMCORE
114+ if(devfn!=0) IT8152_GPIO_GPLR=0x00;
115+#endif
116+
117+ if(size==1) mask=0xff;
118+ if(size==2) mask=0xffff;
119+
120+ shift = (where & 3);
121+
122+ IT8152_PCI_CFG_ADDR = addr + where;
123+ vtemp = IT8152_PCI_CFG_DATA;
124+
125+ if(mask) vtemp &= ~(mask << (8 * shift));
126+ else vtemp = 0;
127+
128+ v = (value << (8 * shift));
129+ IT8152_PCI_CFG_ADDR = addr + where;
130+ IT8152_PCI_CFG_DATA = (v | vtemp);
131+
132+#ifdef CONFIG_MACH_ARMCORE
133+ if(devfn!=0) IT8152_GPIO_GPLR=0x20;
134+#endif
135+
136+ return PCIBIOS_SUCCESSFUL;
137+}
138+
139+static struct pci_ops it8152_ops = {
140+ .read = it8152_pci_read_config,
141+ .write = it8152_pci_write_config,
142+};
143+
144+static struct resource it8152_io = {
145+ .name = "IT8152 PCI I/O region",
146+ .flags = IORESOURCE_IO,
147+};
148+
149+static struct resource it8152_mem1 = {
150+ .name = "First IT8152 PCI memory region",
151+ .start = 0x10000000,
152+ .end = 0x13e00000,
153+ .flags = IORESOURCE_MEM,
154+};
155+
156+/*
157+ * The following functions are needed for DMA bouncing.
158+ * ITE8152 chip can addrees up to 64MByte, so all the devices
159+ * connected to ITE8152 (PCI and USB) should have limited DMA window
160+ */
161+
162+/*
163+ * Setup DMA mask to 64MB on devices connected to ITE8152. Ignore all
164+ * other devices.
165+ */
166+static int it8152_pci_platform_notify(struct device *dev)
167+{
168+ if ( dev->bus == &pci_bus_type ) {
169+ if ( dev->dma_mask )
170+ *dev->dma_mask = (SZ_64M - 1) | PHYS_OFFSET;
171+ dev->coherent_dma_mask = (SZ_64M - 1) | PHYS_OFFSET;
172+ dmabounce_register_dev(dev, 2048, 4096);
173+ }
174+ return 0;
175+}
176+
177+static int it8152_pci_platform_notify_remove(struct device *dev)
178+{
179+ if ( dev->bus == &pci_bus_type ) {
180+ dmabounce_unregister_dev(dev);
181+ }
182+ return 0;
183+}
184+
185+int dma_needs_bounce(struct device *dev, dma_addr_t dma_addr, size_t size)
186+{
187+ dev_dbg(dev, "%s: dma_addr %08x, size %08x\n",
188+ __FUNCTION__, dma_addr, size);
189+ return (dev->bus == &pci_bus_type ) &&
190+ ((dma_addr + size - PHYS_OFFSET) >= SZ_64M);
191+}
192+
193+/*
194+ * Only first 64MB of memory can be accessed via PCI.
195+ * We use GFP_DMA to allocate safe buffers to do map/unmap.
196+ * This is really ugly and we need a better way of specifying
197+ * DMA-capable regions of memory.
198+ */
199+void __init it8152_adjust_zones(int node, unsigned long *zone_size,
200+ unsigned long *zhole_size)
201+{
202+ unsigned int sz = SZ_64M >> PAGE_SHIFT;
203+
204+ /*
205+ * Only adjust if > 64M on current system
206+ */
207+ if (node || (zone_size[0] <= sz))
208+ return;
209+
210+ zone_size[1] = zone_size[0] - sz;
211+ zone_size[0] = sz;
212+ zhole_size[1] = zhole_size[0];
213+ zhole_size[0] = 0;
214+}
215+
216+/*
217+ * We override these so we properly do dmabounce otherwise drivers
218+ * are able to set the dma_mask to 0xffffffff and we can no longer
219+ * trap bounces. :(
220+ *
221+ * We just return true on everyhing except for < 64MB in which case
222+ * we will fail miseralby and die since we can't handle that case.
223+ */
224+int
225+pci_set_dma_mask(struct pci_dev *dev, u64 mask)
226+{
227+ printk(KERN_INFO "===> %s: %s %x\n", __FUNCTION__, dev->dev.bus_id, mask);
228+ if (mask >= PHYS_OFFSET + SZ_64M - 1 )
229+ return 0;
230+
231+ return -EIO;
232+}
233+
234+int
235+pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask)
236+{
237+ printk(KERN_INFO "===> %s: %s %x\n", __FUNCTION__, dev->dev.bus_id, mask);
238+ if (mask >= PHYS_OFFSET + SZ_64M - 1 )
239+ return 0;
240+
241+ return -EIO;
242+}
243+
244+EXPORT_SYMBOL(pci_set_dma_mask);
245+EXPORT_SYMBOL(pci_set_consistent_dma_mask);
246+
247+
248+int __init it8152_pci_setup(int nr, struct pci_sys_data *sys)
249+{
250+ it8152_io.start = IT8152_IO_BASE + 0x12000;
251+ it8152_io.end = IT8152_IO_BASE + 0x100000;
252+
253+ if (request_resource(&ioport_resource, &it8152_io)) {
254+ printk(KERN_ERR "PCI: unable to allocate IO region\n");
255+ return -EBUSY;
256+ }
257+ if (request_resource(&iomem_resource, &it8152_mem1)) {
258+ printk(KERN_ERR "PCI: unable to allocate memory region\n");
259+ return -EBUSY;
260+ }
261+
262+ sys->resource[0] = &it8152_io;
263+ sys->resource[1] = &it8152_mem1;
264+
265+ if (platform_notify || platform_notify_remove) {
266+ printk(KERN_ERR "PCI: Can't use platform_notify\n");
267+ return -EBUSY;
268+ }
269+
270+ platform_notify = it8152_pci_platform_notify;
271+ platform_notify_remove = it8152_pci_platform_notify_remove;
272+
273+ return 1;
274+}
275+
276+/*
277+ * If we set up a device for bus mastering, we need to check the latency
278+ * timer as we don't have even crappy BIOSes to set it properly.
279+ * The implementation is from arch/i386/pci/i386.c
280+ */
281+unsigned int pcibios_max_latency = 255;
282+
283+void pcibios_set_master(struct pci_dev *dev)
284+{
285+ u8 lat;
286+
287+ pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
288+ if (lat < 16)
289+ lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency;
290+ else if (lat > pcibios_max_latency)
291+ lat = pcibios_max_latency;
292+ else
293+ return;
294+ printk(KERN_DEBUG "PCI: Setting latency timer of device %s to %d\n", pci_name(dev), lat);
295+ pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat);
296+}
297+
298+
299+struct pci_bus * __init it8152_pci_scan_bus(int nr, struct pci_sys_data *sys)
300+{
301+ return pci_scan_bus(nr, &it8152_ops, sys);
302+}
303+
304diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c
305index 240c448..d8d2352 100644
306--- a/arch/arm/kernel/bios32.c
307+++ b/arch/arm/kernel/bios32.c
308@@ -279,6 +279,25 @@ static void __devinit pci_fixup_cy82c693(struct pci_dev *dev)
309 }
310 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_CONTAQ, PCI_DEVICE_ID_CONTAQ_82C693, pci_fixup_cy82c693);
311
312+static void __init pci_fixup_it8152(struct pci_dev *dev)
313+{
314+ int i;
315+ /* fixup for ITE 8152 devices */
316+ /* FIXME: add defines for class 0x68000 and 0x80103 */
317+ if ((dev->class >> 8) == PCI_CLASS_BRIDGE_HOST ||
318+ dev->class == 0x68000 ||
319+ dev->class == 0x80103) {
320+ for (i = 0; i < PCI_NUM_RESOURCES; i++) {
321+ dev->resource[i].start = 0;
322+ dev->resource[i].end = 0;
323+ dev->resource[i].flags = 0;
324+ }
325+ }
326+}
327+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ITE, PCI_DEVICE_ID_ITE_8152, pci_fixup_it8152);
328+
329+
330+
331 void __devinit pcibios_update_irq(struct pci_dev *dev, int irq)
332 {
333 if (debug_pci)
334@@ -292,9 +311,12 @@ void __devinit pcibios_update_irq(struct pci_dev *dev, int irq)
335 */
336 static inline int pdev_bad_for_parity(struct pci_dev *dev)
337 {
338- return (dev->vendor == PCI_VENDOR_ID_INTERG &&
339- (dev->device == PCI_DEVICE_ID_INTERG_2000 ||
340- dev->device == PCI_DEVICE_ID_INTERG_2010));
341+ return ((dev->vendor == PCI_VENDOR_ID_INTERG &&
342+ (dev->device == PCI_DEVICE_ID_INTERG_2000 ||
343+ dev->device == PCI_DEVICE_ID_INTERG_2010)) ||
344+ (dev->vendor == PCI_VENDOR_ID_ITE &&
345+ dev->device == PCI_DEVICE_ID_ITE_8152));
346+
347 }
348
349 /*
350diff --git a/include/asm-arm/hardware/it8152.h b/include/asm-arm/hardware/it8152.h
351new file mode 100644
352index 0000000..d28210d
353--- /dev/null
354+++ b/include/asm-arm/hardware/it8152.h
355@@ -0,0 +1,104 @@
356+/*
357+ * arch/arm/mach-pxa/it8152.h
358+ *
359+ * Compulab Ltd., 2006
360+ *
361+ * ITE 8152 companion chip definitions
362+ */
363+
364+
365+/* #define CMX270_IT8152_VIRT (CMX270_VIRT_BASE) */
366+
367+
368+extern unsigned long it8152_base_address;
369+
370+#define IT8152_IO_BASE (it8152_base_address + 0x03e00000)
371+#define IT8152_CFGREG_BASE (it8152_base_address + 0x03f00000)
372+
373+/* #define IRQ_GPIO_IT8152_IRQ IRQ_GPIO(GPIO_IT8152_IRQ) */
374+
375+#define IT8152_SHORT_IO(x) (*((volatile unsigned short *)(IT8152_CFGREG_BASE+(x))))
376+#define IT8152_LONG_IO(x) (*((volatile unsigned long *)(IT8152_CFGREG_BASE+(x))))
377+
378+
379+#define IT8152_PCI_MEMBASE (*((volatile unsigned long *)(it8152_base_address)))
380+/* #define IT8152_PCI_IOBASE (*((volatile unsigned long *)(it8152_base_address + 0x3e00000))) */
381+
382+#define IT8152_PCI_IACK (*((volatile unsigned long *)(it8152_base_address + 0x3f00808)))
383+#define IT8152_PCI_CFG_ADDR (*((volatile unsigned long *)(it8152_base_address + 0x3f00800)))
384+#define IT8152_PCI_CFG_DATA (*((volatile unsigned long *)(it8152_base_address + 0x3f00804)))
385+
386+#define IT_BUSNUM_SHF 16
387+#define IT_DEVNUM_SHF 11
388+#define IT_FUNCNUM_SHF 8
389+#define IT_REGNUM_SHF 2
390+
391+/* Power management & PLL registers */
392+#define IT8152_PMPLL_DSR IT8152_LONG_IO(0x00)
393+#define IT8152_PMPLL_DSSR IT8152_LONG_IO(0x04)
394+#define IT8152_PMPLL_PLLCR IT8152_LONG_IO(0x20)
395+#define IT8152_PMPLL_MFSR IT8152_LONG_IO(0x24)
396+
397+/* Memory controller */
398+#define IT8152_MC_REG_OFFSET 0x100
399+
400+#define IT8152_MC_SDCR IT8152_LONG_IO(IT8152_MC_REG_OFFSET + 0x00)
401+#define IT8152_MC_PCICR IT8152_LONG_IO(IT8152_MC_REG_OFFSET + 0x04)
402+
403+/* Interrupt related definitions */
404+#define IT8152_INTC_REG_OFFSET 0x300
405+
406+#define IT8152_INTC_LDCNIRR IT8152_LONG_IO(IT8152_INTC_REG_OFFSET + 0x00)
407+#define IT8152_INTC_LDPNIRR IT8152_LONG_IO(IT8152_INTC_REG_OFFSET + 0x04)
408+#define IT8152_INTC_LDCNIMR IT8152_LONG_IO(IT8152_INTC_REG_OFFSET + 0x08)
409+#define IT8152_INTC_LDPNIMR IT8152_LONG_IO(IT8152_INTC_REG_OFFSET + 0x0C)
410+#define IT8152_INTC_LDNITR IT8152_LONG_IO(IT8152_INTC_REG_OFFSET + 0x10)
411+#define IT8152_INTC_LDNIAR IT8152_LONG_IO(IT8152_INTC_REG_OFFSET + 0x14)
412+#define IT8152_INTC_LPCNIRR IT8152_LONG_IO(IT8152_INTC_REG_OFFSET + 0x20)
413+#define IT8152_INTC_LPPNIRR IT8152_LONG_IO(IT8152_INTC_REG_OFFSET + 0x24)
414+#define IT8152_INTC_LPCNIMR IT8152_LONG_IO(IT8152_INTC_REG_OFFSET + 0x28)
415+#define IT8152_INTC_LPPNIMR IT8152_LONG_IO(IT8152_INTC_REG_OFFSET + 0x2C)
416+#define IT8152_INTC_LPNITR IT8152_LONG_IO(IT8152_INTC_REG_OFFSET + 0x30)
417+#define IT8152_INTC_LPNIAR IT8152_LONG_IO(IT8152_INTC_REG_OFFSET + 0x34)
418+#define IT8152_INTC_PDCNIRR IT8152_LONG_IO(IT8152_INTC_REG_OFFSET + 0x40)
419+#define IT8152_INTC_PDPNIRR IT8152_LONG_IO(IT8152_INTC_REG_OFFSET + 0x44)
420+#define IT8152_INTC_PDCNIMR IT8152_LONG_IO(IT8152_INTC_REG_OFFSET + 0x48)
421+#define IT8152_INTC_PDPNIMR IT8152_LONG_IO(IT8152_INTC_REG_OFFSET + 0x4C)
422+#define IT8152_INTC_PDNITR IT8152_LONG_IO(IT8152_INTC_REG_OFFSET + 0x50)
423+#define IT8152_INTC_PDNIAR IT8152_LONG_IO(IT8152_INTC_REG_OFFSET + 0x54)
424+#define IT8152_INTC_INTC_TYPER IT8152_LONG_IO(IT8152_INTC_REG_OFFSET + 0xFC)
425+
426+#define IT8152_UART_BASE IT8152_LONG_IO(0x200)
427+
428+#define IT8152_GPIO_REG_OFFSET 0x500
429+
430+#define IT8152_GPIO_GPLR IT8152_LONG_IO(IT8152_GPIO_REG_OFFSET)
431+#define IT8152_GPIO_GPCR12 IT8152_LONG_IO(IT8152_GPIO_REG_OFFSET + 0x04)
432+#define IT8152_GPIO_GPCR34 IT8152_LONG_IO(IT8152_GPIO_REG_OFFSET + 0x08)
433+
434+
435+/* Interrupt bit definitions */
436+#define PCISERR_BIT (1<<14)
437+#define H2PTADR_BIT (1<<13)
438+#define H2PMAR_BIT (1<<12)
439+#define PCI_INTD_BIT (1<<11)
440+#define PCI_INTC_BIT (1<<10)
441+#define PCI_INTB_BIT (1<<9)
442+#define PCI_INTA_BIT (1<<8)
443+#define CDMA_INT_BIT (1<<2)
444+#define USB_INT_BIT (1<<1)
445+#define AUDIO_INT_BIT (1<<0)
446+
447+/* IT8152 UART */
448+#define ITESER_BIT (1<<5)
449+
450+
451+
452+
453+
454+
455+
456+
457+
458+
459+
460diff --git a/include/asm-arm/pci.h b/include/asm-arm/pci.h
461index f21abd4..2cf30bf 100644
462--- a/include/asm-arm/pci.h
463+++ b/include/asm-arm/pci.h
464@@ -8,10 +8,17 @@
465
466 #define pcibios_scan_all_fns(a, b) 0
467
468+#ifdef CONFIG_PCI_HOST_ITE8152
469+/* ITE bridge requires setting latency timer to avoid early bus access
470+ termination by PIC bus mater devices
471+*/
472+extern void pcibios_set_master(struct pci_dev *dev);
473+#else
474 static inline void pcibios_set_master(struct pci_dev *dev)
475 {
476 /* No special bus mastering setup handling */
477 }
478+#endif
479
480 static inline void pcibios_penalize_isa_irq(int irq, int active)
481 {
482diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
483index 5b1c999..b4c81d5 100644
484--- a/include/linux/pci_ids.h
485+++ b/include/linux/pci_ids.h
486@@ -1650,6 +1650,7 @@
487 #define PCI_DEVICE_ID_ITE_8211 0x8211
488 #define PCI_DEVICE_ID_ITE_8212 0x8212
489 #define PCI_DEVICE_ID_ITE_8213 0x8213
490+#define PCI_DEVICE_ID_ITE_8152 0x8152
491 #define PCI_DEVICE_ID_ITE_8872 0x8872
492 #define PCI_DEVICE_ID_ITE_IT8330G_0 0xe886
493
494--
4951.5.1.6
496