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