source: src/linux/universal/linux-3.2/arch/arm/mach-cns3xxx/laguna.c @ 31672

Last change on this file since 31672 was 31672, checked in by brainslayer, 4 months ago

fix fs detection

File size: 24.6 KB
Line 
1/*
2 * Gateworks Corporation Laguna Platform
3 *
4 * Copyright 2000 Deep Blue Solutions Ltd
5 * Copyright 2008 ARM Limited
6 * Copyright 2008 Cavium Networks
7 *                Scott Shu
8 * Copyright 2010 MontaVista Software, LLC.
9 *                Anton Vorontsov <avorontsov@mvista.com>
10 * Copyright 2011 Gateworks Corporation
11 *                Chris Lang <clang@gateworks.com>
12 *
13 * This file is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License, Version 2, as
15 * published by the Free Software Foundation.
16 */
17
18#include <linux/init.h>
19#include <linux/kernel.h>
20#include <linux/compiler.h>
21#include <linux/io.h>
22#include <linux/vmalloc.h>
23#include <linux/dma-mapping.h>
24#include <linux/serial_core.h>
25#include <linux/serial_8250.h>
26#include <linux/platform_device.h>
27#include <linux/mtd/mtd.h>
28#include <linux/mtd/physmap.h>
29#include <linux/mtd/partitions.h>
30#include <linux/leds.h>
31#include <linux/i2c.h>
32#include <linux/i2c/at24.h>
33#include <linux/i2c/pca953x.h>
34#include <linux/spi/spi.h>
35#include <linux/spi/flash.h>
36#include <linux/if_ether.h>
37#include <linux/export.h>
38#include <linux/module.h>
39#include <asm/setup.h>
40#include <asm/mach-types.h>
41#include <asm/mach/arch.h>
42#include <asm/mach/map.h>
43#include <asm/mach/time.h>
44#include <mach/cns3xxx.h>
45#include <mach/platform.h>
46#include <mach/irqs.h>
47#include <linux/squashfs_fs.h>
48#ifdef CONFIG_CPU_FREQ
49#include <linux/cpufreq.h>
50extern struct cpufreq_driver cns_cpu_freq_driver;
51#endif
52#include <mach/pm.h>
53#include <mach/gpio.h>
54#include "core.h"
55#include "devices.h"
56
57unsigned int numcpucores=1;
58EXPORT_SYMBOL(numcpucores);
59
60// Config 1 Bitmap
61#define ETH0_LOAD           BIT(0)
62#define ETH1_LOAD           BIT(1)
63#define ETH2_LOAD           BIT(2)
64#define SATA0_LOAD          BIT(3)
65#define SATA1_LOAD          BIT(4)
66#define PCM_LOAD            BIT(5)
67#define I2S_LOAD            BIT(6)
68#define SPI0_LOAD           BIT(7)
69#define SPI1_LOAD           BIT(8)
70#define PCIE0_LOAD          BIT(9)
71#define PCIE1_LOAD          BIT(10)
72#define USB0_LOAD           BIT(11)
73#define USB1_LOAD           BIT(12)
74#define USB1_ROUTE          BIT(13)
75#define SD_LOAD             BIT(14)
76#define UART0_LOAD          BIT(15)
77#define UART1_LOAD          BIT(16)
78#define UART2_LOAD          BIT(17)
79#define MPCI0_LOAD          BIT(18)
80#define MPCI1_LOAD          BIT(19)
81#define MPCI2_LOAD          BIT(20)
82#define MPCI3_LOAD          BIT(21)
83#define FP_BUT_LOAD         BIT(22)
84#define FP_BUT_HEADER_LOAD  BIT(23)
85#define FP_LED_LOAD         BIT(24)
86#define FP_LED_HEADER_LOAD  BIT(25)
87#define FP_TAMPER_LOAD      BIT(26)
88#define HEADER_33V_LOAD     BIT(27)
89#define SATA_POWER_LOAD     BIT(28)
90#define FP_POWER_LOAD       BIT(29)
91#define GPIO_HEADER_LOAD    BIT(30)
92#define GSP_BAT_LOAD        BIT(31)
93
94// Config 2 Bitmap
95#define FAN_LOAD            BIT(0)
96#define SPI_FLASH_LOAD      BIT(1)
97#define NOR_FLASH_LOAD      BIT(2)
98#define GPS_LOAD            BIT(3)
99#define SUPPLY_5V_LOAD      BIT(6)
100#define SUPPLY_33V_LOAD     BIT(7)
101
102struct laguna_board_info {
103        char model[16];
104        u32 config_bitmap;
105        u32 config2_bitmap;
106        u8 nor_flash_size;
107        u8 spi_flash_size;
108};
109
110struct laguna_board_info laguna_info __initdata;
111
112EXPORT_SYMBOL(laguna_info);
113/*
114 * NOR Flash
115 */
116static struct mtd_partition laguna_norflash_partitions[] = {
117        /* Bootloader */
118        {
119                .name = "bootloader",
120                .offset = 0,
121                .size = SZ_256K,
122                .mask_flags = 0, /* force read-only */
123        },
124        /* Bootloader params */
125        {
126                .name = "params",
127                .offset = SZ_256K,
128                .size = SZ_128K,
129                .mask_flags = 0,
130        },
131        /* linux */
132        {
133                .name = "linux",
134                .offset = SZ_256K + SZ_128K,
135                .size = SZ_2M,
136                .mask_flags = 0,
137        },
138        /* Root FS */
139        {
140                .name = "rootfs",
141                .offset = SZ_256K + SZ_128K + SZ_2M,
142                .size = SZ_16M - SZ_256K - SZ_128K - SZ_2M,
143                .mask_flags = 0,
144        },
145        /* ddwrt */
146        {
147                .name = "ddwrt",
148                .offset = SZ_256K + SZ_128K + SZ_2M,
149                .size = SZ_128K,
150                .mask_flags = 0,
151        },
152        /* NVRAM */
153        {
154                .name = "nvram",
155                .offset = SZ_256K + SZ_128K + SZ_2M,
156                .size = SZ_128K,
157                .mask_flags = 0,
158        }
159};
160
161static struct physmap_flash_data laguna_nor_pdata = {
162        .width = 2,
163        .parts = laguna_norflash_partitions,
164        .nr_parts = ARRAY_SIZE(laguna_norflash_partitions),
165};
166
167static struct resource laguna_norflash_resource = {
168        .start = CNS3XXX_FLASH_BASE,
169        .end = CNS3XXX_FLASH_BASE + SZ_128M - 1,
170        .flags = IORESOURCE_MEM | IORESOURCE_MEM_32BIT,
171};
172
173static struct platform_device laguna_norflash_device = {
174        .name = "physmap-flash",
175        .id = 0,
176        .resource = &laguna_norflash_resource,
177        .num_resources = 1,
178        .dev = {
179                .platform_data = &laguna_nor_pdata,
180        },
181};
182
183/*
184 * SPI
185 */
186/* SPI Flash */
187static struct mtd_partition laguna_spiflash_partitions[] = {
188        /* Bootloader */
189        {
190                .name           = "bootloader",
191                .offset         = 0,
192                .size           = SZ_256K,
193        },
194        /* Bootloader params */
195        {
196                .name           = "params",
197                .offset         = SZ_256K,
198                .size           = SZ_256K,
199        },
200        /* linux */
201        {
202                .name = "linux",
203                .offset = SZ_512K,
204                .size = SZ_2M,
205                .mask_flags = 0,
206        },
207        /* FileSystem */
208        {
209                .name           = "rootfs",
210                .offset         = SZ_512K + SZ_2M ,
211                .size           = SZ_16M - SZ_512K - SZ_2M,
212        },
213        /* ddwrt */
214        {
215                .name = "ddwrt",
216                .offset = SZ_512K + SZ_2M,
217                .size = SZ_128K,
218                .mask_flags = 0,
219        },
220        /* NVRAM */
221        {
222                .name = "nvram",
223                .offset = SZ_512K + SZ_2M,
224                .size = SZ_128K,
225                .mask_flags = 0,
226        }
227};
228
229static struct flash_platform_data laguna_spi_pdata = {
230        .parts = laguna_spiflash_partitions,
231        .nr_parts = ARRAY_SIZE(laguna_spiflash_partitions),
232};
233
234static struct spi_board_info __initdata laguna_spi_devices[] = {
235        {
236                .modalias = "m25p80",
237                .platform_data = &laguna_spi_pdata,
238                .max_speed_hz = 50000000,
239                .bus_num = 1,
240                .chip_select = 0,
241        },
242};
243
244static struct platform_device laguna_spi_controller_device = {
245        .name = "cns3xxx_spi",
246};
247
248/*
249 * LED's
250 */
251static struct gpio_led laguna_gpio_leds[] = {
252        {
253                .name = "user1", /* Green Led */
254                .gpio = 115,
255                .active_low = 1,
256        },{
257                .name = "user2", /* Red Led */
258                .gpio = 114,
259                .active_low = 1,
260        },{
261                .name = "pwr1", /* Green Led */
262                .gpio = 116,
263                .active_low = 1,
264        },{
265                .name = "pwr2", /* Yellow Led */
266                .gpio = 117,
267                .active_low = 1,
268        },{
269                .name = "txd1", /* Green Led */
270                .gpio = 118,
271                .active_low = 1,
272        },{
273                .name = "txd2", /* Yellow Led */
274                .gpio = 119,
275                .active_low = 1,
276        },{
277                .name = "rxd1", /* Green Led */
278                .gpio = 120,
279                .active_low = 1,
280        },{
281                .name = "rxd2", /* Yellow Led */
282                .gpio = 121,
283                .active_low = 1,
284        },{
285                .name = "ser1", /* Green Led */
286                .gpio = 122,
287                .active_low = 1,
288        },{
289                .name = "ser2", /* Yellow Led */
290                .gpio = 123,
291                .active_low = 1,
292        },{
293                .name = "enet1", /* Green Led */
294                .gpio = 124,
295                .active_low = 1,
296        },{
297                .name = "enet2", /* Yellow Led */
298                .gpio = 125,
299                .active_low = 1,
300        },{
301                .name = "sig1_1", /* Green Led */
302                .gpio = 126,
303                .active_low = 1,
304        },{
305                .name = "sig1_2", /* Yellow Led */
306                .gpio = 127,
307                .active_low = 1,
308        },{
309                .name = "sig2_1", /* Green Led */
310                .gpio = 128,
311                .active_low = 1,
312        },{
313                .name = "sig2_2", /* Yellow Led */
314                .gpio = 129,
315                .active_low = 1,
316        },{
317                .name = "sig3_1", /* Green Led */
318                .gpio = 130,
319                .active_low = 1,
320        },{
321                .name = "sig3_2", /* Yellow Led */
322                .gpio = 131,
323                .active_low = 1,
324        },{
325                .name = "net1", /*Green Led */
326                .gpio = 109,
327                .active_low = 1,
328        },{
329                .name = "net2", /* Red Led */
330                .gpio = 110,
331                .active_low = 1,
332        },{
333                .name = "mod1", /* Green Led */
334                .gpio = 111,
335                .active_low = 1,
336        },{
337                .name = "mod2", /* Red Led */
338                .gpio = 112,
339                .active_low = 1,
340        },
341};
342
343static struct gpio_led_platform_data laguna_gpio_leds_data = {
344        .num_leds = 22,
345        .leds = laguna_gpio_leds,
346};
347
348static struct platform_device laguna_gpio_leds_device = {
349        .name = "leds-gpio",
350        .id = -1,
351        .dev.platform_data = &laguna_gpio_leds_data,
352};
353
354/*
355 * Ethernet
356 */
357static struct cns3xxx_plat_info laguna_net_data = {
358        .ports = 0,
359        .phy = {
360                0,
361                1,
362                2,
363        },
364};
365
366static struct platform_device laguna_net_device = {
367        .name = "cns3xxx_eth",
368        .id = 0,
369        .dev.platform_data = &laguna_net_data,
370};
371
372/*
373 * UART
374 */
375static void __init laguna_early_serial_setup(void)
376{
377#ifdef CONFIG_SERIAL_8250_CONSOLE
378        static struct uart_port laguna_serial_port = {
379                .membase        = (void __iomem *)CNS3XXX_UART0_BASE_VIRT,
380                .mapbase        = CNS3XXX_UART0_BASE,
381                .irq            = IRQ_CNS3XXX_UART0,
382                .iotype         = UPIO_MEM,
383                .flags          = UPF_BOOT_AUTOCONF | UPF_FIXED_TYPE,
384                .regshift       = 2,
385                .uartclk        = 24000000,
386                .line           = 0,
387                .type           = PORT_16550A,
388                .fifosize       = 16,
389        };
390
391        early_serial_setup(&laguna_serial_port);
392#endif
393}
394
395static struct resource laguna_uart_resources[] = {
396        {
397                .start = CNS3XXX_UART0_BASE,
398                .end   = CNS3XXX_UART0_BASE + SZ_4K - 1,
399                .flags    = IORESOURCE_MEM
400        },{
401                .start = CNS3XXX_UART2_BASE,
402                .end   = CNS3XXX_UART2_BASE + SZ_4K - 1,
403                .flags    = IORESOURCE_MEM
404        },{
405                .start = CNS3XXX_UART2_BASE,
406                .end   = CNS3XXX_UART2_BASE + SZ_4K - 1,
407                .flags    = IORESOURCE_MEM
408        },
409};
410
411static struct plat_serial8250_port laguna_uart_data[] = {
412        {
413                .membase        = (char*) (CNS3XXX_UART0_BASE_VIRT),
414                .mapbase        = (CNS3XXX_UART0_BASE),
415                .irq            = IRQ_CNS3XXX_UART0,
416                .iotype         = UPIO_MEM,
417                .flags          = UPF_BOOT_AUTOCONF | UPF_FIXED_TYPE | UPF_NO_TXEN_TEST,
418                .regshift       = 2,
419                .uartclk        = 24000000,
420                .type           = PORT_16550A,
421        },{
422                .membase        = (char*) (CNS3XXX_UART1_BASE_VIRT),
423                .mapbase        = (CNS3XXX_UART1_BASE),
424                .irq            = IRQ_CNS3XXX_UART1,
425                .iotype         = UPIO_MEM,
426                .flags          = UPF_BOOT_AUTOCONF | UPF_FIXED_TYPE | UPF_NO_TXEN_TEST,
427                .regshift       = 2,
428                .uartclk        = 24000000,
429                .type           = PORT_16550A,
430        },{
431                .membase        = (char*) (CNS3XXX_UART2_BASE_VIRT),
432                .mapbase        = (CNS3XXX_UART2_BASE),
433                .irq            = IRQ_CNS3XXX_UART2,
434                .iotype         = UPIO_MEM,
435                .flags          = UPF_BOOT_AUTOCONF | UPF_FIXED_TYPE | UPF_NO_TXEN_TEST,
436                .regshift       = 2,
437                .uartclk        = 24000000,
438                .type           = PORT_16550A,
439        },
440};
441
442static struct platform_device laguna_uart = {
443        .name     = "serial8250",
444        .id     = PLAT8250_DEV_PLATFORM,
445        .dev.platform_data  = laguna_uart_data,
446        .num_resources    = 3,
447        .resource   = laguna_uart_resources
448};
449
450/*
451 * USB
452 */
453static struct resource cns3xxx_usb_ehci_resources[] = {
454        [0] = {
455                .start = CNS3XXX_USB_BASE,
456                .end   = CNS3XXX_USB_BASE + SZ_16M - 1,
457                .flags = IORESOURCE_MEM,
458        },
459        [1] = {
460                .start = IRQ_CNS3XXX_USB_EHCI,
461                .flags = IORESOURCE_IRQ,
462        },
463};
464
465static u64 cns3xxx_usb_ehci_dma_mask = DMA_BIT_MASK(32);
466
467static struct platform_device cns3xxx_usb_ehci_device = {
468        .name          = "cns3xxx-ehci",
469        .num_resources = ARRAY_SIZE(cns3xxx_usb_ehci_resources),
470        .resource      = cns3xxx_usb_ehci_resources,
471        .dev           = {
472                .dma_mask          = &cns3xxx_usb_ehci_dma_mask,
473                .coherent_dma_mask = DMA_BIT_MASK(32),
474        },
475};
476
477static struct resource cns3xxx_usb_ohci_resources[] = {
478        [0] = {
479                .start = CNS3XXX_USB_OHCI_BASE,
480                .end   = CNS3XXX_USB_OHCI_BASE + SZ_16M - 1,
481                .flags = IORESOURCE_MEM,
482        },
483        [1] = {
484                .start = IRQ_CNS3XXX_USB_OHCI,
485                .flags = IORESOURCE_IRQ,
486        },
487};
488
489static u64 cns3xxx_usb_ohci_dma_mask = DMA_BIT_MASK(32);
490
491static struct platform_device cns3xxx_usb_ohci_device = {
492        .name          = "cns3xxx-ohci",
493        .num_resources = ARRAY_SIZE(cns3xxx_usb_ohci_resources),
494        .resource      = cns3xxx_usb_ohci_resources,
495        .dev           = {
496                .dma_mask          = &cns3xxx_usb_ohci_dma_mask,
497                .coherent_dma_mask = DMA_BIT_MASK(32),
498        },
499};
500
501static struct resource cns3xxx_usb_otg_resources[] = {
502        [0] = {
503                .start = CNS3XXX_USBOTG_BASE,
504                .end   = CNS3XXX_USBOTG_BASE + SZ_16M - 1,
505                .flags = IORESOURCE_MEM,
506        },
507        [1] = {
508                .start = IRQ_CNS3XXX_USB_OTG,
509                .flags = IORESOURCE_IRQ,
510        },
511};
512
513static u64 cns3xxx_usb_otg_dma_mask = DMA_BIT_MASK(32);
514
515static struct platform_device cns3xxx_usb_otg_device = {
516        .name          = "dwc_otg",
517        .num_resources = ARRAY_SIZE(cns3xxx_usb_otg_resources),
518        .resource      = cns3xxx_usb_otg_resources,
519        .dev           = {
520                .dma_mask          = &cns3xxx_usb_otg_dma_mask,
521                .coherent_dma_mask = DMA_BIT_MASK(32),
522        },
523};
524
525/*
526 * I2C
527 */
528static struct resource laguna_i2c_resource[] = {
529        {
530                .start    = CNS3XXX_SSP_BASE + 0x20,
531                .end      = 0x7100003f,
532                .flags    = IORESOURCE_MEM,
533        },{
534                .start    = IRQ_CNS3XXX_I2C,
535                .flags    = IORESOURCE_IRQ,
536        },
537};
538
539static struct platform_device laguna_i2c_controller = {
540        .name   = "cns3xxx-i2c",
541        .num_resources  = 2,
542        .resource = laguna_i2c_resource,
543};
544
545static struct memory_accessor *at24_mem_acc;
546
547static void at24_setup(struct memory_accessor *mem_acc, void *context)
548{
549        char buf[16];
550
551        at24_mem_acc = mem_acc;
552
553        /* Read MAC addresses */
554        if (at24_mem_acc->read(at24_mem_acc, buf, 0x100, 6) == 6)
555                memcpy(&laguna_net_data.hwaddr[0], buf, ETH_ALEN);
556        if (at24_mem_acc->read(at24_mem_acc, buf, 0x106, 6) == 6)
557                memcpy(&laguna_net_data.hwaddr[1], buf, ETH_ALEN);
558        if (at24_mem_acc->read(at24_mem_acc, buf, 0x10C, 6) == 6)
559                memcpy(&laguna_net_data.hwaddr[2], buf, ETH_ALEN);
560        if (at24_mem_acc->read(at24_mem_acc, buf, 0x112, 6) == 6)
561                memcpy(&laguna_net_data.hwaddr[3], buf, ETH_ALEN);
562
563        /* Read out Model Information */
564        if (at24_mem_acc->read(at24_mem_acc, buf, 0x130, 16) == 16)
565                memcpy(&laguna_info.model, buf, 16);
566        if (at24_mem_acc->read(at24_mem_acc, buf, 0x140, 1) == 1)
567                memcpy(&laguna_info.nor_flash_size, buf, 1);
568        if (at24_mem_acc->read(at24_mem_acc, buf, 0x141, 1) == 1)
569                memcpy(&laguna_info.spi_flash_size, buf, 1);
570        if (at24_mem_acc->read(at24_mem_acc, buf, 0x142, 4) == 4)
571                memcpy(&laguna_info.config_bitmap, buf, 4);
572        if (at24_mem_acc->read(at24_mem_acc, buf, 0x146, 4) == 4)
573                memcpy(&laguna_info.config2_bitmap, buf, 4);
574};
575
576static struct at24_platform_data laguna_eeprom_info = {
577        .byte_len = 1024,
578        .page_size = 16,
579        .flags = AT24_FLAG_READONLY,
580        .setup = at24_setup,
581};
582
583static struct pca953x_platform_data laguna_pca_data = {
584        .gpio_base = 100,
585};
586
587static struct pca953x_platform_data laguna_pca2_data = {
588        .gpio_base = 116,
589        .irq_base = -1,
590};
591
592static struct i2c_board_info __initdata laguna_i2c_devices[] = {
593        {
594                I2C_BOARD_INFO("pca9555", 0x23),
595                .platform_data = &laguna_pca_data,
596        },{
597                I2C_BOARD_INFO("pca9555", 0x27),
598                .platform_data = &laguna_pca2_data,
599        },{
600                I2C_BOARD_INFO("gsp", 0x29),
601        },{
602                I2C_BOARD_INFO ("24c08",0x50),
603                .platform_data = &laguna_eeprom_info,
604        },{
605                I2C_BOARD_INFO("ds1672", 0x68),
606        },
607};
608
609/*
610 * Watchdog
611 */
612
613static struct resource laguna_watchdog_resource[] = {
614        {
615                .start = CNS3XXX_TC11MP_TWD_BASE,
616                .end = CNS3XXX_TC11MP_TWD_BASE + 0x100 - 1,
617                .flags = IORESOURCE_MEM,
618        },{
619                .start = IRQ_LOCALWDOG,
620                .end = IRQ_LOCALWDOG,
621                .flags = IORESOURCE_IRQ,
622        }
623};
624
625static struct platform_device laguna_watchdog = {
626        .name = "mpcore_wdt",
627        .id = -1,
628        .num_resources = ARRAY_SIZE(laguna_watchdog_resource),
629        .resource = laguna_watchdog_resource,
630};
631
632static struct platform_device laguna_gpio_dev = {
633        .name = "GPIODEV",
634        .id = -1,
635};
636
637/*
638 * Initialization
639 */
640
641static void __init laguna_init(void)
642{
643        platform_device_register(&laguna_watchdog);
644
645        platform_device_register(&laguna_i2c_controller);
646
647        i2c_register_board_info(0, laguna_i2c_devices,
648                        ARRAY_SIZE(laguna_i2c_devices));
649
650
651        pm_power_off = cns3xxx_power_off;
652}
653
654static struct map_desc laguna_io_desc[] __initdata = {
655        {
656                .virtual        = CNS3XXX_UART0_BASE_VIRT,
657                .pfn            = __phys_to_pfn(CNS3XXX_UART0_BASE),
658                .length         = SZ_4K,
659                .type           = MT_DEVICE,
660        },{
661                .virtual        = CNS3XXX_UART1_BASE_VIRT,
662                .pfn            = __phys_to_pfn(CNS3XXX_UART1_BASE),
663                .length         = SZ_4K,
664                .type           = MT_DEVICE,
665        },{
666                .virtual        = CNS3XXX_UART2_BASE_VIRT,
667                .pfn            = __phys_to_pfn(CNS3XXX_UART2_BASE),
668                .length         = SZ_4K,
669                .type           = MT_DEVICE,
670        },
671};
672
673static void __init laguna_map_io(void)
674{
675        cns3xxx_common_init();
676        iotable_init(laguna_io_desc, ARRAY_SIZE(laguna_io_desc));
677
678        laguna_early_serial_setup();
679}
680
681 
682#define SPI_MEM_MAP_VALUE(reg_offset)           (*((u32 volatile *)(CNS3XXX_SSP_BASE_VIRT + reg_offset)))
683
684#define SPI_CONFIGURATION_REG                   SPI_MEM_MAP_VALUE(0x40)
685#define SPI_SERVICE_STATUS_REG                  SPI_MEM_MAP_VALUE(0x44)
686#define SPI_BIT_RATE_CONTROL_REG                SPI_MEM_MAP_VALUE(0x48)
687#define SPI_TRANSMIT_CONTROL_REG                SPI_MEM_MAP_VALUE(0x4C)
688#define SPI_TRANSMIT_BUFFER_REG                 SPI_MEM_MAP_VALUE(0x50)
689#define SPI_RECEIVE_CONTROL_REG                 SPI_MEM_MAP_VALUE(0x54)
690#define SPI_RECEIVE_BUFFER_REG                  SPI_MEM_MAP_VALUE(0x58)
691#define SPI_FIFO_TRANSMIT_CONFIG_REG            SPI_MEM_MAP_VALUE(0x5C)
692#define SPI_FIFO_TRANSMIT_CONTROL_REG           SPI_MEM_MAP_VALUE(0x60)
693#define SPI_FIFO_RECEIVE_CONFIG_REG             SPI_MEM_MAP_VALUE(0x64)
694#define SPI_INTERRUPT_STATUS_REG                SPI_MEM_MAP_VALUE(0x68)
695#define SPI_INTERRUPT_ENABLE_REG                SPI_MEM_MAP_VALUE(0x6C)
696
697#define SPI_TRANSMIT_BUFFER_REG_ADDR            (CNS3XXX_SSP_BASE +0x50)
698#define SPI_RECEIVE_BUFFER_REG_ADDR             (CNS3XXX_SSP_BASE +0x58)
699
700static int __init laguna_model_setup(void)
701{
702        u32 __iomem *mem;
703        u32 reg;
704
705        printk("Running on Gateworks Laguna %s\n", laguna_info.model);
706
707        if (strncmp(laguna_info.model, "GW", 2) == 0) {
708                printk("CONFIG BITMAP = 0x%08X\n",laguna_info.config_bitmap);
709                if (laguna_info.config_bitmap & ETH0_LOAD)
710                        laguna_net_data.ports |= BIT(0);
711                if (strncmp(laguna_info.model, "GW2388", 6) == 0)
712                {
713                if (laguna_info.config_bitmap & ETH1_LOAD)
714                        laguna_net_data.ports |= BIT(1);
715                if (laguna_info.config_bitmap & ETH2_LOAD)
716                        laguna_net_data.ports |= BIT(2);
717                }
718                if (laguna_net_data.ports)
719                        platform_device_register(&laguna_net_device);
720
721                if (laguna_info.config_bitmap & (SATA0_LOAD | SATA1_LOAD))
722                        cns3xxx_ahci_init();
723
724
725                gpio_line_set(3, 1);
726                gpio_line_config(3, CNS3XXX_GPIO_OUT);
727                gpio_set_value(3, 1);
728
729                if (strncmp(laguna_info.model, "GW2380", 6) == 0)
730                {
731                if (laguna_info.config_bitmap & (USB0_LOAD)) {
732                        cns3xxx_pwr_power_up(1 << PM_PLL_HM_PD_CTRL_REG_OFFSET_PLL_USB);
733
734                        /* DRVVBUS pins share with GPIOA */
735                        mem = (void __iomem *)(CNS3XXX_MISC_BASE_VIRT + 0x0010);
736                        reg = __raw_readl(mem);
737                        reg |= 0x8;
738                        __raw_writel(reg, mem);
739
740                        /* Enable OTG */
741                        mem = (void __iomem *)(CNS3XXX_MISC_BASE_VIRT + 0x0808);
742                        reg = __raw_readl(mem);
743                        reg &= ~(1 << 10);
744                        __raw_writel(reg, mem);
745
746                        platform_device_register(&cns3xxx_usb_otg_device);
747                }
748
749                if (laguna_info.config_bitmap & (USB1_LOAD)) {
750                        platform_device_register(&cns3xxx_usb_ehci_device);
751                        platform_device_register(&cns3xxx_usb_ohci_device);
752                }
753                }else{
754                if (laguna_info.config_bitmap & (USB0_LOAD)) {
755
756                        printk(KERN_EMERG "power up USB0\n");
757                        cns3xxx_pwr_power_up(1 << PM_PLL_HM_PD_CTRL_REG_OFFSET_PLL_USB);
758
759                        /* DRVVBUS pins share with GPIOA */
760                        mem = (void __iomem *)(CNS3XXX_MISC_BASE_VIRT + 0x0010);
761                        reg = __raw_readl(mem);
762                        reg |= 0x8;
763                        __raw_writel(reg, mem);
764
765                        /* Enable OTG */
766                        mem = (void __iomem *)(CNS3XXX_MISC_BASE_VIRT + 0x0808);
767                        reg = __raw_readl(mem);
768                        reg &= ~(1 << 10);
769                        __raw_writel(reg, mem);
770
771                        platform_device_register(&cns3xxx_usb_otg_device);
772                }
773
774                if (laguna_info.config_bitmap & (USB1_LOAD)) {
775                        printk(KERN_EMERG "power up ehci/ohci\n");
776                        platform_device_register(&cns3xxx_usb_ehci_device);
777                        platform_device_register(&cns3xxx_usb_ohci_device);
778                }
779                }
780
781
782                if (laguna_info.config_bitmap & (SD_LOAD))
783                {
784                        printk(KERN_EMERG "init sdhci\n");
785                        cns3xxx_sdhci_init();
786                }
787                if (laguna_info.config_bitmap & (UART0_LOAD))
788                        laguna_uart.num_resources = 1;
789                if (laguna_info.config_bitmap & (UART1_LOAD))
790                        laguna_uart.num_resources = 2;
791                if (laguna_info.config_bitmap & (UART2_LOAD))
792                        laguna_uart.num_resources = 3;
793                platform_device_register(&laguna_uart);
794
795                printk(KERN_EMERG "notflash size %d\n",laguna_info.nor_flash_size);
796                if ((laguna_info.config2_bitmap & (NOR_FLASH_LOAD)) && (strncmp(laguna_info.model, "GW2388", 6) == 0 || strncmp(laguna_info.model, "GW2387", 6) == 0)) {
797                        printk(KERN_EMERG "detecting NOR FLASH\n");
798//                      if (laguna_info.nor_flash_size < 1 || laguna_info.nor_flash_size > 5)
799//                          laguna_info.nor_flash_size = 2; //guess default for wrong config
800                        laguna_norflash_partitions[2].size = SZ_16M - SZ_256K - SZ_128K  - SZ_128K;
801                        laguna_norflash_resource.end = CNS3XXX_FLASH_BASE + SZ_16M - 1;
802                        switch (laguna_info.nor_flash_size) {
803                                case 1:
804                                        laguna_norflash_partitions[2].size = SZ_8M - SZ_256K - SZ_128K  - SZ_128K;
805                                        laguna_norflash_resource.end = CNS3XXX_FLASH_BASE + SZ_8M - 1;
806                                break;
807                                case 2:
808                                        laguna_norflash_partitions[2].size = SZ_16M - SZ_256K - SZ_128K  - SZ_128K;
809                                        laguna_norflash_resource.end = CNS3XXX_FLASH_BASE + SZ_16M - 1;
810                                break;
811                                case 3:
812                                        laguna_norflash_partitions[2].size = SZ_32M - SZ_256K - SZ_128K  - SZ_128K;
813                                        laguna_norflash_resource.end = CNS3XXX_FLASH_BASE + SZ_32M - 1;
814                                break;
815                                case 4:
816                                        laguna_norflash_partitions[2].size = SZ_64M - SZ_256K - SZ_128K  - SZ_128K;
817                                        laguna_norflash_resource.end = CNS3XXX_FLASH_BASE + SZ_64M - 1;
818                                break;
819                                case 5:
820                                        laguna_norflash_partitions[2].size = SZ_128M - SZ_256K - SZ_128K  - SZ_128K;
821                                        laguna_norflash_resource.end = CNS3XXX_FLASH_BASE + SZ_128M - 1;
822                                break;
823                        }
824                        unsigned int flashsize = laguna_norflash_partitions[2].size + SZ_256K + SZ_128K + SZ_128K;
825                        unsigned char *buf = (unsigned char *)ioremap(laguna_norflash_resource.start,laguna_norflash_resource.end - laguna_norflash_resource.start + 1);
826                        unsigned int offset=0;
827                        int tmplen;
828                        int filesyssize=0;
829                        int erasesize=0x20000;
830                        while(offset<laguna_norflash_resource.end)
831                        {
832                        if (*((__u32 *) buf) == SQUASHFS_MAGIC)
833                        {
834                //      printk(KERN_EMERG "found squashfs\n");
835                        struct squashfs_super_block *sb = (struct squashfs_super_block *) buf;
836                        filesyssize = le64_to_cpu(sb->bytes_used);
837                        tmplen = offset + filesyssize;
838                        tmplen +=  (erasesize - 1);
839                        tmplen &= ~(erasesize - 1);
840                        filesyssize = tmplen - offset;
841                        laguna_norflash_partitions[3].offset = offset;
842                        laguna_norflash_partitions[3].size = filesyssize;
843                        laguna_norflash_partitions[4].offset = offset + filesyssize;
844                        laguna_norflash_partitions[4].size = (flashsize- SZ_128K) - laguna_norflash_partitions[4].offset;
845                        laguna_norflash_partitions[5].offset = (flashsize - SZ_128K);
846                        laguna_norflash_partitions[5].size = SZ_128K;
847                        break;
848                        }
849                        buf+=0x1000;
850                        offset+=0x1000;
851                        }
852
853                        platform_device_register(&laguna_norflash_device);
854                }
855
856                if ((laguna_info.config2_bitmap & (SPI_FLASH_LOAD)) && strncmp(laguna_info.model, "GW2380", 6) == 0) {
857                //      printk(KERN_EMERG "detecting SPI FLASH\n");
858                        SPI_CONFIGURATION_REG = 0x40000000;
859                        HAL_MISC_ENABLE_SPI_SERIAL_FLASH_BANK_ACCESS();
860                        laguna_spiflash_partitions[2].size              = SZ_16M - SZ_512K;
861#if 0
862                        switch (laguna_info.spi_flash_size) {
863                                case 1:
864                                        laguna_spiflash_partitions[2].size              = SZ_4M - SZ_512K;
865                                break;
866                                case 2:
867                                        laguna_spiflash_partitions[2].size              = SZ_8M - SZ_512K;
868                                break;
869                                case 3:
870                                        laguna_spiflash_partitions[2].size              = SZ_16M - SZ_512K;
871                                break;
872                                case 4:
873                                        laguna_spiflash_partitions[2].size              = SZ_32M - SZ_512K;
874                                break;
875                                case 5:
876                                        laguna_spiflash_partitions[2].size              = SZ_64M - SZ_512K;
877                                break;
878                        }
879#endif
880                        unsigned int flashsize = laguna_spiflash_partitions[2].size + SZ_512K;
881                        unsigned char *buf = (unsigned char *)ioremap(CNS3XXX_SPI_FLASH_BASE,SZ_16M-1);
882                //      unsigned char *buf = (unsigned char *)CNS3XXX_SPI_FLASH_BASE;
883                        unsigned int offset=0;
884                        int tmplen;
885                        int filesyssize=0;
886                        int erasesize=0x40000;
887                        while(offset<SZ_8M)
888                        {
889                        if (*((__u32 *) buf) == SQUASHFS_MAGIC)
890                        {
891                        struct squashfs_super_block *sb;
892                        char *block = vmalloc(0x40000);
893                        memcpy(block,buf,0x40000);
894                        sb = (struct squashfs_super_block*)block;
895                        printk(KERN_EMERG "found squashfs @0x%08X magic=0x%08X\n",offset,*((__u32 *) buf));
896                        filesyssize = le64_to_cpu(sb->bytes_used);
897                        vfree(block);
898                        tmplen = offset + filesyssize;
899                        tmplen +=  (erasesize - 1);
900                        tmplen &= ~(erasesize - 1);
901                        filesyssize = tmplen - offset;
902                        laguna_spiflash_partitions[3].offset = offset;
903                        laguna_spiflash_partitions[3].size = filesyssize;
904                        laguna_spiflash_partitions[4].offset = offset + filesyssize;
905                        laguna_spiflash_partitions[4].size = (flashsize- SZ_256K) - laguna_spiflash_partitions[4].offset;
906                        laguna_spiflash_partitions[5].offset = (flashsize - SZ_256K);
907                        laguna_spiflash_partitions[5].size = SZ_256K;
908                        break;
909                        }
910                        buf+=0x1000;
911                        offset+=0x1000;
912                        }
913                        HAL_MISC_DISABLE_SPI_SERIAL_FLASH_BANK_ACCESS();
914
915                if (strncmp(laguna_info.model, "GW2380", 6) == 0)
916                        spi_register_board_info(laguna_spi_devices, ARRAY_SIZE(laguna_spi_devices));
917
918                }
919
920                if (laguna_info.config_bitmap & (SPI0_LOAD | SPI1_LOAD))
921                {
922                        platform_device_register(&laguna_spi_controller_device);
923                }
924
925                /*
926                 *      Do any model specific setup not known by the bitmap by matching
927                 *  the first 6 characters of the model name
928                 */
929
930                if (strncmp(laguna_info.model, "GW2388", 6) == 0)
931                {
932                        laguna_gpio_leds_data.num_leds = 2;
933                }
934                else if (strncmp(laguna_info.model, "GW2380", 6) == 0) {
935                        laguna_gpio_leds[0].gpio = 107;
936                        laguna_gpio_leds[1].gpio = 106;
937                        laguna_gpio_leds_data.num_leds = 2;
938                }
939                        platform_device_register(&laguna_gpio_leds_device);
940                        platform_device_register(&laguna_gpio_dev);
941        } else {
942                // Do some defaults here, not sure what yet
943        }
944        return 0;
945}
946
947late_initcall(laguna_model_setup);
948
949MACHINE_START(GW2388, "Gateworks Corporation Laguna Platform")
950        .atag_offset    = 0x100,
951        .map_io         = laguna_map_io,
952        .init_irq       = cns3xxx_init_irq,
953        .timer          = &cns3xxx_timer,
954        .init_machine   = laguna_init,
955MACHINE_END
Note: See TracBrowser for help on using the repository browser.