diff options
Diffstat (limited to 'arch/arm/mach-orion5x')
25 files changed, 2900 insertions, 629 deletions
diff --git a/arch/arm/mach-orion5x/Kconfig b/arch/arm/mach-orion5x/Kconfig index 93debf336155..ddcd41b15d17 100644 --- a/arch/arm/mach-orion5x/Kconfig +++ b/arch/arm/mach-orion5x/Kconfig | |||
@@ -44,6 +44,54 @@ config MACH_LINKSTATION_PRO | |||
44 | Buffalo Linkstation Pro/Live platform. Both v1 and | 44 | Buffalo Linkstation Pro/Live platform. Both v1 and |
45 | v2 devices are supported. | 45 | v2 devices are supported. |
46 | 46 | ||
47 | config MACH_TS409 | ||
48 | bool "QNAP TS-409" | ||
49 | help | ||
50 | Say 'Y' here if you want your kernel to support the | ||
51 | QNAP TS-409 platform. | ||
52 | |||
53 | config MACH_WRT350N_V2 | ||
54 | bool "Linksys WRT350N v2" | ||
55 | help | ||
56 | Say 'Y' here if you want your kernel to support the | ||
57 | Linksys WRT350N v2 platform. | ||
58 | |||
59 | config MACH_TS78XX | ||
60 | bool "Technologic Systems TS-78xx" | ||
61 | help | ||
62 | Say 'Y' here if you want your kernel to support the | ||
63 | Technologic Systems TS-78xx platform. | ||
64 | |||
65 | config MACH_MV2120 | ||
66 | bool "HP Media Vault mv2120" | ||
67 | help | ||
68 | Say 'Y' here if you want your kernel to support the | ||
69 | HP Media Vault mv2120 or mv5100. | ||
70 | |||
71 | config MACH_MSS2 | ||
72 | bool "Maxtor Shared Storage II" | ||
73 | help | ||
74 | Say 'Y' here if you want your kernel to support the | ||
75 | Maxtor Shared Storage II platform. | ||
76 | |||
77 | config MACH_WNR854T | ||
78 | bool "Netgear WNR854T" | ||
79 | help | ||
80 | Say 'Y' here if you want your kernel to support the | ||
81 | Netgear WNR854T platform. | ||
82 | |||
83 | config MACH_RD88F5181L_GE | ||
84 | bool "Marvell Orion-VoIP GE Reference Design" | ||
85 | help | ||
86 | Say 'Y' here if you want your kernel to support the | ||
87 | Marvell Orion-VoIP GE (88F5181L) RD. | ||
88 | |||
89 | config MACH_RD88F5181L_FXO | ||
90 | bool "Marvell Orion-VoIP FXO Reference Design" | ||
91 | help | ||
92 | Say 'Y' here if you want your kernel to support the | ||
93 | Marvell Orion-VoIP FXO (88F5181L) RD. | ||
94 | |||
47 | endmenu | 95 | endmenu |
48 | 96 | ||
49 | endif | 97 | endif |
diff --git a/arch/arm/mach-orion5x/Makefile b/arch/arm/mach-orion5x/Makefile index 9301bf55910b..fcc48a8864f3 100644 --- a/arch/arm/mach-orion5x/Makefile +++ b/arch/arm/mach-orion5x/Makefile | |||
@@ -1,7 +1,15 @@ | |||
1 | obj-y += common.o addr-map.o pci.o gpio.o irq.o | 1 | obj-y += common.o addr-map.o pci.o gpio.o irq.o mpp.o |
2 | obj-$(CONFIG_MACH_DB88F5281) += db88f5281-setup.o | 2 | obj-$(CONFIG_MACH_DB88F5281) += db88f5281-setup.o |
3 | obj-$(CONFIG_MACH_RD88F5182) += rd88f5182-setup.o | 3 | obj-$(CONFIG_MACH_RD88F5182) += rd88f5182-setup.o |
4 | obj-$(CONFIG_MACH_KUROBOX_PRO) += kurobox_pro-setup.o | 4 | obj-$(CONFIG_MACH_KUROBOX_PRO) += kurobox_pro-setup.o |
5 | obj-$(CONFIG_MACH_LINKSTATION_PRO) += kurobox_pro-setup.o | 5 | obj-$(CONFIG_MACH_LINKSTATION_PRO) += kurobox_pro-setup.o |
6 | obj-$(CONFIG_MACH_DNS323) += dns323-setup.o | 6 | obj-$(CONFIG_MACH_DNS323) += dns323-setup.o |
7 | obj-$(CONFIG_MACH_TS209) += ts209-setup.o | 7 | obj-$(CONFIG_MACH_TS209) += ts209-setup.o tsx09-common.o |
8 | obj-$(CONFIG_MACH_TS409) += ts409-setup.o tsx09-common.o | ||
9 | obj-$(CONFIG_MACH_WRT350N_V2) += wrt350n-v2-setup.o | ||
10 | obj-$(CONFIG_MACH_TS78XX) += ts78xx-setup.o | ||
11 | obj-$(CONFIG_MACH_MV2120) += mv2120-setup.o | ||
12 | obj-$(CONFIG_MACH_MSS2) += mss2-setup.o | ||
13 | obj-$(CONFIG_MACH_WNR854T) += wnr854t-setup.o | ||
14 | obj-$(CONFIG_MACH_RD88F5181L_GE) += rd88f5181l-ge-setup.o | ||
15 | obj-$(CONFIG_MACH_RD88F5181L_FXO) += rd88f5181l-fxo-setup.o | ||
diff --git a/arch/arm/mach-orion5x/addr-map.c b/arch/arm/mach-orion5x/addr-map.c index e63fb05dc893..6f0dbda6c44c 100644 --- a/arch/arm/mach-orion5x/addr-map.c +++ b/arch/arm/mach-orion5x/addr-map.c | |||
@@ -70,6 +70,7 @@ | |||
70 | 70 | ||
71 | 71 | ||
72 | struct mbus_dram_target_info orion5x_mbus_dram_info; | 72 | struct mbus_dram_target_info orion5x_mbus_dram_info; |
73 | static int __initdata win_alloc_count; | ||
73 | 74 | ||
74 | static int __init orion5x_cpu_win_can_remap(int win) | 75 | static int __init orion5x_cpu_win_can_remap(int win) |
75 | { | 76 | { |
@@ -87,16 +88,22 @@ static int __init orion5x_cpu_win_can_remap(int win) | |||
87 | static void __init setup_cpu_win(int win, u32 base, u32 size, | 88 | static void __init setup_cpu_win(int win, u32 base, u32 size, |
88 | u8 target, u8 attr, int remap) | 89 | u8 target, u8 attr, int remap) |
89 | { | 90 | { |
90 | orion5x_write(CPU_WIN_BASE(win), base & 0xffff0000); | 91 | if (win >= 8) { |
91 | orion5x_write(CPU_WIN_CTRL(win), | 92 | printk(KERN_ERR "setup_cpu_win: trying to allocate " |
92 | ((size - 1) & 0xffff0000) | (attr << 8) | (target << 4) | 1); | 93 | "window %d\n", win); |
94 | return; | ||
95 | } | ||
96 | |||
97 | writel(base & 0xffff0000, CPU_WIN_BASE(win)); | ||
98 | writel(((size - 1) & 0xffff0000) | (attr << 8) | (target << 4) | 1, | ||
99 | CPU_WIN_CTRL(win)); | ||
93 | 100 | ||
94 | if (orion5x_cpu_win_can_remap(win)) { | 101 | if (orion5x_cpu_win_can_remap(win)) { |
95 | if (remap < 0) | 102 | if (remap < 0) |
96 | remap = base; | 103 | remap = base; |
97 | 104 | ||
98 | orion5x_write(CPU_WIN_REMAP_LO(win), remap & 0xffff0000); | 105 | writel(remap & 0xffff0000, CPU_WIN_REMAP_LO(win)); |
99 | orion5x_write(CPU_WIN_REMAP_HI(win), 0); | 106 | writel(0, CPU_WIN_REMAP_HI(win)); |
100 | } | 107 | } |
101 | } | 108 | } |
102 | 109 | ||
@@ -109,11 +116,11 @@ void __init orion5x_setup_cpu_mbus_bridge(void) | |||
109 | * First, disable and clear windows. | 116 | * First, disable and clear windows. |
110 | */ | 117 | */ |
111 | for (i = 0; i < 8; i++) { | 118 | for (i = 0; i < 8; i++) { |
112 | orion5x_write(CPU_WIN_BASE(i), 0); | 119 | writel(0, CPU_WIN_BASE(i)); |
113 | orion5x_write(CPU_WIN_CTRL(i), 0); | 120 | writel(0, CPU_WIN_CTRL(i)); |
114 | if (orion5x_cpu_win_can_remap(i)) { | 121 | if (orion5x_cpu_win_can_remap(i)) { |
115 | orion5x_write(CPU_WIN_REMAP_LO(i), 0); | 122 | writel(0, CPU_WIN_REMAP_LO(i)); |
116 | orion5x_write(CPU_WIN_REMAP_HI(i), 0); | 123 | writel(0, CPU_WIN_REMAP_HI(i)); |
117 | } | 124 | } |
118 | } | 125 | } |
119 | 126 | ||
@@ -128,6 +135,7 @@ void __init orion5x_setup_cpu_mbus_bridge(void) | |||
128 | TARGET_PCIE, ATTR_PCIE_MEM, -1); | 135 | TARGET_PCIE, ATTR_PCIE_MEM, -1); |
129 | setup_cpu_win(3, ORION5X_PCI_MEM_PHYS_BASE, ORION5X_PCI_MEM_SIZE, | 136 | setup_cpu_win(3, ORION5X_PCI_MEM_PHYS_BASE, ORION5X_PCI_MEM_SIZE, |
130 | TARGET_PCI, ATTR_PCI_MEM, -1); | 137 | TARGET_PCI, ATTR_PCI_MEM, -1); |
138 | win_alloc_count = 4; | ||
131 | 139 | ||
132 | /* | 140 | /* |
133 | * Setup MBUS dram target info. | 141 | * Setup MBUS dram target info. |
@@ -147,8 +155,8 @@ void __init orion5x_setup_cpu_mbus_bridge(void) | |||
147 | w = &orion5x_mbus_dram_info.cs[cs++]; | 155 | w = &orion5x_mbus_dram_info.cs[cs++]; |
148 | w->cs_index = i; | 156 | w->cs_index = i; |
149 | w->mbus_attr = 0xf & ~(1 << i); | 157 | w->mbus_attr = 0xf & ~(1 << i); |
150 | w->base = base & 0xff000000; | 158 | w->base = base & 0xffff0000; |
151 | w->size = (size | 0x00ffffff) + 1; | 159 | w->size = (size | 0x0000ffff) + 1; |
152 | } | 160 | } |
153 | } | 161 | } |
154 | orion5x_mbus_dram_info.num_cs = cs; | 162 | orion5x_mbus_dram_info.num_cs = cs; |
@@ -156,25 +164,30 @@ void __init orion5x_setup_cpu_mbus_bridge(void) | |||
156 | 164 | ||
157 | void __init orion5x_setup_dev_boot_win(u32 base, u32 size) | 165 | void __init orion5x_setup_dev_boot_win(u32 base, u32 size) |
158 | { | 166 | { |
159 | setup_cpu_win(4, base, size, TARGET_DEV_BUS, ATTR_DEV_BOOT, -1); | 167 | setup_cpu_win(win_alloc_count++, base, size, |
168 | TARGET_DEV_BUS, ATTR_DEV_BOOT, -1); | ||
160 | } | 169 | } |
161 | 170 | ||
162 | void __init orion5x_setup_dev0_win(u32 base, u32 size) | 171 | void __init orion5x_setup_dev0_win(u32 base, u32 size) |
163 | { | 172 | { |
164 | setup_cpu_win(5, base, size, TARGET_DEV_BUS, ATTR_DEV_CS0, -1); | 173 | setup_cpu_win(win_alloc_count++, base, size, |
174 | TARGET_DEV_BUS, ATTR_DEV_CS0, -1); | ||
165 | } | 175 | } |
166 | 176 | ||
167 | void __init orion5x_setup_dev1_win(u32 base, u32 size) | 177 | void __init orion5x_setup_dev1_win(u32 base, u32 size) |
168 | { | 178 | { |
169 | setup_cpu_win(6, base, size, TARGET_DEV_BUS, ATTR_DEV_CS1, -1); | 179 | setup_cpu_win(win_alloc_count++, base, size, |
180 | TARGET_DEV_BUS, ATTR_DEV_CS1, -1); | ||
170 | } | 181 | } |
171 | 182 | ||
172 | void __init orion5x_setup_dev2_win(u32 base, u32 size) | 183 | void __init orion5x_setup_dev2_win(u32 base, u32 size) |
173 | { | 184 | { |
174 | setup_cpu_win(7, base, size, TARGET_DEV_BUS, ATTR_DEV_CS2, -1); | 185 | setup_cpu_win(win_alloc_count++, base, size, |
186 | TARGET_DEV_BUS, ATTR_DEV_CS2, -1); | ||
175 | } | 187 | } |
176 | 188 | ||
177 | void __init orion5x_setup_pcie_wa_win(u32 base, u32 size) | 189 | void __init orion5x_setup_pcie_wa_win(u32 base, u32 size) |
178 | { | 190 | { |
179 | setup_cpu_win(7, base, size, TARGET_PCIE, ATTR_PCIE_WA, -1); | 191 | setup_cpu_win(win_alloc_count++, base, size, |
192 | TARGET_PCIE, ATTR_PCIE_WA, -1); | ||
180 | } | 193 | } |
diff --git a/arch/arm/mach-orion5x/common.c b/arch/arm/mach-orion5x/common.c index 4f13fd037f04..faf4e3211918 100644 --- a/arch/arm/mach-orion5x/common.c +++ b/arch/arm/mach-orion5x/common.c | |||
@@ -39,25 +39,22 @@ static struct map_desc orion5x_io_desc[] __initdata = { | |||
39 | .virtual = ORION5X_REGS_VIRT_BASE, | 39 | .virtual = ORION5X_REGS_VIRT_BASE, |
40 | .pfn = __phys_to_pfn(ORION5X_REGS_PHYS_BASE), | 40 | .pfn = __phys_to_pfn(ORION5X_REGS_PHYS_BASE), |
41 | .length = ORION5X_REGS_SIZE, | 41 | .length = ORION5X_REGS_SIZE, |
42 | .type = MT_DEVICE | 42 | .type = MT_DEVICE, |
43 | }, | 43 | }, { |
44 | { | ||
45 | .virtual = ORION5X_PCIE_IO_VIRT_BASE, | 44 | .virtual = ORION5X_PCIE_IO_VIRT_BASE, |
46 | .pfn = __phys_to_pfn(ORION5X_PCIE_IO_PHYS_BASE), | 45 | .pfn = __phys_to_pfn(ORION5X_PCIE_IO_PHYS_BASE), |
47 | .length = ORION5X_PCIE_IO_SIZE, | 46 | .length = ORION5X_PCIE_IO_SIZE, |
48 | .type = MT_DEVICE | 47 | .type = MT_DEVICE, |
49 | }, | 48 | }, { |
50 | { | ||
51 | .virtual = ORION5X_PCI_IO_VIRT_BASE, | 49 | .virtual = ORION5X_PCI_IO_VIRT_BASE, |
52 | .pfn = __phys_to_pfn(ORION5X_PCI_IO_PHYS_BASE), | 50 | .pfn = __phys_to_pfn(ORION5X_PCI_IO_PHYS_BASE), |
53 | .length = ORION5X_PCI_IO_SIZE, | 51 | .length = ORION5X_PCI_IO_SIZE, |
54 | .type = MT_DEVICE | 52 | .type = MT_DEVICE, |
55 | }, | 53 | }, { |
56 | { | ||
57 | .virtual = ORION5X_PCIE_WA_VIRT_BASE, | 54 | .virtual = ORION5X_PCIE_WA_VIRT_BASE, |
58 | .pfn = __phys_to_pfn(ORION5X_PCIE_WA_PHYS_BASE), | 55 | .pfn = __phys_to_pfn(ORION5X_PCIE_WA_PHYS_BASE), |
59 | .length = ORION5X_PCIE_WA_SIZE, | 56 | .length = ORION5X_PCIE_WA_SIZE, |
60 | .type = MT_DEVICE | 57 | .type = MT_DEVICE, |
61 | }, | 58 | }, |
62 | }; | 59 | }; |
63 | 60 | ||
@@ -66,101 +63,32 @@ void __init orion5x_map_io(void) | |||
66 | iotable_init(orion5x_io_desc, ARRAY_SIZE(orion5x_io_desc)); | 63 | iotable_init(orion5x_io_desc, ARRAY_SIZE(orion5x_io_desc)); |
67 | } | 64 | } |
68 | 65 | ||
66 | |||
69 | /***************************************************************************** | 67 | /***************************************************************************** |
70 | * UART | 68 | * EHCI |
71 | ****************************************************************************/ | 69 | ****************************************************************************/ |
72 | 70 | static struct orion_ehci_data orion5x_ehci_data = { | |
73 | static struct resource orion5x_uart_resources[] = { | 71 | .dram = &orion5x_mbus_dram_info, |
74 | { | ||
75 | .start = UART0_PHYS_BASE, | ||
76 | .end = UART0_PHYS_BASE + 0xff, | ||
77 | .flags = IORESOURCE_MEM, | ||
78 | }, | ||
79 | { | ||
80 | .start = IRQ_ORION5X_UART0, | ||
81 | .end = IRQ_ORION5X_UART0, | ||
82 | .flags = IORESOURCE_IRQ, | ||
83 | }, | ||
84 | { | ||
85 | .start = UART1_PHYS_BASE, | ||
86 | .end = UART1_PHYS_BASE + 0xff, | ||
87 | .flags = IORESOURCE_MEM, | ||
88 | }, | ||
89 | { | ||
90 | .start = IRQ_ORION5X_UART1, | ||
91 | .end = IRQ_ORION5X_UART1, | ||
92 | .flags = IORESOURCE_IRQ, | ||
93 | }, | ||
94 | }; | ||
95 | |||
96 | static struct plat_serial8250_port orion5x_uart_data[] = { | ||
97 | { | ||
98 | .mapbase = UART0_PHYS_BASE, | ||
99 | .membase = (char *)UART0_VIRT_BASE, | ||
100 | .irq = IRQ_ORION5X_UART0, | ||
101 | .flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF, | ||
102 | .iotype = UPIO_MEM, | ||
103 | .regshift = 2, | ||
104 | .uartclk = ORION5X_TCLK, | ||
105 | }, | ||
106 | { | ||
107 | .mapbase = UART1_PHYS_BASE, | ||
108 | .membase = (char *)UART1_VIRT_BASE, | ||
109 | .irq = IRQ_ORION5X_UART1, | ||
110 | .flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF, | ||
111 | .iotype = UPIO_MEM, | ||
112 | .regshift = 2, | ||
113 | .uartclk = ORION5X_TCLK, | ||
114 | }, | ||
115 | { }, | ||
116 | }; | 72 | }; |
117 | 73 | ||
118 | static struct platform_device orion5x_uart = { | 74 | static u64 ehci_dmamask = 0xffffffffUL; |
119 | .name = "serial8250", | ||
120 | .id = PLAT8250_DEV_PLATFORM, | ||
121 | .dev = { | ||
122 | .platform_data = orion5x_uart_data, | ||
123 | }, | ||
124 | .resource = orion5x_uart_resources, | ||
125 | .num_resources = ARRAY_SIZE(orion5x_uart_resources), | ||
126 | }; | ||
127 | 75 | ||
128 | /******************************************************************************* | ||
129 | * USB Controller - 2 interfaces | ||
130 | ******************************************************************************/ | ||
131 | 76 | ||
77 | /***************************************************************************** | ||
78 | * EHCI0 | ||
79 | ****************************************************************************/ | ||
132 | static struct resource orion5x_ehci0_resources[] = { | 80 | static struct resource orion5x_ehci0_resources[] = { |
133 | { | 81 | { |
134 | .start = ORION5X_USB0_PHYS_BASE, | 82 | .start = ORION5X_USB0_PHYS_BASE, |
135 | .end = ORION5X_USB0_PHYS_BASE + SZ_4K - 1, | 83 | .end = ORION5X_USB0_PHYS_BASE + SZ_4K - 1, |
136 | .flags = IORESOURCE_MEM, | 84 | .flags = IORESOURCE_MEM, |
137 | }, | 85 | }, { |
138 | { | ||
139 | .start = IRQ_ORION5X_USB0_CTRL, | 86 | .start = IRQ_ORION5X_USB0_CTRL, |
140 | .end = IRQ_ORION5X_USB0_CTRL, | 87 | .end = IRQ_ORION5X_USB0_CTRL, |
141 | .flags = IORESOURCE_IRQ, | 88 | .flags = IORESOURCE_IRQ, |
142 | }, | 89 | }, |
143 | }; | 90 | }; |
144 | 91 | ||
145 | static struct resource orion5x_ehci1_resources[] = { | ||
146 | { | ||
147 | .start = ORION5X_USB1_PHYS_BASE, | ||
148 | .end = ORION5X_USB1_PHYS_BASE + SZ_4K - 1, | ||
149 | .flags = IORESOURCE_MEM, | ||
150 | }, | ||
151 | { | ||
152 | .start = IRQ_ORION5X_USB1_CTRL, | ||
153 | .end = IRQ_ORION5X_USB1_CTRL, | ||
154 | .flags = IORESOURCE_IRQ, | ||
155 | }, | ||
156 | }; | ||
157 | |||
158 | static struct orion_ehci_data orion5x_ehci_data = { | ||
159 | .dram = &orion5x_mbus_dram_info, | ||
160 | }; | ||
161 | |||
162 | static u64 ehci_dmamask = 0xffffffffUL; | ||
163 | |||
164 | static struct platform_device orion5x_ehci0 = { | 92 | static struct platform_device orion5x_ehci0 = { |
165 | .name = "orion-ehci", | 93 | .name = "orion-ehci", |
166 | .id = 0, | 94 | .id = 0, |
@@ -173,6 +101,27 @@ static struct platform_device orion5x_ehci0 = { | |||
173 | .num_resources = ARRAY_SIZE(orion5x_ehci0_resources), | 101 | .num_resources = ARRAY_SIZE(orion5x_ehci0_resources), |
174 | }; | 102 | }; |
175 | 103 | ||
104 | void __init orion5x_ehci0_init(void) | ||
105 | { | ||
106 | platform_device_register(&orion5x_ehci0); | ||
107 | } | ||
108 | |||
109 | |||
110 | /***************************************************************************** | ||
111 | * EHCI1 | ||
112 | ****************************************************************************/ | ||
113 | static struct resource orion5x_ehci1_resources[] = { | ||
114 | { | ||
115 | .start = ORION5X_USB1_PHYS_BASE, | ||
116 | .end = ORION5X_USB1_PHYS_BASE + SZ_4K - 1, | ||
117 | .flags = IORESOURCE_MEM, | ||
118 | }, { | ||
119 | .start = IRQ_ORION5X_USB1_CTRL, | ||
120 | .end = IRQ_ORION5X_USB1_CTRL, | ||
121 | .flags = IORESOURCE_IRQ, | ||
122 | }, | ||
123 | }; | ||
124 | |||
176 | static struct platform_device orion5x_ehci1 = { | 125 | static struct platform_device orion5x_ehci1 = { |
177 | .name = "orion-ehci", | 126 | .name = "orion-ehci", |
178 | .id = 1, | 127 | .id = 1, |
@@ -185,11 +134,15 @@ static struct platform_device orion5x_ehci1 = { | |||
185 | .num_resources = ARRAY_SIZE(orion5x_ehci1_resources), | 134 | .num_resources = ARRAY_SIZE(orion5x_ehci1_resources), |
186 | }; | 135 | }; |
187 | 136 | ||
137 | void __init orion5x_ehci1_init(void) | ||
138 | { | ||
139 | platform_device_register(&orion5x_ehci1); | ||
140 | } | ||
141 | |||
142 | |||
188 | /***************************************************************************** | 143 | /***************************************************************************** |
189 | * Gigabit Ethernet port | 144 | * GigE |
190 | * (The Orion and Discovery (MV643xx) families use the same Ethernet driver) | ||
191 | ****************************************************************************/ | 145 | ****************************************************************************/ |
192 | |||
193 | struct mv643xx_eth_shared_platform_data orion5x_eth_shared_data = { | 146 | struct mv643xx_eth_shared_platform_data orion5x_eth_shared_data = { |
194 | .dram = &orion5x_mbus_dram_info, | 147 | .dram = &orion5x_mbus_dram_info, |
195 | .t_clk = ORION5X_TCLK, | 148 | .t_clk = ORION5X_TCLK, |
@@ -219,7 +172,7 @@ static struct resource orion5x_eth_resources[] = { | |||
219 | .start = IRQ_ORION5X_ETH_SUM, | 172 | .start = IRQ_ORION5X_ETH_SUM, |
220 | .end = IRQ_ORION5X_ETH_SUM, | 173 | .end = IRQ_ORION5X_ETH_SUM, |
221 | .flags = IORESOURCE_IRQ, | 174 | .flags = IORESOURCE_IRQ, |
222 | } | 175 | }, |
223 | }; | 176 | }; |
224 | 177 | ||
225 | static struct platform_device orion5x_eth = { | 178 | static struct platform_device orion5x_eth = { |
@@ -238,11 +191,10 @@ void __init orion5x_eth_init(struct mv643xx_eth_platform_data *eth_data) | |||
238 | platform_device_register(&orion5x_eth); | 191 | platform_device_register(&orion5x_eth); |
239 | } | 192 | } |
240 | 193 | ||
194 | |||
241 | /***************************************************************************** | 195 | /***************************************************************************** |
242 | * I2C controller | 196 | * I2C |
243 | * (The Orion and Discovery (MV643xx) families share the same I2C controller) | ||
244 | ****************************************************************************/ | 197 | ****************************************************************************/ |
245 | |||
246 | static struct mv64xxx_i2c_pdata orion5x_i2c_pdata = { | 198 | static struct mv64xxx_i2c_pdata orion5x_i2c_pdata = { |
247 | .freq_m = 8, /* assumes 166 MHz TCLK */ | 199 | .freq_m = 8, /* assumes 166 MHz TCLK */ |
248 | .freq_n = 3, | 200 | .freq_n = 3, |
@@ -251,16 +203,15 @@ static struct mv64xxx_i2c_pdata orion5x_i2c_pdata = { | |||
251 | 203 | ||
252 | static struct resource orion5x_i2c_resources[] = { | 204 | static struct resource orion5x_i2c_resources[] = { |
253 | { | 205 | { |
254 | .name = "i2c base", | 206 | .name = "i2c base", |
255 | .start = I2C_PHYS_BASE, | 207 | .start = I2C_PHYS_BASE, |
256 | .end = I2C_PHYS_BASE + 0x20 -1, | 208 | .end = I2C_PHYS_BASE + 0x1f, |
257 | .flags = IORESOURCE_MEM, | 209 | .flags = IORESOURCE_MEM, |
258 | }, | 210 | }, { |
259 | { | 211 | .name = "i2c irq", |
260 | .name = "i2c irq", | 212 | .start = IRQ_ORION5X_I2C, |
261 | .start = IRQ_ORION5X_I2C, | 213 | .end = IRQ_ORION5X_I2C, |
262 | .end = IRQ_ORION5X_I2C, | 214 | .flags = IORESOURCE_IRQ, |
263 | .flags = IORESOURCE_IRQ, | ||
264 | }, | 215 | }, |
265 | }; | 216 | }; |
266 | 217 | ||
@@ -270,36 +221,41 @@ static struct platform_device orion5x_i2c = { | |||
270 | .num_resources = ARRAY_SIZE(orion5x_i2c_resources), | 221 | .num_resources = ARRAY_SIZE(orion5x_i2c_resources), |
271 | .resource = orion5x_i2c_resources, | 222 | .resource = orion5x_i2c_resources, |
272 | .dev = { | 223 | .dev = { |
273 | .platform_data = &orion5x_i2c_pdata, | 224 | .platform_data = &orion5x_i2c_pdata, |
274 | }, | 225 | }, |
275 | }; | 226 | }; |
276 | 227 | ||
228 | void __init orion5x_i2c_init(void) | ||
229 | { | ||
230 | platform_device_register(&orion5x_i2c); | ||
231 | } | ||
232 | |||
233 | |||
277 | /***************************************************************************** | 234 | /***************************************************************************** |
278 | * Sata port | 235 | * SATA |
279 | ****************************************************************************/ | 236 | ****************************************************************************/ |
280 | static struct resource orion5x_sata_resources[] = { | 237 | static struct resource orion5x_sata_resources[] = { |
281 | { | ||
282 | .name = "sata base", | ||
283 | .start = ORION5X_SATA_PHYS_BASE, | ||
284 | .end = ORION5X_SATA_PHYS_BASE + 0x5000 - 1, | ||
285 | .flags = IORESOURCE_MEM, | ||
286 | }, | ||
287 | { | 238 | { |
288 | .name = "sata irq", | 239 | .name = "sata base", |
289 | .start = IRQ_ORION5X_SATA, | 240 | .start = ORION5X_SATA_PHYS_BASE, |
290 | .end = IRQ_ORION5X_SATA, | 241 | .end = ORION5X_SATA_PHYS_BASE + 0x5000 - 1, |
291 | .flags = IORESOURCE_IRQ, | 242 | .flags = IORESOURCE_MEM, |
292 | }, | 243 | }, { |
244 | .name = "sata irq", | ||
245 | .start = IRQ_ORION5X_SATA, | ||
246 | .end = IRQ_ORION5X_SATA, | ||
247 | .flags = IORESOURCE_IRQ, | ||
248 | }, | ||
293 | }; | 249 | }; |
294 | 250 | ||
295 | static struct platform_device orion5x_sata = { | 251 | static struct platform_device orion5x_sata = { |
296 | .name = "sata_mv", | 252 | .name = "sata_mv", |
297 | .id = 0, | 253 | .id = 0, |
298 | .dev = { | 254 | .dev = { |
299 | .coherent_dma_mask = 0xffffffff, | 255 | .coherent_dma_mask = 0xffffffff, |
300 | }, | 256 | }, |
301 | .num_resources = ARRAY_SIZE(orion5x_sata_resources), | 257 | .num_resources = ARRAY_SIZE(orion5x_sata_resources), |
302 | .resource = orion5x_sata_resources, | 258 | .resource = orion5x_sata_resources, |
303 | }; | 259 | }; |
304 | 260 | ||
305 | void __init orion5x_sata_init(struct mv_sata_platform_data *sata_data) | 261 | void __init orion5x_sata_init(struct mv_sata_platform_data *sata_data) |
@@ -309,23 +265,111 @@ void __init orion5x_sata_init(struct mv_sata_platform_data *sata_data) | |||
309 | platform_device_register(&orion5x_sata); | 265 | platform_device_register(&orion5x_sata); |
310 | } | 266 | } |
311 | 267 | ||
268 | |||
312 | /***************************************************************************** | 269 | /***************************************************************************** |
313 | * Time handling | 270 | * UART0 |
271 | ****************************************************************************/ | ||
272 | static struct plat_serial8250_port orion5x_uart0_data[] = { | ||
273 | { | ||
274 | .mapbase = UART0_PHYS_BASE, | ||
275 | .membase = (char *)UART0_VIRT_BASE, | ||
276 | .irq = IRQ_ORION5X_UART0, | ||
277 | .flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF, | ||
278 | .iotype = UPIO_MEM, | ||
279 | .regshift = 2, | ||
280 | .uartclk = ORION5X_TCLK, | ||
281 | }, { | ||
282 | }, | ||
283 | }; | ||
284 | |||
285 | static struct resource orion5x_uart0_resources[] = { | ||
286 | { | ||
287 | .start = UART0_PHYS_BASE, | ||
288 | .end = UART0_PHYS_BASE + 0xff, | ||
289 | .flags = IORESOURCE_MEM, | ||
290 | }, { | ||
291 | .start = IRQ_ORION5X_UART0, | ||
292 | .end = IRQ_ORION5X_UART0, | ||
293 | .flags = IORESOURCE_IRQ, | ||
294 | }, | ||
295 | }; | ||
296 | |||
297 | static struct platform_device orion5x_uart0 = { | ||
298 | .name = "serial8250", | ||
299 | .id = PLAT8250_DEV_PLATFORM, | ||
300 | .dev = { | ||
301 | .platform_data = orion5x_uart0_data, | ||
302 | }, | ||
303 | .resource = orion5x_uart0_resources, | ||
304 | .num_resources = ARRAY_SIZE(orion5x_uart0_resources), | ||
305 | }; | ||
306 | |||
307 | void __init orion5x_uart0_init(void) | ||
308 | { | ||
309 | platform_device_register(&orion5x_uart0); | ||
310 | } | ||
311 | |||
312 | |||
313 | /***************************************************************************** | ||
314 | * UART1 | ||
314 | ****************************************************************************/ | 315 | ****************************************************************************/ |
316 | static struct plat_serial8250_port orion5x_uart1_data[] = { | ||
317 | { | ||
318 | .mapbase = UART1_PHYS_BASE, | ||
319 | .membase = (char *)UART1_VIRT_BASE, | ||
320 | .irq = IRQ_ORION5X_UART1, | ||
321 | .flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF, | ||
322 | .iotype = UPIO_MEM, | ||
323 | .regshift = 2, | ||
324 | .uartclk = ORION5X_TCLK, | ||
325 | }, { | ||
326 | }, | ||
327 | }; | ||
328 | |||
329 | static struct resource orion5x_uart1_resources[] = { | ||
330 | { | ||
331 | .start = UART1_PHYS_BASE, | ||
332 | .end = UART1_PHYS_BASE + 0xff, | ||
333 | .flags = IORESOURCE_MEM, | ||
334 | }, { | ||
335 | .start = IRQ_ORION5X_UART1, | ||
336 | .end = IRQ_ORION5X_UART1, | ||
337 | .flags = IORESOURCE_IRQ, | ||
338 | }, | ||
339 | }; | ||
340 | |||
341 | static struct platform_device orion5x_uart1 = { | ||
342 | .name = "serial8250", | ||
343 | .id = PLAT8250_DEV_PLATFORM1, | ||
344 | .dev = { | ||
345 | .platform_data = orion5x_uart1_data, | ||
346 | }, | ||
347 | .resource = orion5x_uart1_resources, | ||
348 | .num_resources = ARRAY_SIZE(orion5x_uart1_resources), | ||
349 | }; | ||
350 | |||
351 | void __init orion5x_uart1_init(void) | ||
352 | { | ||
353 | platform_device_register(&orion5x_uart1); | ||
354 | } | ||
355 | |||
315 | 356 | ||
357 | /***************************************************************************** | ||
358 | * Time handling | ||
359 | ****************************************************************************/ | ||
316 | static void orion5x_timer_init(void) | 360 | static void orion5x_timer_init(void) |
317 | { | 361 | { |
318 | orion_time_init(IRQ_ORION5X_BRIDGE, ORION5X_TCLK); | 362 | orion_time_init(IRQ_ORION5X_BRIDGE, ORION5X_TCLK); |
319 | } | 363 | } |
320 | 364 | ||
321 | struct sys_timer orion5x_timer = { | 365 | struct sys_timer orion5x_timer = { |
322 | .init = orion5x_timer_init, | 366 | .init = orion5x_timer_init, |
323 | }; | 367 | }; |
324 | 368 | ||
369 | |||
325 | /***************************************************************************** | 370 | /***************************************************************************** |
326 | * General | 371 | * General |
327 | ****************************************************************************/ | 372 | ****************************************************************************/ |
328 | |||
329 | /* | 373 | /* |
330 | * Identify device ID and rev from PCIe configuration header space '0'. | 374 | * Identify device ID and rev from PCIe configuration header space '0'. |
331 | */ | 375 | */ |
@@ -350,8 +394,10 @@ static void __init orion5x_id(u32 *dev, u32 *rev, char **dev_name) | |||
350 | } else if (*dev == MV88F5181_DEV_ID) { | 394 | } else if (*dev == MV88F5181_DEV_ID) { |
351 | if (*rev == MV88F5181_REV_B1) { | 395 | if (*rev == MV88F5181_REV_B1) { |
352 | *dev_name = "MV88F5181-Rev-B1"; | 396 | *dev_name = "MV88F5181-Rev-B1"; |
397 | } else if (*rev == MV88F5181L_REV_A1) { | ||
398 | *dev_name = "MV88F5181L-Rev-A1"; | ||
353 | } else { | 399 | } else { |
354 | *dev_name = "MV88F5181-Rev-Unsupported"; | 400 | *dev_name = "MV88F5181(L)-Rev-Unsupported"; |
355 | } | 401 | } |
356 | } else { | 402 | } else { |
357 | *dev_name = "Device-Unknown"; | 403 | *dev_name = "Device-Unknown"; |
@@ -370,15 +416,6 @@ void __init orion5x_init(void) | |||
370 | * Setup Orion address map | 416 | * Setup Orion address map |
371 | */ | 417 | */ |
372 | orion5x_setup_cpu_mbus_bridge(); | 418 | orion5x_setup_cpu_mbus_bridge(); |
373 | |||
374 | /* | ||
375 | * Register devices. | ||
376 | */ | ||
377 | platform_device_register(&orion5x_uart); | ||
378 | platform_device_register(&orion5x_ehci0); | ||
379 | if (dev == MV88F5182_DEV_ID) | ||
380 | platform_device_register(&orion5x_ehci1); | ||
381 | platform_device_register(&orion5x_i2c); | ||
382 | } | 419 | } |
383 | 420 | ||
384 | /* | 421 | /* |
diff --git a/arch/arm/mach-orion5x/common.h b/arch/arm/mach-orion5x/common.h index bd0f05de6e18..f72cf0e77544 100644 --- a/arch/arm/mach-orion5x/common.h +++ b/arch/arm/mach-orion5x/common.h | |||
@@ -1,10 +1,12 @@ | |||
1 | #ifndef __ARCH_ORION5X_COMMON_H | 1 | #ifndef __ARCH_ORION5X_COMMON_H |
2 | #define __ARCH_ORION5X_COMMON_H | 2 | #define __ARCH_ORION5X_COMMON_H |
3 | 3 | ||
4 | struct mv643xx_eth_platform_data; | ||
5 | struct mv_sata_platform_data; | ||
6 | |||
4 | /* | 7 | /* |
5 | * Basic Orion init functions used early by machine-setup. | 8 | * Basic Orion init functions used early by machine-setup. |
6 | */ | 9 | */ |
7 | |||
8 | void orion5x_map_io(void); | 10 | void orion5x_map_io(void); |
9 | void orion5x_init_irq(void); | 11 | void orion5x_init_irq(void); |
10 | void orion5x_init(void); | 12 | void orion5x_init(void); |
@@ -23,15 +25,22 @@ void orion5x_setup_dev1_win(u32 base, u32 size); | |||
23 | void orion5x_setup_dev2_win(u32 base, u32 size); | 25 | void orion5x_setup_dev2_win(u32 base, u32 size); |
24 | void orion5x_setup_pcie_wa_win(u32 base, u32 size); | 26 | void orion5x_setup_pcie_wa_win(u32 base, u32 size); |
25 | 27 | ||
28 | void orion5x_ehci0_init(void); | ||
29 | void orion5x_ehci1_init(void); | ||
30 | void orion5x_eth_init(struct mv643xx_eth_platform_data *eth_data); | ||
31 | void orion5x_i2c_init(void); | ||
32 | void orion5x_sata_init(struct mv_sata_platform_data *sata_data); | ||
33 | void orion5x_uart0_init(void); | ||
34 | void orion5x_uart1_init(void); | ||
35 | |||
26 | /* | 36 | /* |
27 | * Shared code used internally by other Orion core functions. | 37 | * PCIe/PCI functions. |
28 | * (/mach-orion/pci.c) | ||
29 | */ | 38 | */ |
30 | |||
31 | struct pci_sys_data; | ||
32 | struct pci_bus; | 39 | struct pci_bus; |
40 | struct pci_sys_data; | ||
33 | 41 | ||
34 | void orion5x_pcie_id(u32 *dev, u32 *rev); | 42 | void orion5x_pcie_id(u32 *dev, u32 *rev); |
43 | void orion5x_pci_set_cardbus_mode(void); | ||
35 | int orion5x_pci_sys_setup(int nr, struct pci_sys_data *sys); | 44 | int orion5x_pci_sys_setup(int nr, struct pci_sys_data *sys); |
36 | struct pci_bus *orion5x_pci_sys_scan_bus(int nr, struct pci_sys_data *sys); | 45 | struct pci_bus *orion5x_pci_sys_scan_bus(int nr, struct pci_sys_data *sys); |
37 | int orion5x_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin); | 46 | int orion5x_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin); |
@@ -40,26 +49,9 @@ int orion5x_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin); | |||
40 | * Valid GPIO pins according to MPP setup, used by machine-setup. | 49 | * Valid GPIO pins according to MPP setup, used by machine-setup. |
41 | * (/mach-orion/gpio.c). | 50 | * (/mach-orion/gpio.c). |
42 | */ | 51 | */ |
43 | 52 | void orion5x_gpio_set_valid(unsigned pin, int valid); | |
44 | void orion5x_gpio_set_valid_pins(u32 pins); | ||
45 | void gpio_display(void); /* debug */ | 53 | void gpio_display(void); /* debug */ |
46 | 54 | ||
47 | /* | ||
48 | * Pull in Orion Ethernet platform_data, used by machine-setup | ||
49 | */ | ||
50 | |||
51 | struct mv643xx_eth_platform_data; | ||
52 | |||
53 | void orion5x_eth_init(struct mv643xx_eth_platform_data *eth_data); | ||
54 | |||
55 | /* | ||
56 | * Orion Sata platform_data, used by machine-setup | ||
57 | */ | ||
58 | |||
59 | struct mv_sata_platform_data; | ||
60 | |||
61 | void orion5x_sata_init(struct mv_sata_platform_data *sata_data); | ||
62 | |||
63 | struct machine_desc; | 55 | struct machine_desc; |
64 | struct meminfo; | 56 | struct meminfo; |
65 | struct tag; | 57 | struct tag; |
diff --git a/arch/arm/mach-orion5x/db88f5281-setup.c b/arch/arm/mach-orion5x/db88f5281-setup.c index 44c64342dacb..88405e74e5e3 100644 --- a/arch/arm/mach-orion5x/db88f5281-setup.c +++ b/arch/arm/mach-orion5x/db88f5281-setup.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <asm/arch/orion5x.h> | 27 | #include <asm/arch/orion5x.h> |
28 | #include <asm/plat-orion/orion_nand.h> | 28 | #include <asm/plat-orion/orion_nand.h> |
29 | #include "common.h" | 29 | #include "common.h" |
30 | #include "mpp.h" | ||
30 | 31 | ||
31 | /***************************************************************************** | 32 | /***************************************************************************** |
32 | * DB-88F5281 on board devices | 33 | * DB-88F5281 on board devices |
@@ -86,7 +87,7 @@ static struct platform_device db88f5281_boot_flash = { | |||
86 | .name = "physmap-flash", | 87 | .name = "physmap-flash", |
87 | .id = 0, | 88 | .id = 0, |
88 | .dev = { | 89 | .dev = { |
89 | .platform_data = &db88f5281_boot_flash_data, | 90 | .platform_data = &db88f5281_boot_flash_data, |
90 | }, | 91 | }, |
91 | .num_resources = 1, | 92 | .num_resources = 1, |
92 | .resource = &db88f5281_boot_flash_resource, | 93 | .resource = &db88f5281_boot_flash_resource, |
@@ -110,7 +111,7 @@ static struct platform_device db88f5281_nor_flash = { | |||
110 | .name = "physmap-flash", | 111 | .name = "physmap-flash", |
111 | .id = 1, | 112 | .id = 1, |
112 | .dev = { | 113 | .dev = { |
113 | .platform_data = &db88f5281_nor_flash_data, | 114 | .platform_data = &db88f5281_nor_flash_data, |
114 | }, | 115 | }, |
115 | .num_resources = 1, | 116 | .num_resources = 1, |
116 | .resource = &db88f5281_nor_flash_resource, | 117 | .resource = &db88f5281_nor_flash_resource, |
@@ -125,18 +126,15 @@ static struct mtd_partition db88f5281_nand_parts[] = { | |||
125 | .name = "kernel", | 126 | .name = "kernel", |
126 | .offset = 0, | 127 | .offset = 0, |
127 | .size = SZ_2M, | 128 | .size = SZ_2M, |
128 | }, | 129 | }, { |
129 | { | ||
130 | .name = "root", | 130 | .name = "root", |
131 | .offset = SZ_2M, | 131 | .offset = SZ_2M, |
132 | .size = (SZ_16M - SZ_2M), | 132 | .size = (SZ_16M - SZ_2M), |
133 | }, | 133 | }, { |
134 | { | ||
135 | .name = "user", | 134 | .name = "user", |
136 | .offset = SZ_16M, | 135 | .offset = SZ_16M, |
137 | .size = SZ_8M, | 136 | .size = SZ_8M, |
138 | }, | 137 | }, { |
139 | { | ||
140 | .name = "recovery", | 138 | .name = "recovery", |
141 | .offset = (SZ_16M + SZ_8M), | 139 | .offset = (SZ_16M + SZ_8M), |
142 | .size = SZ_8M, | 140 | .size = SZ_8M, |
@@ -288,7 +286,6 @@ subsys_initcall(db88f5281_pci_init); | |||
288 | ****************************************************************************/ | 286 | ****************************************************************************/ |
289 | static struct mv643xx_eth_platform_data db88f5281_eth_data = { | 287 | static struct mv643xx_eth_platform_data db88f5281_eth_data = { |
290 | .phy_addr = 8, | 288 | .phy_addr = 8, |
291 | .force_phy_addr = 1, | ||
292 | }; | 289 | }; |
293 | 290 | ||
294 | /***************************************************************************** | 291 | /***************************************************************************** |
@@ -301,11 +298,28 @@ static struct i2c_board_info __initdata db88f5281_i2c_rtc = { | |||
301 | /***************************************************************************** | 298 | /***************************************************************************** |
302 | * General Setup | 299 | * General Setup |
303 | ****************************************************************************/ | 300 | ****************************************************************************/ |
304 | 301 | static struct orion5x_mpp_mode db88f5281_mpp_modes[] __initdata = { | |
305 | static struct platform_device *db88f5281_devs[] __initdata = { | 302 | { 0, MPP_GPIO }, /* USB Over Current */ |
306 | &db88f5281_boot_flash, | 303 | { 1, MPP_GPIO }, /* USB Vbat input */ |
307 | &db88f5281_nor_flash, | 304 | { 2, MPP_PCI_ARB }, /* PCI_REQn[2] */ |
308 | &db88f5281_nand_flash, | 305 | { 3, MPP_PCI_ARB }, /* PCI_GNTn[2] */ |
306 | { 4, MPP_PCI_ARB }, /* PCI_REQn[3] */ | ||
307 | { 5, MPP_PCI_ARB }, /* PCI_GNTn[3] */ | ||
308 | { 6, MPP_GPIO }, /* JP0, CON17.2 */ | ||
309 | { 7, MPP_GPIO }, /* JP1, CON17.1 */ | ||
310 | { 8, MPP_GPIO }, /* JP2, CON11.2 */ | ||
311 | { 9, MPP_GPIO }, /* JP3, CON11.3 */ | ||
312 | { 10, MPP_GPIO }, /* RTC int */ | ||
313 | { 11, MPP_GPIO }, /* Baud Rate Generator */ | ||
314 | { 12, MPP_GPIO }, /* PCI int 1 */ | ||
315 | { 13, MPP_GPIO }, /* PCI int 2 */ | ||
316 | { 14, MPP_NAND }, /* NAND_REn[2] */ | ||
317 | { 15, MPP_NAND }, /* NAND_WEn[2] */ | ||
318 | { 16, MPP_UART }, /* UART1_RX */ | ||
319 | { 17, MPP_UART }, /* UART1_TX */ | ||
320 | { 18, MPP_UART }, /* UART1_CTSn */ | ||
321 | { 19, MPP_UART }, /* UART1_RTSn */ | ||
322 | { -1 }, | ||
309 | }; | 323 | }; |
310 | 324 | ||
311 | static void __init db88f5281_init(void) | 325 | static void __init db88f5281_init(void) |
@@ -315,39 +329,31 @@ static void __init db88f5281_init(void) | |||
315 | */ | 329 | */ |
316 | orion5x_init(); | 330 | orion5x_init(); |
317 | 331 | ||
332 | orion5x_mpp_conf(db88f5281_mpp_modes); | ||
333 | writel(0, MPP_DEV_CTRL); /* DEV_D[31:16] */ | ||
334 | |||
318 | /* | 335 | /* |
319 | * Setup the CPU address decode windows for our on-board devices | 336 | * Configure peripherals. |
320 | */ | 337 | */ |
338 | orion5x_ehci0_init(); | ||
339 | orion5x_eth_init(&db88f5281_eth_data); | ||
340 | orion5x_i2c_init(); | ||
341 | orion5x_uart0_init(); | ||
342 | orion5x_uart1_init(); | ||
343 | |||
321 | orion5x_setup_dev_boot_win(DB88F5281_NOR_BOOT_BASE, | 344 | orion5x_setup_dev_boot_win(DB88F5281_NOR_BOOT_BASE, |
322 | DB88F5281_NOR_BOOT_SIZE); | 345 | DB88F5281_NOR_BOOT_SIZE); |
346 | platform_device_register(&db88f5281_boot_flash); | ||
347 | |||
323 | orion5x_setup_dev0_win(DB88F5281_7SEG_BASE, DB88F5281_7SEG_SIZE); | 348 | orion5x_setup_dev0_win(DB88F5281_7SEG_BASE, DB88F5281_7SEG_SIZE); |
324 | orion5x_setup_dev1_win(DB88F5281_NOR_BASE, DB88F5281_NOR_SIZE); | ||
325 | orion5x_setup_dev2_win(DB88F5281_NAND_BASE, DB88F5281_NAND_SIZE); | ||
326 | 349 | ||
327 | /* | 350 | orion5x_setup_dev1_win(DB88F5281_NOR_BASE, DB88F5281_NOR_SIZE); |
328 | * Setup Multiplexing Pins: | 351 | platform_device_register(&db88f5281_nor_flash); |
329 | * MPP0: GPIO (USB Over Current) MPP1: GPIO (USB Vbat input) | ||
330 | * MPP2: PCI_REQn[2] MPP3: PCI_GNTn[2] | ||
331 | * MPP4: PCI_REQn[3] MPP5: PCI_GNTn[3] | ||
332 | * MPP6: GPIO (JP0, CON17.2) MPP7: GPIO (JP1, CON17.1) | ||
333 | * MPP8: GPIO (JP2, CON11.2) MPP9: GPIO (JP3, CON11.3) | ||
334 | * MPP10: GPIO (RTC int) MPP11: GPIO (Baud Rate Generator) | ||
335 | * MPP12: GPIO (PCI int 1) MPP13: GPIO (PCI int 2) | ||
336 | * MPP14: NAND_REn[2] MPP15: NAND_WEn[2] | ||
337 | * MPP16: UART1_RX MPP17: UART1_TX | ||
338 | * MPP18: UART1_CTS MPP19: UART1_RTS | ||
339 | * MPP-DEV: DEV_D[16:31] | ||
340 | */ | ||
341 | orion5x_write(MPP_0_7_CTRL, 0x00222203); | ||
342 | orion5x_write(MPP_8_15_CTRL, 0x44000000); | ||
343 | orion5x_write(MPP_16_19_CTRL, 0); | ||
344 | orion5x_write(MPP_DEV_CTRL, 0); | ||
345 | 352 | ||
346 | orion5x_gpio_set_valid_pins(0x00003fc3); | 353 | orion5x_setup_dev2_win(DB88F5281_NAND_BASE, DB88F5281_NAND_SIZE); |
354 | platform_device_register(&db88f5281_nand_flash); | ||
347 | 355 | ||
348 | platform_add_devices(db88f5281_devs, ARRAY_SIZE(db88f5281_devs)); | ||
349 | i2c_register_board_info(0, &db88f5281_i2c_rtc, 1); | 356 | i2c_register_board_info(0, &db88f5281_i2c_rtc, 1); |
350 | orion5x_eth_init(&db88f5281_eth_data); | ||
351 | } | 357 | } |
352 | 358 | ||
353 | MACHINE_START(DB88F5281, "Marvell Orion-2 Development Board") | 359 | MACHINE_START(DB88F5281, "Marvell Orion-2 Development Board") |
diff --git a/arch/arm/mach-orion5x/dns323-setup.c b/arch/arm/mach-orion5x/dns323-setup.c index 27ce967ab9e5..3791ca6f001a 100644 --- a/arch/arm/mach-orion5x/dns323-setup.c +++ b/arch/arm/mach-orion5x/dns323-setup.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <asm/mach/pci.h> | 27 | #include <asm/mach/pci.h> |
28 | #include <asm/arch/orion5x.h> | 28 | #include <asm/arch/orion5x.h> |
29 | #include "common.h" | 29 | #include "common.h" |
30 | #include "mpp.h" | ||
30 | 31 | ||
31 | #define DNS323_GPIO_LED_RIGHT_AMBER 1 | 32 | #define DNS323_GPIO_LED_RIGHT_AMBER 1 |
32 | #define DNS323_GPIO_LED_LEFT_AMBER 2 | 33 | #define DNS323_GPIO_LED_LEFT_AMBER 2 |
@@ -52,8 +53,6 @@ static int __init dns323_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) | |||
52 | if (irq != -1) | 53 | if (irq != -1) |
53 | return irq; | 54 | return irq; |
54 | 55 | ||
55 | pr_err("%s: requested mapping for unknown device\n", __func__); | ||
56 | |||
57 | return -1; | 56 | return -1; |
58 | } | 57 | } |
59 | 58 | ||
@@ -81,7 +80,6 @@ subsys_initcall(dns323_pci_init); | |||
81 | 80 | ||
82 | static struct mv643xx_eth_platform_data dns323_eth_data = { | 81 | static struct mv643xx_eth_platform_data dns323_eth_data = { |
83 | .phy_addr = 8, | 82 | .phy_addr = 8, |
84 | .force_phy_addr = 1, | ||
85 | }; | 83 | }; |
86 | 84 | ||
87 | /**************************************************************************** | 85 | /**************************************************************************** |
@@ -119,7 +117,7 @@ static struct mtd_partition dns323_partitions[] = { | |||
119 | .name = "u-boot", | 117 | .name = "u-boot", |
120 | .size = 0x00030000, | 118 | .size = 0x00030000, |
121 | .offset = 0x007d0000, | 119 | .offset = 0x007d0000, |
122 | } | 120 | }, |
123 | }; | 121 | }; |
124 | 122 | ||
125 | static struct physmap_flash_data dns323_nor_flash_data = { | 123 | static struct physmap_flash_data dns323_nor_flash_data = { |
@@ -137,7 +135,9 @@ static struct resource dns323_nor_flash_resource = { | |||
137 | static struct platform_device dns323_nor_flash = { | 135 | static struct platform_device dns323_nor_flash = { |
138 | .name = "physmap-flash", | 136 | .name = "physmap-flash", |
139 | .id = 0, | 137 | .id = 0, |
140 | .dev = { .platform_data = &dns323_nor_flash_data, }, | 138 | .dev = { |
139 | .platform_data = &dns323_nor_flash_data, | ||
140 | }, | ||
141 | .resource = &dns323_nor_flash_resource, | 141 | .resource = &dns323_nor_flash_resource, |
142 | .num_resources = 1, | 142 | .num_resources = 1, |
143 | }; | 143 | }; |
@@ -170,7 +170,9 @@ static struct gpio_led_platform_data dns323_led_data = { | |||
170 | static struct platform_device dns323_gpio_leds = { | 170 | static struct platform_device dns323_gpio_leds = { |
171 | .name = "leds-gpio", | 171 | .name = "leds-gpio", |
172 | .id = -1, | 172 | .id = -1, |
173 | .dev = { .platform_data = &dns323_led_data, }, | 173 | .dev = { |
174 | .platform_data = &dns323_led_data, | ||
175 | }, | ||
174 | }; | 176 | }; |
175 | 177 | ||
176 | /**************************************************************************** | 178 | /**************************************************************************** |
@@ -183,35 +185,53 @@ static struct gpio_keys_button dns323_buttons[] = { | |||
183 | .gpio = DNS323_GPIO_KEY_RESET, | 185 | .gpio = DNS323_GPIO_KEY_RESET, |
184 | .desc = "Reset Button", | 186 | .desc = "Reset Button", |
185 | .active_low = 1, | 187 | .active_low = 1, |
186 | }, | 188 | }, { |
187 | { | ||
188 | .code = KEY_POWER, | 189 | .code = KEY_POWER, |
189 | .gpio = DNS323_GPIO_KEY_POWER, | 190 | .gpio = DNS323_GPIO_KEY_POWER, |
190 | .desc = "Power Button", | 191 | .desc = "Power Button", |
191 | .active_low = 1, | 192 | .active_low = 1, |
192 | } | 193 | }, |
193 | }; | 194 | }; |
194 | 195 | ||
195 | static struct gpio_keys_platform_data dns323_button_data = { | 196 | static struct gpio_keys_platform_data dns323_button_data = { |
196 | .buttons = dns323_buttons, | 197 | .buttons = dns323_buttons, |
197 | .nbuttons = ARRAY_SIZE(dns323_buttons), | 198 | .nbuttons = ARRAY_SIZE(dns323_buttons), |
198 | }; | 199 | }; |
199 | 200 | ||
200 | static struct platform_device dns323_button_device = { | 201 | static struct platform_device dns323_button_device = { |
201 | .name = "gpio-keys", | 202 | .name = "gpio-keys", |
202 | .id = -1, | 203 | .id = -1, |
203 | .num_resources = 0, | 204 | .num_resources = 0, |
204 | .dev = { .platform_data = &dns323_button_data, }, | 205 | .dev = { |
206 | .platform_data = &dns323_button_data, | ||
207 | }, | ||
205 | }; | 208 | }; |
206 | 209 | ||
207 | /**************************************************************************** | 210 | /**************************************************************************** |
208 | * General Setup | 211 | * General Setup |
209 | */ | 212 | */ |
210 | 213 | static struct orion5x_mpp_mode dns323_mpp_modes[] __initdata = { | |
211 | static struct platform_device *dns323_plat_devices[] __initdata = { | 214 | { 0, MPP_PCIE_RST_OUTn }, |
212 | &dns323_nor_flash, | 215 | { 1, MPP_GPIO }, /* right amber LED (sata ch0) */ |
213 | &dns323_gpio_leds, | 216 | { 2, MPP_GPIO }, /* left amber LED (sata ch1) */ |
214 | &dns323_button_device, | 217 | { 3, MPP_UNUSED }, |
218 | { 4, MPP_GPIO }, /* power button LED */ | ||
219 | { 5, MPP_GPIO }, /* power button LED */ | ||
220 | { 6, MPP_GPIO }, /* GMT G751-2f overtemp */ | ||
221 | { 7, MPP_GPIO }, /* M41T80 nIRQ/OUT/SQW */ | ||
222 | { 8, MPP_GPIO }, /* triggers power off */ | ||
223 | { 9, MPP_GPIO }, /* power button switch */ | ||
224 | { 10, MPP_GPIO }, /* reset button switch */ | ||
225 | { 11, MPP_UNUSED }, | ||
226 | { 12, MPP_UNUSED }, | ||
227 | { 13, MPP_UNUSED }, | ||
228 | { 14, MPP_UNUSED }, | ||
229 | { 15, MPP_UNUSED }, | ||
230 | { 16, MPP_UNUSED }, | ||
231 | { 17, MPP_UNUSED }, | ||
232 | { 18, MPP_UNUSED }, | ||
233 | { 19, MPP_UNUSED }, | ||
234 | { -1 }, | ||
215 | }; | 235 | }; |
216 | 236 | ||
217 | /* | 237 | /* |
@@ -225,17 +245,15 @@ static struct platform_device *dns323_plat_devices[] __initdata = { | |||
225 | static struct i2c_board_info __initdata dns323_i2c_devices[] = { | 245 | static struct i2c_board_info __initdata dns323_i2c_devices[] = { |
226 | { | 246 | { |
227 | I2C_BOARD_INFO("g760a", 0x3e), | 247 | I2C_BOARD_INFO("g760a", 0x3e), |
228 | }, | ||
229 | #if 0 | 248 | #if 0 |
230 | /* this entry requires the new-style driver model lm75 driver, | 249 | /* this entry requires the new-style driver model lm75 driver, |
231 | * for the meantime "insmod lm75.ko force_lm75=0,0x48" is needed */ | 250 | * for the meantime "insmod lm75.ko force_lm75=0,0x48" is needed */ |
232 | { | 251 | }, { |
233 | I2C_BOARD_INFO("g751", 0x48), | 252 | I2C_BOARD_INFO("g751", 0x48), |
234 | }, | ||
235 | #endif | 253 | #endif |
236 | { | 254 | }, { |
237 | I2C_BOARD_INFO("m41t80", 0x68), | 255 | I2C_BOARD_INFO("m41t80", 0x68), |
238 | } | 256 | }, |
239 | }; | 257 | }; |
240 | 258 | ||
241 | /* DNS-323 specific power off method */ | 259 | /* DNS-323 specific power off method */ |
@@ -250,62 +268,35 @@ static void __init dns323_init(void) | |||
250 | /* Setup basic Orion functions. Need to be called early. */ | 268 | /* Setup basic Orion functions. Need to be called early. */ |
251 | orion5x_init(); | 269 | orion5x_init(); |
252 | 270 | ||
271 | orion5x_mpp_conf(dns323_mpp_modes); | ||
272 | writel(0, MPP_DEV_CTRL); /* DEV_D[31:16] */ | ||
273 | |||
274 | /* | ||
275 | * Configure peripherals. | ||
276 | */ | ||
277 | orion5x_ehci0_init(); | ||
278 | orion5x_eth_init(&dns323_eth_data); | ||
279 | orion5x_i2c_init(); | ||
280 | orion5x_uart0_init(); | ||
281 | |||
253 | /* setup flash mapping | 282 | /* setup flash mapping |
254 | * CS3 holds a 8 MB Spansion S29GL064M90TFIR4 | 283 | * CS3 holds a 8 MB Spansion S29GL064M90TFIR4 |
255 | */ | 284 | */ |
256 | orion5x_setup_dev_boot_win(DNS323_NOR_BOOT_BASE, DNS323_NOR_BOOT_SIZE); | 285 | orion5x_setup_dev_boot_win(DNS323_NOR_BOOT_BASE, DNS323_NOR_BOOT_SIZE); |
286 | platform_device_register(&dns323_nor_flash); | ||
257 | 287 | ||
258 | /* DNS-323 has a Marvell 88X7042 SATA controller attached via PCIe | 288 | platform_device_register(&dns323_gpio_leds); |
259 | * | ||
260 | * Open a special address decode windows for the PCIe WA. | ||
261 | */ | ||
262 | orion5x_setup_pcie_wa_win(ORION5X_PCIE_WA_PHYS_BASE, | ||
263 | ORION5X_PCIE_WA_SIZE); | ||
264 | |||
265 | /* set MPP to 0 as D-Link's 2.6.12.6 kernel did */ | ||
266 | orion5x_write(MPP_0_7_CTRL, 0); | ||
267 | orion5x_write(MPP_8_15_CTRL, 0); | ||
268 | orion5x_write(MPP_16_19_CTRL, 0); | ||
269 | orion5x_write(MPP_DEV_CTRL, 0); | ||
270 | |||
271 | /* Define used GPIO pins | ||
272 | |||
273 | GPIO Map: | ||
274 | |||
275 | | 0 | | PEX_RST_OUT (not controlled by GPIO) | ||
276 | | 1 | Out | right amber LED (= sata ch0 LED) (low-active) | ||
277 | | 2 | Out | left amber LED (= sata ch1 LED) (low-active) | ||
278 | | 3 | Out | //unknown// | ||
279 | | 4 | Out | power button LED (low-active, together with pin #5) | ||
280 | | 5 | Out | power button LED (low-active, together with pin #4) | ||
281 | | 6 | In | GMT G751-2f overtemp. shutdown signal (low-active) | ||
282 | | 7 | In | M41T80 nIRQ/OUT/SQW signal | ||
283 | | 8 | Out | triggers power off (high-active) | ||
284 | | 9 | In | power button switch (low-active) | ||
285 | | 10 | In | reset button switch (low-active) | ||
286 | | 11 | Out | //unknown// | ||
287 | | 12 | Out | //unknown// | ||
288 | | 13 | Out | //unknown// | ||
289 | | 14 | Out | //unknown// | ||
290 | | 15 | Out | //unknown// | ||
291 | */ | ||
292 | orion5x_gpio_set_valid_pins(0x07f6); | ||
293 | |||
294 | /* register dns323 specific power-off method */ | ||
295 | if ((gpio_request(DNS323_GPIO_POWER_OFF, "POWEROFF") != 0) | ||
296 | || (gpio_direction_output(DNS323_GPIO_POWER_OFF, 0) != 0)) | ||
297 | pr_err("DNS323: failed to setup power-off GPIO\n"); | ||
298 | |||
299 | pm_power_off = dns323_power_off; | ||
300 | 289 | ||
301 | /* register flash and other platform devices */ | 290 | platform_device_register(&dns323_button_device); |
302 | platform_add_devices(dns323_plat_devices, | ||
303 | ARRAY_SIZE(dns323_plat_devices)); | ||
304 | 291 | ||
305 | i2c_register_board_info(0, dns323_i2c_devices, | 292 | i2c_register_board_info(0, dns323_i2c_devices, |
306 | ARRAY_SIZE(dns323_i2c_devices)); | 293 | ARRAY_SIZE(dns323_i2c_devices)); |
307 | 294 | ||
308 | orion5x_eth_init(&dns323_eth_data); | 295 | /* register dns323 specific power-off method */ |
296 | if (gpio_request(DNS323_GPIO_POWER_OFF, "POWEROFF") != 0 || | ||
297 | gpio_direction_output(DNS323_GPIO_POWER_OFF, 0) != 0) | ||
298 | pr_err("DNS323: failed to setup power-off GPIO\n"); | ||
299 | pm_power_off = dns323_power_off; | ||
309 | } | 300 | } |
310 | 301 | ||
311 | /* Warning: D-Link uses a wrong mach-type (=526) in their bootloader */ | 302 | /* Warning: D-Link uses a wrong mach-type (=526) in their bootloader */ |
diff --git a/arch/arm/mach-orion5x/gpio.c b/arch/arm/mach-orion5x/gpio.c index 8108c316c426..d09797990f41 100644 --- a/arch/arm/mach-orion5x/gpio.c +++ b/arch/arm/mach-orion5x/gpio.c | |||
@@ -24,9 +24,12 @@ static DEFINE_SPINLOCK(gpio_lock); | |||
24 | static unsigned long gpio_valid[BITS_TO_LONGS(GPIO_MAX)]; | 24 | static unsigned long gpio_valid[BITS_TO_LONGS(GPIO_MAX)]; |
25 | static const char *gpio_label[GPIO_MAX]; /* non null for allocated GPIOs */ | 25 | static const char *gpio_label[GPIO_MAX]; /* non null for allocated GPIOs */ |
26 | 26 | ||
27 | void __init orion5x_gpio_set_valid_pins(u32 pins) | 27 | void __init orion5x_gpio_set_valid(unsigned pin, int valid) |
28 | { | 28 | { |
29 | gpio_valid[0] = pins; | 29 | if (valid) |
30 | __set_bit(pin, gpio_valid); | ||
31 | else | ||
32 | __clear_bit(pin, gpio_valid); | ||
30 | } | 33 | } |
31 | 34 | ||
32 | /* | 35 | /* |
@@ -93,10 +96,10 @@ int gpio_get_value(unsigned pin) | |||
93 | { | 96 | { |
94 | int val, mask = 1 << pin; | 97 | int val, mask = 1 << pin; |
95 | 98 | ||
96 | if (orion5x_read(GPIO_IO_CONF) & mask) | 99 | if (readl(GPIO_IO_CONF) & mask) |
97 | val = orion5x_read(GPIO_DATA_IN) ^ orion5x_read(GPIO_IN_POL); | 100 | val = readl(GPIO_DATA_IN) ^ readl(GPIO_IN_POL); |
98 | else | 101 | else |
99 | val = orion5x_read(GPIO_OUT); | 102 | val = readl(GPIO_OUT); |
100 | 103 | ||
101 | return val & mask; | 104 | return val & mask; |
102 | } | 105 | } |
@@ -188,39 +191,39 @@ void gpio_display(void) | |||
188 | printk("GPIO, free\n"); | 191 | printk("GPIO, free\n"); |
189 | } else { | 192 | } else { |
190 | printk("GPIO, used by %s, ", gpio_label[i]); | 193 | printk("GPIO, used by %s, ", gpio_label[i]); |
191 | if (orion5x_read(GPIO_IO_CONF) & (1 << i)) { | 194 | if (readl(GPIO_IO_CONF) & (1 << i)) { |
192 | printk("input, active %s, level %s, edge %s\n", | 195 | printk("input, active %s, level %s, edge %s\n", |
193 | ((orion5x_read(GPIO_IN_POL) >> i) & 1) ? "low" : "high", | 196 | ((readl(GPIO_IN_POL) >> i) & 1) ? "low" : "high", |
194 | ((orion5x_read(GPIO_LEVEL_MASK) >> i) & 1) ? "enabled" : "masked", | 197 | ((readl(GPIO_LEVEL_MASK) >> i) & 1) ? "enabled" : "masked", |
195 | ((orion5x_read(GPIO_EDGE_MASK) >> i) & 1) ? "enabled" : "masked"); | 198 | ((readl(GPIO_EDGE_MASK) >> i) & 1) ? "enabled" : "masked"); |
196 | } else { | 199 | } else { |
197 | printk("output, val=%d\n", (orion5x_read(GPIO_OUT) >> i) & 1); | 200 | printk("output, val=%d\n", (readl(GPIO_OUT) >> i) & 1); |
198 | } | 201 | } |
199 | } | 202 | } |
200 | } | 203 | } |
201 | 204 | ||
202 | printk(KERN_DEBUG "MPP_0_7_CTRL (0x%08x) = 0x%08x\n", | 205 | printk(KERN_DEBUG "MPP_0_7_CTRL (0x%08x) = 0x%08x\n", |
203 | MPP_0_7_CTRL, orion5x_read(MPP_0_7_CTRL)); | 206 | MPP_0_7_CTRL, readl(MPP_0_7_CTRL)); |
204 | printk(KERN_DEBUG "MPP_8_15_CTRL (0x%08x) = 0x%08x\n", | 207 | printk(KERN_DEBUG "MPP_8_15_CTRL (0x%08x) = 0x%08x\n", |
205 | MPP_8_15_CTRL, orion5x_read(MPP_8_15_CTRL)); | 208 | MPP_8_15_CTRL, readl(MPP_8_15_CTRL)); |
206 | printk(KERN_DEBUG "MPP_16_19_CTRL (0x%08x) = 0x%08x\n", | 209 | printk(KERN_DEBUG "MPP_16_19_CTRL (0x%08x) = 0x%08x\n", |
207 | MPP_16_19_CTRL, orion5x_read(MPP_16_19_CTRL)); | 210 | MPP_16_19_CTRL, readl(MPP_16_19_CTRL)); |
208 | printk(KERN_DEBUG "MPP_DEV_CTRL (0x%08x) = 0x%08x\n", | 211 | printk(KERN_DEBUG "MPP_DEV_CTRL (0x%08x) = 0x%08x\n", |
209 | MPP_DEV_CTRL, orion5x_read(MPP_DEV_CTRL)); | 212 | MPP_DEV_CTRL, readl(MPP_DEV_CTRL)); |
210 | printk(KERN_DEBUG "GPIO_OUT (0x%08x) = 0x%08x\n", | 213 | printk(KERN_DEBUG "GPIO_OUT (0x%08x) = 0x%08x\n", |
211 | GPIO_OUT, orion5x_read(GPIO_OUT)); | 214 | GPIO_OUT, readl(GPIO_OUT)); |
212 | printk(KERN_DEBUG "GPIO_IO_CONF (0x%08x) = 0x%08x\n", | 215 | printk(KERN_DEBUG "GPIO_IO_CONF (0x%08x) = 0x%08x\n", |
213 | GPIO_IO_CONF, orion5x_read(GPIO_IO_CONF)); | 216 | GPIO_IO_CONF, readl(GPIO_IO_CONF)); |
214 | printk(KERN_DEBUG "GPIO_BLINK_EN (0x%08x) = 0x%08x\n", | 217 | printk(KERN_DEBUG "GPIO_BLINK_EN (0x%08x) = 0x%08x\n", |
215 | GPIO_BLINK_EN, orion5x_read(GPIO_BLINK_EN)); | 218 | GPIO_BLINK_EN, readl(GPIO_BLINK_EN)); |
216 | printk(KERN_DEBUG "GPIO_IN_POL (0x%08x) = 0x%08x\n", | 219 | printk(KERN_DEBUG "GPIO_IN_POL (0x%08x) = 0x%08x\n", |
217 | GPIO_IN_POL, orion5x_read(GPIO_IN_POL)); | 220 | GPIO_IN_POL, readl(GPIO_IN_POL)); |
218 | printk(KERN_DEBUG "GPIO_DATA_IN (0x%08x) = 0x%08x\n", | 221 | printk(KERN_DEBUG "GPIO_DATA_IN (0x%08x) = 0x%08x\n", |
219 | GPIO_DATA_IN, orion5x_read(GPIO_DATA_IN)); | 222 | GPIO_DATA_IN, readl(GPIO_DATA_IN)); |
220 | printk(KERN_DEBUG "GPIO_LEVEL_MASK (0x%08x) = 0x%08x\n", | 223 | printk(KERN_DEBUG "GPIO_LEVEL_MASK (0x%08x) = 0x%08x\n", |
221 | GPIO_LEVEL_MASK, orion5x_read(GPIO_LEVEL_MASK)); | 224 | GPIO_LEVEL_MASK, readl(GPIO_LEVEL_MASK)); |
222 | printk(KERN_DEBUG "GPIO_EDGE_CAUSE (0x%08x) = 0x%08x\n", | 225 | printk(KERN_DEBUG "GPIO_EDGE_CAUSE (0x%08x) = 0x%08x\n", |
223 | GPIO_EDGE_CAUSE, orion5x_read(GPIO_EDGE_CAUSE)); | 226 | GPIO_EDGE_CAUSE, readl(GPIO_EDGE_CAUSE)); |
224 | printk(KERN_DEBUG "GPIO_EDGE_MASK (0x%08x) = 0x%08x\n", | 227 | printk(KERN_DEBUG "GPIO_EDGE_MASK (0x%08x) = 0x%08x\n", |
225 | GPIO_EDGE_MASK, orion5x_read(GPIO_EDGE_MASK)); | 228 | GPIO_EDGE_MASK, readl(GPIO_EDGE_MASK)); |
226 | } | 229 | } |
diff --git a/arch/arm/mach-orion5x/irq.c b/arch/arm/mach-orion5x/irq.c index dd21f38c5d37..e2a0084ab4a3 100644 --- a/arch/arm/mach-orion5x/irq.c +++ b/arch/arm/mach-orion5x/irq.c | |||
@@ -82,7 +82,7 @@ static int orion5x_gpio_set_irq_type(u32 irq, u32 type) | |||
82 | int pin = irq_to_gpio(irq); | 82 | int pin = irq_to_gpio(irq); |
83 | struct irq_desc *desc; | 83 | struct irq_desc *desc; |
84 | 84 | ||
85 | if ((orion5x_read(GPIO_IO_CONF) & (1 << pin)) == 0) { | 85 | if ((readl(GPIO_IO_CONF) & (1 << pin)) == 0) { |
86 | printk(KERN_ERR "orion5x_gpio_set_irq_type failed " | 86 | printk(KERN_ERR "orion5x_gpio_set_irq_type failed " |
87 | "(irq %d, pin %d).\n", irq, pin); | 87 | "(irq %d, pin %d).\n", irq, pin); |
88 | return -EINVAL; | 88 | return -EINVAL; |
@@ -117,7 +117,7 @@ static int orion5x_gpio_set_irq_type(u32 irq, u32 type) | |||
117 | /* | 117 | /* |
118 | * set initial polarity based on current input level | 118 | * set initial polarity based on current input level |
119 | */ | 119 | */ |
120 | if ((orion5x_read(GPIO_IN_POL) ^ orion5x_read(GPIO_DATA_IN)) | 120 | if ((readl(GPIO_IN_POL) ^ readl(GPIO_DATA_IN)) |
121 | & (1 << pin)) | 121 | & (1 << pin)) |
122 | orion5x_setbits(GPIO_IN_POL, (1 << pin)); /* falling */ | 122 | orion5x_setbits(GPIO_IN_POL, (1 << pin)); /* falling */ |
123 | else | 123 | else |
@@ -149,8 +149,8 @@ static void orion5x_gpio_irq_handler(unsigned int irq, struct irq_desc *desc) | |||
149 | 149 | ||
150 | BUG_ON(irq < IRQ_ORION5X_GPIO_0_7 || irq > IRQ_ORION5X_GPIO_24_31); | 150 | BUG_ON(irq < IRQ_ORION5X_GPIO_0_7 || irq > IRQ_ORION5X_GPIO_24_31); |
151 | offs = (irq - IRQ_ORION5X_GPIO_0_7) * 8; | 151 | offs = (irq - IRQ_ORION5X_GPIO_0_7) * 8; |
152 | cause = (orion5x_read(GPIO_DATA_IN) & orion5x_read(GPIO_LEVEL_MASK)) | | 152 | cause = (readl(GPIO_DATA_IN) & readl(GPIO_LEVEL_MASK)) | |
153 | (orion5x_read(GPIO_EDGE_CAUSE) & orion5x_read(GPIO_EDGE_MASK)); | 153 | (readl(GPIO_EDGE_CAUSE) & readl(GPIO_EDGE_MASK)); |
154 | 154 | ||
155 | for (pin = offs; pin < offs + 8; pin++) { | 155 | for (pin = offs; pin < offs + 8; pin++) { |
156 | if (cause & (1 << pin)) { | 156 | if (cause & (1 << pin)) { |
@@ -158,9 +158,9 @@ static void orion5x_gpio_irq_handler(unsigned int irq, struct irq_desc *desc) | |||
158 | desc = irq_desc + irq; | 158 | desc = irq_desc + irq; |
159 | if ((desc->status & IRQ_TYPE_SENSE_MASK) == IRQT_BOTHEDGE) { | 159 | if ((desc->status & IRQ_TYPE_SENSE_MASK) == IRQT_BOTHEDGE) { |
160 | /* Swap polarity (race with GPIO line) */ | 160 | /* Swap polarity (race with GPIO line) */ |
161 | u32 polarity = orion5x_read(GPIO_IN_POL); | 161 | u32 polarity = readl(GPIO_IN_POL); |
162 | polarity ^= 1 << pin; | 162 | polarity ^= 1 << pin; |
163 | orion5x_write(GPIO_IN_POL, polarity); | 163 | writel(polarity, GPIO_IN_POL); |
164 | } | 164 | } |
165 | desc_handle_irq(irq, desc); | 165 | desc_handle_irq(irq, desc); |
166 | } | 166 | } |
@@ -175,9 +175,9 @@ static void __init orion5x_init_gpio_irq(void) | |||
175 | /* | 175 | /* |
176 | * Mask and clear GPIO IRQ interrupts | 176 | * Mask and clear GPIO IRQ interrupts |
177 | */ | 177 | */ |
178 | orion5x_write(GPIO_LEVEL_MASK, 0x0); | 178 | writel(0x0, GPIO_LEVEL_MASK); |
179 | orion5x_write(GPIO_EDGE_MASK, 0x0); | 179 | writel(0x0, GPIO_EDGE_MASK); |
180 | orion5x_write(GPIO_EDGE_CAUSE, 0x0); | 180 | writel(0x0, GPIO_EDGE_CAUSE); |
181 | 181 | ||
182 | /* | 182 | /* |
183 | * Register chained level handlers for GPIO IRQs by default. | 183 | * Register chained level handlers for GPIO IRQs by default. |
diff --git a/arch/arm/mach-orion5x/kurobox_pro-setup.c b/arch/arm/mach-orion5x/kurobox_pro-setup.c index f5074b877b7f..84feac4a1fe2 100644 --- a/arch/arm/mach-orion5x/kurobox_pro-setup.c +++ b/arch/arm/mach-orion5x/kurobox_pro-setup.c | |||
@@ -13,10 +13,12 @@ | |||
13 | #include <linux/platform_device.h> | 13 | #include <linux/platform_device.h> |
14 | #include <linux/pci.h> | 14 | #include <linux/pci.h> |
15 | #include <linux/irq.h> | 15 | #include <linux/irq.h> |
16 | #include <linux/delay.h> | ||
16 | #include <linux/mtd/physmap.h> | 17 | #include <linux/mtd/physmap.h> |
17 | #include <linux/mtd/nand.h> | 18 | #include <linux/mtd/nand.h> |
18 | #include <linux/mv643xx_eth.h> | 19 | #include <linux/mv643xx_eth.h> |
19 | #include <linux/i2c.h> | 20 | #include <linux/i2c.h> |
21 | #include <linux/serial_reg.h> | ||
20 | #include <linux/ata_platform.h> | 22 | #include <linux/ata_platform.h> |
21 | #include <asm/mach-types.h> | 23 | #include <asm/mach-types.h> |
22 | #include <asm/gpio.h> | 24 | #include <asm/gpio.h> |
@@ -25,6 +27,7 @@ | |||
25 | #include <asm/arch/orion5x.h> | 27 | #include <asm/arch/orion5x.h> |
26 | #include <asm/plat-orion/orion_nand.h> | 28 | #include <asm/plat-orion/orion_nand.h> |
27 | #include "common.h" | 29 | #include "common.h" |
30 | #include "mpp.h" | ||
28 | 31 | ||
29 | /***************************************************************************** | 32 | /***************************************************************************** |
30 | * KUROBOX-PRO Info | 33 | * KUROBOX-PRO Info |
@@ -53,13 +56,11 @@ static struct mtd_partition kurobox_pro_nand_parts[] = { | |||
53 | .name = "uImage", | 56 | .name = "uImage", |
54 | .offset = 0, | 57 | .offset = 0, |
55 | .size = SZ_4M, | 58 | .size = SZ_4M, |
56 | }, | 59 | }, { |
57 | { | ||
58 | .name = "rootfs", | 60 | .name = "rootfs", |
59 | .offset = SZ_4M, | 61 | .offset = SZ_4M, |
60 | .size = SZ_64M, | 62 | .size = SZ_64M, |
61 | }, | 63 | }, { |
62 | { | ||
63 | .name = "extra", | 64 | .name = "extra", |
64 | .offset = SZ_4M + SZ_64M, | 65 | .offset = SZ_4M + SZ_64M, |
65 | .size = SZ_256M - (SZ_4M + SZ_64M), | 66 | .size = SZ_256M - (SZ_4M + SZ_64M), |
@@ -132,8 +133,6 @@ static int __init kurobox_pro_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) | |||
132 | /* | 133 | /* |
133 | * PCI isn't used on the Kuro | 134 | * PCI isn't used on the Kuro |
134 | */ | 135 | */ |
135 | printk(KERN_ERR "kurobox_pro_pci_map_irq failed, unknown bus\n"); | ||
136 | |||
137 | return -1; | 136 | return -1; |
138 | } | 137 | } |
139 | 138 | ||
@@ -161,7 +160,6 @@ subsys_initcall(kurobox_pro_pci_init); | |||
161 | 160 | ||
162 | static struct mv643xx_eth_platform_data kurobox_pro_eth_data = { | 161 | static struct mv643xx_eth_platform_data kurobox_pro_eth_data = { |
163 | .phy_addr = 8, | 162 | .phy_addr = 8, |
164 | .force_phy_addr = 1, | ||
165 | }; | 163 | }; |
166 | 164 | ||
167 | /***************************************************************************** | 165 | /***************************************************************************** |
@@ -175,12 +173,169 @@ static struct i2c_board_info __initdata kurobox_pro_i2c_rtc = { | |||
175 | * SATA | 173 | * SATA |
176 | ****************************************************************************/ | 174 | ****************************************************************************/ |
177 | static struct mv_sata_platform_data kurobox_pro_sata_data = { | 175 | static struct mv_sata_platform_data kurobox_pro_sata_data = { |
178 | .n_ports = 2, | 176 | .n_ports = 2, |
179 | }; | 177 | }; |
180 | 178 | ||
181 | /***************************************************************************** | 179 | /***************************************************************************** |
180 | * Kurobox Pro specific power off method via UART1-attached microcontroller | ||
181 | ****************************************************************************/ | ||
182 | |||
183 | #define UART1_REG(x) (UART1_VIRT_BASE + ((UART_##x) << 2)) | ||
184 | |||
185 | static int kurobox_pro_miconread(unsigned char *buf, int count) | ||
186 | { | ||
187 | int i; | ||
188 | int timeout; | ||
189 | |||
190 | for (i = 0; i < count; i++) { | ||
191 | timeout = 10; | ||
192 | |||
193 | while (!(readl(UART1_REG(LSR)) & UART_LSR_DR)) { | ||
194 | if (--timeout == 0) | ||
195 | break; | ||
196 | udelay(1000); | ||
197 | } | ||
198 | |||
199 | if (timeout == 0) | ||
200 | break; | ||
201 | buf[i] = readl(UART1_REG(RX)); | ||
202 | } | ||
203 | |||
204 | /* return read bytes */ | ||
205 | return i; | ||
206 | } | ||
207 | |||
208 | static int kurobox_pro_miconwrite(const unsigned char *buf, int count) | ||
209 | { | ||
210 | int i = 0; | ||
211 | |||
212 | while (count--) { | ||
213 | while (!(readl(UART1_REG(LSR)) & UART_LSR_THRE)) | ||
214 | barrier(); | ||
215 | writel(buf[i++], UART1_REG(TX)); | ||
216 | } | ||
217 | |||
218 | return 0; | ||
219 | } | ||
220 | |||
221 | static int kurobox_pro_miconsend(const unsigned char *data, int count) | ||
222 | { | ||
223 | int i; | ||
224 | unsigned char checksum = 0; | ||
225 | unsigned char recv_buf[40]; | ||
226 | unsigned char send_buf[40]; | ||
227 | unsigned char correct_ack[3]; | ||
228 | int retry = 2; | ||
229 | |||
230 | /* Generate checksum */ | ||
231 | for (i = 0; i < count; i++) | ||
232 | checksum -= data[i]; | ||
233 | |||
234 | do { | ||
235 | /* Send data */ | ||
236 | kurobox_pro_miconwrite(data, count); | ||
237 | |||
238 | /* send checksum */ | ||
239 | kurobox_pro_miconwrite(&checksum, 1); | ||
240 | |||
241 | if (kurobox_pro_miconread(recv_buf, sizeof(recv_buf)) <= 3) { | ||
242 | printk(KERN_ERR ">%s: receive failed.\n", __func__); | ||
243 | |||
244 | /* send preamble to clear the receive buffer */ | ||
245 | memset(&send_buf, 0xff, sizeof(send_buf)); | ||
246 | kurobox_pro_miconwrite(send_buf, sizeof(send_buf)); | ||
247 | |||
248 | /* make dummy reads */ | ||
249 | mdelay(100); | ||
250 | kurobox_pro_miconread(recv_buf, sizeof(recv_buf)); | ||
251 | } else { | ||
252 | /* Generate expected ack */ | ||
253 | correct_ack[0] = 0x01; | ||
254 | correct_ack[1] = data[1]; | ||
255 | correct_ack[2] = 0x00; | ||
256 | |||
257 | /* checksum Check */ | ||
258 | if ((recv_buf[0] + recv_buf[1] + recv_buf[2] + | ||
259 | recv_buf[3]) & 0xFF) { | ||
260 | printk(KERN_ERR ">%s: Checksum Error : " | ||
261 | "Received data[%02x, %02x, %02x, %02x]" | ||
262 | "\n", __func__, recv_buf[0], | ||
263 | recv_buf[1], recv_buf[2], recv_buf[3]); | ||
264 | } else { | ||
265 | /* Check Received Data */ | ||
266 | if (correct_ack[0] == recv_buf[0] && | ||
267 | correct_ack[1] == recv_buf[1] && | ||
268 | correct_ack[2] == recv_buf[2]) { | ||
269 | /* Interval for next command */ | ||
270 | mdelay(10); | ||
271 | |||
272 | /* Receive ACK */ | ||
273 | return 0; | ||
274 | } | ||
275 | } | ||
276 | /* Received NAK or illegal Data */ | ||
277 | printk(KERN_ERR ">%s: Error : NAK or Illegal Data " | ||
278 | "Received\n", __func__); | ||
279 | } | ||
280 | } while (retry--); | ||
281 | |||
282 | /* Interval for next command */ | ||
283 | mdelay(10); | ||
284 | |||
285 | return -1; | ||
286 | } | ||
287 | |||
288 | static void kurobox_pro_power_off(void) | ||
289 | { | ||
290 | const unsigned char watchdogkill[] = {0x01, 0x35, 0x00}; | ||
291 | const unsigned char shutdownwait[] = {0x00, 0x0c}; | ||
292 | const unsigned char poweroff[] = {0x00, 0x06}; | ||
293 | /* 38400 baud divisor */ | ||
294 | const unsigned divisor = ((ORION5X_TCLK + (8 * 38400)) / (16 * 38400)); | ||
295 | |||
296 | pr_info("%s: triggering power-off...\n", __func__); | ||
297 | |||
298 | /* hijack uart1 and reset into sane state (38400,8n1,even parity) */ | ||
299 | writel(0x83, UART1_REG(LCR)); | ||
300 | writel(divisor & 0xff, UART1_REG(DLL)); | ||
301 | writel((divisor >> 8) & 0xff, UART1_REG(DLM)); | ||
302 | writel(0x1b, UART1_REG(LCR)); | ||
303 | writel(0x00, UART1_REG(IER)); | ||
304 | writel(0x07, UART1_REG(FCR)); | ||
305 | writel(0x00, UART1_REG(MCR)); | ||
306 | |||
307 | /* Send the commands to shutdown the Kurobox Pro */ | ||
308 | kurobox_pro_miconsend(watchdogkill, sizeof(watchdogkill)) ; | ||
309 | kurobox_pro_miconsend(shutdownwait, sizeof(shutdownwait)) ; | ||
310 | kurobox_pro_miconsend(poweroff, sizeof(poweroff)); | ||
311 | } | ||
312 | |||
313 | /***************************************************************************** | ||
182 | * General Setup | 314 | * General Setup |
183 | ****************************************************************************/ | 315 | ****************************************************************************/ |
316 | static struct orion5x_mpp_mode kurobox_pro_mpp_modes[] __initdata = { | ||
317 | { 0, MPP_UNUSED }, | ||
318 | { 1, MPP_UNUSED }, | ||
319 | { 2, MPP_GPIO }, /* GPIO Micon */ | ||
320 | { 3, MPP_GPIO }, /* GPIO Rtc */ | ||
321 | { 4, MPP_UNUSED }, | ||
322 | { 5, MPP_UNUSED }, | ||
323 | { 6, MPP_NAND }, /* NAND Flash REn */ | ||
324 | { 7, MPP_NAND }, /* NAND Flash WEn */ | ||
325 | { 8, MPP_UNUSED }, | ||
326 | { 9, MPP_UNUSED }, | ||
327 | { 10, MPP_UNUSED }, | ||
328 | { 11, MPP_UNUSED }, | ||
329 | { 12, MPP_SATA_LED }, /* SATA 0 presence */ | ||
330 | { 13, MPP_SATA_LED }, /* SATA 1 presence */ | ||
331 | { 14, MPP_SATA_LED }, /* SATA 0 active */ | ||
332 | { 15, MPP_SATA_LED }, /* SATA 1 active */ | ||
333 | { 16, MPP_UART }, /* UART1 RXD */ | ||
334 | { 17, MPP_UART }, /* UART1 TXD */ | ||
335 | { 18, MPP_UART }, /* UART1 CTSn */ | ||
336 | { 19, MPP_UART }, /* UART1 RTSn */ | ||
337 | { -1 }, | ||
338 | }; | ||
184 | 339 | ||
185 | static void __init kurobox_pro_init(void) | 340 | static void __init kurobox_pro_init(void) |
186 | { | 341 | { |
@@ -189,46 +344,33 @@ static void __init kurobox_pro_init(void) | |||
189 | */ | 344 | */ |
190 | orion5x_init(); | 345 | orion5x_init(); |
191 | 346 | ||
192 | /* | 347 | orion5x_mpp_conf(kurobox_pro_mpp_modes); |
193 | * Setup the CPU address decode windows for our devices | ||
194 | */ | ||
195 | orion5x_setup_dev_boot_win(KUROBOX_PRO_NOR_BOOT_BASE, | ||
196 | KUROBOX_PRO_NOR_BOOT_SIZE); | ||
197 | orion5x_setup_dev0_win(KUROBOX_PRO_NAND_BASE, KUROBOX_PRO_NAND_SIZE); | ||
198 | 348 | ||
199 | /* | 349 | /* |
200 | * Open a special address decode windows for the PCIe WA. | 350 | * Configure peripherals. |
201 | */ | 351 | */ |
202 | orion5x_setup_pcie_wa_win(ORION5X_PCIE_WA_PHYS_BASE, | 352 | orion5x_ehci0_init(); |
203 | ORION5X_PCIE_WA_SIZE); | 353 | orion5x_ehci1_init(); |
204 | 354 | orion5x_eth_init(&kurobox_pro_eth_data); | |
205 | /* | 355 | orion5x_i2c_init(); |
206 | * Setup Multiplexing Pins -- | 356 | orion5x_sata_init(&kurobox_pro_sata_data); |
207 | * MPP[0-1] Not used | 357 | orion5x_uart0_init(); |
208 | * MPP[2] GPIO Micon | 358 | orion5x_uart1_init(); |
209 | * MPP[3] GPIO RTC | ||
210 | * MPP[4-5] Not used | ||
211 | * MPP[6] Nand Flash REn | ||
212 | * MPP[7] Nand Flash WEn | ||
213 | * MPP[8-11] Not used | ||
214 | * MPP[12] SATA 0 presence Indication | ||
215 | * MPP[13] SATA 1 presence Indication | ||
216 | * MPP[14] SATA 0 active Indication | ||
217 | * MPP[15] SATA 1 active indication | ||
218 | * MPP[16-19] Not used | ||
219 | */ | ||
220 | orion5x_write(MPP_0_7_CTRL, 0x44220003); | ||
221 | orion5x_write(MPP_8_15_CTRL, 0x55550000); | ||
222 | orion5x_write(MPP_16_19_CTRL, 0x0); | ||
223 | |||
224 | orion5x_gpio_set_valid_pins(0x0000000c); | ||
225 | 359 | ||
360 | orion5x_setup_dev_boot_win(KUROBOX_PRO_NOR_BOOT_BASE, | ||
361 | KUROBOX_PRO_NOR_BOOT_SIZE); | ||
226 | platform_device_register(&kurobox_pro_nor_flash); | 362 | platform_device_register(&kurobox_pro_nor_flash); |
227 | if (machine_is_kurobox_pro()) | 363 | |
364 | if (machine_is_kurobox_pro()) { | ||
365 | orion5x_setup_dev0_win(KUROBOX_PRO_NAND_BASE, | ||
366 | KUROBOX_PRO_NAND_SIZE); | ||
228 | platform_device_register(&kurobox_pro_nand_flash); | 367 | platform_device_register(&kurobox_pro_nand_flash); |
368 | } | ||
369 | |||
229 | i2c_register_board_info(0, &kurobox_pro_i2c_rtc, 1); | 370 | i2c_register_board_info(0, &kurobox_pro_i2c_rtc, 1); |
230 | orion5x_eth_init(&kurobox_pro_eth_data); | 371 | |
231 | orion5x_sata_init(&kurobox_pro_sata_data); | 372 | /* register Kurobox Pro specific power-off method */ |
373 | pm_power_off = kurobox_pro_power_off; | ||
232 | } | 374 | } |
233 | 375 | ||
234 | #ifdef CONFIG_MACH_KUROBOX_PRO | 376 | #ifdef CONFIG_MACH_KUROBOX_PRO |
diff --git a/arch/arm/mach-orion5x/mpp.c b/arch/arm/mach-orion5x/mpp.c new file mode 100644 index 000000000000..a48cadb01590 --- /dev/null +++ b/arch/arm/mach-orion5x/mpp.c | |||
@@ -0,0 +1,163 @@ | |||
1 | /* | ||
2 | * arch/arm/mach-orion5x/mpp.c | ||
3 | * | ||
4 | * MPP functions for Marvell Orion 5x SoCs | ||
5 | * | ||
6 | * This file is licensed under the terms of the GNU General Public | ||
7 | * License version 2. This program is licensed "as is" without any | ||
8 | * warranty of any kind, whether express or implied. | ||
9 | */ | ||
10 | |||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/init.h> | ||
13 | #include <linux/mbus.h> | ||
14 | #include <asm/hardware.h> | ||
15 | #include <asm/io.h> | ||
16 | #include "common.h" | ||
17 | #include "mpp.h" | ||
18 | |||
19 | static int is_5181l(void) | ||
20 | { | ||
21 | u32 dev; | ||
22 | u32 rev; | ||
23 | |||
24 | orion5x_pcie_id(&dev, &rev); | ||
25 | |||
26 | return !!(dev == MV88F5181_DEV_ID && rev >= MV88F5181L_REV_A0); | ||
27 | } | ||
28 | |||
29 | static int is_5182(void) | ||
30 | { | ||
31 | u32 dev; | ||
32 | u32 rev; | ||
33 | |||
34 | orion5x_pcie_id(&dev, &rev); | ||
35 | |||
36 | return !!(dev == MV88F5182_DEV_ID); | ||
37 | } | ||
38 | |||
39 | static int is_5281(void) | ||
40 | { | ||
41 | u32 dev; | ||
42 | u32 rev; | ||
43 | |||
44 | orion5x_pcie_id(&dev, &rev); | ||
45 | |||
46 | return !!(dev == MV88F5281_DEV_ID); | ||
47 | } | ||
48 | |||
49 | static int __init determine_type_encoding(int mpp, enum orion5x_mpp_type type) | ||
50 | { | ||
51 | switch (type) { | ||
52 | case MPP_UNUSED: | ||
53 | case MPP_GPIO: | ||
54 | if (mpp == 0) | ||
55 | return 3; | ||
56 | if (mpp >= 1 && mpp <= 15) | ||
57 | return 0; | ||
58 | if (mpp >= 16 && mpp <= 19) { | ||
59 | if (is_5182()) | ||
60 | return 5; | ||
61 | if (type == MPP_UNUSED) | ||
62 | return 0; | ||
63 | } | ||
64 | return -1; | ||
65 | |||
66 | case MPP_PCIE_RST_OUTn: | ||
67 | if (mpp == 0) | ||
68 | return 0; | ||
69 | return -1; | ||
70 | |||
71 | case MPP_PCI_ARB: | ||
72 | if (mpp >= 0 && mpp <= 7) | ||
73 | return 2; | ||
74 | return -1; | ||
75 | |||
76 | case MPP_PCI_PMEn: | ||
77 | if (mpp == 2) | ||
78 | return 3; | ||
79 | return -1; | ||
80 | |||
81 | case MPP_GIGE: | ||
82 | if (mpp >= 8 && mpp <= 19) | ||
83 | return 1; | ||
84 | return -1; | ||
85 | |||
86 | case MPP_NAND: | ||
87 | if (is_5182() || is_5281()) { | ||
88 | if (mpp >= 4 && mpp <= 7) | ||
89 | return 4; | ||
90 | if (mpp >= 12 && mpp <= 17) | ||
91 | return 4; | ||
92 | } | ||
93 | return -1; | ||
94 | |||
95 | case MPP_PCI_CLK: | ||
96 | if (is_5181l() && mpp >= 6 && mpp <= 7) | ||
97 | return 5; | ||
98 | return -1; | ||
99 | |||
100 | case MPP_SATA_LED: | ||
101 | if (is_5182()) { | ||
102 | if (mpp >= 4 && mpp <= 7) | ||
103 | return 5; | ||
104 | if (mpp >= 12 && mpp <= 15) | ||
105 | return 5; | ||
106 | } | ||
107 | return -1; | ||
108 | |||
109 | case MPP_UART: | ||
110 | if (mpp >= 16 && mpp <= 19) | ||
111 | return 0; | ||
112 | return -1; | ||
113 | } | ||
114 | |||
115 | printk(KERN_INFO "unknown MPP type %d\n", type); | ||
116 | |||
117 | return -1; | ||
118 | } | ||
119 | |||
120 | void __init orion5x_mpp_conf(struct orion5x_mpp_mode *mode) | ||
121 | { | ||
122 | u32 mpp_0_7_ctrl = readl(MPP_0_7_CTRL); | ||
123 | u32 mpp_8_15_ctrl = readl(MPP_8_15_CTRL); | ||
124 | u32 mpp_16_19_ctrl = readl(MPP_16_19_CTRL); | ||
125 | |||
126 | while (mode->mpp >= 0) { | ||
127 | u32 *reg; | ||
128 | int num_type; | ||
129 | int shift; | ||
130 | |||
131 | if (mode->mpp >= 0 && mode->mpp <= 7) | ||
132 | reg = &mpp_0_7_ctrl; | ||
133 | else if (mode->mpp >= 8 && mode->mpp <= 15) | ||
134 | reg = &mpp_8_15_ctrl; | ||
135 | else if (mode->mpp >= 16 && mode->mpp <= 19) | ||
136 | reg = &mpp_16_19_ctrl; | ||
137 | else { | ||
138 | printk(KERN_ERR "orion5x_mpp_conf: invalid MPP " | ||
139 | "(%d)\n", mode->mpp); | ||
140 | continue; | ||
141 | } | ||
142 | |||
143 | num_type = determine_type_encoding(mode->mpp, mode->type); | ||
144 | if (num_type < 0) { | ||
145 | printk(KERN_ERR "orion5x_mpp_conf: invalid MPP " | ||
146 | "combination (%d, %d)\n", mode->mpp, | ||
147 | mode->type); | ||
148 | continue; | ||
149 | } | ||
150 | |||
151 | shift = (mode->mpp & 7) << 2; | ||
152 | *reg &= ~(0xf << shift); | ||
153 | *reg |= (num_type & 0xf) << shift; | ||
154 | |||
155 | orion5x_gpio_set_valid(mode->mpp, !!(mode->type == MPP_GPIO)); | ||
156 | |||
157 | mode++; | ||
158 | } | ||
159 | |||
160 | writel(mpp_0_7_ctrl, MPP_0_7_CTRL); | ||
161 | writel(mpp_8_15_ctrl, MPP_8_15_CTRL); | ||
162 | writel(mpp_16_19_ctrl, MPP_16_19_CTRL); | ||
163 | } | ||
diff --git a/arch/arm/mach-orion5x/mpp.h b/arch/arm/mach-orion5x/mpp.h new file mode 100644 index 000000000000..290e610dc012 --- /dev/null +++ b/arch/arm/mach-orion5x/mpp.h | |||
@@ -0,0 +1,74 @@ | |||
1 | #ifndef __ARCH_ORION5X_MPP_H | ||
2 | #define __ARCH_ORION5X_MPP_H | ||
3 | |||
4 | enum orion5x_mpp_type { | ||
5 | /* | ||
6 | * This MPP is unused. | ||
7 | */ | ||
8 | MPP_UNUSED, | ||
9 | |||
10 | /* | ||
11 | * This MPP pin is used as a generic GPIO pin. Valid for | ||
12 | * MPPs 0-15 and device bus data pins 16-31. On 5182, also | ||
13 | * valid for MPPs 16-19. | ||
14 | */ | ||
15 | MPP_GPIO, | ||
16 | |||
17 | /* | ||
18 | * This MPP is used as PCIe_RST_OUTn pin. Valid for | ||
19 | * MPP 0 only. | ||
20 | */ | ||
21 | MPP_PCIE_RST_OUTn, | ||
22 | |||
23 | /* | ||
24 | * This MPP is used as PCI arbiter pin (REQn/GNTn). | ||
25 | * Valid for MPPs 0-7 only. | ||
26 | */ | ||
27 | MPP_PCI_ARB, | ||
28 | |||
29 | /* | ||
30 | * This MPP is used as PCI_PMEn pin. Valid for MPP 2 only. | ||
31 | */ | ||
32 | MPP_PCI_PMEn, | ||
33 | |||
34 | /* | ||
35 | * This MPP is used as GigE half-duplex (COL, CRS) or GMII | ||
36 | * (RXERR, CRS, TXERR, TXD[7:4], RXD[7:4]) pin. Valid for | ||
37 | * MPPs 8-19 only. | ||
38 | */ | ||
39 | MPP_GIGE, | ||
40 | |||
41 | /* | ||
42 | * This MPP is used as NAND REn/WEn pin. Valid for MPPs | ||
43 | * 4-7 and 12-17 only, and only on the 5181l/5182/5281. | ||
44 | */ | ||
45 | MPP_NAND, | ||
46 | |||
47 | /* | ||
48 | * This MPP is used as a PCI clock output pin. Valid for | ||
49 | * MPPs 6-7 only, and only on the 5181l. | ||
50 | */ | ||
51 | MPP_PCI_CLK, | ||
52 | |||
53 | /* | ||
54 | * This MPP is used as a SATA presence/activity LED. | ||
55 | * Valid for MPPs 4-7 and 12-15 only, and only on the 5182. | ||
56 | */ | ||
57 | MPP_SATA_LED, | ||
58 | |||
59 | /* | ||
60 | * This MPP is used as UART1 RXD/TXD/CTSn/RTSn pin. | ||
61 | * Valid for MPPs 16-19 only. | ||
62 | */ | ||
63 | MPP_UART, | ||
64 | }; | ||
65 | |||
66 | struct orion5x_mpp_mode { | ||
67 | int mpp; | ||
68 | enum orion5x_mpp_type type; | ||
69 | }; | ||
70 | |||
71 | void orion5x_mpp_conf(struct orion5x_mpp_mode *mode); | ||
72 | |||
73 | |||
74 | #endif | ||
diff --git a/arch/arm/mach-orion5x/mss2-setup.c b/arch/arm/mach-orion5x/mss2-setup.c new file mode 100644 index 000000000000..7ce9e407d9d1 --- /dev/null +++ b/arch/arm/mach-orion5x/mss2-setup.c | |||
@@ -0,0 +1,270 @@ | |||
1 | /* | ||
2 | * Maxtor Shared Storage II Board Setup | ||
3 | * | ||
4 | * Maintainer: Sylver Bruneau <sylver.bruneau@googlemail.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * as published by the Free Software Foundation; either version | ||
9 | * 2 of the License, or (at your option) any later version. | ||
10 | */ | ||
11 | |||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/init.h> | ||
14 | #include <linux/platform_device.h> | ||
15 | #include <linux/pci.h> | ||
16 | #include <linux/irq.h> | ||
17 | #include <linux/mtd/physmap.h> | ||
18 | #include <linux/mv643xx_eth.h> | ||
19 | #include <linux/leds.h> | ||
20 | #include <linux/gpio_keys.h> | ||
21 | #include <linux/input.h> | ||
22 | #include <linux/i2c.h> | ||
23 | #include <linux/ata_platform.h> | ||
24 | #include <linux/gpio.h> | ||
25 | #include <asm/mach-types.h> | ||
26 | #include <asm/mach/arch.h> | ||
27 | #include <asm/mach/pci.h> | ||
28 | #include <asm/arch/orion5x.h> | ||
29 | #include "common.h" | ||
30 | #include "mpp.h" | ||
31 | |||
32 | #define MSS2_NOR_BOOT_BASE 0xff800000 | ||
33 | #define MSS2_NOR_BOOT_SIZE SZ_256K | ||
34 | |||
35 | /***************************************************************************** | ||
36 | * Maxtor Shared Storage II Info | ||
37 | ****************************************************************************/ | ||
38 | |||
39 | /* | ||
40 | * Maxtor Shared Storage II hardware : | ||
41 | * - Marvell 88F5182-A2 C500 | ||
42 | * - Marvell 88E1111 Gigabit Ethernet PHY | ||
43 | * - RTC M41T81 (@0x68) on I2C bus | ||
44 | * - 256KB NOR flash | ||
45 | * - 64MB of RAM | ||
46 | */ | ||
47 | |||
48 | /***************************************************************************** | ||
49 | * 256KB NOR Flash on BOOT Device | ||
50 | ****************************************************************************/ | ||
51 | |||
52 | static struct physmap_flash_data mss2_nor_flash_data = { | ||
53 | .width = 1, | ||
54 | }; | ||
55 | |||
56 | static struct resource mss2_nor_flash_resource = { | ||
57 | .flags = IORESOURCE_MEM, | ||
58 | .start = MSS2_NOR_BOOT_BASE, | ||
59 | .end = MSS2_NOR_BOOT_BASE + MSS2_NOR_BOOT_SIZE - 1, | ||
60 | }; | ||
61 | |||
62 | static struct platform_device mss2_nor_flash = { | ||
63 | .name = "physmap-flash", | ||
64 | .id = 0, | ||
65 | .dev = { | ||
66 | .platform_data = &mss2_nor_flash_data, | ||
67 | }, | ||
68 | .resource = &mss2_nor_flash_resource, | ||
69 | .num_resources = 1, | ||
70 | }; | ||
71 | |||
72 | /**************************************************************************** | ||
73 | * PCI setup | ||
74 | ****************************************************************************/ | ||
75 | static int __init mss2_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) | ||
76 | { | ||
77 | int irq; | ||
78 | |||
79 | /* | ||
80 | * Check for devices with hard-wired IRQs. | ||
81 | */ | ||
82 | irq = orion5x_pci_map_irq(dev, slot, pin); | ||
83 | if (irq != -1) | ||
84 | return irq; | ||
85 | |||
86 | return -1; | ||
87 | } | ||
88 | |||
89 | static struct hw_pci mss2_pci __initdata = { | ||
90 | .nr_controllers = 2, | ||
91 | .swizzle = pci_std_swizzle, | ||
92 | .setup = orion5x_pci_sys_setup, | ||
93 | .scan = orion5x_pci_sys_scan_bus, | ||
94 | .map_irq = mss2_pci_map_irq, | ||
95 | }; | ||
96 | |||
97 | static int __init mss2_pci_init(void) | ||
98 | { | ||
99 | if (machine_is_mss2()) | ||
100 | pci_common_init(&mss2_pci); | ||
101 | |||
102 | return 0; | ||
103 | } | ||
104 | subsys_initcall(mss2_pci_init); | ||
105 | |||
106 | |||
107 | /***************************************************************************** | ||
108 | * Ethernet | ||
109 | ****************************************************************************/ | ||
110 | |||
111 | static struct mv643xx_eth_platform_data mss2_eth_data = { | ||
112 | .phy_addr = 8, | ||
113 | }; | ||
114 | |||
115 | /***************************************************************************** | ||
116 | * SATA | ||
117 | ****************************************************************************/ | ||
118 | |||
119 | static struct mv_sata_platform_data mss2_sata_data = { | ||
120 | .n_ports = 2, | ||
121 | }; | ||
122 | |||
123 | /***************************************************************************** | ||
124 | * GPIO buttons | ||
125 | ****************************************************************************/ | ||
126 | |||
127 | #define MSS2_GPIO_KEY_RESET 12 | ||
128 | #define MSS2_GPIO_KEY_POWER 11 | ||
129 | |||
130 | static struct gpio_keys_button mss2_buttons[] = { | ||
131 | { | ||
132 | .code = KEY_POWER, | ||
133 | .gpio = MSS2_GPIO_KEY_POWER, | ||
134 | .desc = "Power", | ||
135 | .active_low = 1, | ||
136 | }, { | ||
137 | .code = KEY_RESTART, | ||
138 | .gpio = MSS2_GPIO_KEY_RESET, | ||
139 | .desc = "Reset", | ||
140 | .active_low = 1, | ||
141 | }, | ||
142 | }; | ||
143 | |||
144 | static struct gpio_keys_platform_data mss2_button_data = { | ||
145 | .buttons = mss2_buttons, | ||
146 | .nbuttons = ARRAY_SIZE(mss2_buttons), | ||
147 | }; | ||
148 | |||
149 | static struct platform_device mss2_button_device = { | ||
150 | .name = "gpio-keys", | ||
151 | .id = -1, | ||
152 | .dev = { | ||
153 | .platform_data = &mss2_button_data, | ||
154 | }, | ||
155 | }; | ||
156 | |||
157 | /***************************************************************************** | ||
158 | * RTC m41t81 on I2C bus | ||
159 | ****************************************************************************/ | ||
160 | |||
161 | #define MSS2_GPIO_RTC_IRQ 3 | ||
162 | |||
163 | static struct i2c_board_info __initdata mss2_i2c_rtc = { | ||
164 | I2C_BOARD_INFO("m41t81", 0x68), | ||
165 | }; | ||
166 | |||
167 | /***************************************************************************** | ||
168 | * MSS2 power off method | ||
169 | ****************************************************************************/ | ||
170 | /* | ||
171 | * On the Maxtor Shared Storage II, the shutdown process is the following : | ||
172 | * - Userland modifies U-boot env to tell U-boot to go idle at next boot | ||
173 | * - The board reboots | ||
174 | * - U-boot starts and go into an idle mode until the user press "power" | ||
175 | */ | ||
176 | static void mss2_power_off(void) | ||
177 | { | ||
178 | u32 reg; | ||
179 | |||
180 | /* | ||
181 | * Enable and issue soft reset | ||
182 | */ | ||
183 | reg = readl(CPU_RESET_MASK); | ||
184 | reg |= 1 << 2; | ||
185 | writel(reg, CPU_RESET_MASK); | ||
186 | |||
187 | reg = readl(CPU_SOFT_RESET); | ||
188 | reg |= 1; | ||
189 | writel(reg, CPU_SOFT_RESET); | ||
190 | } | ||
191 | |||
192 | /**************************************************************************** | ||
193 | * General Setup | ||
194 | ****************************************************************************/ | ||
195 | static struct orion5x_mpp_mode mss2_mpp_modes[] __initdata = { | ||
196 | { 0, MPP_GPIO }, /* Power LED */ | ||
197 | { 1, MPP_GPIO }, /* Error LED */ | ||
198 | { 2, MPP_UNUSED }, | ||
199 | { 3, MPP_GPIO }, /* RTC interrupt */ | ||
200 | { 4, MPP_GPIO }, /* HDD ind. (Single/Dual)*/ | ||
201 | { 5, MPP_GPIO }, /* HD0 5V control */ | ||
202 | { 6, MPP_GPIO }, /* HD0 12V control */ | ||
203 | { 7, MPP_GPIO }, /* HD1 5V control */ | ||
204 | { 8, MPP_GPIO }, /* HD1 12V control */ | ||
205 | { 9, MPP_UNUSED }, | ||
206 | { 10, MPP_GPIO }, /* Fan control */ | ||
207 | { 11, MPP_GPIO }, /* Power button */ | ||
208 | { 12, MPP_GPIO }, /* Reset button */ | ||
209 | { 13, MPP_UNUSED }, | ||
210 | { 14, MPP_SATA_LED }, /* SATA 0 active */ | ||
211 | { 15, MPP_SATA_LED }, /* SATA 1 active */ | ||
212 | { 16, MPP_UNUSED }, | ||
213 | { 17, MPP_UNUSED }, | ||
214 | { 18, MPP_UNUSED }, | ||
215 | { 19, MPP_UNUSED }, | ||
216 | { -1 }, | ||
217 | }; | ||
218 | |||
219 | static void __init mss2_init(void) | ||
220 | { | ||
221 | /* Setup basic Orion functions. Need to be called early. */ | ||
222 | orion5x_init(); | ||
223 | |||
224 | orion5x_mpp_conf(mss2_mpp_modes); | ||
225 | |||
226 | /* | ||
227 | * MPP[20] Unused | ||
228 | * MPP[21] PCI clock | ||
229 | * MPP[22] USB 0 over current | ||
230 | * MPP[23] USB 1 over current | ||
231 | */ | ||
232 | |||
233 | /* | ||
234 | * Configure peripherals. | ||
235 | */ | ||
236 | orion5x_ehci0_init(); | ||
237 | orion5x_ehci1_init(); | ||
238 | orion5x_eth_init(&mss2_eth_data); | ||
239 | orion5x_i2c_init(); | ||
240 | orion5x_sata_init(&mss2_sata_data); | ||
241 | orion5x_uart0_init(); | ||
242 | |||
243 | orion5x_setup_dev_boot_win(MSS2_NOR_BOOT_BASE, MSS2_NOR_BOOT_SIZE); | ||
244 | platform_device_register(&mss2_nor_flash); | ||
245 | |||
246 | platform_device_register(&mss2_button_device); | ||
247 | |||
248 | if (gpio_request(MSS2_GPIO_RTC_IRQ, "rtc") == 0) { | ||
249 | if (gpio_direction_input(MSS2_GPIO_RTC_IRQ) == 0) | ||
250 | mss2_i2c_rtc.irq = gpio_to_irq(MSS2_GPIO_RTC_IRQ); | ||
251 | else | ||
252 | gpio_free(MSS2_GPIO_RTC_IRQ); | ||
253 | } | ||
254 | i2c_register_board_info(0, &mss2_i2c_rtc, 1); | ||
255 | |||
256 | /* register mss2 specific power-off method */ | ||
257 | pm_power_off = mss2_power_off; | ||
258 | } | ||
259 | |||
260 | MACHINE_START(MSS2, "Maxtor Shared Storage II") | ||
261 | /* Maintainer: Sylver Bruneau <sylver.bruneau@googlemail.com> */ | ||
262 | .phys_io = ORION5X_REGS_PHYS_BASE, | ||
263 | .io_pg_offst = ((ORION5X_REGS_VIRT_BASE) >> 18) & 0xFFFC, | ||
264 | .boot_params = 0x00000100, | ||
265 | .init_machine = mss2_init, | ||
266 | .map_io = orion5x_map_io, | ||
267 | .init_irq = orion5x_init_irq, | ||
268 | .timer = &orion5x_timer, | ||
269 | .fixup = tag_fixup_mem32 | ||
270 | MACHINE_END | ||
diff --git a/arch/arm/mach-orion5x/mv2120-setup.c b/arch/arm/mach-orion5x/mv2120-setup.c new file mode 100644 index 000000000000..55f3b0fdef8b --- /dev/null +++ b/arch/arm/mach-orion5x/mv2120-setup.c | |||
@@ -0,0 +1,239 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2007 Herbert Valerio Riedel <hvr@gnu.org> | ||
3 | * Copyright (C) 2008 Martin Michlmayr <tbm@cyrius.com> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU Lesser General Public License as | ||
7 | * published by the Free Software Foundation; either version 2 of the | ||
8 | * License, or (at your option) any later version. | ||
9 | */ | ||
10 | |||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/init.h> | ||
13 | #include <linux/platform_device.h> | ||
14 | #include <linux/irq.h> | ||
15 | #include <linux/mtd/physmap.h> | ||
16 | #include <linux/mv643xx_eth.h> | ||
17 | #include <linux/leds.h> | ||
18 | #include <linux/gpio_keys.h> | ||
19 | #include <linux/input.h> | ||
20 | #include <linux/i2c.h> | ||
21 | #include <linux/ata_platform.h> | ||
22 | #include <asm/mach-types.h> | ||
23 | #include <asm/gpio.h> | ||
24 | #include <asm/mach/arch.h> | ||
25 | #include <asm/arch/orion5x.h> | ||
26 | #include "common.h" | ||
27 | #include "mpp.h" | ||
28 | |||
29 | #define MV2120_NOR_BOOT_BASE 0xf4000000 | ||
30 | #define MV2120_NOR_BOOT_SIZE SZ_512K | ||
31 | |||
32 | #define MV2120_GPIO_RTC_IRQ 3 | ||
33 | #define MV2120_GPIO_KEY_RESET 17 | ||
34 | #define MV2120_GPIO_KEY_POWER 18 | ||
35 | #define MV2120_GPIO_POWER_OFF 19 | ||
36 | |||
37 | |||
38 | /***************************************************************************** | ||
39 | * Ethernet | ||
40 | ****************************************************************************/ | ||
41 | static struct mv643xx_eth_platform_data mv2120_eth_data = { | ||
42 | .phy_addr = 8, | ||
43 | }; | ||
44 | |||
45 | static struct mv_sata_platform_data mv2120_sata_data = { | ||
46 | .n_ports = 2, | ||
47 | }; | ||
48 | |||
49 | static struct mtd_partition mv2120_partitions[] = { | ||
50 | { | ||
51 | .name = "firmware", | ||
52 | .size = 0x00080000, | ||
53 | .offset = 0, | ||
54 | }, | ||
55 | }; | ||
56 | |||
57 | static struct physmap_flash_data mv2120_nor_flash_data = { | ||
58 | .width = 1, | ||
59 | .parts = mv2120_partitions, | ||
60 | .nr_parts = ARRAY_SIZE(mv2120_partitions) | ||
61 | }; | ||
62 | |||
63 | static struct resource mv2120_nor_flash_resource = { | ||
64 | .flags = IORESOURCE_MEM, | ||
65 | .start = MV2120_NOR_BOOT_BASE, | ||
66 | .end = MV2120_NOR_BOOT_BASE + MV2120_NOR_BOOT_SIZE - 1, | ||
67 | }; | ||
68 | |||
69 | static struct platform_device mv2120_nor_flash = { | ||
70 | .name = "physmap-flash", | ||
71 | .id = 0, | ||
72 | .dev = { | ||
73 | .platform_data = &mv2120_nor_flash_data, | ||
74 | }, | ||
75 | .resource = &mv2120_nor_flash_resource, | ||
76 | .num_resources = 1, | ||
77 | }; | ||
78 | |||
79 | static struct gpio_keys_button mv2120_buttons[] = { | ||
80 | { | ||
81 | .code = KEY_RESTART, | ||
82 | .gpio = MV2120_GPIO_KEY_RESET, | ||
83 | .desc = "reset", | ||
84 | .active_low = 1, | ||
85 | }, { | ||
86 | .code = KEY_POWER, | ||
87 | .gpio = MV2120_GPIO_KEY_POWER, | ||
88 | .desc = "power", | ||
89 | .active_low = 1, | ||
90 | }, | ||
91 | }; | ||
92 | |||
93 | static struct gpio_keys_platform_data mv2120_button_data = { | ||
94 | .buttons = mv2120_buttons, | ||
95 | .nbuttons = ARRAY_SIZE(mv2120_buttons), | ||
96 | }; | ||
97 | |||
98 | static struct platform_device mv2120_button_device = { | ||
99 | .name = "gpio-keys", | ||
100 | .id = -1, | ||
101 | .num_resources = 0, | ||
102 | .dev = { | ||
103 | .platform_data = &mv2120_button_data, | ||
104 | }, | ||
105 | }; | ||
106 | |||
107 | |||
108 | /**************************************************************************** | ||
109 | * General Setup | ||
110 | ****************************************************************************/ | ||
111 | static struct orion5x_mpp_mode mv2120_mpp_modes[] __initdata = { | ||
112 | { 0, MPP_GPIO }, /* Sys status LED */ | ||
113 | { 1, MPP_GPIO }, /* Sys error LED */ | ||
114 | { 2, MPP_GPIO }, /* OverTemp interrupt */ | ||
115 | { 3, MPP_GPIO }, /* RTC interrupt */ | ||
116 | { 4, MPP_GPIO }, /* V_LED 5V */ | ||
117 | { 5, MPP_GPIO }, /* V_LED 3.3V */ | ||
118 | { 6, MPP_UNUSED }, | ||
119 | { 7, MPP_UNUSED }, | ||
120 | { 8, MPP_GPIO }, /* SATA 0 fail LED */ | ||
121 | { 9, MPP_GPIO }, /* SATA 1 fail LED */ | ||
122 | { 10, MPP_UNUSED }, | ||
123 | { 11, MPP_UNUSED }, | ||
124 | { 12, MPP_SATA_LED }, /* SATA 0 presence */ | ||
125 | { 13, MPP_SATA_LED }, /* SATA 1 presence */ | ||
126 | { 14, MPP_SATA_LED }, /* SATA 0 active */ | ||
127 | { 15, MPP_SATA_LED }, /* SATA 1 active */ | ||
128 | { 16, MPP_UNUSED }, | ||
129 | { 17, MPP_GPIO }, /* Reset button */ | ||
130 | { 18, MPP_GPIO }, /* Power button */ | ||
131 | { 19, MPP_GPIO }, /* Power off */ | ||
132 | { -1 }, | ||
133 | }; | ||
134 | |||
135 | static struct i2c_board_info __initdata mv2120_i2c_rtc = { | ||
136 | I2C_BOARD_INFO("pcf8563", 0x51), | ||
137 | .irq = 0, | ||
138 | }; | ||
139 | |||
140 | static struct gpio_led mv2120_led_pins[] = { | ||
141 | { | ||
142 | .name = "mv2120:blue:health", | ||
143 | .gpio = 0, | ||
144 | }, | ||
145 | { | ||
146 | .name = "mv2120:red:health", | ||
147 | .gpio = 1, | ||
148 | }, | ||
149 | { | ||
150 | .name = "mv2120:led:bright", | ||
151 | .gpio = 4, | ||
152 | .default_trigger = "default-on", | ||
153 | }, | ||
154 | { | ||
155 | .name = "mv2120:led:dimmed", | ||
156 | .gpio = 5, | ||
157 | }, | ||
158 | { | ||
159 | .name = "mv2120:red:sata0", | ||
160 | .gpio = 8, | ||
161 | .active_low = 1, | ||
162 | }, | ||
163 | { | ||
164 | .name = "mv2120:red:sata1", | ||
165 | .gpio = 9, | ||
166 | .active_low = 1, | ||
167 | }, | ||
168 | |||
169 | }; | ||
170 | |||
171 | static struct gpio_led_platform_data mv2120_led_data = { | ||
172 | .leds = mv2120_led_pins, | ||
173 | .num_leds = ARRAY_SIZE(mv2120_led_pins), | ||
174 | }; | ||
175 | |||
176 | static struct platform_device mv2120_leds = { | ||
177 | .name = "leds-gpio", | ||
178 | .id = -1, | ||
179 | .dev = { | ||
180 | .platform_data = &mv2120_led_data, | ||
181 | } | ||
182 | }; | ||
183 | |||
184 | static void mv2120_power_off(void) | ||
185 | { | ||
186 | pr_info("%s: triggering power-off...\n", __func__); | ||
187 | gpio_set_value(MV2120_GPIO_POWER_OFF, 0); | ||
188 | } | ||
189 | |||
190 | static void __init mv2120_init(void) | ||
191 | { | ||
192 | /* Setup basic Orion functions. Need to be called early. */ | ||
193 | orion5x_init(); | ||
194 | |||
195 | orion5x_mpp_conf(mv2120_mpp_modes); | ||
196 | |||
197 | /* | ||
198 | * Configure peripherals. | ||
199 | */ | ||
200 | orion5x_ehci0_init(); | ||
201 | orion5x_ehci1_init(); | ||
202 | orion5x_eth_init(&mv2120_eth_data); | ||
203 | orion5x_i2c_init(); | ||
204 | orion5x_sata_init(&mv2120_sata_data); | ||
205 | orion5x_uart0_init(); | ||
206 | |||
207 | orion5x_setup_dev_boot_win(MV2120_NOR_BOOT_BASE, MV2120_NOR_BOOT_SIZE); | ||
208 | platform_device_register(&mv2120_nor_flash); | ||
209 | |||
210 | platform_device_register(&mv2120_button_device); | ||
211 | |||
212 | if (gpio_request(MV2120_GPIO_RTC_IRQ, "rtc") == 0) { | ||
213 | if (gpio_direction_input(MV2120_GPIO_RTC_IRQ) == 0) | ||
214 | mv2120_i2c_rtc.irq = gpio_to_irq(MV2120_GPIO_RTC_IRQ); | ||
215 | else | ||
216 | gpio_free(MV2120_GPIO_RTC_IRQ); | ||
217 | } | ||
218 | i2c_register_board_info(0, &mv2120_i2c_rtc, 1); | ||
219 | platform_device_register(&mv2120_leds); | ||
220 | |||
221 | /* register mv2120 specific power-off method */ | ||
222 | if (gpio_request(MV2120_GPIO_POWER_OFF, "POWEROFF") != 0 || | ||
223 | gpio_direction_output(MV2120_GPIO_POWER_OFF, 1) != 0) | ||
224 | pr_err("mv2120: failed to setup power-off GPIO\n"); | ||
225 | pm_power_off = mv2120_power_off; | ||
226 | } | ||
227 | |||
228 | /* Warning: HP uses a wrong mach-type (=526) in their bootloader */ | ||
229 | MACHINE_START(MV2120, "HP Media Vault mv2120") | ||
230 | /* Maintainer: Martin Michlmayr <tbm@cyrius.com> */ | ||
231 | .phys_io = ORION5X_REGS_PHYS_BASE, | ||
232 | .io_pg_offst = ((ORION5X_REGS_VIRT_BASE) >> 18) & 0xFFFC, | ||
233 | .boot_params = 0x00000100, | ||
234 | .init_machine = mv2120_init, | ||
235 | .map_io = orion5x_map_io, | ||
236 | .init_irq = orion5x_init_irq, | ||
237 | .timer = &orion5x_timer, | ||
238 | .fixup = tag_fixup_mem32 | ||
239 | MACHINE_END | ||
diff --git a/arch/arm/mach-orion5x/pci.c b/arch/arm/mach-orion5x/pci.c index 9d5d39fa19c3..256a4f680935 100644 --- a/arch/arm/mach-orion5x/pci.c +++ b/arch/arm/mach-orion5x/pci.c | |||
@@ -152,6 +152,8 @@ static int __init pcie_setup(struct pci_sys_data *sys) | |||
152 | if (dev == MV88F5181_DEV_ID || dev == MV88F5182_DEV_ID) { | 152 | if (dev == MV88F5181_DEV_ID || dev == MV88F5182_DEV_ID) { |
153 | printk(KERN_NOTICE "Applying Orion-1/Orion-NAS PCIe config " | 153 | printk(KERN_NOTICE "Applying Orion-1/Orion-NAS PCIe config " |
154 | "read transaction workaround\n"); | 154 | "read transaction workaround\n"); |
155 | orion5x_setup_pcie_wa_win(ORION5X_PCIE_WA_PHYS_BASE, | ||
156 | ORION5X_PCIE_WA_SIZE); | ||
155 | pcie_ops.read = pcie_rd_conf_wa; | 157 | pcie_ops.read = pcie_rd_conf_wa; |
156 | } | 158 | } |
157 | 159 | ||
@@ -240,13 +242,13 @@ static int __init pcie_setup(struct pci_sys_data *sys) | |||
240 | * PCI Address Decode Windows registers | 242 | * PCI Address Decode Windows registers |
241 | */ | 243 | */ |
242 | #define PCI_BAR_SIZE_DDR_CS(n) (((n) == 0) ? ORION5X_PCI_REG(0xc08) : \ | 244 | #define PCI_BAR_SIZE_DDR_CS(n) (((n) == 0) ? ORION5X_PCI_REG(0xc08) : \ |
243 | ((n) == 1) ? ORION5X_PCI_REG(0xd08) : \ | 245 | ((n) == 1) ? ORION5X_PCI_REG(0xd08) : \ |
244 | ((n) == 2) ? ORION5X_PCI_REG(0xc0c) : \ | 246 | ((n) == 2) ? ORION5X_PCI_REG(0xc0c) : \ |
245 | ((n) == 3) ? ORION5X_PCI_REG(0xd0c) : 0) | 247 | ((n) == 3) ? ORION5X_PCI_REG(0xd0c) : 0) |
246 | #define PCI_BAR_REMAP_DDR_CS(n) (((n) ==0) ? ORION5X_PCI_REG(0xc48) : \ | 248 | #define PCI_BAR_REMAP_DDR_CS(n) (((n) == 0) ? ORION5X_PCI_REG(0xc48) : \ |
247 | ((n) == 1) ? ORION5X_PCI_REG(0xd48) : \ | 249 | ((n) == 1) ? ORION5X_PCI_REG(0xd48) : \ |
248 | ((n) == 2) ? ORION5X_PCI_REG(0xc4c) : \ | 250 | ((n) == 2) ? ORION5X_PCI_REG(0xc4c) : \ |
249 | ((n) == 3) ? ORION5X_PCI_REG(0xd4c) : 0) | 251 | ((n) == 3) ? ORION5X_PCI_REG(0xd4c) : 0) |
250 | #define PCI_BAR_ENABLE ORION5X_PCI_REG(0xc3c) | 252 | #define PCI_BAR_ENABLE ORION5X_PCI_REG(0xc3c) |
251 | #define PCI_ADDR_DECODE_CTRL ORION5X_PCI_REG(0xd3c) | 253 | #define PCI_ADDR_DECODE_CTRL ORION5X_PCI_REG(0xd3c) |
252 | 254 | ||
@@ -264,9 +266,11 @@ static int __init pcie_setup(struct pci_sys_data *sys) | |||
264 | */ | 266 | */ |
265 | static DEFINE_SPINLOCK(orion5x_pci_lock); | 267 | static DEFINE_SPINLOCK(orion5x_pci_lock); |
266 | 268 | ||
269 | static int orion5x_pci_cardbus_mode; | ||
270 | |||
267 | static int orion5x_pci_local_bus_nr(void) | 271 | static int orion5x_pci_local_bus_nr(void) |
268 | { | 272 | { |
269 | u32 conf = orion5x_read(PCI_P2P_CONF); | 273 | u32 conf = readl(PCI_P2P_CONF); |
270 | return((conf & PCI_P2P_BUS_MASK) >> PCI_P2P_BUS_OFFS); | 274 | return((conf & PCI_P2P_BUS_MASK) >> PCI_P2P_BUS_OFFS); |
271 | } | 275 | } |
272 | 276 | ||
@@ -276,11 +280,11 @@ static int orion5x_pci_hw_rd_conf(int bus, int dev, u32 func, | |||
276 | unsigned long flags; | 280 | unsigned long flags; |
277 | spin_lock_irqsave(&orion5x_pci_lock, flags); | 281 | spin_lock_irqsave(&orion5x_pci_lock, flags); |
278 | 282 | ||
279 | orion5x_write(PCI_CONF_ADDR, PCI_CONF_BUS(bus) | | 283 | writel(PCI_CONF_BUS(bus) | |
280 | PCI_CONF_DEV(dev) | PCI_CONF_REG(where) | | 284 | PCI_CONF_DEV(dev) | PCI_CONF_REG(where) | |
281 | PCI_CONF_FUNC(func) | PCI_CONF_ADDR_EN); | 285 | PCI_CONF_FUNC(func) | PCI_CONF_ADDR_EN, PCI_CONF_ADDR); |
282 | 286 | ||
283 | *val = orion5x_read(PCI_CONF_DATA); | 287 | *val = readl(PCI_CONF_DATA); |
284 | 288 | ||
285 | if (size == 1) | 289 | if (size == 1) |
286 | *val = (*val >> (8*(where & 0x3))) & 0xff; | 290 | *val = (*val >> (8*(where & 0x3))) & 0xff; |
@@ -300,9 +304,9 @@ static int orion5x_pci_hw_wr_conf(int bus, int dev, u32 func, | |||
300 | 304 | ||
301 | spin_lock_irqsave(&orion5x_pci_lock, flags); | 305 | spin_lock_irqsave(&orion5x_pci_lock, flags); |
302 | 306 | ||
303 | orion5x_write(PCI_CONF_ADDR, PCI_CONF_BUS(bus) | | 307 | writel(PCI_CONF_BUS(bus) | |
304 | PCI_CONF_DEV(dev) | PCI_CONF_REG(where) | | 308 | PCI_CONF_DEV(dev) | PCI_CONF_REG(where) | |
305 | PCI_CONF_FUNC(func) | PCI_CONF_ADDR_EN); | 309 | PCI_CONF_FUNC(func) | PCI_CONF_ADDR_EN, PCI_CONF_ADDR); |
306 | 310 | ||
307 | if (size == 4) { | 311 | if (size == 4) { |
308 | __raw_writel(val, PCI_CONF_DATA); | 312 | __raw_writel(val, PCI_CONF_DATA); |
@@ -319,14 +323,30 @@ static int orion5x_pci_hw_wr_conf(int bus, int dev, u32 func, | |||
319 | return ret; | 323 | return ret; |
320 | } | 324 | } |
321 | 325 | ||
326 | static int orion5x_pci_valid_config(int bus, u32 devfn) | ||
327 | { | ||
328 | if (bus == orion5x_pci_local_bus_nr()) { | ||
329 | /* | ||
330 | * Don't go out for local device | ||
331 | */ | ||
332 | if (PCI_SLOT(devfn) == 0 && PCI_FUNC(devfn) != 0) | ||
333 | return 0; | ||
334 | |||
335 | /* | ||
336 | * When the PCI signals are directly connected to a | ||
337 | * Cardbus slot, ignore all but device IDs 0 and 1. | ||
338 | */ | ||
339 | if (orion5x_pci_cardbus_mode && PCI_SLOT(devfn) > 1) | ||
340 | return 0; | ||
341 | } | ||
342 | |||
343 | return 1; | ||
344 | } | ||
345 | |||
322 | static int orion5x_pci_rd_conf(struct pci_bus *bus, u32 devfn, | 346 | static int orion5x_pci_rd_conf(struct pci_bus *bus, u32 devfn, |
323 | int where, int size, u32 *val) | 347 | int where, int size, u32 *val) |
324 | { | 348 | { |
325 | /* | 349 | if (!orion5x_pci_valid_config(bus->number, devfn)) { |
326 | * Don't go out for local device | ||
327 | */ | ||
328 | if (bus->number == orion5x_pci_local_bus_nr() && | ||
329 | PCI_SLOT(devfn) == 0 && PCI_FUNC(devfn) != 0) { | ||
330 | *val = 0xffffffff; | 350 | *val = 0xffffffff; |
331 | return PCIBIOS_DEVICE_NOT_FOUND; | 351 | return PCIBIOS_DEVICE_NOT_FOUND; |
332 | } | 352 | } |
@@ -338,8 +358,7 @@ static int orion5x_pci_rd_conf(struct pci_bus *bus, u32 devfn, | |||
338 | static int orion5x_pci_wr_conf(struct pci_bus *bus, u32 devfn, | 358 | static int orion5x_pci_wr_conf(struct pci_bus *bus, u32 devfn, |
339 | int where, int size, u32 val) | 359 | int where, int size, u32 val) |
340 | { | 360 | { |
341 | if (bus->number == orion5x_pci_local_bus_nr() && | 361 | if (!orion5x_pci_valid_config(bus->number, devfn)) |
342 | PCI_SLOT(devfn) == 0 && PCI_FUNC(devfn) != 0) | ||
343 | return PCIBIOS_DEVICE_NOT_FOUND; | 362 | return PCIBIOS_DEVICE_NOT_FOUND; |
344 | 363 | ||
345 | return orion5x_pci_hw_wr_conf(bus->number, PCI_SLOT(devfn), | 364 | return orion5x_pci_hw_wr_conf(bus->number, PCI_SLOT(devfn), |
@@ -353,9 +372,9 @@ static struct pci_ops pci_ops = { | |||
353 | 372 | ||
354 | static void __init orion5x_pci_set_bus_nr(int nr) | 373 | static void __init orion5x_pci_set_bus_nr(int nr) |
355 | { | 374 | { |
356 | u32 p2p = orion5x_read(PCI_P2P_CONF); | 375 | u32 p2p = readl(PCI_P2P_CONF); |
357 | 376 | ||
358 | if (orion5x_read(PCI_MODE) & PCI_MODE_PCIX) { | 377 | if (readl(PCI_MODE) & PCI_MODE_PCIX) { |
359 | /* | 378 | /* |
360 | * PCI-X mode | 379 | * PCI-X mode |
361 | */ | 380 | */ |
@@ -372,7 +391,7 @@ static void __init orion5x_pci_set_bus_nr(int nr) | |||
372 | */ | 391 | */ |
373 | p2p &= ~PCI_P2P_BUS_MASK; | 392 | p2p &= ~PCI_P2P_BUS_MASK; |
374 | p2p |= (nr << PCI_P2P_BUS_OFFS); | 393 | p2p |= (nr << PCI_P2P_BUS_OFFS); |
375 | orion5x_write(PCI_P2P_CONF, p2p); | 394 | writel(p2p, PCI_P2P_CONF); |
376 | } | 395 | } |
377 | } | 396 | } |
378 | 397 | ||
@@ -399,7 +418,7 @@ static void __init orion5x_setup_pci_wins(struct mbus_dram_target_info *dram) | |||
399 | * First, disable windows. | 418 | * First, disable windows. |
400 | */ | 419 | */ |
401 | win_enable = 0xffffffff; | 420 | win_enable = 0xffffffff; |
402 | orion5x_write(PCI_BAR_ENABLE, win_enable); | 421 | writel(win_enable, PCI_BAR_ENABLE); |
403 | 422 | ||
404 | /* | 423 | /* |
405 | * Setup windows for DDR banks. | 424 | * Setup windows for DDR banks. |
@@ -425,10 +444,10 @@ static void __init orion5x_setup_pci_wins(struct mbus_dram_target_info *dram) | |||
425 | */ | 444 | */ |
426 | reg = PCI_CONF_REG_BAR_HI_CS(cs->cs_index); | 445 | reg = PCI_CONF_REG_BAR_HI_CS(cs->cs_index); |
427 | orion5x_pci_hw_wr_conf(bus, 0, func, reg, 4, 0); | 446 | orion5x_pci_hw_wr_conf(bus, 0, func, reg, 4, 0); |
428 | orion5x_write(PCI_BAR_SIZE_DDR_CS(cs->cs_index), | 447 | writel((cs->size - 1) & 0xfffff000, |
429 | (cs->size - 1) & 0xfffff000); | 448 | PCI_BAR_SIZE_DDR_CS(cs->cs_index)); |
430 | orion5x_write(PCI_BAR_REMAP_DDR_CS(cs->cs_index), | 449 | writel(cs->base & 0xfffff000, |
431 | cs->base & 0xfffff000); | 450 | PCI_BAR_REMAP_DDR_CS(cs->cs_index)); |
432 | 451 | ||
433 | /* | 452 | /* |
434 | * Enable decode window for this chip select. | 453 | * Enable decode window for this chip select. |
@@ -439,7 +458,7 @@ static void __init orion5x_setup_pci_wins(struct mbus_dram_target_info *dram) | |||
439 | /* | 458 | /* |
440 | * Re-enable decode windows. | 459 | * Re-enable decode windows. |
441 | */ | 460 | */ |
442 | orion5x_write(PCI_BAR_ENABLE, win_enable); | 461 | writel(win_enable, PCI_BAR_ENABLE); |
443 | 462 | ||
444 | /* | 463 | /* |
445 | * Disable automatic update of address remaping when writing to BARs. | 464 | * Disable automatic update of address remaping when writing to BARs. |
@@ -522,6 +541,11 @@ static void __devinit rc_pci_fixup(struct pci_dev *dev) | |||
522 | } | 541 | } |
523 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL, PCI_ANY_ID, rc_pci_fixup); | 542 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL, PCI_ANY_ID, rc_pci_fixup); |
524 | 543 | ||
544 | void __init orion5x_pci_set_cardbus_mode(void) | ||
545 | { | ||
546 | orion5x_pci_cardbus_mode = 1; | ||
547 | } | ||
548 | |||
525 | int __init orion5x_pci_sys_setup(int nr, struct pci_sys_data *sys) | 549 | int __init orion5x_pci_sys_setup(int nr, struct pci_sys_data *sys) |
526 | { | 550 | { |
527 | int ret = 0; | 551 | int ret = 0; |
diff --git a/arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c b/arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c new file mode 100644 index 000000000000..d50e3650a09e --- /dev/null +++ b/arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c | |||
@@ -0,0 +1,161 @@ | |||
1 | /* | ||
2 | * arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c | ||
3 | * | ||
4 | * Marvell Orion-VoIP FXO Reference Design Setup | ||
5 | * | ||
6 | * This file is licensed under the terms of the GNU General Public | ||
7 | * License version 2. This program is licensed "as is" without any | ||
8 | * warranty of any kind, whether express or implied. | ||
9 | */ | ||
10 | |||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/init.h> | ||
13 | #include <linux/platform_device.h> | ||
14 | #include <linux/pci.h> | ||
15 | #include <linux/irq.h> | ||
16 | #include <linux/mtd/physmap.h> | ||
17 | #include <linux/mv643xx_eth.h> | ||
18 | #include <asm/mach-types.h> | ||
19 | #include <asm/gpio.h> | ||
20 | #include <asm/leds.h> | ||
21 | #include <asm/mach/arch.h> | ||
22 | #include <asm/mach/pci.h> | ||
23 | #include <asm/arch/orion5x.h> | ||
24 | #include "common.h" | ||
25 | #include "mpp.h" | ||
26 | |||
27 | /***************************************************************************** | ||
28 | * RD-88F5181L FXO Info | ||
29 | ****************************************************************************/ | ||
30 | /* | ||
31 | * 8M NOR flash Device bus boot chip select | ||
32 | */ | ||
33 | #define RD88F5181L_FXO_NOR_BOOT_BASE 0xff800000 | ||
34 | #define RD88F5181L_FXO_NOR_BOOT_SIZE SZ_8M | ||
35 | |||
36 | |||
37 | /***************************************************************************** | ||
38 | * 8M NOR Flash on Device bus Boot chip select | ||
39 | ****************************************************************************/ | ||
40 | static struct physmap_flash_data rd88f5181l_fxo_nor_boot_flash_data = { | ||
41 | .width = 1, | ||
42 | }; | ||
43 | |||
44 | static struct resource rd88f5181l_fxo_nor_boot_flash_resource = { | ||
45 | .flags = IORESOURCE_MEM, | ||
46 | .start = RD88F5181L_FXO_NOR_BOOT_BASE, | ||
47 | .end = RD88F5181L_FXO_NOR_BOOT_BASE + | ||
48 | RD88F5181L_FXO_NOR_BOOT_SIZE - 1, | ||
49 | }; | ||
50 | |||
51 | static struct platform_device rd88f5181l_fxo_nor_boot_flash = { | ||
52 | .name = "physmap-flash", | ||
53 | .id = 0, | ||
54 | .dev = { | ||
55 | .platform_data = &rd88f5181l_fxo_nor_boot_flash_data, | ||
56 | }, | ||
57 | .num_resources = 1, | ||
58 | .resource = &rd88f5181l_fxo_nor_boot_flash_resource, | ||
59 | }; | ||
60 | |||
61 | |||
62 | /***************************************************************************** | ||
63 | * General Setup | ||
64 | ****************************************************************************/ | ||
65 | static struct orion5x_mpp_mode rd88f5181l_fxo_mpp_modes[] __initdata = { | ||
66 | { 0, MPP_GPIO }, /* LED1 CardBus LED (front panel) */ | ||
67 | { 1, MPP_GPIO }, /* PCI_intA */ | ||
68 | { 2, MPP_GPIO }, /* Hard Reset / Factory Init*/ | ||
69 | { 3, MPP_GPIO }, /* FXS or DAA select */ | ||
70 | { 4, MPP_GPIO }, /* LED6 - phone LED (front panel) */ | ||
71 | { 5, MPP_GPIO }, /* LED5 - phone LED (front panel) */ | ||
72 | { 6, MPP_PCI_CLK }, /* CPU PCI refclk */ | ||
73 | { 7, MPP_PCI_CLK }, /* PCI/PCIe refclk */ | ||
74 | { 8, MPP_GPIO }, /* CardBus reset */ | ||
75 | { 9, MPP_GPIO }, /* GE_RXERR */ | ||
76 | { 10, MPP_GPIO }, /* LED2 MiniPCI LED (front panel) */ | ||
77 | { 11, MPP_GPIO }, /* Lifeline control */ | ||
78 | { 12, MPP_GIGE }, /* GE_TXD[4] */ | ||
79 | { 13, MPP_GIGE }, /* GE_TXD[5] */ | ||
80 | { 14, MPP_GIGE }, /* GE_TXD[6] */ | ||
81 | { 15, MPP_GIGE }, /* GE_TXD[7] */ | ||
82 | { 16, MPP_GIGE }, /* GE_RXD[4] */ | ||
83 | { 17, MPP_GIGE }, /* GE_RXD[5] */ | ||
84 | { 18, MPP_GIGE }, /* GE_RXD[6] */ | ||
85 | { 19, MPP_GIGE }, /* GE_RXD[7] */ | ||
86 | { -1 }, | ||
87 | }; | ||
88 | |||
89 | static struct mv643xx_eth_platform_data rd88f5181l_fxo_eth_data = { | ||
90 | .phy_addr = -1, | ||
91 | }; | ||
92 | |||
93 | static void __init rd88f5181l_fxo_init(void) | ||
94 | { | ||
95 | /* | ||
96 | * Setup basic Orion functions. Need to be called early. | ||
97 | */ | ||
98 | orion5x_init(); | ||
99 | |||
100 | orion5x_mpp_conf(rd88f5181l_fxo_mpp_modes); | ||
101 | |||
102 | /* | ||
103 | * Configure peripherals. | ||
104 | */ | ||
105 | orion5x_ehci0_init(); | ||
106 | orion5x_eth_init(&rd88f5181l_fxo_eth_data); | ||
107 | orion5x_uart0_init(); | ||
108 | |||
109 | orion5x_setup_dev_boot_win(RD88F5181L_FXO_NOR_BOOT_BASE, | ||
110 | RD88F5181L_FXO_NOR_BOOT_SIZE); | ||
111 | platform_device_register(&rd88f5181l_fxo_nor_boot_flash); | ||
112 | } | ||
113 | |||
114 | static int __init | ||
115 | rd88f5181l_fxo_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) | ||
116 | { | ||
117 | int irq; | ||
118 | |||
119 | /* | ||
120 | * Check for devices with hard-wired IRQs. | ||
121 | */ | ||
122 | irq = orion5x_pci_map_irq(dev, slot, pin); | ||
123 | if (irq != -1) | ||
124 | return irq; | ||
125 | |||
126 | /* | ||
127 | * Mini-PCI / Cardbus slot. | ||
128 | */ | ||
129 | return gpio_to_irq(1); | ||
130 | } | ||
131 | |||
132 | static struct hw_pci rd88f5181l_fxo_pci __initdata = { | ||
133 | .nr_controllers = 2, | ||
134 | .swizzle = pci_std_swizzle, | ||
135 | .setup = orion5x_pci_sys_setup, | ||
136 | .scan = orion5x_pci_sys_scan_bus, | ||
137 | .map_irq = rd88f5181l_fxo_pci_map_irq, | ||
138 | }; | ||
139 | |||
140 | static int __init rd88f5181l_fxo_pci_init(void) | ||
141 | { | ||
142 | if (machine_is_rd88f5181l_fxo()) { | ||
143 | orion5x_pci_set_cardbus_mode(); | ||
144 | pci_common_init(&rd88f5181l_fxo_pci); | ||
145 | } | ||
146 | |||
147 | return 0; | ||
148 | } | ||
149 | subsys_initcall(rd88f5181l_fxo_pci_init); | ||
150 | |||
151 | MACHINE_START(RD88F5181L_FXO, "Marvell Orion-VoIP FXO Reference Design") | ||
152 | /* Maintainer: Nicolas Pitre <nico@marvell.com> */ | ||
153 | .phys_io = ORION5X_REGS_PHYS_BASE, | ||
154 | .io_pg_offst = ((ORION5X_REGS_VIRT_BASE) >> 18) & 0xFFFC, | ||
155 | .boot_params = 0x00000100, | ||
156 | .init_machine = rd88f5181l_fxo_init, | ||
157 | .map_io = orion5x_map_io, | ||
158 | .init_irq = orion5x_init_irq, | ||
159 | .timer = &orion5x_timer, | ||
160 | .fixup = tag_fixup_mem32, | ||
161 | MACHINE_END | ||
diff --git a/arch/arm/mach-orion5x/rd88f5181l-ge-setup.c b/arch/arm/mach-orion5x/rd88f5181l-ge-setup.c new file mode 100644 index 000000000000..b56447d32e17 --- /dev/null +++ b/arch/arm/mach-orion5x/rd88f5181l-ge-setup.c | |||
@@ -0,0 +1,172 @@ | |||
1 | /* | ||
2 | * arch/arm/mach-orion5x/rd88f5181l-ge-setup.c | ||
3 | * | ||
4 | * Marvell Orion-VoIP GE Reference Design Setup | ||
5 | * | ||
6 | * This file is licensed under the terms of the GNU General Public | ||
7 | * License version 2. This program is licensed "as is" without any | ||
8 | * warranty of any kind, whether express or implied. | ||
9 | */ | ||
10 | |||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/init.h> | ||
13 | #include <linux/platform_device.h> | ||
14 | #include <linux/pci.h> | ||
15 | #include <linux/irq.h> | ||
16 | #include <linux/mtd/physmap.h> | ||
17 | #include <linux/mv643xx_eth.h> | ||
18 | #include <linux/i2c.h> | ||
19 | #include <asm/mach-types.h> | ||
20 | #include <asm/gpio.h> | ||
21 | #include <asm/leds.h> | ||
22 | #include <asm/mach/arch.h> | ||
23 | #include <asm/mach/pci.h> | ||
24 | #include <asm/arch/orion5x.h> | ||
25 | #include "common.h" | ||
26 | #include "mpp.h" | ||
27 | |||
28 | /***************************************************************************** | ||
29 | * RD-88F5181L GE Info | ||
30 | ****************************************************************************/ | ||
31 | /* | ||
32 | * 16M NOR flash Device bus boot chip select | ||
33 | */ | ||
34 | #define RD88F5181L_GE_NOR_BOOT_BASE 0xff000000 | ||
35 | #define RD88F5181L_GE_NOR_BOOT_SIZE SZ_16M | ||
36 | |||
37 | |||
38 | /***************************************************************************** | ||
39 | * 16M NOR Flash on Device bus Boot chip select | ||
40 | ****************************************************************************/ | ||
41 | static struct physmap_flash_data rd88f5181l_ge_nor_boot_flash_data = { | ||
42 | .width = 1, | ||
43 | }; | ||
44 | |||
45 | static struct resource rd88f5181l_ge_nor_boot_flash_resource = { | ||
46 | .flags = IORESOURCE_MEM, | ||
47 | .start = RD88F5181L_GE_NOR_BOOT_BASE, | ||
48 | .end = RD88F5181L_GE_NOR_BOOT_BASE + | ||
49 | RD88F5181L_GE_NOR_BOOT_SIZE - 1, | ||
50 | }; | ||
51 | |||
52 | static struct platform_device rd88f5181l_ge_nor_boot_flash = { | ||
53 | .name = "physmap-flash", | ||
54 | .id = 0, | ||
55 | .dev = { | ||
56 | .platform_data = &rd88f5181l_ge_nor_boot_flash_data, | ||
57 | }, | ||
58 | .num_resources = 1, | ||
59 | .resource = &rd88f5181l_ge_nor_boot_flash_resource, | ||
60 | }; | ||
61 | |||
62 | |||
63 | /***************************************************************************** | ||
64 | * General Setup | ||
65 | ****************************************************************************/ | ||
66 | static struct orion5x_mpp_mode rd88f5181l_ge_mpp_modes[] __initdata = { | ||
67 | { 0, MPP_GPIO }, /* LED1 */ | ||
68 | { 1, MPP_GPIO }, /* LED5 */ | ||
69 | { 2, MPP_GPIO }, /* LED4 */ | ||
70 | { 3, MPP_GPIO }, /* LED3 */ | ||
71 | { 4, MPP_GPIO }, /* PCI_intA */ | ||
72 | { 5, MPP_GPIO }, /* RTC interrupt */ | ||
73 | { 6, MPP_PCI_CLK }, /* CPU PCI refclk */ | ||
74 | { 7, MPP_PCI_CLK }, /* PCI/PCIe refclk */ | ||
75 | { 8, MPP_GPIO }, /* 88e6131 interrupt */ | ||
76 | { 9, MPP_GPIO }, /* GE_RXERR */ | ||
77 | { 10, MPP_GPIO }, /* PCI_intB */ | ||
78 | { 11, MPP_GPIO }, /* LED2 */ | ||
79 | { 12, MPP_GIGE }, /* GE_TXD[4] */ | ||
80 | { 13, MPP_GIGE }, /* GE_TXD[5] */ | ||
81 | { 14, MPP_GIGE }, /* GE_TXD[6] */ | ||
82 | { 15, MPP_GIGE }, /* GE_TXD[7] */ | ||
83 | { 16, MPP_GIGE }, /* GE_RXD[4] */ | ||
84 | { 17, MPP_GIGE }, /* GE_RXD[5] */ | ||
85 | { 18, MPP_GIGE }, /* GE_RXD[6] */ | ||
86 | { 19, MPP_GIGE }, /* GE_RXD[7] */ | ||
87 | { -1 }, | ||
88 | }; | ||
89 | |||
90 | static struct mv643xx_eth_platform_data rd88f5181l_ge_eth_data = { | ||
91 | .phy_addr = -1, | ||
92 | }; | ||
93 | |||
94 | static struct i2c_board_info __initdata rd88f5181l_ge_i2c_rtc = { | ||
95 | I2C_BOARD_INFO("ds1338", 0x68), | ||
96 | }; | ||
97 | |||
98 | static void __init rd88f5181l_ge_init(void) | ||
99 | { | ||
100 | /* | ||
101 | * Setup basic Orion functions. Need to be called early. | ||
102 | */ | ||
103 | orion5x_init(); | ||
104 | |||
105 | orion5x_mpp_conf(rd88f5181l_ge_mpp_modes); | ||
106 | |||
107 | /* | ||
108 | * Configure peripherals. | ||
109 | */ | ||
110 | orion5x_ehci0_init(); | ||
111 | orion5x_eth_init(&rd88f5181l_ge_eth_data); | ||
112 | orion5x_i2c_init(); | ||
113 | orion5x_uart0_init(); | ||
114 | |||
115 | orion5x_setup_dev_boot_win(RD88F5181L_GE_NOR_BOOT_BASE, | ||
116 | RD88F5181L_GE_NOR_BOOT_SIZE); | ||
117 | platform_device_register(&rd88f5181l_ge_nor_boot_flash); | ||
118 | |||
119 | i2c_register_board_info(0, &rd88f5181l_ge_i2c_rtc, 1); | ||
120 | } | ||
121 | |||
122 | static int __init | ||
123 | rd88f5181l_ge_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) | ||
124 | { | ||
125 | int irq; | ||
126 | |||
127 | /* | ||
128 | * Check for devices with hard-wired IRQs. | ||
129 | */ | ||
130 | irq = orion5x_pci_map_irq(dev, slot, pin); | ||
131 | if (irq != -1) | ||
132 | return irq; | ||
133 | |||
134 | /* | ||
135 | * Cardbus slot. | ||
136 | */ | ||
137 | if (pin == 1) | ||
138 | return gpio_to_irq(4); | ||
139 | else | ||
140 | return gpio_to_irq(10); | ||
141 | } | ||
142 | |||
143 | static struct hw_pci rd88f5181l_ge_pci __initdata = { | ||
144 | .nr_controllers = 2, | ||
145 | .swizzle = pci_std_swizzle, | ||
146 | .setup = orion5x_pci_sys_setup, | ||
147 | .scan = orion5x_pci_sys_scan_bus, | ||
148 | .map_irq = rd88f5181l_ge_pci_map_irq, | ||
149 | }; | ||
150 | |||
151 | static int __init rd88f5181l_ge_pci_init(void) | ||
152 | { | ||
153 | if (machine_is_rd88f5181l_ge()) { | ||
154 | orion5x_pci_set_cardbus_mode(); | ||
155 | pci_common_init(&rd88f5181l_ge_pci); | ||
156 | } | ||
157 | |||
158 | return 0; | ||
159 | } | ||
160 | subsys_initcall(rd88f5181l_ge_pci_init); | ||
161 | |||
162 | MACHINE_START(RD88F5181L_GE, "Marvell Orion-VoIP GE Reference Design") | ||
163 | /* Maintainer: Lennert Buytenhek <buytenh@marvell.com> */ | ||
164 | .phys_io = ORION5X_REGS_PHYS_BASE, | ||
165 | .io_pg_offst = ((ORION5X_REGS_VIRT_BASE) >> 18) & 0xFFFC, | ||
166 | .boot_params = 0x00000100, | ||
167 | .init_machine = rd88f5181l_ge_init, | ||
168 | .map_io = orion5x_map_io, | ||
169 | .init_irq = orion5x_init_irq, | ||
170 | .timer = &orion5x_timer, | ||
171 | .fixup = tag_fixup_mem32, | ||
172 | MACHINE_END | ||
diff --git a/arch/arm/mach-orion5x/rd88f5182-setup.c b/arch/arm/mach-orion5x/rd88f5182-setup.c index 81abc1003aae..10ae62864269 100644 --- a/arch/arm/mach-orion5x/rd88f5182-setup.c +++ b/arch/arm/mach-orion5x/rd88f5182-setup.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <asm/mach/pci.h> | 26 | #include <asm/mach/pci.h> |
27 | #include <asm/arch/orion5x.h> | 27 | #include <asm/arch/orion5x.h> |
28 | #include "common.h" | 28 | #include "common.h" |
29 | #include "mpp.h" | ||
29 | 30 | ||
30 | /***************************************************************************** | 31 | /***************************************************************************** |
31 | * RD-88F5182 Info | 32 | * RD-88F5182 Info |
@@ -125,6 +126,7 @@ static int __init rd88f5182_dbgled_init(void) | |||
125 | 126 | ||
126 | leds_event = rd88f5182_dbgled_event; | 127 | leds_event = rd88f5182_dbgled_event; |
127 | } | 128 | } |
129 | |||
128 | return 0; | 130 | return 0; |
129 | } | 131 | } |
130 | 132 | ||
@@ -220,7 +222,6 @@ subsys_initcall(rd88f5182_pci_init); | |||
220 | 222 | ||
221 | static struct mv643xx_eth_platform_data rd88f5182_eth_data = { | 223 | static struct mv643xx_eth_platform_data rd88f5182_eth_data = { |
222 | .phy_addr = 8, | 224 | .phy_addr = 8, |
223 | .force_phy_addr = 1, | ||
224 | }; | 225 | }; |
225 | 226 | ||
226 | /***************************************************************************** | 227 | /***************************************************************************** |
@@ -234,15 +235,34 @@ static struct i2c_board_info __initdata rd88f5182_i2c_rtc = { | |||
234 | * Sata | 235 | * Sata |
235 | ****************************************************************************/ | 236 | ****************************************************************************/ |
236 | static struct mv_sata_platform_data rd88f5182_sata_data = { | 237 | static struct mv_sata_platform_data rd88f5182_sata_data = { |
237 | .n_ports = 2, | 238 | .n_ports = 2, |
238 | }; | 239 | }; |
239 | 240 | ||
240 | /***************************************************************************** | 241 | /***************************************************************************** |
241 | * General Setup | 242 | * General Setup |
242 | ****************************************************************************/ | 243 | ****************************************************************************/ |
243 | 244 | static struct orion5x_mpp_mode rd88f5182_mpp_modes[] __initdata = { | |
244 | static struct platform_device *rd88f5182_devices[] __initdata = { | 245 | { 0, MPP_GPIO }, /* Debug Led */ |
245 | &rd88f5182_nor_flash, | 246 | { 1, MPP_GPIO }, /* Reset Switch */ |
247 | { 2, MPP_UNUSED }, | ||
248 | { 3, MPP_GPIO }, /* RTC Int */ | ||
249 | { 4, MPP_GPIO }, | ||
250 | { 5, MPP_GPIO }, | ||
251 | { 6, MPP_GPIO }, /* PCI_intA */ | ||
252 | { 7, MPP_GPIO }, /* PCI_intB */ | ||
253 | { 8, MPP_UNUSED }, | ||
254 | { 9, MPP_UNUSED }, | ||
255 | { 10, MPP_UNUSED }, | ||
256 | { 11, MPP_UNUSED }, | ||
257 | { 12, MPP_SATA_LED }, /* SATA 0 presence */ | ||
258 | { 13, MPP_SATA_LED }, /* SATA 1 presence */ | ||
259 | { 14, MPP_SATA_LED }, /* SATA 0 active */ | ||
260 | { 15, MPP_SATA_LED }, /* SATA 1 active */ | ||
261 | { 16, MPP_UNUSED }, | ||
262 | { 17, MPP_UNUSED }, | ||
263 | { 18, MPP_UNUSED }, | ||
264 | { 19, MPP_UNUSED }, | ||
265 | { -1 }, | ||
246 | }; | 266 | }; |
247 | 267 | ||
248 | static void __init rd88f5182_init(void) | 268 | static void __init rd88f5182_init(void) |
@@ -252,35 +272,9 @@ static void __init rd88f5182_init(void) | |||
252 | */ | 272 | */ |
253 | orion5x_init(); | 273 | orion5x_init(); |
254 | 274 | ||
255 | /* | 275 | orion5x_mpp_conf(rd88f5182_mpp_modes); |
256 | * Setup the CPU address decode windows for our devices | ||
257 | */ | ||
258 | orion5x_setup_dev_boot_win(RD88F5182_NOR_BOOT_BASE, | ||
259 | RD88F5182_NOR_BOOT_SIZE); | ||
260 | orion5x_setup_dev1_win(RD88F5182_NOR_BASE, RD88F5182_NOR_SIZE); | ||
261 | |||
262 | /* | ||
263 | * Open a special address decode windows for the PCIe WA. | ||
264 | */ | ||
265 | orion5x_setup_pcie_wa_win(ORION5X_PCIE_WA_PHYS_BASE, | ||
266 | ORION5X_PCIE_WA_SIZE); | ||
267 | 276 | ||
268 | /* | 277 | /* |
269 | * Setup Multiplexing Pins -- | ||
270 | * MPP[0] Debug Led (GPIO - Out) | ||
271 | * MPP[1] Debug Led (GPIO - Out) | ||
272 | * MPP[2] N/A | ||
273 | * MPP[3] RTC_Int (GPIO - In) | ||
274 | * MPP[4] GPIO | ||
275 | * MPP[5] GPIO | ||
276 | * MPP[6] PCI_intA (GPIO - In) | ||
277 | * MPP[7] PCI_intB (GPIO - In) | ||
278 | * MPP[8-11] N/A | ||
279 | * MPP[12] SATA 0 presence Indication | ||
280 | * MPP[13] SATA 1 presence Indication | ||
281 | * MPP[14] SATA 0 active Indication | ||
282 | * MPP[15] SATA 1 active indication | ||
283 | * MPP[16-19] Not used | ||
284 | * MPP[20] PCI Clock to MV88F5182 | 278 | * MPP[20] PCI Clock to MV88F5182 |
285 | * MPP[21] PCI Clock to mini PCI CON11 | 279 | * MPP[21] PCI Clock to mini PCI CON11 |
286 | * MPP[22] USB 0 over current indication | 280 | * MPP[22] USB 0 over current indication |
@@ -289,16 +283,23 @@ static void __init rd88f5182_init(void) | |||
289 | * MPP[25] USB 0 over current enable | 283 | * MPP[25] USB 0 over current enable |
290 | */ | 284 | */ |
291 | 285 | ||
292 | orion5x_write(MPP_0_7_CTRL, 0x00000003); | 286 | /* |
293 | orion5x_write(MPP_8_15_CTRL, 0x55550000); | 287 | * Configure peripherals. |
294 | orion5x_write(MPP_16_19_CTRL, 0x5555); | 288 | */ |
289 | orion5x_ehci0_init(); | ||
290 | orion5x_ehci1_init(); | ||
291 | orion5x_eth_init(&rd88f5182_eth_data); | ||
292 | orion5x_i2c_init(); | ||
293 | orion5x_sata_init(&rd88f5182_sata_data); | ||
294 | orion5x_uart0_init(); | ||
295 | 295 | ||
296 | orion5x_gpio_set_valid_pins(0x000000fb); | 296 | orion5x_setup_dev_boot_win(RD88F5182_NOR_BOOT_BASE, |
297 | RD88F5182_NOR_BOOT_SIZE); | ||
298 | |||
299 | orion5x_setup_dev1_win(RD88F5182_NOR_BASE, RD88F5182_NOR_SIZE); | ||
300 | platform_device_register(&rd88f5182_nor_flash); | ||
297 | 301 | ||
298 | platform_add_devices(rd88f5182_devices, ARRAY_SIZE(rd88f5182_devices)); | ||
299 | i2c_register_board_info(0, &rd88f5182_i2c_rtc, 1); | 302 | i2c_register_board_info(0, &rd88f5182_i2c_rtc, 1); |
300 | orion5x_eth_init(&rd88f5182_eth_data); | ||
301 | orion5x_sata_init(&rd88f5182_sata_data); | ||
302 | } | 303 | } |
303 | 304 | ||
304 | MACHINE_START(RD88F5182, "Marvell Orion-NAS Reference Design") | 305 | MACHINE_START(RD88F5182, "Marvell Orion-NAS Reference Design") |
diff --git a/arch/arm/mach-orion5x/ts209-setup.c b/arch/arm/mach-orion5x/ts209-setup.c index 9afb41ee6e07..a9cef9703d5b 100644 --- a/arch/arm/mach-orion5x/ts209-setup.c +++ b/arch/arm/mach-orion5x/ts209-setup.c | |||
@@ -28,6 +28,8 @@ | |||
28 | #include <asm/mach/pci.h> | 28 | #include <asm/mach/pci.h> |
29 | #include <asm/arch/orion5x.h> | 29 | #include <asm/arch/orion5x.h> |
30 | #include "common.h" | 30 | #include "common.h" |
31 | #include "mpp.h" | ||
32 | #include "tsx09-common.h" | ||
31 | 33 | ||
32 | #define QNAP_TS209_NOR_BOOT_BASE 0xf4000000 | 34 | #define QNAP_TS209_NOR_BOOT_BASE 0xf4000000 |
33 | #define QNAP_TS209_NOR_BOOT_SIZE SZ_8M | 35 | #define QNAP_TS209_NOR_BOOT_SIZE SZ_8M |
@@ -47,52 +49,54 @@ | |||
47 | ***************************************************************************/ | 49 | ***************************************************************************/ |
48 | static struct mtd_partition qnap_ts209_partitions[] = { | 50 | static struct mtd_partition qnap_ts209_partitions[] = { |
49 | { | 51 | { |
50 | .name = "U-Boot", | 52 | .name = "U-Boot", |
51 | .size = 0x00080000, | 53 | .size = 0x00080000, |
52 | .offset = 0x00780000, | 54 | .offset = 0x00780000, |
53 | .mask_flags = MTD_WRITEABLE, | 55 | .mask_flags = MTD_WRITEABLE, |
54 | }, { | 56 | }, { |
55 | .name = "Kernel", | 57 | .name = "Kernel", |
56 | .size = 0x00200000, | 58 | .size = 0x00200000, |
57 | .offset = 0, | 59 | .offset = 0, |
58 | }, { | 60 | }, { |
59 | .name = "RootFS1", | 61 | .name = "RootFS1", |
60 | .size = 0x00400000, | 62 | .size = 0x00400000, |
61 | .offset = 0x00200000, | 63 | .offset = 0x00200000, |
62 | }, { | 64 | }, { |
63 | .name = "RootFS2", | 65 | .name = "RootFS2", |
64 | .size = 0x00100000, | 66 | .size = 0x00100000, |
65 | .offset = 0x00600000, | 67 | .offset = 0x00600000, |
66 | }, { | 68 | }, { |
67 | .name = "U-Boot Config", | 69 | .name = "U-Boot Config", |
68 | .size = 0x00020000, | 70 | .size = 0x00020000, |
69 | .offset = 0x00760000, | 71 | .offset = 0x00760000, |
70 | }, { | 72 | }, { |
71 | .name = "NAS Config", | 73 | .name = "NAS Config", |
72 | .size = 0x00060000, | 74 | .size = 0x00060000, |
73 | .offset = 0x00700000, | 75 | .offset = 0x00700000, |
74 | .mask_flags = MTD_WRITEABLE, | 76 | .mask_flags = MTD_WRITEABLE, |
75 | } | 77 | }, |
76 | }; | 78 | }; |
77 | 79 | ||
78 | static struct physmap_flash_data qnap_ts209_nor_flash_data = { | 80 | static struct physmap_flash_data qnap_ts209_nor_flash_data = { |
79 | .width = 1, | 81 | .width = 1, |
80 | .parts = qnap_ts209_partitions, | 82 | .parts = qnap_ts209_partitions, |
81 | .nr_parts = ARRAY_SIZE(qnap_ts209_partitions) | 83 | .nr_parts = ARRAY_SIZE(qnap_ts209_partitions) |
82 | }; | 84 | }; |
83 | 85 | ||
84 | static struct resource qnap_ts209_nor_flash_resource = { | 86 | static struct resource qnap_ts209_nor_flash_resource = { |
85 | .flags = IORESOURCE_MEM, | 87 | .flags = IORESOURCE_MEM, |
86 | .start = QNAP_TS209_NOR_BOOT_BASE, | 88 | .start = QNAP_TS209_NOR_BOOT_BASE, |
87 | .end = QNAP_TS209_NOR_BOOT_BASE + QNAP_TS209_NOR_BOOT_SIZE - 1, | 89 | .end = QNAP_TS209_NOR_BOOT_BASE + QNAP_TS209_NOR_BOOT_SIZE - 1, |
88 | }; | 90 | }; |
89 | 91 | ||
90 | static struct platform_device qnap_ts209_nor_flash = { | 92 | static struct platform_device qnap_ts209_nor_flash = { |
91 | .name = "physmap-flash", | 93 | .name = "physmap-flash", |
92 | .id = 0, | 94 | .id = 0, |
93 | .dev = { .platform_data = &qnap_ts209_nor_flash_data, }, | 95 | .dev = { |
94 | .resource = &qnap_ts209_nor_flash_resource, | 96 | .platform_data = &qnap_ts209_nor_flash_data, |
95 | .num_resources = 1, | 97 | }, |
98 | .resource = &qnap_ts209_nor_flash_resource, | ||
99 | .num_resources = 1, | ||
96 | }; | 100 | }; |
97 | 101 | ||
98 | /***************************************************************************** | 102 | /***************************************************************************** |
@@ -164,12 +168,12 @@ static int __init qnap_ts209_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) | |||
164 | } | 168 | } |
165 | 169 | ||
166 | static struct hw_pci qnap_ts209_pci __initdata = { | 170 | static struct hw_pci qnap_ts209_pci __initdata = { |
167 | .nr_controllers = 2, | 171 | .nr_controllers = 2, |
168 | .preinit = qnap_ts209_pci_preinit, | 172 | .preinit = qnap_ts209_pci_preinit, |
169 | .swizzle = pci_std_swizzle, | 173 | .swizzle = pci_std_swizzle, |
170 | .setup = orion5x_pci_sys_setup, | 174 | .setup = orion5x_pci_sys_setup, |
171 | .scan = orion5x_pci_sys_scan_bus, | 175 | .scan = orion5x_pci_sys_scan_bus, |
172 | .map_irq = qnap_ts209_pci_map_irq, | 176 | .map_irq = qnap_ts209_pci_map_irq, |
173 | }; | 177 | }; |
174 | 178 | ||
175 | static int __init qnap_ts209_pci_init(void) | 179 | static int __init qnap_ts209_pci_init(void) |
@@ -183,96 +187,6 @@ static int __init qnap_ts209_pci_init(void) | |||
183 | subsys_initcall(qnap_ts209_pci_init); | 187 | subsys_initcall(qnap_ts209_pci_init); |
184 | 188 | ||
185 | /***************************************************************************** | 189 | /***************************************************************************** |
186 | * Ethernet | ||
187 | ****************************************************************************/ | ||
188 | |||
189 | static struct mv643xx_eth_platform_data qnap_ts209_eth_data = { | ||
190 | .phy_addr = 8, | ||
191 | .force_phy_addr = 1, | ||
192 | }; | ||
193 | |||
194 | static int __init parse_hex_nibble(char n) | ||
195 | { | ||
196 | if (n >= '0' && n <= '9') | ||
197 | return n - '0'; | ||
198 | |||
199 | if (n >= 'A' && n <= 'F') | ||
200 | return n - 'A' + 10; | ||
201 | |||
202 | if (n >= 'a' && n <= 'f') | ||
203 | return n - 'a' + 10; | ||
204 | |||
205 | return -1; | ||
206 | } | ||
207 | |||
208 | static int __init parse_hex_byte(const char *b) | ||
209 | { | ||
210 | int hi; | ||
211 | int lo; | ||
212 | |||
213 | hi = parse_hex_nibble(b[0]); | ||
214 | lo = parse_hex_nibble(b[1]); | ||
215 | |||
216 | if (hi < 0 || lo < 0) | ||
217 | return -1; | ||
218 | |||
219 | return (hi << 4) | lo; | ||
220 | } | ||
221 | |||
222 | static int __init check_mac_addr(const char *addr_str) | ||
223 | { | ||
224 | u_int8_t addr[6]; | ||
225 | int i; | ||
226 | |||
227 | for (i = 0; i < 6; i++) { | ||
228 | int byte; | ||
229 | |||
230 | /* | ||
231 | * Enforce "xx:xx:xx:xx:xx:xx\n" format. | ||
232 | */ | ||
233 | if (addr_str[(i * 3) + 2] != ((i < 5) ? ':' : '\n')) | ||
234 | return -1; | ||
235 | |||
236 | byte = parse_hex_byte(addr_str + (i * 3)); | ||
237 | if (byte < 0) | ||
238 | return -1; | ||
239 | addr[i] = byte; | ||
240 | } | ||
241 | |||
242 | printk(KERN_INFO "ts209: found ethernet mac address "); | ||
243 | for (i = 0; i < 6; i++) | ||
244 | printk("%.2x%s", addr[i], (i < 5) ? ":" : ".\n"); | ||
245 | |||
246 | memcpy(qnap_ts209_eth_data.mac_addr, addr, 6); | ||
247 | |||
248 | return 0; | ||
249 | } | ||
250 | |||
251 | /* | ||
252 | * The 'NAS Config' flash partition has an ext2 filesystem which | ||
253 | * contains a file that has the ethernet MAC address in plain text | ||
254 | * (format "xx:xx:xx:xx:xx:xx\n".) | ||
255 | */ | ||
256 | static void __init ts209_find_mac_addr(void) | ||
257 | { | ||
258 | unsigned long addr; | ||
259 | |||
260 | for (addr = 0x00700000; addr < 0x00760000; addr += 1024) { | ||
261 | char *nor_page; | ||
262 | int ret = 0; | ||
263 | |||
264 | nor_page = ioremap(QNAP_TS209_NOR_BOOT_BASE + addr, 1024); | ||
265 | if (nor_page != NULL) { | ||
266 | ret = check_mac_addr(nor_page); | ||
267 | iounmap(nor_page); | ||
268 | } | ||
269 | |||
270 | if (ret == 0) | ||
271 | break; | ||
272 | } | ||
273 | } | ||
274 | |||
275 | /***************************************************************************** | ||
276 | * RTC S35390A on I2C bus | 190 | * RTC S35390A on I2C bus |
277 | ****************************************************************************/ | 191 | ****************************************************************************/ |
278 | 192 | ||
@@ -280,7 +194,7 @@ static void __init ts209_find_mac_addr(void) | |||
280 | 194 | ||
281 | static struct i2c_board_info __initdata qnap_ts209_i2c_rtc = { | 195 | static struct i2c_board_info __initdata qnap_ts209_i2c_rtc = { |
282 | I2C_BOARD_INFO("s35390a", 0x30), | 196 | I2C_BOARD_INFO("s35390a", 0x30), |
283 | .irq = 0, | 197 | .irq = 0, |
284 | }; | 198 | }; |
285 | 199 | ||
286 | /**************************************************************************** | 200 | /**************************************************************************** |
@@ -297,70 +211,63 @@ static struct gpio_keys_button qnap_ts209_buttons[] = { | |||
297 | .gpio = QNAP_TS209_GPIO_KEY_MEDIA, | 211 | .gpio = QNAP_TS209_GPIO_KEY_MEDIA, |
298 | .desc = "USB Copy Button", | 212 | .desc = "USB Copy Button", |
299 | .active_low = 1, | 213 | .active_low = 1, |
300 | }, | 214 | }, { |
301 | { | ||
302 | .code = KEY_POWER, | 215 | .code = KEY_POWER, |
303 | .gpio = QNAP_TS209_GPIO_KEY_RESET, | 216 | .gpio = QNAP_TS209_GPIO_KEY_RESET, |
304 | .desc = "Reset Button", | 217 | .desc = "Reset Button", |
305 | .active_low = 1, | 218 | .active_low = 1, |
306 | } | 219 | }, |
307 | }; | 220 | }; |
308 | 221 | ||
309 | static struct gpio_keys_platform_data qnap_ts209_button_data = { | 222 | static struct gpio_keys_platform_data qnap_ts209_button_data = { |
310 | .buttons = qnap_ts209_buttons, | 223 | .buttons = qnap_ts209_buttons, |
311 | .nbuttons = ARRAY_SIZE(qnap_ts209_buttons), | 224 | .nbuttons = ARRAY_SIZE(qnap_ts209_buttons), |
312 | }; | 225 | }; |
313 | 226 | ||
314 | static struct platform_device qnap_ts209_button_device = { | 227 | static struct platform_device qnap_ts209_button_device = { |
315 | .name = "gpio-keys", | 228 | .name = "gpio-keys", |
316 | .id = -1, | 229 | .id = -1, |
317 | .num_resources = 0, | 230 | .num_resources = 0, |
318 | .dev = { .platform_data = &qnap_ts209_button_data, }, | 231 | .dev = { |
232 | .platform_data = &qnap_ts209_button_data, | ||
233 | }, | ||
319 | }; | 234 | }; |
320 | 235 | ||
321 | /***************************************************************************** | 236 | /***************************************************************************** |
322 | * SATA | 237 | * SATA |
323 | ****************************************************************************/ | 238 | ****************************************************************************/ |
324 | static struct mv_sata_platform_data qnap_ts209_sata_data = { | 239 | static struct mv_sata_platform_data qnap_ts209_sata_data = { |
325 | .n_ports = 2, | 240 | .n_ports = 2, |
326 | }; | 241 | }; |
327 | 242 | ||
328 | /***************************************************************************** | 243 | /***************************************************************************** |
329 | 244 | ||
330 | * General Setup | 245 | * General Setup |
331 | ****************************************************************************/ | 246 | ****************************************************************************/ |
332 | 247 | static struct orion5x_mpp_mode ts209_mpp_modes[] __initdata = { | |
333 | static struct platform_device *qnap_ts209_devices[] __initdata = { | 248 | { 0, MPP_UNUSED }, |
334 | &qnap_ts209_nor_flash, | 249 | { 1, MPP_GPIO }, /* USB copy button */ |
335 | &qnap_ts209_button_device, | 250 | { 2, MPP_GPIO }, /* Load defaults button */ |
251 | { 3, MPP_GPIO }, /* GPIO RTC */ | ||
252 | { 4, MPP_UNUSED }, | ||
253 | { 5, MPP_UNUSED }, | ||
254 | { 6, MPP_GPIO }, /* PCI Int A */ | ||
255 | { 7, MPP_GPIO }, /* PCI Int B */ | ||
256 | { 8, MPP_UNUSED }, | ||
257 | { 9, MPP_UNUSED }, | ||
258 | { 10, MPP_UNUSED }, | ||
259 | { 11, MPP_UNUSED }, | ||
260 | { 12, MPP_SATA_LED }, /* SATA 0 presence */ | ||
261 | { 13, MPP_SATA_LED }, /* SATA 1 presence */ | ||
262 | { 14, MPP_SATA_LED }, /* SATA 0 active */ | ||
263 | { 15, MPP_SATA_LED }, /* SATA 1 active */ | ||
264 | { 16, MPP_UART }, /* UART1 RXD */ | ||
265 | { 17, MPP_UART }, /* UART1 TXD */ | ||
266 | { 18, MPP_GPIO }, /* SW_RST */ | ||
267 | { 19, MPP_UNUSED }, | ||
268 | { -1 }, | ||
336 | }; | 269 | }; |
337 | 270 | ||
338 | /* | ||
339 | * QNAP TS-[12]09 specific power off method via UART1-attached PIC | ||
340 | */ | ||
341 | |||
342 | #define UART1_REG(x) (UART1_VIRT_BASE + ((UART_##x) << 2)) | ||
343 | |||
344 | static void qnap_ts209_power_off(void) | ||
345 | { | ||
346 | /* 19200 baud divisor */ | ||
347 | const unsigned divisor = ((ORION5X_TCLK + (8 * 19200)) / (16 * 19200)); | ||
348 | |||
349 | pr_info("%s: triggering power-off...\n", __func__); | ||
350 | |||
351 | /* hijack uart1 and reset into sane state (19200,8n1) */ | ||
352 | orion5x_write(UART1_REG(LCR), 0x83); | ||
353 | orion5x_write(UART1_REG(DLL), divisor & 0xff); | ||
354 | orion5x_write(UART1_REG(DLM), (divisor >> 8) & 0xff); | ||
355 | orion5x_write(UART1_REG(LCR), 0x03); | ||
356 | orion5x_write(UART1_REG(IER), 0x00); | ||
357 | orion5x_write(UART1_REG(FCR), 0x00); | ||
358 | orion5x_write(UART1_REG(MCR), 0x00); | ||
359 | |||
360 | /* send the power-off command 'A' to PIC */ | ||
361 | orion5x_write(UART1_REG(TX), 'A'); | ||
362 | } | ||
363 | |||
364 | static void __init qnap_ts209_init(void) | 271 | static void __init qnap_ts209_init(void) |
365 | { | 272 | { |
366 | /* | 273 | /* |
@@ -368,51 +275,33 @@ static void __init qnap_ts209_init(void) | |||
368 | */ | 275 | */ |
369 | orion5x_init(); | 276 | orion5x_init(); |
370 | 277 | ||
371 | /* | 278 | orion5x_mpp_conf(ts209_mpp_modes); |
372 | * Setup flash mapping | ||
373 | */ | ||
374 | orion5x_setup_dev_boot_win(QNAP_TS209_NOR_BOOT_BASE, | ||
375 | QNAP_TS209_NOR_BOOT_SIZE); | ||
376 | |||
377 | /* | ||
378 | * Open a special address decode windows for the PCIe WA. | ||
379 | */ | ||
380 | orion5x_setup_pcie_wa_win(ORION5X_PCIE_WA_PHYS_BASE, | ||
381 | ORION5X_PCIE_WA_SIZE); | ||
382 | 279 | ||
383 | /* | 280 | /* |
384 | * Setup Multiplexing Pins -- | ||
385 | * MPP[0] Reserved | ||
386 | * MPP[1] USB copy button (0 active) | ||
387 | * MPP[2] Load defaults button (0 active) | ||
388 | * MPP[3] GPIO RTC | ||
389 | * MPP[4-5] Reserved | ||
390 | * MPP[6] PCI Int A | ||
391 | * MPP[7] PCI Int B | ||
392 | * MPP[8-11] Reserved | ||
393 | * MPP[12] SATA 0 presence | ||
394 | * MPP[13] SATA 1 presence | ||
395 | * MPP[14] SATA 0 active | ||
396 | * MPP[15] SATA 1 active | ||
397 | * MPP[16] UART1 RXD | ||
398 | * MPP[17] UART1 TXD | ||
399 | * MPP[18] SW_RST (0 active) | ||
400 | * MPP[19] Reserved | ||
401 | * MPP[20] PCI clock 0 | 281 | * MPP[20] PCI clock 0 |
402 | * MPP[21] PCI clock 1 | 282 | * MPP[21] PCI clock 1 |
403 | * MPP[22] USB 0 over current | 283 | * MPP[22] USB 0 over current |
404 | * MPP[23-25] Reserved | 284 | * MPP[23-25] Reserved |
405 | */ | 285 | */ |
406 | orion5x_write(MPP_0_7_CTRL, 0x3); | ||
407 | orion5x_write(MPP_8_15_CTRL, 0x55550000); | ||
408 | orion5x_write(MPP_16_19_CTRL, 0x5500); | ||
409 | orion5x_gpio_set_valid_pins(0x3cc0fff); | ||
410 | 286 | ||
411 | /* register ts209 specific power-off method */ | 287 | /* |
412 | pm_power_off = qnap_ts209_power_off; | 288 | * Configure peripherals. |
289 | */ | ||
290 | orion5x_ehci0_init(); | ||
291 | orion5x_ehci1_init(); | ||
292 | qnap_tsx09_find_mac_addr(QNAP_TS209_NOR_BOOT_BASE + | ||
293 | qnap_ts209_partitions[5].offset, | ||
294 | qnap_ts209_partitions[5].size); | ||
295 | orion5x_eth_init(&qnap_tsx09_eth_data); | ||
296 | orion5x_i2c_init(); | ||
297 | orion5x_sata_init(&qnap_ts209_sata_data); | ||
298 | orion5x_uart0_init(); | ||
299 | |||
300 | orion5x_setup_dev_boot_win(QNAP_TS209_NOR_BOOT_BASE, | ||
301 | QNAP_TS209_NOR_BOOT_SIZE); | ||
302 | platform_device_register(&qnap_ts209_nor_flash); | ||
413 | 303 | ||
414 | platform_add_devices(qnap_ts209_devices, | 304 | platform_device_register(&qnap_ts209_button_device); |
415 | ARRAY_SIZE(qnap_ts209_devices)); | ||
416 | 305 | ||
417 | /* Get RTC IRQ and register the chip */ | 306 | /* Get RTC IRQ and register the chip */ |
418 | if (gpio_request(TS209_RTC_GPIO, "rtc") == 0) { | 307 | if (gpio_request(TS209_RTC_GPIO, "rtc") == 0) { |
@@ -425,14 +314,12 @@ static void __init qnap_ts209_init(void) | |||
425 | pr_warning("qnap_ts209_init: failed to get RTC IRQ\n"); | 314 | pr_warning("qnap_ts209_init: failed to get RTC IRQ\n"); |
426 | i2c_register_board_info(0, &qnap_ts209_i2c_rtc, 1); | 315 | i2c_register_board_info(0, &qnap_ts209_i2c_rtc, 1); |
427 | 316 | ||
428 | ts209_find_mac_addr(); | 317 | /* register tsx09 specific power-off method */ |
429 | orion5x_eth_init(&qnap_ts209_eth_data); | 318 | pm_power_off = qnap_tsx09_power_off; |
430 | |||
431 | orion5x_sata_init(&qnap_ts209_sata_data); | ||
432 | } | 319 | } |
433 | 320 | ||
434 | MACHINE_START(TS209, "QNAP TS-109/TS-209") | 321 | MACHINE_START(TS209, "QNAP TS-109/TS-209") |
435 | /* Maintainer: Byron Bradley <byron.bbradley@gmail.com> */ | 322 | /* Maintainer: Byron Bradley <byron.bbradley@gmail.com> */ |
436 | .phys_io = ORION5X_REGS_PHYS_BASE, | 323 | .phys_io = ORION5X_REGS_PHYS_BASE, |
437 | .io_pg_offst = ((ORION5X_REGS_VIRT_BASE) >> 18) & 0xFFFC, | 324 | .io_pg_offst = ((ORION5X_REGS_VIRT_BASE) >> 18) & 0xFFFC, |
438 | .boot_params = 0x00000100, | 325 | .boot_params = 0x00000100, |
diff --git a/arch/arm/mach-orion5x/ts409-setup.c b/arch/arm/mach-orion5x/ts409-setup.c new file mode 100644 index 000000000000..32f0ff073b7e --- /dev/null +++ b/arch/arm/mach-orion5x/ts409-setup.c | |||
@@ -0,0 +1,273 @@ | |||
1 | /* | ||
2 | * QNAP TS-409 Board Setup | ||
3 | * | ||
4 | * Maintainer: Sylver Bruneau <sylver.bruneau@gmail.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * as published by the Free Software Foundation; either version | ||
9 | * 2 of the License, or (at your option) any later version. | ||
10 | */ | ||
11 | |||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/init.h> | ||
14 | #include <linux/platform_device.h> | ||
15 | #include <linux/pci.h> | ||
16 | #include <linux/irq.h> | ||
17 | #include <linux/mtd/physmap.h> | ||
18 | #include <linux/mv643xx_eth.h> | ||
19 | #include <linux/gpio_keys.h> | ||
20 | #include <linux/input.h> | ||
21 | #include <linux/i2c.h> | ||
22 | #include <linux/serial_reg.h> | ||
23 | #include <asm/mach-types.h> | ||
24 | #include <asm/gpio.h> | ||
25 | #include <asm/mach/arch.h> | ||
26 | #include <asm/mach/pci.h> | ||
27 | #include <asm/arch/orion5x.h> | ||
28 | #include "common.h" | ||
29 | #include "mpp.h" | ||
30 | #include "tsx09-common.h" | ||
31 | |||
32 | /***************************************************************************** | ||
33 | * QNAP TS-409 Info | ||
34 | ****************************************************************************/ | ||
35 | |||
36 | /* | ||
37 | * QNAP TS-409 hardware : | ||
38 | * - Marvell 88F5281-D0 | ||
39 | * - Marvell 88SX7042 SATA controller (PCIe) | ||
40 | * - Marvell 88E1118 Gigabit Ethernet PHY | ||
41 | * - RTC S35390A (@0x30) on I2C bus | ||
42 | * - 8MB NOR flash | ||
43 | * - 256MB of DDR-2 RAM | ||
44 | */ | ||
45 | |||
46 | /* | ||
47 | * 8MB NOR flash Device bus boot chip select | ||
48 | */ | ||
49 | |||
50 | #define QNAP_TS409_NOR_BOOT_BASE 0xff800000 | ||
51 | #define QNAP_TS409_NOR_BOOT_SIZE SZ_8M | ||
52 | |||
53 | /**************************************************************************** | ||
54 | * 8MiB NOR flash. The struct mtd_partition is not in the same order as the | ||
55 | * partitions on the device because we want to keep compatability with | ||
56 | * existing QNAP firmware. | ||
57 | * | ||
58 | * Layout as used by QNAP: | ||
59 | * [2] 0x00000000-0x00200000 : "Kernel" | ||
60 | * [3] 0x00200000-0x00600000 : "RootFS1" | ||
61 | * [4] 0x00600000-0x00700000 : "RootFS2" | ||
62 | * [6] 0x00700000-0x00760000 : "NAS Config" (read-only) | ||
63 | * [5] 0x00760000-0x00780000 : "U-Boot Config" | ||
64 | * [1] 0x00780000-0x00800000 : "U-Boot" (read-only) | ||
65 | ***************************************************************************/ | ||
66 | static struct mtd_partition qnap_ts409_partitions[] = { | ||
67 | { | ||
68 | .name = "U-Boot", | ||
69 | .size = 0x00080000, | ||
70 | .offset = 0x00780000, | ||
71 | .mask_flags = MTD_WRITEABLE, | ||
72 | }, { | ||
73 | .name = "Kernel", | ||
74 | .size = 0x00200000, | ||
75 | .offset = 0, | ||
76 | }, { | ||
77 | .name = "RootFS1", | ||
78 | .size = 0x00400000, | ||
79 | .offset = 0x00200000, | ||
80 | }, { | ||
81 | .name = "RootFS2", | ||
82 | .size = 0x00100000, | ||
83 | .offset = 0x00600000, | ||
84 | }, { | ||
85 | .name = "U-Boot Config", | ||
86 | .size = 0x00020000, | ||
87 | .offset = 0x00760000, | ||
88 | }, { | ||
89 | .name = "NAS Config", | ||
90 | .size = 0x00060000, | ||
91 | .offset = 0x00700000, | ||
92 | .mask_flags = MTD_WRITEABLE, | ||
93 | }, | ||
94 | }; | ||
95 | |||
96 | static struct physmap_flash_data qnap_ts409_nor_flash_data = { | ||
97 | .width = 1, | ||
98 | .parts = qnap_ts409_partitions, | ||
99 | .nr_parts = ARRAY_SIZE(qnap_ts409_partitions) | ||
100 | }; | ||
101 | |||
102 | static struct resource qnap_ts409_nor_flash_resource = { | ||
103 | .flags = IORESOURCE_MEM, | ||
104 | .start = QNAP_TS409_NOR_BOOT_BASE, | ||
105 | .end = QNAP_TS409_NOR_BOOT_BASE + QNAP_TS409_NOR_BOOT_SIZE - 1, | ||
106 | }; | ||
107 | |||
108 | static struct platform_device qnap_ts409_nor_flash = { | ||
109 | .name = "physmap-flash", | ||
110 | .id = 0, | ||
111 | .dev = { .platform_data = &qnap_ts409_nor_flash_data, }, | ||
112 | .num_resources = 1, | ||
113 | .resource = &qnap_ts409_nor_flash_resource, | ||
114 | }; | ||
115 | |||
116 | /***************************************************************************** | ||
117 | * PCI | ||
118 | ****************************************************************************/ | ||
119 | |||
120 | static int __init qnap_ts409_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) | ||
121 | { | ||
122 | int irq; | ||
123 | |||
124 | /* | ||
125 | * Check for devices with hard-wired IRQs. | ||
126 | */ | ||
127 | irq = orion5x_pci_map_irq(dev, slot, pin); | ||
128 | if (irq != -1) | ||
129 | return irq; | ||
130 | |||
131 | /* | ||
132 | * PCI isn't used on the TS-409 | ||
133 | */ | ||
134 | return -1; | ||
135 | } | ||
136 | |||
137 | static struct hw_pci qnap_ts409_pci __initdata = { | ||
138 | .nr_controllers = 2, | ||
139 | .swizzle = pci_std_swizzle, | ||
140 | .setup = orion5x_pci_sys_setup, | ||
141 | .scan = orion5x_pci_sys_scan_bus, | ||
142 | .map_irq = qnap_ts409_pci_map_irq, | ||
143 | }; | ||
144 | |||
145 | static int __init qnap_ts409_pci_init(void) | ||
146 | { | ||
147 | if (machine_is_ts409()) | ||
148 | pci_common_init(&qnap_ts409_pci); | ||
149 | |||
150 | return 0; | ||
151 | } | ||
152 | |||
153 | subsys_initcall(qnap_ts409_pci_init); | ||
154 | |||
155 | /***************************************************************************** | ||
156 | * RTC S35390A on I2C bus | ||
157 | ****************************************************************************/ | ||
158 | |||
159 | #define TS409_RTC_GPIO 10 | ||
160 | |||
161 | static struct i2c_board_info __initdata qnap_ts409_i2c_rtc = { | ||
162 | I2C_BOARD_INFO("s35390a", 0x30), | ||
163 | }; | ||
164 | |||
165 | /**************************************************************************** | ||
166 | * GPIO Attached Keys | ||
167 | * Power button is attached to the PIC microcontroller | ||
168 | ****************************************************************************/ | ||
169 | |||
170 | #define QNAP_TS409_GPIO_KEY_MEDIA 15 | ||
171 | |||
172 | static struct gpio_keys_button qnap_ts409_buttons[] = { | ||
173 | { | ||
174 | .code = KEY_RESTART, | ||
175 | .gpio = QNAP_TS409_GPIO_KEY_MEDIA, | ||
176 | .desc = "USB Copy Button", | ||
177 | .active_low = 1, | ||
178 | }, | ||
179 | }; | ||
180 | |||
181 | static struct gpio_keys_platform_data qnap_ts409_button_data = { | ||
182 | .buttons = qnap_ts409_buttons, | ||
183 | .nbuttons = ARRAY_SIZE(qnap_ts409_buttons), | ||
184 | }; | ||
185 | |||
186 | static struct platform_device qnap_ts409_button_device = { | ||
187 | .name = "gpio-keys", | ||
188 | .id = -1, | ||
189 | .num_resources = 0, | ||
190 | .dev = { | ||
191 | .platform_data = &qnap_ts409_button_data, | ||
192 | }, | ||
193 | }; | ||
194 | |||
195 | /***************************************************************************** | ||
196 | * General Setup | ||
197 | ****************************************************************************/ | ||
198 | static struct orion5x_mpp_mode ts409_mpp_modes[] __initdata = { | ||
199 | { 0, MPP_UNUSED }, | ||
200 | { 1, MPP_UNUSED }, | ||
201 | { 2, MPP_UNUSED }, | ||
202 | { 3, MPP_UNUSED }, | ||
203 | { 4, MPP_GPIO }, /* HDD 1 status */ | ||
204 | { 5, MPP_GPIO }, /* HDD 2 status */ | ||
205 | { 6, MPP_GPIO }, /* HDD 3 status */ | ||
206 | { 7, MPP_GPIO }, /* HDD 4 status */ | ||
207 | { 8, MPP_UNUSED }, | ||
208 | { 9, MPP_UNUSED }, | ||
209 | { 10, MPP_GPIO }, /* RTC int */ | ||
210 | { 11, MPP_UNUSED }, | ||
211 | { 12, MPP_UNUSED }, | ||
212 | { 13, MPP_UNUSED }, | ||
213 | { 14, MPP_GPIO }, /* SW_RST */ | ||
214 | { 15, MPP_GPIO }, /* USB copy button */ | ||
215 | { 16, MPP_UART }, /* UART1 RXD */ | ||
216 | { 17, MPP_UART }, /* UART1 TXD */ | ||
217 | { 18, MPP_UNUSED }, | ||
218 | { 19, MPP_UNUSED }, | ||
219 | { -1 }, | ||
220 | }; | ||
221 | |||
222 | static void __init qnap_ts409_init(void) | ||
223 | { | ||
224 | /* | ||
225 | * Setup basic Orion functions. Need to be called early. | ||
226 | */ | ||
227 | orion5x_init(); | ||
228 | |||
229 | orion5x_mpp_conf(ts409_mpp_modes); | ||
230 | |||
231 | /* | ||
232 | * Configure peripherals. | ||
233 | */ | ||
234 | orion5x_ehci0_init(); | ||
235 | qnap_tsx09_find_mac_addr(QNAP_TS409_NOR_BOOT_BASE + | ||
236 | qnap_ts409_partitions[5].offset, | ||
237 | qnap_ts409_partitions[5].size); | ||
238 | orion5x_eth_init(&qnap_tsx09_eth_data); | ||
239 | orion5x_i2c_init(); | ||
240 | orion5x_uart0_init(); | ||
241 | |||
242 | orion5x_setup_dev_boot_win(QNAP_TS409_NOR_BOOT_BASE, | ||
243 | QNAP_TS409_NOR_BOOT_SIZE); | ||
244 | platform_device_register(&qnap_ts409_nor_flash); | ||
245 | |||
246 | platform_device_register(&qnap_ts409_button_device); | ||
247 | |||
248 | /* Get RTC IRQ and register the chip */ | ||
249 | if (gpio_request(TS409_RTC_GPIO, "rtc") == 0) { | ||
250 | if (gpio_direction_input(TS409_RTC_GPIO) == 0) | ||
251 | qnap_ts409_i2c_rtc.irq = gpio_to_irq(TS409_RTC_GPIO); | ||
252 | else | ||
253 | gpio_free(TS409_RTC_GPIO); | ||
254 | } | ||
255 | if (qnap_ts409_i2c_rtc.irq == 0) | ||
256 | pr_warning("qnap_ts409_init: failed to get RTC IRQ\n"); | ||
257 | i2c_register_board_info(0, &qnap_ts409_i2c_rtc, 1); | ||
258 | |||
259 | /* register tsx09 specific power-off method */ | ||
260 | pm_power_off = qnap_tsx09_power_off; | ||
261 | } | ||
262 | |||
263 | MACHINE_START(TS409, "QNAP TS-409") | ||
264 | /* Maintainer: Sylver Bruneau <sylver.bruneau@gmail.com> */ | ||
265 | .phys_io = ORION5X_REGS_PHYS_BASE, | ||
266 | .io_pg_offst = ((ORION5X_REGS_VIRT_BASE) >> 18) & 0xFFFC, | ||
267 | .boot_params = 0x00000100, | ||
268 | .init_machine = qnap_ts409_init, | ||
269 | .map_io = orion5x_map_io, | ||
270 | .init_irq = orion5x_init_irq, | ||
271 | .timer = &orion5x_timer, | ||
272 | .fixup = tag_fixup_mem32, | ||
273 | MACHINE_END | ||
diff --git a/arch/arm/mach-orion5x/ts78xx-setup.c b/arch/arm/mach-orion5x/ts78xx-setup.c new file mode 100644 index 000000000000..77e9f351f07a --- /dev/null +++ b/arch/arm/mach-orion5x/ts78xx-setup.c | |||
@@ -0,0 +1,277 @@ | |||
1 | /* | ||
2 | * arch/arm/mach-orion5x/ts78xx-setup.c | ||
3 | * | ||
4 | * Maintainer: Alexander Clouter <alex@digriz.org.uk> | ||
5 | * | ||
6 | * This file is licensed under the terms of the GNU General Public | ||
7 | * License version 2. This program is licensed "as is" without any | ||
8 | * warranty of any kind, whether express or implied. | ||
9 | */ | ||
10 | |||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/init.h> | ||
13 | #include <linux/platform_device.h> | ||
14 | #include <linux/mtd/physmap.h> | ||
15 | #include <linux/mv643xx_eth.h> | ||
16 | #include <linux/ata_platform.h> | ||
17 | #include <linux/m48t86.h> | ||
18 | #include <asm/mach-types.h> | ||
19 | #include <asm/mach/arch.h> | ||
20 | #include <asm/mach/map.h> | ||
21 | #include <asm/arch/orion5x.h> | ||
22 | #include "common.h" | ||
23 | #include "mpp.h" | ||
24 | |||
25 | /***************************************************************************** | ||
26 | * TS-78xx Info | ||
27 | ****************************************************************************/ | ||
28 | |||
29 | /* | ||
30 | * FPGA - lives where the PCI bus would be at ORION5X_PCI_MEM_PHYS_BASE | ||
31 | */ | ||
32 | #define TS78XX_FPGA_REGS_PHYS_BASE 0xe8000000 | ||
33 | #define TS78XX_FPGA_REGS_VIRT_BASE 0xff900000 | ||
34 | #define TS78XX_FPGA_REGS_SIZE SZ_1M | ||
35 | |||
36 | #define TS78XX_FPGA_REGS_SYSCON_ID (TS78XX_FPGA_REGS_VIRT_BASE | 0x000) | ||
37 | #define TS78XX_FPGA_REGS_SYSCON_LCDI (TS78XX_FPGA_REGS_VIRT_BASE | 0x004) | ||
38 | #define TS78XX_FPGA_REGS_SYSCON_LCDO (TS78XX_FPGA_REGS_VIRT_BASE | 0x008) | ||
39 | |||
40 | #define TS78XX_FPGA_REGS_RTC_CTRL (TS78XX_FPGA_REGS_VIRT_BASE | 0x808) | ||
41 | #define TS78XX_FPGA_REGS_RTC_DATA (TS78XX_FPGA_REGS_VIRT_BASE | 0x80c) | ||
42 | |||
43 | /* | ||
44 | * 512kB NOR flash Device | ||
45 | */ | ||
46 | #define TS78XX_NOR_BOOT_BASE 0xff800000 | ||
47 | #define TS78XX_NOR_BOOT_SIZE SZ_512K | ||
48 | |||
49 | /***************************************************************************** | ||
50 | * I/O Address Mapping | ||
51 | ****************************************************************************/ | ||
52 | static struct map_desc ts78xx_io_desc[] __initdata = { | ||
53 | { | ||
54 | .virtual = TS78XX_FPGA_REGS_VIRT_BASE, | ||
55 | .pfn = __phys_to_pfn(TS78XX_FPGA_REGS_PHYS_BASE), | ||
56 | .length = TS78XX_FPGA_REGS_SIZE, | ||
57 | .type = MT_DEVICE, | ||
58 | }, | ||
59 | }; | ||
60 | |||
61 | void __init ts78xx_map_io(void) | ||
62 | { | ||
63 | orion5x_map_io(); | ||
64 | iotable_init(ts78xx_io_desc, ARRAY_SIZE(ts78xx_io_desc)); | ||
65 | } | ||
66 | |||
67 | /***************************************************************************** | ||
68 | * 512kB NOR Boot Flash - the chip is a M25P40 | ||
69 | ****************************************************************************/ | ||
70 | static struct mtd_partition ts78xx_nor_boot_flash_resources[] = { | ||
71 | { | ||
72 | .name = "ts-bootrom", | ||
73 | .offset = 0, | ||
74 | /* only the first 256kB is used */ | ||
75 | .size = SZ_256K, | ||
76 | .mask_flags = MTD_WRITEABLE, | ||
77 | }, | ||
78 | }; | ||
79 | |||
80 | static struct physmap_flash_data ts78xx_nor_boot_flash_data = { | ||
81 | .width = 1, | ||
82 | .parts = ts78xx_nor_boot_flash_resources, | ||
83 | .nr_parts = ARRAY_SIZE(ts78xx_nor_boot_flash_resources), | ||
84 | }; | ||
85 | |||
86 | static struct resource ts78xx_nor_boot_flash_resource = { | ||
87 | .flags = IORESOURCE_MEM, | ||
88 | .start = TS78XX_NOR_BOOT_BASE, | ||
89 | .end = TS78XX_NOR_BOOT_BASE + TS78XX_NOR_BOOT_SIZE - 1, | ||
90 | }; | ||
91 | |||
92 | static struct platform_device ts78xx_nor_boot_flash = { | ||
93 | .name = "physmap-flash", | ||
94 | .id = -1, | ||
95 | .dev = { | ||
96 | .platform_data = &ts78xx_nor_boot_flash_data, | ||
97 | }, | ||
98 | .num_resources = 1, | ||
99 | .resource = &ts78xx_nor_boot_flash_resource, | ||
100 | }; | ||
101 | |||
102 | /***************************************************************************** | ||
103 | * Ethernet | ||
104 | ****************************************************************************/ | ||
105 | static struct mv643xx_eth_platform_data ts78xx_eth_data = { | ||
106 | .phy_addr = 0, | ||
107 | .force_phy_addr = 1, | ||
108 | }; | ||
109 | |||
110 | /***************************************************************************** | ||
111 | * RTC M48T86 - nicked^Wborrowed from arch/arm/mach-ep93xx/ts72xx.c | ||
112 | ****************************************************************************/ | ||
113 | #ifdef CONFIG_RTC_DRV_M48T86 | ||
114 | static unsigned char ts78xx_rtc_readbyte(unsigned long addr) | ||
115 | { | ||
116 | writeb(addr, TS78XX_FPGA_REGS_RTC_CTRL); | ||
117 | return readb(TS78XX_FPGA_REGS_RTC_DATA); | ||
118 | } | ||
119 | |||
120 | static void ts78xx_rtc_writebyte(unsigned char value, unsigned long addr) | ||
121 | { | ||
122 | writeb(addr, TS78XX_FPGA_REGS_RTC_CTRL); | ||
123 | writeb(value, TS78XX_FPGA_REGS_RTC_DATA); | ||
124 | } | ||
125 | |||
126 | static struct m48t86_ops ts78xx_rtc_ops = { | ||
127 | .readbyte = ts78xx_rtc_readbyte, | ||
128 | .writebyte = ts78xx_rtc_writebyte, | ||
129 | }; | ||
130 | |||
131 | static struct platform_device ts78xx_rtc_device = { | ||
132 | .name = "rtc-m48t86", | ||
133 | .id = -1, | ||
134 | .dev = { | ||
135 | .platform_data = &ts78xx_rtc_ops, | ||
136 | }, | ||
137 | .num_resources = 0, | ||
138 | }; | ||
139 | |||
140 | /* | ||
141 | * TS uses some of the user storage space on the RTC chip so see if it is | ||
142 | * present; as it's an optional feature at purchase time and not all boards | ||
143 | * will have it present | ||
144 | * | ||
145 | * I've used the method TS use in their rtc7800.c example for the detection | ||
146 | * | ||
147 | * TODO: track down a guinea pig without an RTC to see if we can work out a | ||
148 | * better RTC detection routine | ||
149 | */ | ||
150 | static int __init ts78xx_rtc_init(void) | ||
151 | { | ||
152 | unsigned char tmp_rtc0, tmp_rtc1; | ||
153 | |||
154 | tmp_rtc0 = ts78xx_rtc_readbyte(126); | ||
155 | tmp_rtc1 = ts78xx_rtc_readbyte(127); | ||
156 | |||
157 | ts78xx_rtc_writebyte(0x00, 126); | ||
158 | ts78xx_rtc_writebyte(0x55, 127); | ||
159 | if (ts78xx_rtc_readbyte(127) == 0x55) { | ||
160 | ts78xx_rtc_writebyte(0xaa, 127); | ||
161 | if (ts78xx_rtc_readbyte(127) == 0xaa | ||
162 | && ts78xx_rtc_readbyte(126) == 0x00) { | ||
163 | ts78xx_rtc_writebyte(tmp_rtc0, 126); | ||
164 | ts78xx_rtc_writebyte(tmp_rtc1, 127); | ||
165 | platform_device_register(&ts78xx_rtc_device); | ||
166 | return 1; | ||
167 | } | ||
168 | } | ||
169 | |||
170 | return 0; | ||
171 | }; | ||
172 | #else | ||
173 | static int __init ts78xx_rtc_init(void) | ||
174 | { | ||
175 | return 0; | ||
176 | } | ||
177 | #endif | ||
178 | |||
179 | /***************************************************************************** | ||
180 | * SATA | ||
181 | ****************************************************************************/ | ||
182 | static struct mv_sata_platform_data ts78xx_sata_data = { | ||
183 | .n_ports = 2, | ||
184 | }; | ||
185 | |||
186 | /***************************************************************************** | ||
187 | * print some information regarding the board | ||
188 | ****************************************************************************/ | ||
189 | static void __init ts78xx_print_board_id(void) | ||
190 | { | ||
191 | unsigned int board_info; | ||
192 | |||
193 | board_info = readl(TS78XX_FPGA_REGS_SYSCON_ID); | ||
194 | printk(KERN_INFO "TS-78xx Info: FPGA rev=%.2x, Board Magic=%.6x, ", | ||
195 | board_info & 0xff, | ||
196 | (board_info >> 8) & 0xffffff); | ||
197 | board_info = readl(TS78XX_FPGA_REGS_SYSCON_LCDI); | ||
198 | printk("JP1=%d, JP2=%d\n", | ||
199 | (board_info >> 30) & 0x1, | ||
200 | (board_info >> 31) & 0x1); | ||
201 | }; | ||
202 | |||
203 | /***************************************************************************** | ||
204 | * General Setup | ||
205 | ****************************************************************************/ | ||
206 | static struct orion5x_mpp_mode ts78xx_mpp_modes[] __initdata = { | ||
207 | { 0, MPP_UNUSED }, | ||
208 | { 1, MPP_GPIO }, /* JTAG Clock */ | ||
209 | { 2, MPP_GPIO }, /* JTAG Data In */ | ||
210 | { 3, MPP_GPIO }, /* Lat ECP2 256 FPGA - PB2B */ | ||
211 | { 4, MPP_GPIO }, /* JTAG Data Out */ | ||
212 | { 5, MPP_GPIO }, /* JTAG TMS */ | ||
213 | { 6, MPP_GPIO }, /* Lat ECP2 256 FPGA - PB31A_CLK4+ */ | ||
214 | { 7, MPP_GPIO }, /* Lat ECP2 256 FPGA - PB22B */ | ||
215 | { 8, MPP_UNUSED }, | ||
216 | { 9, MPP_UNUSED }, | ||
217 | { 10, MPP_UNUSED }, | ||
218 | { 11, MPP_UNUSED }, | ||
219 | { 12, MPP_UNUSED }, | ||
220 | { 13, MPP_UNUSED }, | ||
221 | { 14, MPP_UNUSED }, | ||
222 | { 15, MPP_UNUSED }, | ||
223 | { 16, MPP_UART }, | ||
224 | { 17, MPP_UART }, | ||
225 | { 18, MPP_UART }, | ||
226 | { 19, MPP_UART }, | ||
227 | { -1 }, | ||
228 | }; | ||
229 | |||
230 | static void __init ts78xx_init(void) | ||
231 | { | ||
232 | /* | ||
233 | * Setup basic Orion functions. Need to be called early. | ||
234 | */ | ||
235 | orion5x_init(); | ||
236 | |||
237 | ts78xx_print_board_id(); | ||
238 | |||
239 | orion5x_mpp_conf(ts78xx_mpp_modes); | ||
240 | |||
241 | /* | ||
242 | * MPP[20] PCI Clock Out 1 | ||
243 | * MPP[21] PCI Clock Out 0 | ||
244 | * MPP[22] Unused | ||
245 | * MPP[23] Unused | ||
246 | * MPP[24] Unused | ||
247 | * MPP[25] Unused | ||
248 | */ | ||
249 | |||
250 | /* | ||
251 | * Configure peripherals. | ||
252 | */ | ||
253 | orion5x_ehci0_init(); | ||
254 | orion5x_ehci1_init(); | ||
255 | orion5x_eth_init(&ts78xx_eth_data); | ||
256 | orion5x_sata_init(&ts78xx_sata_data); | ||
257 | orion5x_uart0_init(); | ||
258 | orion5x_uart1_init(); | ||
259 | |||
260 | orion5x_setup_dev_boot_win(TS78XX_NOR_BOOT_BASE, | ||
261 | TS78XX_NOR_BOOT_SIZE); | ||
262 | platform_device_register(&ts78xx_nor_boot_flash); | ||
263 | |||
264 | if (!ts78xx_rtc_init()) | ||
265 | printk(KERN_INFO "TS-78xx RTC not detected or enabled\n"); | ||
266 | } | ||
267 | |||
268 | MACHINE_START(TS78XX, "Technologic Systems TS-78xx SBC") | ||
269 | /* Maintainer: Alexander Clouter <alex@digriz.org.uk> */ | ||
270 | .phys_io = ORION5X_REGS_PHYS_BASE, | ||
271 | .io_pg_offst = ((ORION5X_REGS_VIRT_BASE) >> 18) & 0xFFFC, | ||
272 | .boot_params = 0x00000100, | ||
273 | .init_machine = ts78xx_init, | ||
274 | .map_io = ts78xx_map_io, | ||
275 | .init_irq = orion5x_init_irq, | ||
276 | .timer = &orion5x_timer, | ||
277 | MACHINE_END | ||
diff --git a/arch/arm/mach-orion5x/tsx09-common.c b/arch/arm/mach-orion5x/tsx09-common.c new file mode 100644 index 000000000000..83feac3147a6 --- /dev/null +++ b/arch/arm/mach-orion5x/tsx09-common.c | |||
@@ -0,0 +1,133 @@ | |||
1 | /* | ||
2 | * QNAP TS-x09 Boards common functions | ||
3 | * | ||
4 | * Maintainers: Lennert Buytenhek <buytenh@marvell.com> | ||
5 | * Byron Bradley <byron.bbradley@gmail.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or | ||
8 | * modify it under the terms of the GNU General Public License | ||
9 | * as published by the Free Software Foundation; either version | ||
10 | * 2 of the License, or (at your option) any later version. | ||
11 | */ | ||
12 | |||
13 | #include <linux/kernel.h> | ||
14 | #include <linux/pci.h> | ||
15 | #include <linux/mv643xx_eth.h> | ||
16 | #include <linux/timex.h> | ||
17 | #include <linux/serial_reg.h> | ||
18 | #include "tsx09-common.h" | ||
19 | |||
20 | /***************************************************************************** | ||
21 | * QNAP TS-x09 specific power off method via UART1-attached PIC | ||
22 | ****************************************************************************/ | ||
23 | |||
24 | #define UART1_REG(x) (UART1_VIRT_BASE + ((UART_##x) << 2)) | ||
25 | |||
26 | void qnap_tsx09_power_off(void) | ||
27 | { | ||
28 | /* 19200 baud divisor */ | ||
29 | const unsigned divisor = ((ORION5X_TCLK + (8 * 19200)) / (16 * 19200)); | ||
30 | |||
31 | pr_info("%s: triggering power-off...\n", __func__); | ||
32 | |||
33 | /* hijack uart1 and reset into sane state (19200,8n1) */ | ||
34 | writel(0x83, UART1_REG(LCR)); | ||
35 | writel(divisor & 0xff, UART1_REG(DLL)); | ||
36 | writel((divisor >> 8) & 0xff, UART1_REG(DLM)); | ||
37 | writel(0x03, UART1_REG(LCR)); | ||
38 | writel(0x00, UART1_REG(IER)); | ||
39 | writel(0x00, UART1_REG(FCR)); | ||
40 | writel(0x00, UART1_REG(MCR)); | ||
41 | |||
42 | /* send the power-off command 'A' to PIC */ | ||
43 | writel('A', UART1_REG(TX)); | ||
44 | } | ||
45 | |||
46 | /***************************************************************************** | ||
47 | * Ethernet | ||
48 | ****************************************************************************/ | ||
49 | |||
50 | struct mv643xx_eth_platform_data qnap_tsx09_eth_data = { | ||
51 | .phy_addr = 8, | ||
52 | }; | ||
53 | |||
54 | static int __init qnap_tsx09_parse_hex_nibble(char n) | ||
55 | { | ||
56 | if (n >= '0' && n <= '9') | ||
57 | return n - '0'; | ||
58 | |||
59 | if (n >= 'A' && n <= 'F') | ||
60 | return n - 'A' + 10; | ||
61 | |||
62 | if (n >= 'a' && n <= 'f') | ||
63 | return n - 'a' + 10; | ||
64 | |||
65 | return -1; | ||
66 | } | ||
67 | |||
68 | static int __init qnap_tsx09_parse_hex_byte(const char *b) | ||
69 | { | ||
70 | int hi; | ||
71 | int lo; | ||
72 | |||
73 | hi = qnap_tsx09_parse_hex_nibble(b[0]); | ||
74 | lo = qnap_tsx09_parse_hex_nibble(b[1]); | ||
75 | |||
76 | if (hi < 0 || lo < 0) | ||
77 | return -1; | ||
78 | |||
79 | return (hi << 4) | lo; | ||
80 | } | ||
81 | |||
82 | static int __init qnap_tsx09_check_mac_addr(const char *addr_str) | ||
83 | { | ||
84 | u_int8_t addr[6]; | ||
85 | int i; | ||
86 | |||
87 | for (i = 0; i < 6; i++) { | ||
88 | int byte; | ||
89 | |||
90 | /* | ||
91 | * Enforce "xx:xx:xx:xx:xx:xx\n" format. | ||
92 | */ | ||
93 | if (addr_str[(i * 3) + 2] != ((i < 5) ? ':' : '\n')) | ||
94 | return -1; | ||
95 | |||
96 | byte = qnap_tsx09_parse_hex_byte(addr_str + (i * 3)); | ||
97 | if (byte < 0) | ||
98 | return -1; | ||
99 | addr[i] = byte; | ||
100 | } | ||
101 | |||
102 | printk(KERN_INFO "tsx09: found ethernet mac address "); | ||
103 | for (i = 0; i < 6; i++) | ||
104 | printk("%.2x%s", addr[i], (i < 5) ? ":" : ".\n"); | ||
105 | |||
106 | memcpy(qnap_tsx09_eth_data.mac_addr, addr, 6); | ||
107 | |||
108 | return 0; | ||
109 | } | ||
110 | |||
111 | /* | ||
112 | * The 'NAS Config' flash partition has an ext2 filesystem which | ||
113 | * contains a file that has the ethernet MAC address in plain text | ||
114 | * (format "xx:xx:xx:xx:xx:xx\n"). | ||
115 | */ | ||
116 | void __init qnap_tsx09_find_mac_addr(u32 mem_base, u32 size) | ||
117 | { | ||
118 | unsigned long addr; | ||
119 | |||
120 | for (addr = mem_base; addr < (mem_base + size); addr += 1024) { | ||
121 | char *nor_page; | ||
122 | int ret = 0; | ||
123 | |||
124 | nor_page = ioremap(addr, 1024); | ||
125 | if (nor_page != NULL) { | ||
126 | ret = qnap_tsx09_check_mac_addr(nor_page); | ||
127 | iounmap(nor_page); | ||
128 | } | ||
129 | |||
130 | if (ret == 0) | ||
131 | break; | ||
132 | } | ||
133 | } | ||
diff --git a/arch/arm/mach-orion5x/tsx09-common.h b/arch/arm/mach-orion5x/tsx09-common.h new file mode 100644 index 000000000000..0984264616f0 --- /dev/null +++ b/arch/arm/mach-orion5x/tsx09-common.h | |||
@@ -0,0 +1,20 @@ | |||
1 | #ifndef __ARCH_ORION5X_TSX09_COMMON_H | ||
2 | #define __ARCH_ORION5X_TSX09_COMMON_H | ||
3 | |||
4 | /* | ||
5 | * QNAP TS-x09 Boards power-off function | ||
6 | */ | ||
7 | extern void qnap_tsx09_power_off(void); | ||
8 | |||
9 | /* | ||
10 | * QNAP TS-x09 Boards function to find Ethernet MAC address in flash memory | ||
11 | */ | ||
12 | extern void __init qnap_tsx09_find_mac_addr(u32 mem_base, u32 size); | ||
13 | |||
14 | /* | ||
15 | * QNAP TS-x09 Boards ethernet declaration | ||
16 | */ | ||
17 | extern struct mv643xx_eth_platform_data qnap_tsx09_eth_data; | ||
18 | |||
19 | |||
20 | #endif | ||
diff --git a/arch/arm/mach-orion5x/wnr854t-setup.c b/arch/arm/mach-orion5x/wnr854t-setup.c new file mode 100644 index 000000000000..1af093ff8cf3 --- /dev/null +++ b/arch/arm/mach-orion5x/wnr854t-setup.c | |||
@@ -0,0 +1,164 @@ | |||
1 | /* | ||
2 | * arch/arm/mach-orion5x/wnr854t-setup.c | ||
3 | * | ||
4 | * This file is licensed under the terms of the GNU General Public | ||
5 | * License version 2. This program is licensed "as is" without any | ||
6 | * warranty of any kind, whether express or implied. | ||
7 | */ | ||
8 | |||
9 | #include <linux/kernel.h> | ||
10 | #include <linux/init.h> | ||
11 | #include <linux/platform_device.h> | ||
12 | #include <linux/pci.h> | ||
13 | #include <linux/irq.h> | ||
14 | #include <linux/delay.h> | ||
15 | #include <linux/mtd/physmap.h> | ||
16 | #include <linux/mv643xx_eth.h> | ||
17 | #include <asm/mach-types.h> | ||
18 | #include <asm/gpio.h> | ||
19 | #include <asm/mach/arch.h> | ||
20 | #include <asm/mach/pci.h> | ||
21 | #include <asm/arch/orion5x.h> | ||
22 | #include "common.h" | ||
23 | #include "mpp.h" | ||
24 | |||
25 | static struct orion5x_mpp_mode wnr854t_mpp_modes[] __initdata = { | ||
26 | { 0, MPP_GPIO }, /* Power LED green (0=on) */ | ||
27 | { 1, MPP_GPIO }, /* Reset Button (0=off) */ | ||
28 | { 2, MPP_GPIO }, /* Power LED blink (0=off) */ | ||
29 | { 3, MPP_GPIO }, /* WAN Status LED amber (0=off) */ | ||
30 | { 4, MPP_GPIO }, /* PCI int */ | ||
31 | { 5, MPP_GPIO }, /* ??? */ | ||
32 | { 6, MPP_GPIO }, /* ??? */ | ||
33 | { 7, MPP_GPIO }, /* ??? */ | ||
34 | { 8, MPP_UNUSED }, /* ??? */ | ||
35 | { 9, MPP_GIGE }, /* GE_RXERR */ | ||
36 | { 10, MPP_UNUSED }, /* ??? */ | ||
37 | { 11, MPP_UNUSED }, /* ??? */ | ||
38 | { 12, MPP_GIGE }, /* GE_TXD[4] */ | ||
39 | { 13, MPP_GIGE }, /* GE_TXD[5] */ | ||
40 | { 14, MPP_GIGE }, /* GE_TXD[6] */ | ||
41 | { 15, MPP_GIGE }, /* GE_TXD[7] */ | ||
42 | { 16, MPP_GIGE }, /* GE_RXD[4] */ | ||
43 | { 17, MPP_GIGE }, /* GE_RXD[5] */ | ||
44 | { 18, MPP_GIGE }, /* GE_RXD[6] */ | ||
45 | { 19, MPP_GIGE }, /* GE_RXD[7] */ | ||
46 | { -1 }, | ||
47 | }; | ||
48 | |||
49 | /* | ||
50 | * 8M NOR flash Device bus boot chip select | ||
51 | */ | ||
52 | #define WNR854T_NOR_BOOT_BASE 0xf4000000 | ||
53 | #define WNR854T_NOR_BOOT_SIZE SZ_8M | ||
54 | |||
55 | static struct mtd_partition wnr854t_nor_flash_partitions[] = { | ||
56 | { | ||
57 | .name = "kernel", | ||
58 | .offset = 0x00000000, | ||
59 | .size = 0x00100000, | ||
60 | }, { | ||
61 | .name = "rootfs", | ||
62 | .offset = 0x00100000, | ||
63 | .size = 0x00660000, | ||
64 | }, { | ||
65 | .name = "uboot", | ||
66 | .offset = 0x00760000, | ||
67 | .size = 0x00040000, | ||
68 | }, | ||
69 | }; | ||
70 | |||
71 | static struct physmap_flash_data wnr854t_nor_flash_data = { | ||
72 | .width = 2, | ||
73 | .parts = wnr854t_nor_flash_partitions, | ||
74 | .nr_parts = ARRAY_SIZE(wnr854t_nor_flash_partitions), | ||
75 | }; | ||
76 | |||
77 | static struct resource wnr854t_nor_flash_resource = { | ||
78 | .flags = IORESOURCE_MEM, | ||
79 | .start = WNR854T_NOR_BOOT_BASE, | ||
80 | .end = WNR854T_NOR_BOOT_BASE + WNR854T_NOR_BOOT_SIZE - 1, | ||
81 | }; | ||
82 | |||
83 | static struct platform_device wnr854t_nor_flash = { | ||
84 | .name = "physmap-flash", | ||
85 | .id = 0, | ||
86 | .dev = { | ||
87 | .platform_data = &wnr854t_nor_flash_data, | ||
88 | }, | ||
89 | .num_resources = 1, | ||
90 | .resource = &wnr854t_nor_flash_resource, | ||
91 | }; | ||
92 | |||
93 | static struct mv643xx_eth_platform_data wnr854t_eth_data = { | ||
94 | .phy_addr = -1, | ||
95 | }; | ||
96 | |||
97 | static void __init wnr854t_init(void) | ||
98 | { | ||
99 | /* | ||
100 | * Setup basic Orion functions. Need to be called early. | ||
101 | */ | ||
102 | orion5x_init(); | ||
103 | |||
104 | orion5x_mpp_conf(wnr854t_mpp_modes); | ||
105 | |||
106 | /* | ||
107 | * Configure peripherals. | ||
108 | */ | ||
109 | orion5x_eth_init(&wnr854t_eth_data); | ||
110 | orion5x_uart0_init(); | ||
111 | |||
112 | orion5x_setup_dev_boot_win(WNR854T_NOR_BOOT_BASE, | ||
113 | WNR854T_NOR_BOOT_SIZE); | ||
114 | platform_device_register(&wnr854t_nor_flash); | ||
115 | } | ||
116 | |||
117 | static int __init wnr854t_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) | ||
118 | { | ||
119 | int irq; | ||
120 | |||
121 | /* | ||
122 | * Check for devices with hard-wired IRQs. | ||
123 | */ | ||
124 | irq = orion5x_pci_map_irq(dev, slot, pin); | ||
125 | if (irq != -1) | ||
126 | return irq; | ||
127 | |||
128 | /* | ||
129 | * Mini-PCI slot. | ||
130 | */ | ||
131 | if (slot == 7) | ||
132 | return gpio_to_irq(4); | ||
133 | |||
134 | return -1; | ||
135 | } | ||
136 | |||
137 | static struct hw_pci wnr854t_pci __initdata = { | ||
138 | .nr_controllers = 2, | ||
139 | .swizzle = pci_std_swizzle, | ||
140 | .setup = orion5x_pci_sys_setup, | ||
141 | .scan = orion5x_pci_sys_scan_bus, | ||
142 | .map_irq = wnr854t_pci_map_irq, | ||
143 | }; | ||
144 | |||
145 | static int __init wnr854t_pci_init(void) | ||
146 | { | ||
147 | if (machine_is_wnr854t()) | ||
148 | pci_common_init(&wnr854t_pci); | ||
149 | |||
150 | return 0; | ||
151 | } | ||
152 | subsys_initcall(wnr854t_pci_init); | ||
153 | |||
154 | MACHINE_START(WNR854T, "Netgear WNR854T") | ||
155 | /* Maintainer: Imre Kaloz <kaloz@openwrt.org> */ | ||
156 | .phys_io = ORION5X_REGS_PHYS_BASE, | ||
157 | .io_pg_offst = ((ORION5X_REGS_VIRT_BASE) >> 18) & 0xFFFC, | ||
158 | .boot_params = 0x00000100, | ||
159 | .init_machine = wnr854t_init, | ||
160 | .map_io = orion5x_map_io, | ||
161 | .init_irq = orion5x_init_irq, | ||
162 | .timer = &orion5x_timer, | ||
163 | .fixup = tag_fixup_mem32, | ||
164 | MACHINE_END | ||
diff --git a/arch/arm/mach-orion5x/wrt350n-v2-setup.c b/arch/arm/mach-orion5x/wrt350n-v2-setup.c new file mode 100644 index 000000000000..aeab55c6a82d --- /dev/null +++ b/arch/arm/mach-orion5x/wrt350n-v2-setup.c | |||
@@ -0,0 +1,173 @@ | |||
1 | /* | ||
2 | * arch/arm/mach-orion5x/wrt350n-v2-setup.c | ||
3 | * | ||
4 | * This file is licensed under the terms of the GNU General Public | ||
5 | * License version 2. This program is licensed "as is" without any | ||
6 | * warranty of any kind, whether express or implied. | ||
7 | */ | ||
8 | |||
9 | #include <linux/kernel.h> | ||
10 | #include <linux/init.h> | ||
11 | #include <linux/platform_device.h> | ||
12 | #include <linux/pci.h> | ||
13 | #include <linux/irq.h> | ||
14 | #include <linux/delay.h> | ||
15 | #include <linux/mtd/physmap.h> | ||
16 | #include <linux/mv643xx_eth.h> | ||
17 | #include <asm/mach-types.h> | ||
18 | #include <asm/gpio.h> | ||
19 | #include <asm/mach/arch.h> | ||
20 | #include <asm/mach/pci.h> | ||
21 | #include <asm/arch/orion5x.h> | ||
22 | #include "common.h" | ||
23 | #include "mpp.h" | ||
24 | |||
25 | static struct orion5x_mpp_mode wrt350n_v2_mpp_modes[] __initdata = { | ||
26 | { 0, MPP_GPIO }, /* Power LED green (0=on) */ | ||
27 | { 1, MPP_GPIO }, /* Security LED (0=on) */ | ||
28 | { 2, MPP_GPIO }, /* Internal Button (0=on) */ | ||
29 | { 3, MPP_GPIO }, /* Reset Button (0=on) */ | ||
30 | { 4, MPP_GPIO }, /* PCI int */ | ||
31 | { 5, MPP_GPIO }, /* Power LED orange (0=on) */ | ||
32 | { 6, MPP_GPIO }, /* USB LED (0=on) */ | ||
33 | { 7, MPP_GPIO }, /* Wireless LED (0=on) */ | ||
34 | { 8, MPP_UNUSED }, /* ??? */ | ||
35 | { 9, MPP_GIGE }, /* GE_RXERR */ | ||
36 | { 10, MPP_UNUSED }, /* ??? */ | ||
37 | { 11, MPP_UNUSED }, /* ??? */ | ||
38 | { 12, MPP_GIGE }, /* GE_TXD[4] */ | ||
39 | { 13, MPP_GIGE }, /* GE_TXD[5] */ | ||
40 | { 14, MPP_GIGE }, /* GE_TXD[6] */ | ||
41 | { 15, MPP_GIGE }, /* GE_TXD[7] */ | ||
42 | { 16, MPP_GIGE }, /* GE_RXD[4] */ | ||
43 | { 17, MPP_GIGE }, /* GE_RXD[5] */ | ||
44 | { 18, MPP_GIGE }, /* GE_RXD[6] */ | ||
45 | { 19, MPP_GIGE }, /* GE_RXD[7] */ | ||
46 | { -1 }, | ||
47 | }; | ||
48 | |||
49 | /* | ||
50 | * 8M NOR flash Device bus boot chip select | ||
51 | */ | ||
52 | #define WRT350N_V2_NOR_BOOT_BASE 0xf4000000 | ||
53 | #define WRT350N_V2_NOR_BOOT_SIZE SZ_8M | ||
54 | |||
55 | static struct mtd_partition wrt350n_v2_nor_flash_partitions[] = { | ||
56 | { | ||
57 | .name = "kernel", | ||
58 | .offset = 0x00000000, | ||
59 | .size = 0x00760000, | ||
60 | }, { | ||
61 | .name = "rootfs", | ||
62 | .offset = 0x001a0000, | ||
63 | .size = 0x005c0000, | ||
64 | }, { | ||
65 | .name = "lang", | ||
66 | .offset = 0x00760000, | ||
67 | .size = 0x00040000, | ||
68 | }, { | ||
69 | .name = "nvram", | ||
70 | .offset = 0x007a0000, | ||
71 | .size = 0x00020000, | ||
72 | }, { | ||
73 | .name = "u-boot", | ||
74 | .offset = 0x007c0000, | ||
75 | .size = 0x00040000, | ||
76 | }, | ||
77 | }; | ||
78 | |||
79 | static struct physmap_flash_data wrt350n_v2_nor_flash_data = { | ||
80 | .width = 1, | ||
81 | .parts = wrt350n_v2_nor_flash_partitions, | ||
82 | .nr_parts = ARRAY_SIZE(wrt350n_v2_nor_flash_partitions), | ||
83 | }; | ||
84 | |||
85 | static struct resource wrt350n_v2_nor_flash_resource = { | ||
86 | .flags = IORESOURCE_MEM, | ||
87 | .start = WRT350N_V2_NOR_BOOT_BASE, | ||
88 | .end = WRT350N_V2_NOR_BOOT_BASE + WRT350N_V2_NOR_BOOT_SIZE - 1, | ||
89 | }; | ||
90 | |||
91 | static struct platform_device wrt350n_v2_nor_flash = { | ||
92 | .name = "physmap-flash", | ||
93 | .id = 0, | ||
94 | .dev = { | ||
95 | .platform_data = &wrt350n_v2_nor_flash_data, | ||
96 | }, | ||
97 | .num_resources = 1, | ||
98 | .resource = &wrt350n_v2_nor_flash_resource, | ||
99 | }; | ||
100 | |||
101 | static struct mv643xx_eth_platform_data wrt350n_v2_eth_data = { | ||
102 | .phy_addr = -1, | ||
103 | }; | ||
104 | |||
105 | static void __init wrt350n_v2_init(void) | ||
106 | { | ||
107 | /* | ||
108 | * Setup basic Orion functions. Need to be called early. | ||
109 | */ | ||
110 | orion5x_init(); | ||
111 | |||
112 | orion5x_mpp_conf(wrt350n_v2_mpp_modes); | ||
113 | |||
114 | /* | ||
115 | * Configure peripherals. | ||
116 | */ | ||
117 | orion5x_ehci0_init(); | ||
118 | orion5x_eth_init(&wrt350n_v2_eth_data); | ||
119 | orion5x_uart0_init(); | ||
120 | |||
121 | orion5x_setup_dev_boot_win(WRT350N_V2_NOR_BOOT_BASE, | ||
122 | WRT350N_V2_NOR_BOOT_SIZE); | ||
123 | platform_device_register(&wrt350n_v2_nor_flash); | ||
124 | } | ||
125 | |||
126 | static int __init wrt350n_v2_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) | ||
127 | { | ||
128 | int irq; | ||
129 | |||
130 | /* | ||
131 | * Check for devices with hard-wired IRQs. | ||
132 | */ | ||
133 | irq = orion5x_pci_map_irq(dev, slot, pin); | ||
134 | if (irq != -1) | ||
135 | return irq; | ||
136 | |||
137 | /* | ||
138 | * Mini-PCI slot. | ||
139 | */ | ||
140 | if (slot == 7) | ||
141 | return gpio_to_irq(4); | ||
142 | |||
143 | return -1; | ||
144 | } | ||
145 | |||
146 | static struct hw_pci wrt350n_v2_pci __initdata = { | ||
147 | .nr_controllers = 2, | ||
148 | .swizzle = pci_std_swizzle, | ||
149 | .setup = orion5x_pci_sys_setup, | ||
150 | .scan = orion5x_pci_sys_scan_bus, | ||
151 | .map_irq = wrt350n_v2_pci_map_irq, | ||
152 | }; | ||
153 | |||
154 | static int __init wrt350n_v2_pci_init(void) | ||
155 | { | ||
156 | if (machine_is_wrt350n_v2()) | ||
157 | pci_common_init(&wrt350n_v2_pci); | ||
158 | |||
159 | return 0; | ||
160 | } | ||
161 | subsys_initcall(wrt350n_v2_pci_init); | ||
162 | |||
163 | MACHINE_START(WRT350N_V2, "Linksys WRT350N v2") | ||
164 | /* Maintainer: Lennert Buytenhek <buytenh@marvell.com> */ | ||
165 | .phys_io = ORION5X_REGS_PHYS_BASE, | ||
166 | .io_pg_offst = ((ORION5X_REGS_VIRT_BASE) >> 18) & 0xFFFC, | ||
167 | .boot_params = 0x00000100, | ||
168 | .init_machine = wrt350n_v2_init, | ||
169 | .map_io = orion5x_map_io, | ||
170 | .init_irq = orion5x_init_irq, | ||
171 | .timer = &orion5x_timer, | ||
172 | .fixup = tag_fixup_mem32, | ||
173 | MACHINE_END | ||