1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * linux/arch/arm/mach-pxa/gumstix.c |
4 | * |
5 | * Support for the Gumstix motherboards. |
6 | * |
7 | * Original Author: Craig Hughes |
8 | * Created: Feb 14, 2008 |
9 | * Copyright: Craig Hughes |
10 | * |
11 | * Implemented based on lubbock.c by Nicolas Pitre and code from Craig |
12 | * Hughes |
13 | */ |
14 | |
15 | #include <linux/module.h> |
16 | #include <linux/kernel.h> |
17 | #include <linux/init.h> |
18 | #include <linux/platform_device.h> |
19 | #include <linux/interrupt.h> |
20 | #include <linux/delay.h> |
21 | #include <linux/mtd/mtd.h> |
22 | #include <linux/mtd/partitions.h> |
23 | #include <linux/gpio/machine.h> |
24 | #include <linux/gpio.h> |
25 | #include <linux/err.h> |
26 | #include <linux/clk.h> |
27 | |
28 | #include <asm/setup.h> |
29 | #include <asm/page.h> |
30 | #include <asm/mach-types.h> |
31 | #include <asm/irq.h> |
32 | #include <linux/sizes.h> |
33 | |
34 | #include <asm/mach/arch.h> |
35 | #include <asm/mach/map.h> |
36 | #include <asm/mach/irq.h> |
37 | #include <asm/mach/flash.h> |
38 | |
39 | #include "pxa25x.h" |
40 | #include <linux/platform_data/mmc-pxamci.h> |
41 | #include "udc.h" |
42 | #include "gumstix.h" |
43 | |
44 | #include "generic.h" |
45 | |
46 | static struct resource flash_resource = { |
47 | .start = 0x00000000, |
48 | .end = SZ_64M - 1, |
49 | .flags = IORESOURCE_MEM, |
50 | }; |
51 | |
52 | static struct mtd_partition gumstix_partitions[] = { |
53 | { |
54 | .name = "Bootloader" , |
55 | .size = 0x00040000, |
56 | .offset = 0, |
57 | .mask_flags = MTD_WRITEABLE /* force read-only */ |
58 | } , { |
59 | .name = "rootfs" , |
60 | .size = MTDPART_SIZ_FULL, |
61 | .offset = MTDPART_OFS_APPEND |
62 | } |
63 | }; |
64 | |
65 | static struct flash_platform_data gumstix_flash_data = { |
66 | .map_name = "cfi_probe" , |
67 | .parts = gumstix_partitions, |
68 | .nr_parts = ARRAY_SIZE(gumstix_partitions), |
69 | .width = 2, |
70 | }; |
71 | |
72 | static struct platform_device gumstix_flash_device = { |
73 | .name = "pxa2xx-flash" , |
74 | .id = 0, |
75 | .dev = { |
76 | .platform_data = &gumstix_flash_data, |
77 | }, |
78 | .resource = &flash_resource, |
79 | .num_resources = 1, |
80 | }; |
81 | |
82 | static struct platform_device *devices[] __initdata = { |
83 | &gumstix_flash_device, |
84 | }; |
85 | |
86 | #ifdef CONFIG_MMC_PXA |
87 | static struct pxamci_platform_data gumstix_mci_platform_data = { |
88 | .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, |
89 | }; |
90 | |
91 | static void __init gumstix_mmc_init(void) |
92 | { |
93 | pxa_set_mci_info(&gumstix_mci_platform_data); |
94 | } |
95 | #else |
96 | static void __init gumstix_mmc_init(void) |
97 | { |
98 | pr_debug("Gumstix mmc disabled\n" ); |
99 | } |
100 | #endif |
101 | |
102 | #ifdef CONFIG_USB_PXA25X |
103 | static struct gpiod_lookup_table gumstix_gpio_vbus_gpiod_table = { |
104 | .dev_id = "gpio-vbus" , |
105 | .table = { |
106 | GPIO_LOOKUP("gpio-pxa" , GPIO_GUMSTIX_USB_GPIOn, |
107 | "vbus" , GPIO_ACTIVE_HIGH), |
108 | GPIO_LOOKUP("gpio-pxa" , GPIO_GUMSTIX_USB_GPIOx, |
109 | "pullup" , GPIO_ACTIVE_HIGH), |
110 | { }, |
111 | }, |
112 | }; |
113 | |
114 | static struct platform_device gumstix_gpio_vbus = { |
115 | .name = "gpio-vbus" , |
116 | .id = -1, |
117 | }; |
118 | |
119 | static void __init gumstix_udc_init(void) |
120 | { |
121 | gpiod_add_lookup_table(&gumstix_gpio_vbus_gpiod_table); |
122 | platform_device_register(&gumstix_gpio_vbus); |
123 | } |
124 | #else |
125 | static void gumstix_udc_init(void) |
126 | { |
127 | pr_debug("Gumstix udc is disabled\n" ); |
128 | } |
129 | #endif |
130 | |
131 | #ifdef CONFIG_BT |
132 | /* Normally, the bootloader would have enabled this 32kHz clock but many |
133 | ** boards still have u-boot 1.1.4 so we check if it has been turned on and |
134 | ** if not, we turn it on with a warning message. */ |
135 | static void gumstix_setup_bt_clock(void) |
136 | { |
137 | int timeout = 500; |
138 | |
139 | if (!(readl(OSCC) & OSCC_OOK)) |
140 | pr_warn("32kHz clock was not on. Bootloader may need to be updated\n" ); |
141 | else |
142 | return; |
143 | |
144 | writel(readl(OSCC) | OSCC_OON, OSCC); |
145 | do { |
146 | if (readl(OSCC) & OSCC_OOK) |
147 | break; |
148 | udelay(1); |
149 | } while (--timeout); |
150 | if (!timeout) |
151 | pr_err("Failed to start 32kHz clock\n" ); |
152 | } |
153 | |
154 | static void __init gumstix_bluetooth_init(void) |
155 | { |
156 | int err; |
157 | |
158 | gumstix_setup_bt_clock(); |
159 | |
160 | err = gpio_request(GPIO_GUMSTIX_BTRESET, label: "BTRST" ); |
161 | if (err) { |
162 | pr_err("gumstix: failed request gpio for bluetooth reset\n" ); |
163 | return; |
164 | } |
165 | |
166 | err = gpio_direction_output(GPIO_GUMSTIX_BTRESET, value: 1); |
167 | if (err) { |
168 | pr_err("gumstix: can't reset bluetooth\n" ); |
169 | return; |
170 | } |
171 | gpio_set_value(GPIO_GUMSTIX_BTRESET, value: 0); |
172 | udelay(100); |
173 | gpio_set_value(GPIO_GUMSTIX_BTRESET, value: 1); |
174 | } |
175 | #else |
176 | static void gumstix_bluetooth_init(void) |
177 | { |
178 | pr_debug("Gumstix Bluetooth is disabled\n" ); |
179 | } |
180 | #endif |
181 | |
182 | static unsigned long gumstix_pin_config[] __initdata = { |
183 | GPIO12_32KHz, |
184 | /* BTUART */ |
185 | GPIO42_HWUART_RXD, |
186 | GPIO43_HWUART_TXD, |
187 | GPIO44_HWUART_CTS, |
188 | GPIO45_HWUART_RTS, |
189 | /* MMC */ |
190 | GPIO6_MMC_CLK, |
191 | GPIO53_MMC_CLK, |
192 | GPIO8_MMC_CS0, |
193 | }; |
194 | |
195 | int __attribute__((weak)) am200_init(void) |
196 | { |
197 | return 0; |
198 | } |
199 | |
200 | int __attribute__((weak)) am300_init(void) |
201 | { |
202 | return 0; |
203 | } |
204 | |
205 | static void __init carrier_board_init(void) |
206 | { |
207 | /* |
208 | * put carrier/expansion board init here if |
209 | * they cannot be detected programatically |
210 | */ |
211 | am200_init(); |
212 | am300_init(); |
213 | } |
214 | |
215 | static void __init gumstix_init(void) |
216 | { |
217 | pxa2xx_mfp_config(ARRAY_AND_SIZE(gumstix_pin_config)); |
218 | |
219 | pxa_set_ffuart_info(NULL); |
220 | pxa_set_btuart_info(NULL); |
221 | pxa_set_stuart_info(NULL); |
222 | pxa_set_hwuart_info(NULL); |
223 | |
224 | gumstix_bluetooth_init(); |
225 | gumstix_udc_init(); |
226 | gumstix_mmc_init(); |
227 | (void) platform_add_devices(devices, ARRAY_SIZE(devices)); |
228 | carrier_board_init(); |
229 | } |
230 | |
231 | MACHINE_START(GUMSTIX, "Gumstix" ) |
232 | .atag_offset = 0x100, /* match u-boot bi_boot_params */ |
233 | .map_io = pxa25x_map_io, |
234 | .nr_irqs = PXA_NR_IRQS, |
235 | .init_irq = pxa25x_init_irq, |
236 | .init_time = pxa_timer_init, |
237 | .init_machine = gumstix_init, |
238 | .restart = pxa_restart, |
239 | MACHINE_END |
240 | |