blob: 8e8d51f4a2762275e5c3171ca6b3f988e61dea2b [file] [log] [blame]
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001/*
2 * Hawkboard.org based on TI's OMAP-L138 Platform
3 *
4 * Initial code: Syed Mohammed Khasim
5 *
6 * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com
7 *
8 * This file is licensed under the terms of the GNU General Public License
9 * version 2. This program is licensed "as is" without any warranty of
10 * any kind, whether express or implied.
11 */
12#include <linux/kernel.h>
13#include <linux/init.h>
14#include <linux/console.h>
15#include <linux/interrupt.h>
16#include <linux/gpio.h>
17#include <linux/gpio/machine.h>
18#include <linux/mtd/partitions.h>
19#include <linux/mtd/rawnand.h>
20#include <linux/platform_data/gpio-davinci.h>
21#include <linux/platform_data/mtd-davinci.h>
22#include <linux/platform_data/mtd-davinci-aemif.h>
23#include <linux/platform_data/ti-aemif.h>
24#include <linux/regulator/machine.h>
25
26#include <asm/mach-types.h>
27#include <asm/mach/arch.h>
28
29#include <mach/common.h>
30#include "cp_intc.h"
31#include <mach/da8xx.h>
32#include <mach/mux.h>
33
34#define HAWKBOARD_PHY_ID "davinci_mdio-0:07"
35
36#define DA850_USB1_VBUS_PIN GPIO_TO_PIN(2, 4)
37#define DA850_USB1_OC_PIN GPIO_TO_PIN(6, 13)
38
39static short omapl138_hawk_mii_pins[] __initdata = {
40 DA850_MII_TXEN, DA850_MII_TXCLK, DA850_MII_COL, DA850_MII_TXD_3,
41 DA850_MII_TXD_2, DA850_MII_TXD_1, DA850_MII_TXD_0, DA850_MII_RXER,
42 DA850_MII_CRS, DA850_MII_RXCLK, DA850_MII_RXDV, DA850_MII_RXD_3,
43 DA850_MII_RXD_2, DA850_MII_RXD_1, DA850_MII_RXD_0, DA850_MDIO_CLK,
44 DA850_MDIO_D,
45 -1
46};
47
48static __init void omapl138_hawk_config_emac(void)
49{
50 void __iomem *cfgchip3 = DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG);
51 int ret;
52 u32 val;
53 struct davinci_soc_info *soc_info = &davinci_soc_info;
54
55 val = __raw_readl(cfgchip3);
56 val &= ~BIT(8);
57 ret = davinci_cfg_reg_list(omapl138_hawk_mii_pins);
58 if (ret) {
59 pr_warn("%s: CPGMAC/MII mux setup failed: %d\n", __func__, ret);
60 return;
61 }
62
63 /* configure the CFGCHIP3 register for MII */
64 __raw_writel(val, cfgchip3);
65 pr_info("EMAC: MII PHY configured\n");
66
67 soc_info->emac_pdata->phy_id = HAWKBOARD_PHY_ID;
68
69 ret = da8xx_register_emac();
70 if (ret)
71 pr_warn("%s: EMAC registration failed: %d\n", __func__, ret);
72}
73
74/*
75 * The following EDMA channels/slots are not being used by drivers (for
76 * example: Timer, GPIO, UART events etc) on da850/omap-l138 EVM/Hawkboard,
77 * hence they are being reserved for codecs on the DSP side.
78 */
79static const s16 da850_dma0_rsv_chans[][2] = {
80 /* (offset, number) */
81 { 8, 6},
82 {24, 4},
83 {30, 2},
84 {-1, -1}
85};
86
87static const s16 da850_dma0_rsv_slots[][2] = {
88 /* (offset, number) */
89 { 8, 6},
90 {24, 4},
91 {30, 50},
92 {-1, -1}
93};
94
95static const s16 da850_dma1_rsv_chans[][2] = {
96 /* (offset, number) */
97 { 0, 28},
98 {30, 2},
99 {-1, -1}
100};
101
102static const s16 da850_dma1_rsv_slots[][2] = {
103 /* (offset, number) */
104 { 0, 28},
105 {30, 90},
106 {-1, -1}
107};
108
109static struct edma_rsv_info da850_edma_cc0_rsv = {
110 .rsv_chans = da850_dma0_rsv_chans,
111 .rsv_slots = da850_dma0_rsv_slots,
112};
113
114static struct edma_rsv_info da850_edma_cc1_rsv = {
115 .rsv_chans = da850_dma1_rsv_chans,
116 .rsv_slots = da850_dma1_rsv_slots,
117};
118
119static struct edma_rsv_info *da850_edma_rsv[2] = {
120 &da850_edma_cc0_rsv,
121 &da850_edma_cc1_rsv,
122};
123
124static const short hawk_mmcsd0_pins[] = {
125 DA850_MMCSD0_DAT_0, DA850_MMCSD0_DAT_1, DA850_MMCSD0_DAT_2,
126 DA850_MMCSD0_DAT_3, DA850_MMCSD0_CLK, DA850_MMCSD0_CMD,
127 DA850_GPIO3_12, DA850_GPIO3_13,
128 -1
129};
130
131#define DA850_HAWK_MMCSD_CD_PIN GPIO_TO_PIN(3, 12)
132#define DA850_HAWK_MMCSD_WP_PIN GPIO_TO_PIN(3, 13)
133
134static struct gpiod_lookup_table mmc_gpios_table = {
135 .dev_id = "da830-mmc.0",
136 .table = {
137 GPIO_LOOKUP("davinci_gpio.0", DA850_HAWK_MMCSD_CD_PIN, "cd",
138 GPIO_ACTIVE_LOW),
139 GPIO_LOOKUP("davinci_gpio.0", DA850_HAWK_MMCSD_WP_PIN, "wp",
140 GPIO_ACTIVE_LOW),
141 },
142};
143
144static struct davinci_mmc_config da850_mmc_config = {
145 .wires = 4,
146 .max_freq = 50000000,
147 .caps = MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED,
148};
149
150static __init void omapl138_hawk_mmc_init(void)
151{
152 int ret;
153
154 ret = davinci_cfg_reg_list(hawk_mmcsd0_pins);
155 if (ret) {
156 pr_warn("%s: MMC/SD0 mux setup failed: %d\n", __func__, ret);
157 return;
158 }
159
160 gpiod_add_lookup_table(&mmc_gpios_table);
161
162 ret = da8xx_register_mmcsd0(&da850_mmc_config);
163 if (ret) {
164 pr_warn("%s: MMC/SD0 registration failed: %d\n", __func__, ret);
165 goto mmc_setup_mmcsd_fail;
166 }
167
168 return;
169
170mmc_setup_mmcsd_fail:
171 gpiod_remove_lookup_table(&mmc_gpios_table);
172}
173
174static struct mtd_partition omapl138_hawk_nandflash_partition[] = {
175 {
176 .name = "u-boot env",
177 .offset = 0,
178 .size = SZ_128K,
179 .mask_flags = MTD_WRITEABLE,
180 },
181 {
182 .name = "u-boot",
183 .offset = MTDPART_OFS_APPEND,
184 .size = SZ_512K,
185 .mask_flags = MTD_WRITEABLE,
186 },
187 {
188 .name = "free space",
189 .offset = MTDPART_OFS_APPEND,
190 .size = MTDPART_SIZ_FULL,
191 .mask_flags = 0,
192 },
193};
194
195static struct davinci_aemif_timing omapl138_hawk_nandflash_timing = {
196 .wsetup = 24,
197 .wstrobe = 21,
198 .whold = 14,
199 .rsetup = 19,
200 .rstrobe = 50,
201 .rhold = 0,
202 .ta = 20,
203};
204
205static struct davinci_nand_pdata omapl138_hawk_nandflash_data = {
206 .core_chipsel = 1,
207 .parts = omapl138_hawk_nandflash_partition,
208 .nr_parts = ARRAY_SIZE(omapl138_hawk_nandflash_partition),
209 .ecc_mode = NAND_ECC_HW,
210 .ecc_bits = 4,
211 .bbt_options = NAND_BBT_USE_FLASH,
212 .options = NAND_BUSWIDTH_16,
213 .timing = &omapl138_hawk_nandflash_timing,
214 .mask_chipsel = 0,
215 .mask_ale = 0,
216 .mask_cle = 0,
217};
218
219static struct resource omapl138_hawk_nandflash_resource[] = {
220 {
221 .start = DA8XX_AEMIF_CS3_BASE,
222 .end = DA8XX_AEMIF_CS3_BASE + SZ_32M,
223 .flags = IORESOURCE_MEM,
224 },
225 {
226 .start = DA8XX_AEMIF_CTL_BASE,
227 .end = DA8XX_AEMIF_CTL_BASE + SZ_32K,
228 .flags = IORESOURCE_MEM,
229 },
230};
231
232static struct resource omapl138_hawk_aemif_resource[] = {
233 {
234 .start = DA8XX_AEMIF_CTL_BASE,
235 .end = DA8XX_AEMIF_CTL_BASE + SZ_32K,
236 .flags = IORESOURCE_MEM,
237 }
238};
239
240static struct aemif_abus_data omapl138_hawk_aemif_abus_data[] = {
241 {
242 .cs = 3,
243 }
244};
245
246static struct platform_device omapl138_hawk_aemif_devices[] = {
247 {
248 .name = "davinci_nand",
249 .id = -1,
250 .dev = {
251 .platform_data = &omapl138_hawk_nandflash_data,
252 },
253 .resource = omapl138_hawk_nandflash_resource,
254 .num_resources = ARRAY_SIZE(omapl138_hawk_nandflash_resource),
255 }
256};
257
258static struct aemif_platform_data omapl138_hawk_aemif_pdata = {
259 .cs_offset = 2,
260 .abus_data = omapl138_hawk_aemif_abus_data,
261 .num_abus_data = ARRAY_SIZE(omapl138_hawk_aemif_abus_data),
262 .sub_devices = omapl138_hawk_aemif_devices,
263 .num_sub_devices = ARRAY_SIZE(omapl138_hawk_aemif_devices),
264};
265
266static struct platform_device omapl138_hawk_aemif_device = {
267 .name = "ti-aemif",
268 .id = -1,
269 .dev = {
270 .platform_data = &omapl138_hawk_aemif_pdata,
271 },
272 .resource = omapl138_hawk_aemif_resource,
273 .num_resources = ARRAY_SIZE(omapl138_hawk_aemif_resource),
274};
275
276static const short omapl138_hawk_nand_pins[] = {
277 DA850_EMA_WAIT_1, DA850_NEMA_OE, DA850_NEMA_WE, DA850_NEMA_CS_3,
278 DA850_EMA_D_0, DA850_EMA_D_1, DA850_EMA_D_2, DA850_EMA_D_3,
279 DA850_EMA_D_4, DA850_EMA_D_5, DA850_EMA_D_6, DA850_EMA_D_7,
280 DA850_EMA_D_8, DA850_EMA_D_9, DA850_EMA_D_10, DA850_EMA_D_11,
281 DA850_EMA_D_12, DA850_EMA_D_13, DA850_EMA_D_14, DA850_EMA_D_15,
282 DA850_EMA_A_1, DA850_EMA_A_2,
283 -1
284};
285
286static int omapl138_hawk_register_aemif(void)
287{
288 int ret;
289
290 ret = davinci_cfg_reg_list(omapl138_hawk_nand_pins);
291 if (ret)
292 pr_warn("%s: NAND mux setup failed: %d\n", __func__, ret);
293
294 return platform_device_register(&omapl138_hawk_aemif_device);
295}
296
297static irqreturn_t omapl138_hawk_usb_ocic_irq(int irq, void *dev_id);
298static da8xx_ocic_handler_t hawk_usb_ocic_handler;
299
300static const short da850_hawk_usb11_pins[] = {
301 DA850_GPIO2_4, DA850_GPIO6_13,
302 -1
303};
304
305static int hawk_usb_set_power(unsigned port, int on)
306{
307 gpio_set_value(DA850_USB1_VBUS_PIN, on);
308 return 0;
309}
310
311static int hawk_usb_get_power(unsigned port)
312{
313 return gpio_get_value(DA850_USB1_VBUS_PIN);
314}
315
316static int hawk_usb_get_oci(unsigned port)
317{
318 return !gpio_get_value(DA850_USB1_OC_PIN);
319}
320
321static int hawk_usb_ocic_notify(da8xx_ocic_handler_t handler)
322{
323 int irq = gpio_to_irq(DA850_USB1_OC_PIN);
324 int error = 0;
325
326 if (handler != NULL) {
327 hawk_usb_ocic_handler = handler;
328
329 error = request_irq(irq, omapl138_hawk_usb_ocic_irq,
330 IRQF_TRIGGER_RISING |
331 IRQF_TRIGGER_FALLING,
332 "OHCI over-current indicator", NULL);
333 if (error)
334 pr_err("%s: could not request IRQ to watch "
335 "over-current indicator changes\n", __func__);
336 } else {
337 free_irq(irq, NULL);
338 }
339 return error;
340}
341
342static struct da8xx_ohci_root_hub omapl138_hawk_usb11_pdata = {
343 .set_power = hawk_usb_set_power,
344 .get_power = hawk_usb_get_power,
345 .get_oci = hawk_usb_get_oci,
346 .ocic_notify = hawk_usb_ocic_notify,
347 /* TPS2087 switch @ 5V */
348 .potpgt = (3 + 1) / 2, /* 3 ms max */
349};
350
351static irqreturn_t omapl138_hawk_usb_ocic_irq(int irq, void *dev_id)
352{
353 hawk_usb_ocic_handler(&omapl138_hawk_usb11_pdata, 1);
354 return IRQ_HANDLED;
355}
356
357static __init void omapl138_hawk_usb_init(void)
358{
359 int ret;
360
361 ret = davinci_cfg_reg_list(da850_hawk_usb11_pins);
362 if (ret) {
363 pr_warn("%s: USB 1.1 PinMux setup failed: %d\n", __func__, ret);
364 return;
365 }
366
367 ret = da8xx_register_usb_phy_clocks();
368 if (ret)
369 pr_warn("%s: USB PHY CLK registration failed: %d\n",
370 __func__, ret);
371
372 ret = da8xx_register_usb_phy();
373 if (ret)
374 pr_warn("%s: USB PHY registration failed: %d\n",
375 __func__, ret);
376
377 ret = gpio_request_one(DA850_USB1_VBUS_PIN,
378 GPIOF_DIR_OUT, "USB1 VBUS");
379 if (ret < 0) {
380 pr_err("%s: failed to request GPIO for USB 1.1 port "
381 "power control: %d\n", __func__, ret);
382 return;
383 }
384
385 ret = gpio_request_one(DA850_USB1_OC_PIN,
386 GPIOF_DIR_IN, "USB1 OC");
387 if (ret < 0) {
388 pr_err("%s: failed to request GPIO for USB 1.1 port "
389 "over-current indicator: %d\n", __func__, ret);
390 goto usb11_setup_oc_fail;
391 }
392
393 ret = da8xx_register_usb11(&omapl138_hawk_usb11_pdata);
394 if (ret) {
395 pr_warn("%s: USB 1.1 registration failed: %d\n", __func__, ret);
396 goto usb11_setup_fail;
397 }
398
399 return;
400
401usb11_setup_fail:
402 gpio_free(DA850_USB1_OC_PIN);
403usb11_setup_oc_fail:
404 gpio_free(DA850_USB1_VBUS_PIN);
405}
406
407static __init void omapl138_hawk_init(void)
408{
409 int ret;
410
411 da850_register_clocks();
412
413 ret = da850_register_gpio();
414 if (ret)
415 pr_warn("%s: GPIO init failed: %d\n", __func__, ret);
416
417 davinci_serial_init(da8xx_serial_device);
418
419 omapl138_hawk_config_emac();
420
421 ret = da850_register_edma(da850_edma_rsv);
422 if (ret)
423 pr_warn("%s: EDMA registration failed: %d\n", __func__, ret);
424
425 omapl138_hawk_mmc_init();
426
427 omapl138_hawk_usb_init();
428
429 ret = omapl138_hawk_register_aemif();
430 if (ret)
431 pr_warn("%s: aemif registration failed: %d\n", __func__, ret);
432
433 ret = da8xx_register_watchdog();
434 if (ret)
435 pr_warn("%s: watchdog registration failed: %d\n",
436 __func__, ret);
437
438 ret = da8xx_register_rproc();
439 if (ret)
440 pr_warn("%s: dsp/rproc registration failed: %d\n",
441 __func__, ret);
442
443 regulator_has_full_constraints();
444}
445
446#ifdef CONFIG_SERIAL_8250_CONSOLE
447static int __init omapl138_hawk_console_init(void)
448{
449 if (!machine_is_omapl138_hawkboard())
450 return 0;
451
452 return add_preferred_console("ttyS", 2, "115200");
453}
454console_initcall(omapl138_hawk_console_init);
455#endif
456
457static void __init omapl138_hawk_map_io(void)
458{
459 da850_init();
460}
461
462MACHINE_START(OMAPL138_HAWKBOARD, "AM18x/OMAP-L138 Hawkboard")
463 .atag_offset = 0x100,
464 .map_io = omapl138_hawk_map_io,
465 .init_irq = cp_intc_init,
466 .init_time = da850_init_time,
467 .init_machine = omapl138_hawk_init,
468 .init_late = davinci_init_late,
469 .dma_zone_size = SZ_128M,
470 .reserve = da8xx_rproc_reserve_cma,
471MACHINE_END