diff options
Diffstat (limited to 'arch/arm/mach-pxa')
-rw-r--r-- | arch/arm/mach-pxa/Kconfig | 5 | ||||
-rw-r--r-- | arch/arm/mach-pxa/Makefile | 6 | ||||
-rw-r--r-- | arch/arm/mach-pxa/cm-x270-pci.c | 218 | ||||
-rw-r--r-- | arch/arm/mach-pxa/cm-x270-pci.h | 13 | ||||
-rw-r--r-- | arch/arm/mach-pxa/cm-x270.c | 645 |
5 files changed, 887 insertions, 0 deletions
diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig index e895188cadcd..656d49661a29 100644 --- a/arch/arm/mach-pxa/Kconfig +++ b/arch/arm/mach-pxa/Kconfig | |||
@@ -63,6 +63,11 @@ config MACH_ZYLONITE | |||
63 | bool "PXA3xx Development Platform" | 63 | bool "PXA3xx Development Platform" |
64 | select PXA3xx | 64 | select PXA3xx |
65 | 65 | ||
66 | config MACH_ARMCORE | ||
67 | bool "CompuLab CM-X270 modules" | ||
68 | select PXA27x | ||
69 | select IWMMXT | ||
70 | |||
66 | endchoice | 71 | endchoice |
67 | 72 | ||
68 | if PXA_SHARPSL | 73 | if PXA_SHARPSL |
diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile index bfdd0c5fcd7a..4263527e5123 100644 --- a/arch/arm/mach-pxa/Makefile +++ b/arch/arm/mach-pxa/Makefile | |||
@@ -29,6 +29,8 @@ ifeq ($(CONFIG_MACH_ZYLONITE),y) | |||
29 | obj-$(CONFIG_CPU_PXA320) += zylonite_pxa320.o | 29 | obj-$(CONFIG_CPU_PXA320) += zylonite_pxa320.o |
30 | endif | 30 | endif |
31 | 31 | ||
32 | obj-$(CONFIG_MACH_ARMCORE) += cm-x270.o | ||
33 | |||
32 | # Support for blinky lights | 34 | # Support for blinky lights |
33 | led-y := leds.o | 35 | led-y := leds.o |
34 | led-$(CONFIG_ARCH_LUBBOCK) += leds-lubbock.o | 36 | led-$(CONFIG_ARCH_LUBBOCK) += leds-lubbock.o |
@@ -45,3 +47,7 @@ obj-$(CONFIG_PXA_SSP) += ssp.o | |||
45 | ifeq ($(CONFIG_PXA27x),y) | 47 | ifeq ($(CONFIG_PXA27x),y) |
46 | obj-$(CONFIG_PM) += standby.o | 48 | obj-$(CONFIG_PM) += standby.o |
47 | endif | 49 | endif |
50 | |||
51 | ifeq ($(CONFIG_PCI),y) | ||
52 | obj-$(CONFIG_MACH_ARMCORE) += cm-x270-pci.o | ||
53 | endif | ||
diff --git a/arch/arm/mach-pxa/cm-x270-pci.c b/arch/arm/mach-pxa/cm-x270-pci.c new file mode 100644 index 000000000000..878d3b9b8633 --- /dev/null +++ b/arch/arm/mach-pxa/cm-x270-pci.c | |||
@@ -0,0 +1,218 @@ | |||
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/mach-types.h> | ||
27 | |||
28 | #include <asm/hardware/it8152.h> | ||
29 | |||
30 | unsigned long it8152_base_address = CMX270_IT8152_VIRT; | ||
31 | |||
32 | /* | ||
33 | * Only first 64MB of memory can be accessed via PCI. | ||
34 | * We use GFP_DMA to allocate safe buffers to do map/unmap. | ||
35 | * This is really ugly and we need a better way of specifying | ||
36 | * DMA-capable regions of memory. | ||
37 | */ | ||
38 | void __init cmx270_pci_adjust_zones(int node, unsigned long *zone_size, | ||
39 | unsigned long *zhole_size) | ||
40 | { | ||
41 | unsigned int sz = SZ_64M >> PAGE_SHIFT; | ||
42 | |||
43 | printk(KERN_INFO "Adjusting zones for CM-x270\n"); | ||
44 | |||
45 | /* | ||
46 | * Only adjust if > 64M on current system | ||
47 | */ | ||
48 | if (node || (zone_size[0] <= sz)) | ||
49 | return; | ||
50 | |||
51 | zone_size[1] = zone_size[0] - sz; | ||
52 | zone_size[0] = sz; | ||
53 | zhole_size[1] = zhole_size[0]; | ||
54 | zhole_size[0] = 0; | ||
55 | } | ||
56 | |||
57 | static void cmx270_it8152_irq_demux(unsigned int irq, struct irq_desc *desc) | ||
58 | { | ||
59 | /* clear our parent irq */ | ||
60 | GEDR(GPIO_IT8152_IRQ) = GPIO_bit(GPIO_IT8152_IRQ); | ||
61 | |||
62 | it8152_irq_demux(irq, desc); | ||
63 | } | ||
64 | |||
65 | void __cmx270_pci_init_irq(void) | ||
66 | { | ||
67 | it8152_init_irq(); | ||
68 | pxa_gpio_mode(IRQ_TO_GPIO(GPIO_IT8152_IRQ)); | ||
69 | set_irq_type(IRQ_GPIO(GPIO_IT8152_IRQ), IRQT_RISING); | ||
70 | |||
71 | set_irq_chained_handler(IRQ_GPIO(GPIO_IT8152_IRQ), | ||
72 | cmx270_it8152_irq_demux); | ||
73 | } | ||
74 | |||
75 | #ifdef CONFIG_PM | ||
76 | static unsigned long sleep_save_ite[10]; | ||
77 | |||
78 | void __cmx270_pci_suspend(void) | ||
79 | { | ||
80 | /* save ITE state */ | ||
81 | sleep_save_ite[0] = __raw_readl(IT8152_INTC_PDCNIMR); | ||
82 | sleep_save_ite[1] = __raw_readl(IT8152_INTC_LPCNIMR); | ||
83 | sleep_save_ite[2] = __raw_readl(IT8152_INTC_LPNIAR); | ||
84 | |||
85 | /* Clear ITE IRQ's */ | ||
86 | __raw_writel((0), IT8152_INTC_PDCNIRR); | ||
87 | __raw_writel((0), IT8152_INTC_LPCNIRR); | ||
88 | } | ||
89 | |||
90 | void __cmx270_pci_resume(void) | ||
91 | { | ||
92 | /* restore IT8152 state */ | ||
93 | __raw_writel((sleep_save_ite[0]), IT8152_INTC_PDCNIMR); | ||
94 | __raw_writel((sleep_save_ite[1]), IT8152_INTC_LPCNIMR); | ||
95 | __raw_writel((sleep_save_ite[2]), IT8152_INTC_LPNIAR); | ||
96 | } | ||
97 | #else | ||
98 | void cmx270_pci_suspend(void) {} | ||
99 | void cmx270_pci_resume(void) {} | ||
100 | #endif | ||
101 | |||
102 | /* PCI IRQ mapping*/ | ||
103 | static int __init cmx270_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) | ||
104 | { | ||
105 | int irq; | ||
106 | |||
107 | printk(KERN_DEBUG "===> %s: %s slot=%x, pin=%x\n", __FUNCTION__, | ||
108 | pci_name(dev), slot, pin); | ||
109 | |||
110 | irq = it8152_pci_map_irq(dev, slot, pin); | ||
111 | if (irq) | ||
112 | return irq; | ||
113 | |||
114 | /* | ||
115 | Here comes the ugly part. The routing is baseboard specific, | ||
116 | but defining a platform for each possible base of CM-x270 is | ||
117 | unrealistic. Here we keep mapping for ATXBase and SB-x270. | ||
118 | */ | ||
119 | /* ATXBASE PCI slot */ | ||
120 | if (slot == 7) | ||
121 | return IT8152_PCI_INTA; | ||
122 | |||
123 | /* ATXBase/SB-x270 CardBus */ | ||
124 | if (slot == 8 || slot == 0) | ||
125 | return IT8152_PCI_INTB; | ||
126 | |||
127 | /* ATXBase Ethernet */ | ||
128 | if (slot == 9) | ||
129 | return IT8152_PCI_INTA; | ||
130 | |||
131 | /* SB-x270 Ethernet */ | ||
132 | if (slot == 16) | ||
133 | return IT8152_PCI_INTA; | ||
134 | |||
135 | /* PC104+ interrupt routing */ | ||
136 | if ((slot == 17) || (slot == 19)) | ||
137 | return IT8152_PCI_INTA; | ||
138 | if ((slot == 18) || (slot == 20)) | ||
139 | return IT8152_PCI_INTB; | ||
140 | |||
141 | return(0); | ||
142 | } | ||
143 | |||
144 | static struct pci_bus * __init | ||
145 | cmx270_pci_scan_bus(int nr, struct pci_sys_data *sys) | ||
146 | { | ||
147 | printk(KERN_INFO "Initializing CM-X270 PCI subsystem\n"); | ||
148 | |||
149 | __raw_writel(0x800, IT8152_PCI_CFG_ADDR); | ||
150 | if (__raw_readl(IT8152_PCI_CFG_DATA) == 0x81521283) { | ||
151 | printk(KERN_INFO "PCI Bridge found.\n"); | ||
152 | |||
153 | /* set PCI I/O base at 0 */ | ||
154 | writel(0x848, IT8152_PCI_CFG_ADDR); | ||
155 | writel(0, IT8152_PCI_CFG_DATA); | ||
156 | |||
157 | /* set PCI memory base at 0 */ | ||
158 | writel(0x840, IT8152_PCI_CFG_ADDR); | ||
159 | writel(0, IT8152_PCI_CFG_DATA); | ||
160 | |||
161 | writel(0x20, IT8152_GPIO_GPDR); | ||
162 | |||
163 | /* CardBus Controller on ATXbase baseboard */ | ||
164 | writel(0x4000, IT8152_PCI_CFG_ADDR); | ||
165 | if (readl(IT8152_PCI_CFG_DATA) == 0xAC51104C) { | ||
166 | printk(KERN_INFO "CardBus Bridge found.\n"); | ||
167 | |||
168 | /* Configure socket 0 */ | ||
169 | writel(0x408C, IT8152_PCI_CFG_ADDR); | ||
170 | writel(0x1022, IT8152_PCI_CFG_DATA); | ||
171 | |||
172 | writel(0x4080, IT8152_PCI_CFG_ADDR); | ||
173 | writel(0x3844d060, IT8152_PCI_CFG_DATA); | ||
174 | |||
175 | writel(0x4090, IT8152_PCI_CFG_ADDR); | ||
176 | writel(((readl(IT8152_PCI_CFG_DATA) & 0xffff) | | ||
177 | 0x60440000), | ||
178 | IT8152_PCI_CFG_DATA); | ||
179 | |||
180 | writel(0x4018, IT8152_PCI_CFG_ADDR); | ||
181 | writel(0xb0000000, IT8152_PCI_CFG_DATA); | ||
182 | |||
183 | /* Configure socket 1 */ | ||
184 | writel(0x418C, IT8152_PCI_CFG_ADDR); | ||
185 | writel(0x1022, IT8152_PCI_CFG_DATA); | ||
186 | |||
187 | writel(0x4180, IT8152_PCI_CFG_ADDR); | ||
188 | writel(0x3844d060, IT8152_PCI_CFG_DATA); | ||
189 | |||
190 | writel(0x4190, IT8152_PCI_CFG_ADDR); | ||
191 | writel(((readl(IT8152_PCI_CFG_DATA) & 0xffff) | | ||
192 | 0x60440000), | ||
193 | IT8152_PCI_CFG_DATA); | ||
194 | |||
195 | writel(0x4118, IT8152_PCI_CFG_ADDR); | ||
196 | writel(0xb0000000, IT8152_PCI_CFG_DATA); | ||
197 | } | ||
198 | } | ||
199 | return it8152_pci_scan_bus(nr, sys); | ||
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 = cmx270_pci_scan_bus, | ||
208 | }; | ||
209 | |||
210 | static int __init cmx270_init_pci(void) | ||
211 | { | ||
212 | if (machine_is_armcore()) | ||
213 | pci_common_init(&cmx270_pci); | ||
214 | |||
215 | return 0; | ||
216 | } | ||
217 | |||
218 | subsys_initcall(cmx270_init_pci); | ||
diff --git a/arch/arm/mach-pxa/cm-x270-pci.h b/arch/arm/mach-pxa/cm-x270-pci.h new file mode 100644 index 000000000000..ffe37b66f9a0 --- /dev/null +++ b/arch/arm/mach-pxa/cm-x270-pci.h | |||
@@ -0,0 +1,13 @@ | |||
1 | extern void __cmx270_pci_init_irq(void); | ||
2 | extern void __cmx270_pci_suspend(void); | ||
3 | extern void __cmx270_pci_resume(void); | ||
4 | |||
5 | #ifdef CONFIG_PCI | ||
6 | #define cmx270_pci_init_irq __cmx270_pci_init_irq | ||
7 | #define cmx270_pci_suspend __cmx270_pci_suspend | ||
8 | #define cmx270_pci_resume __cmx270_pci_resume | ||
9 | #else | ||
10 | #define cmx270_pci_init_irq() do {} while (0) | ||
11 | #define cmx270_pci_suspend() do {} while (0) | ||
12 | #define cmx270_pci_resume() do {} while (0) | ||
13 | #endif | ||
diff --git a/arch/arm/mach-pxa/cm-x270.c b/arch/arm/mach-pxa/cm-x270.c new file mode 100644 index 000000000000..177664ccb2e2 --- /dev/null +++ b/arch/arm/mach-pxa/cm-x270.c | |||
@@ -0,0 +1,645 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-pxa/cm-x270.c | ||
3 | * | ||
4 | * Copyright (C) 2007 CompuLab, Ltd. | ||
5 | * Mike Rapoport <mike@compulab.co.il> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #include <linux/types.h> | ||
13 | #include <linux/pm.h> | ||
14 | #include <linux/fb.h> | ||
15 | #include <linux/platform_device.h> | ||
16 | #include <linux/irq.h> | ||
17 | #include <linux/sysdev.h> | ||
18 | #include <linux/io.h> | ||
19 | #include <linux/delay.h> | ||
20 | |||
21 | #include <linux/dm9000.h> | ||
22 | #include <linux/rtc-v3020.h> | ||
23 | #include <linux/serial_8250.h> | ||
24 | |||
25 | #include <video/mbxfb.h> | ||
26 | |||
27 | #include <asm/mach/arch.h> | ||
28 | #include <asm/mach-types.h> | ||
29 | #include <asm/mach/map.h> | ||
30 | |||
31 | #include <asm/arch/pxa-regs.h> | ||
32 | #include <asm/arch/pxafb.h> | ||
33 | #include <asm/arch/ohci.h> | ||
34 | #include <asm/arch/mmc.h> | ||
35 | #include <asm/arch/bitfield.h> | ||
36 | #include <asm/arch/cm-x270.h> | ||
37 | |||
38 | #include <asm/hardware/it8152.h> | ||
39 | |||
40 | #include "generic.h" | ||
41 | #include "cm-x270-pci.h" | ||
42 | |||
43 | #define RTC_PHYS_BASE (PXA_CS1_PHYS + (5 << 22)) | ||
44 | #define DM9000_PHYS_BASE (PXA_CS1_PHYS + (6 << 22)) | ||
45 | |||
46 | static struct resource cmx270_dm9k_resource[] = { | ||
47 | [0] = { | ||
48 | .start = DM9000_PHYS_BASE, | ||
49 | .end = DM9000_PHYS_BASE + 4, | ||
50 | .flags = IORESOURCE_MEM, | ||
51 | }, | ||
52 | [1] = { | ||
53 | .start = DM9000_PHYS_BASE + 8, | ||
54 | .end = DM9000_PHYS_BASE + 8 + 500, | ||
55 | .flags = IORESOURCE_MEM, | ||
56 | }, | ||
57 | [2] = { | ||
58 | .start = CMX270_ETHIRQ, | ||
59 | .end = CMX270_ETHIRQ, | ||
60 | .flags = IORESOURCE_IRQ, | ||
61 | } | ||
62 | }; | ||
63 | |||
64 | /* for the moment we limit ourselves to 32bit IO until some | ||
65 | * better IO routines can be written and tested | ||
66 | */ | ||
67 | static struct dm9000_plat_data cmx270_dm9k_platdata = { | ||
68 | .flags = DM9000_PLATF_32BITONLY, | ||
69 | }; | ||
70 | |||
71 | /* Ethernet device */ | ||
72 | static struct platform_device cmx270_device_dm9k = { | ||
73 | .name = "dm9000", | ||
74 | .id = 0, | ||
75 | .num_resources = ARRAY_SIZE(cmx270_dm9k_resource), | ||
76 | .resource = cmx270_dm9k_resource, | ||
77 | .dev = { | ||
78 | .platform_data = &cmx270_dm9k_platdata, | ||
79 | } | ||
80 | }; | ||
81 | |||
82 | /* audio device */ | ||
83 | static struct platform_device cmx270_audio_device = { | ||
84 | .name = "pxa2xx-ac97", | ||
85 | .id = -1, | ||
86 | }; | ||
87 | |||
88 | /* touchscreen controller */ | ||
89 | static struct platform_device cmx270_ts_device = { | ||
90 | .name = "ucb1400_ts", | ||
91 | .id = -1, | ||
92 | }; | ||
93 | |||
94 | /* RTC */ | ||
95 | static struct resource cmx270_v3020_resource[] = { | ||
96 | [0] = { | ||
97 | .start = RTC_PHYS_BASE, | ||
98 | .end = RTC_PHYS_BASE + 4, | ||
99 | .flags = IORESOURCE_MEM, | ||
100 | }, | ||
101 | }; | ||
102 | |||
103 | struct v3020_platform_data cmx270_v3020_pdata = { | ||
104 | .leftshift = 16, | ||
105 | }; | ||
106 | |||
107 | static struct platform_device cmx270_rtc_device = { | ||
108 | .name = "v3020", | ||
109 | .num_resources = ARRAY_SIZE(cmx270_v3020_resource), | ||
110 | .resource = cmx270_v3020_resource, | ||
111 | .id = -1, | ||
112 | .dev = { | ||
113 | .platform_data = &cmx270_v3020_pdata, | ||
114 | } | ||
115 | }; | ||
116 | |||
117 | /* | ||
118 | * CM-X270 LEDs | ||
119 | */ | ||
120 | static struct platform_device cmx270_led_device = { | ||
121 | .name = "cm-x270-led", | ||
122 | .id = -1, | ||
123 | }; | ||
124 | |||
125 | /* 2700G graphics */ | ||
126 | static u64 fb_dma_mask = ~(u64)0; | ||
127 | |||
128 | static struct resource cmx270_2700G_resource[] = { | ||
129 | /* frame buffer memory including ODFB and External SDRAM */ | ||
130 | [0] = { | ||
131 | .start = MARATHON_PHYS, | ||
132 | .end = MARATHON_PHYS + 0x02000000, | ||
133 | .flags = IORESOURCE_MEM, | ||
134 | }, | ||
135 | /* Marathon registers */ | ||
136 | [1] = { | ||
137 | .start = MARATHON_PHYS + 0x03fe0000, | ||
138 | .end = MARATHON_PHYS + 0x03ffffff, | ||
139 | .flags = IORESOURCE_MEM, | ||
140 | }, | ||
141 | }; | ||
142 | |||
143 | static unsigned long save_lcd_regs[10]; | ||
144 | |||
145 | static int cmx270_marathon_probe(struct fb_info *fb) | ||
146 | { | ||
147 | /* save PXA-270 pin settings before enabling 2700G */ | ||
148 | save_lcd_regs[0] = GPDR1; | ||
149 | save_lcd_regs[1] = GPDR2; | ||
150 | save_lcd_regs[2] = GAFR1_U; | ||
151 | save_lcd_regs[3] = GAFR2_L; | ||
152 | save_lcd_regs[4] = GAFR2_U; | ||
153 | |||
154 | /* Disable PXA-270 on-chip controller driving pins */ | ||
155 | GPDR1 &= ~(0xfc000000); | ||
156 | GPDR2 &= ~(0x00c03fff); | ||
157 | GAFR1_U &= ~(0xfff00000); | ||
158 | GAFR2_L &= ~(0x0fffffff); | ||
159 | GAFR2_U &= ~(0x0000f000); | ||
160 | return 0; | ||
161 | } | ||
162 | |||
163 | static int cmx270_marathon_remove(struct fb_info *fb) | ||
164 | { | ||
165 | GPDR1 = save_lcd_regs[0]; | ||
166 | GPDR2 = save_lcd_regs[1]; | ||
167 | GAFR1_U = save_lcd_regs[2]; | ||
168 | GAFR2_L = save_lcd_regs[3]; | ||
169 | GAFR2_U = save_lcd_regs[4]; | ||
170 | return 0; | ||
171 | } | ||
172 | |||
173 | static struct mbxfb_platform_data cmx270_2700G_data = { | ||
174 | .xres = { | ||
175 | .min = 240, | ||
176 | .max = 1200, | ||
177 | .defval = 640, | ||
178 | }, | ||
179 | .yres = { | ||
180 | .min = 240, | ||
181 | .max = 1200, | ||
182 | .defval = 480, | ||
183 | }, | ||
184 | .bpp = { | ||
185 | .min = 16, | ||
186 | .max = 32, | ||
187 | .defval = 16, | ||
188 | }, | ||
189 | .memsize = 8*1024*1024, | ||
190 | .probe = cmx270_marathon_probe, | ||
191 | .remove = cmx270_marathon_remove, | ||
192 | }; | ||
193 | |||
194 | static struct platform_device cmx270_2700G = { | ||
195 | .name = "mbx-fb", | ||
196 | .dev = { | ||
197 | .platform_data = &cmx270_2700G_data, | ||
198 | .dma_mask = &fb_dma_mask, | ||
199 | .coherent_dma_mask = 0xffffffff, | ||
200 | }, | ||
201 | .num_resources = ARRAY_SIZE(cmx270_2700G_resource), | ||
202 | .resource = cmx270_2700G_resource, | ||
203 | .id = -1, | ||
204 | }; | ||
205 | |||
206 | static u64 ata_dma_mask = ~(u64)0; | ||
207 | |||
208 | static struct platform_device cmx270_ata = { | ||
209 | .name = "pata_cm_x270", | ||
210 | .id = -1, | ||
211 | .dev = { | ||
212 | .dma_mask = &ata_dma_mask, | ||
213 | .coherent_dma_mask = 0xffffffff, | ||
214 | }, | ||
215 | }; | ||
216 | |||
217 | /* platform devices */ | ||
218 | static struct platform_device *platform_devices[] __initdata = { | ||
219 | &cmx270_device_dm9k, | ||
220 | &cmx270_audio_device, | ||
221 | &cmx270_rtc_device, | ||
222 | &cmx270_2700G, | ||
223 | &cmx270_led_device, | ||
224 | &cmx270_ts_device, | ||
225 | &cmx270_ata, | ||
226 | }; | ||
227 | |||
228 | /* Map PCI companion and IDE/General Purpose CS statically */ | ||
229 | static struct map_desc cmx270_io_desc[] __initdata = { | ||
230 | [0] = { /* IDE/general purpose space */ | ||
231 | .virtual = CMX270_IDE104_VIRT, | ||
232 | .pfn = __phys_to_pfn(CMX270_IDE104_PHYS), | ||
233 | .length = SZ_64M - SZ_8M, | ||
234 | .type = MT_DEVICE | ||
235 | }, | ||
236 | [1] = { /* PCI bridge */ | ||
237 | .virtual = CMX270_IT8152_VIRT, | ||
238 | .pfn = __phys_to_pfn(CMX270_IT8152_PHYS), | ||
239 | .length = SZ_64M, | ||
240 | .type = MT_DEVICE | ||
241 | }, | ||
242 | }; | ||
243 | |||
244 | /* | ||
245 | Display definitions | ||
246 | keep these for backwards compatibility, although symbolic names (as | ||
247 | e.g. in lpd270.c) looks better | ||
248 | */ | ||
249 | #define MTYPE_STN320x240 0 | ||
250 | #define MTYPE_TFT640x480 1 | ||
251 | #define MTYPE_CRT640x480 2 | ||
252 | #define MTYPE_CRT800x600 3 | ||
253 | #define MTYPE_TFT320x240 6 | ||
254 | #define MTYPE_STN640x480 7 | ||
255 | |||
256 | static struct pxafb_mode_info generic_stn_320x240_mode = { | ||
257 | .pixclock = 76923, | ||
258 | .bpp = 8, | ||
259 | .xres = 320, | ||
260 | .yres = 240, | ||
261 | .hsync_len = 3, | ||
262 | .vsync_len = 2, | ||
263 | .left_margin = 3, | ||
264 | .upper_margin = 0, | ||
265 | .right_margin = 3, | ||
266 | .lower_margin = 0, | ||
267 | .sync = (FB_SYNC_HOR_HIGH_ACT | | ||
268 | FB_SYNC_VERT_HIGH_ACT), | ||
269 | .cmap_greyscale = 0, | ||
270 | }; | ||
271 | |||
272 | static struct pxafb_mach_info generic_stn_320x240 = { | ||
273 | .modes = &generic_stn_320x240_mode, | ||
274 | .num_modes = 1, | ||
275 | .lccr0 = 0, | ||
276 | .lccr3 = (LCCR3_PixClkDiv(0x03) | | ||
277 | LCCR3_Acb(0xff) | | ||
278 | LCCR3_PCP), | ||
279 | .cmap_inverse = 0, | ||
280 | .cmap_static = 0, | ||
281 | }; | ||
282 | |||
283 | static struct pxafb_mode_info generic_tft_640x480_mode = { | ||
284 | .pixclock = 38461, | ||
285 | .bpp = 8, | ||
286 | .xres = 640, | ||
287 | .yres = 480, | ||
288 | .hsync_len = 60, | ||
289 | .vsync_len = 2, | ||
290 | .left_margin = 70, | ||
291 | .upper_margin = 10, | ||
292 | .right_margin = 70, | ||
293 | .lower_margin = 5, | ||
294 | .sync = 0, | ||
295 | .cmap_greyscale = 0, | ||
296 | }; | ||
297 | |||
298 | static struct pxafb_mach_info generic_tft_640x480 = { | ||
299 | .modes = &generic_tft_640x480_mode, | ||
300 | .num_modes = 1, | ||
301 | .lccr0 = (LCCR0_PAS), | ||
302 | .lccr3 = (LCCR3_PixClkDiv(0x01) | | ||
303 | LCCR3_Acb(0xff) | | ||
304 | LCCR3_PCP), | ||
305 | .cmap_inverse = 0, | ||
306 | .cmap_static = 0, | ||
307 | }; | ||
308 | |||
309 | static struct pxafb_mode_info generic_crt_640x480_mode = { | ||
310 | .pixclock = 38461, | ||
311 | .bpp = 8, | ||
312 | .xres = 640, | ||
313 | .yres = 480, | ||
314 | .hsync_len = 63, | ||
315 | .vsync_len = 2, | ||
316 | .left_margin = 81, | ||
317 | .upper_margin = 33, | ||
318 | .right_margin = 16, | ||
319 | .lower_margin = 10, | ||
320 | .sync = (FB_SYNC_HOR_HIGH_ACT | | ||
321 | FB_SYNC_VERT_HIGH_ACT), | ||
322 | .cmap_greyscale = 0, | ||
323 | }; | ||
324 | |||
325 | static struct pxafb_mach_info generic_crt_640x480 = { | ||
326 | .modes = &generic_crt_640x480_mode, | ||
327 | .num_modes = 1, | ||
328 | .lccr0 = (LCCR0_PAS), | ||
329 | .lccr3 = (LCCR3_PixClkDiv(0x01) | | ||
330 | LCCR3_Acb(0xff)), | ||
331 | .cmap_inverse = 0, | ||
332 | .cmap_static = 0, | ||
333 | }; | ||
334 | |||
335 | static struct pxafb_mode_info generic_crt_800x600_mode = { | ||
336 | .pixclock = 28846, | ||
337 | .bpp = 8, | ||
338 | .xres = 800, | ||
339 | .yres = 600, | ||
340 | .hsync_len = 63, | ||
341 | .vsync_len = 2, | ||
342 | .left_margin = 26, | ||
343 | .upper_margin = 21, | ||
344 | .right_margin = 26, | ||
345 | .lower_margin = 11, | ||
346 | .sync = (FB_SYNC_HOR_HIGH_ACT | | ||
347 | FB_SYNC_VERT_HIGH_ACT), | ||
348 | .cmap_greyscale = 0, | ||
349 | }; | ||
350 | |||
351 | static struct pxafb_mach_info generic_crt_800x600 = { | ||
352 | .modes = &generic_crt_800x600_mode, | ||
353 | .num_modes = 1, | ||
354 | .lccr0 = (LCCR0_PAS), | ||
355 | .lccr3 = (LCCR3_PixClkDiv(0x02) | | ||
356 | LCCR3_Acb(0xff)), | ||
357 | .cmap_inverse = 0, | ||
358 | .cmap_static = 0, | ||
359 | }; | ||
360 | |||
361 | static struct pxafb_mode_info generic_tft_320x240_mode = { | ||
362 | .pixclock = 134615, | ||
363 | .bpp = 16, | ||
364 | .xres = 320, | ||
365 | .yres = 240, | ||
366 | .hsync_len = 63, | ||
367 | .vsync_len = 7, | ||
368 | .left_margin = 75, | ||
369 | .upper_margin = 0, | ||
370 | .right_margin = 15, | ||
371 | .lower_margin = 15, | ||
372 | .sync = 0, | ||
373 | .cmap_greyscale = 0, | ||
374 | }; | ||
375 | |||
376 | static struct pxafb_mach_info generic_tft_320x240 = { | ||
377 | .modes = &generic_tft_320x240_mode, | ||
378 | .num_modes = 1, | ||
379 | .lccr0 = (LCCR0_PAS), | ||
380 | .lccr3 = (LCCR3_PixClkDiv(0x06) | | ||
381 | LCCR3_Acb(0xff) | | ||
382 | LCCR3_PCP), | ||
383 | .cmap_inverse = 0, | ||
384 | .cmap_static = 0, | ||
385 | }; | ||
386 | |||
387 | static struct pxafb_mode_info generic_stn_640x480_mode = { | ||
388 | .pixclock = 57692, | ||
389 | .bpp = 8, | ||
390 | .xres = 640, | ||
391 | .yres = 480, | ||
392 | .hsync_len = 4, | ||
393 | .vsync_len = 2, | ||
394 | .left_margin = 10, | ||
395 | .upper_margin = 5, | ||
396 | .right_margin = 10, | ||
397 | .lower_margin = 5, | ||
398 | .sync = (FB_SYNC_HOR_HIGH_ACT | | ||
399 | FB_SYNC_VERT_HIGH_ACT), | ||
400 | .cmap_greyscale = 0, | ||
401 | }; | ||
402 | |||
403 | static struct pxafb_mach_info generic_stn_640x480 = { | ||
404 | .modes = &generic_stn_640x480_mode, | ||
405 | .num_modes = 1, | ||
406 | .lccr0 = 0, | ||
407 | .lccr3 = (LCCR3_PixClkDiv(0x02) | | ||
408 | LCCR3_Acb(0xff)), | ||
409 | .cmap_inverse = 0, | ||
410 | .cmap_static = 0, | ||
411 | }; | ||
412 | |||
413 | static struct pxafb_mach_info *cmx270_display = &generic_crt_640x480; | ||
414 | |||
415 | static int __init cmx270_set_display(char *str) | ||
416 | { | ||
417 | int disp_type = simple_strtol(str, NULL, 0); | ||
418 | switch (disp_type) { | ||
419 | case MTYPE_STN320x240: | ||
420 | cmx270_display = &generic_stn_320x240; | ||
421 | break; | ||
422 | case MTYPE_TFT640x480: | ||
423 | cmx270_display = &generic_tft_640x480; | ||
424 | break; | ||
425 | case MTYPE_CRT640x480: | ||
426 | cmx270_display = &generic_crt_640x480; | ||
427 | break; | ||
428 | case MTYPE_CRT800x600: | ||
429 | cmx270_display = &generic_crt_800x600; | ||
430 | break; | ||
431 | case MTYPE_TFT320x240: | ||
432 | cmx270_display = &generic_tft_320x240; | ||
433 | break; | ||
434 | case MTYPE_STN640x480: | ||
435 | cmx270_display = &generic_stn_640x480; | ||
436 | break; | ||
437 | default: /* fallback to CRT 640x480 */ | ||
438 | cmx270_display = &generic_crt_640x480; | ||
439 | break; | ||
440 | } | ||
441 | return 1; | ||
442 | } | ||
443 | |||
444 | /* | ||
445 | This should be done really early to get proper configuration for | ||
446 | frame buffer. | ||
447 | Indeed, pxafb parameters can be used istead, but CM-X270 bootloader | ||
448 | has limitied line length for kernel command line, and also it will | ||
449 | break compatibitlty with proprietary releases already in field. | ||
450 | */ | ||
451 | __setup("monitor=", cmx270_set_display); | ||
452 | |||
453 | /* PXA27x OHCI controller setup */ | ||
454 | static int cmx270_ohci_init(struct device *dev) | ||
455 | { | ||
456 | /* Set the Power Control Polarity Low */ | ||
457 | UHCHR = (UHCHR | UHCHR_PCPL) & | ||
458 | ~(UHCHR_SSEP1 | UHCHR_SSEP2 | UHCHR_SSE); | ||
459 | |||
460 | return 0; | ||
461 | } | ||
462 | |||
463 | static struct pxaohci_platform_data cmx270_ohci_platform_data = { | ||
464 | .port_mode = PMM_PERPORT_MODE, | ||
465 | .init = cmx270_ohci_init, | ||
466 | }; | ||
467 | |||
468 | |||
469 | static int cmx270_mci_init(struct device *dev, | ||
470 | irq_handler_t cmx270_detect_int, | ||
471 | void *data) | ||
472 | { | ||
473 | int err; | ||
474 | |||
475 | /* | ||
476 | * setup GPIO for PXA27x MMC controller | ||
477 | */ | ||
478 | pxa_gpio_mode(GPIO32_MMCCLK_MD); | ||
479 | pxa_gpio_mode(GPIO112_MMCCMD_MD); | ||
480 | pxa_gpio_mode(GPIO92_MMCDAT0_MD); | ||
481 | pxa_gpio_mode(GPIO109_MMCDAT1_MD); | ||
482 | pxa_gpio_mode(GPIO110_MMCDAT2_MD); | ||
483 | pxa_gpio_mode(GPIO111_MMCDAT3_MD); | ||
484 | |||
485 | /* SB-X270 uses GPIO105 as SD power enable */ | ||
486 | pxa_gpio_mode(105 | GPIO_OUT); | ||
487 | |||
488 | /* card detect IRQ on GPIO 83 */ | ||
489 | pxa_gpio_mode(IRQ_TO_GPIO(CMX270_MMC_IRQ)); | ||
490 | set_irq_type(CMX270_MMC_IRQ, IRQT_FALLING); | ||
491 | |||
492 | err = request_irq(CMX270_MMC_IRQ, cmx270_detect_int, | ||
493 | IRQF_DISABLED | IRQF_TRIGGER_FALLING, | ||
494 | "MMC card detect", data); | ||
495 | if (err) { | ||
496 | printk(KERN_ERR "cmx270_mci_init: MMC/SD: can't" | ||
497 | " request MMC card detect IRQ\n"); | ||
498 | return -1; | ||
499 | } | ||
500 | |||
501 | return 0; | ||
502 | } | ||
503 | |||
504 | static void cmx270_mci_setpower(struct device *dev, unsigned int vdd) | ||
505 | { | ||
506 | struct pxamci_platform_data *p_d = dev->platform_data; | ||
507 | |||
508 | if ((1 << vdd) & p_d->ocr_mask) { | ||
509 | printk(KERN_DEBUG "%s: on\n", __FUNCTION__); | ||
510 | GPCR(105) = GPIO_bit(105); | ||
511 | } else { | ||
512 | GPSR(105) = GPIO_bit(105); | ||
513 | printk(KERN_DEBUG "%s: off\n", __FUNCTION__); | ||
514 | } | ||
515 | } | ||
516 | |||
517 | static void cmx270_mci_exit(struct device *dev, void *data) | ||
518 | { | ||
519 | free_irq(CMX270_MMC_IRQ, data); | ||
520 | } | ||
521 | |||
522 | static struct pxamci_platform_data cmx270_mci_platform_data = { | ||
523 | .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, | ||
524 | .init = cmx270_mci_init, | ||
525 | .setpower = cmx270_mci_setpower, | ||
526 | .exit = cmx270_mci_exit, | ||
527 | }; | ||
528 | |||
529 | #ifdef CONFIG_PM | ||
530 | static unsigned long sleep_save_msc[10]; | ||
531 | |||
532 | static int cmx270_suspend(struct sys_device *dev, pm_message_t state) | ||
533 | { | ||
534 | cmx270_pci_suspend(); | ||
535 | |||
536 | /* save MSC registers */ | ||
537 | sleep_save_msc[0] = MSC0; | ||
538 | sleep_save_msc[1] = MSC1; | ||
539 | sleep_save_msc[2] = MSC2; | ||
540 | |||
541 | /* setup power saving mode registers */ | ||
542 | PCFR = 0x0; | ||
543 | PSLR = 0xff400000; | ||
544 | PMCR = 0x00000005; | ||
545 | PWER = 0x80000000; | ||
546 | PFER = 0x00000000; | ||
547 | PRER = 0x00000000; | ||
548 | PGSR0 = 0xC0018800; | ||
549 | PGSR1 = 0x004F0002; | ||
550 | PGSR2 = 0x6021C000; | ||
551 | PGSR3 = 0x00020000; | ||
552 | |||
553 | return 0; | ||
554 | } | ||
555 | |||
556 | static int cmx270_resume(struct sys_device *dev) | ||
557 | { | ||
558 | cmx270_pci_resume(); | ||
559 | |||
560 | /* restore MSC registers */ | ||
561 | MSC0 = sleep_save_msc[0]; | ||
562 | MSC1 = sleep_save_msc[1]; | ||
563 | MSC2 = sleep_save_msc[2]; | ||
564 | |||
565 | return 0; | ||
566 | } | ||
567 | |||
568 | static struct sysdev_class cmx270_pm_sysclass = { | ||
569 | set_kset_name("pm"), | ||
570 | .resume = cmx270_resume, | ||
571 | .suspend = cmx270_suspend, | ||
572 | }; | ||
573 | |||
574 | static struct sys_device cmx270_pm_device = { | ||
575 | .cls = &cmx270_pm_sysclass, | ||
576 | }; | ||
577 | |||
578 | static int __init cmx270_pm_init(void) | ||
579 | { | ||
580 | int error; | ||
581 | error = sysdev_class_register(&cmx270_pm_sysclass); | ||
582 | if (error == 0) | ||
583 | error = sysdev_register(&cmx270_pm_device); | ||
584 | return error; | ||
585 | } | ||
586 | #else | ||
587 | static int __init cmx270_pm_init(void) { return 0; } | ||
588 | #endif | ||
589 | |||
590 | static void __init cmx270_init(void) | ||
591 | { | ||
592 | cmx270_pm_init(); | ||
593 | |||
594 | set_pxa_fb_info(cmx270_display); | ||
595 | |||
596 | /* register CM-X270 platform devices */ | ||
597 | platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices)); | ||
598 | |||
599 | /* set MCI and OHCI platform parameters */ | ||
600 | pxa_set_mci_info(&cmx270_mci_platform_data); | ||
601 | pxa_set_ohci_info(&cmx270_ohci_platform_data); | ||
602 | |||
603 | /* This enables the STUART */ | ||
604 | pxa_gpio_mode(GPIO46_STRXD_MD); | ||
605 | pxa_gpio_mode(GPIO47_STTXD_MD); | ||
606 | |||
607 | /* This enables the BTUART */ | ||
608 | pxa_gpio_mode(GPIO42_BTRXD_MD); | ||
609 | pxa_gpio_mode(GPIO43_BTTXD_MD); | ||
610 | pxa_gpio_mode(GPIO44_BTCTS_MD); | ||
611 | pxa_gpio_mode(GPIO45_BTRTS_MD); | ||
612 | } | ||
613 | |||
614 | static void __init cmx270_init_irq(void) | ||
615 | { | ||
616 | pxa27x_init_irq(); | ||
617 | |||
618 | |||
619 | cmx270_pci_init_irq(); | ||
620 | |||
621 | /* Setup interrupt for dm9000 */ | ||
622 | pxa_gpio_mode(IRQ_TO_GPIO(CMX270_ETHIRQ)); | ||
623 | set_irq_type(CMX270_ETHIRQ, IRQT_RISING); | ||
624 | |||
625 | /* Setup interrupt for 2700G */ | ||
626 | pxa_gpio_mode(IRQ_TO_GPIO(CMX270_GFXIRQ)); | ||
627 | set_irq_type(CMX270_GFXIRQ, IRQT_FALLING); | ||
628 | } | ||
629 | |||
630 | static void __init cmx270_map_io(void) | ||
631 | { | ||
632 | pxa_map_io(); | ||
633 | iotable_init(cmx270_io_desc, ARRAY_SIZE(cmx270_io_desc)); | ||
634 | } | ||
635 | |||
636 | |||
637 | MACHINE_START(ARMCORE, "Compulab CM-x270") | ||
638 | .boot_params = 0xa0000100, | ||
639 | .phys_io = 0x40000000, | ||
640 | .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, | ||
641 | .map_io = cmx270_map_io, | ||
642 | .init_irq = cmx270_init_irq, | ||
643 | .timer = &pxa_timer, | ||
644 | .init_machine = cmx270_init, | ||
645 | MACHINE_END | ||