source: src/linux/universal/linux-3.18/arch/arm/mach-cns3xxx/laguna.c @ 29549

Last change on this file since 29549 was 29549, checked in by BrainSlayer, 11 months ago

latest code

File size: 36.8 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/irq.h>
23#include <linux/gpio.h>
24#include <linux/vmalloc.h>
25#include <linux/dma-mapping.h>
26#include <linux/serial_core.h>
27#include <linux/serial_8250.h>
28#include <linux/platform_device.h>
29#include <linux/mtd/mtd.h>
30#include <linux/mtd/physmap.h>
31#include <linux/mtd/partitions.h>
32#include <linux/usb/ehci_pdriver.h>
33#include <linux/usb/ohci_pdriver.h>
34#include <linux/leds.h>
35#include <linux/i2c.h>
36#include <linux/platform_data/at24.h>
37#include <linux/i2c/pca953x.h>
38#include <linux/spi/spi.h>
39#include <linux/spi/flash.h>
40#include <linux/if_ether.h>
41#include <linux/pps-gpio.h>
42#include <linux/export.h>
43#include <linux/module.h>
44#include <asm/setup.h>
45#include <asm/mach-types.h>
46#include <asm/mach/arch.h>
47#include <asm/mach/map.h>
48#include <asm/mach/time.h>
49#include <mach/cns3xxx.h>
50#include <mach/platform.h>
51#include <mach/irqs.h>
52#include <linux/squashfs_fs.h>
53#ifdef CONFIG_CPU_FREQ
54#include <linux/cpufreq.h>
55extern struct cpufreq_driver cns_cpu_freq_driver;
56#endif
57#include <mach/pm.h>
58#include <mach/gpio.h>
59#include "core.h"
60#include "devices.h"
61
62#define ARRAY_AND_SIZE(x)       (x), ARRAY_SIZE(x)
63
64unsigned int numcpucores=1;
65EXPORT_SYMBOL(numcpucores);
66
67// Config 1 Bitmap
68#define ETH0_LOAD           BIT(0)
69#define ETH1_LOAD           BIT(1)
70#define ETH2_LOAD           BIT(2)
71#define SATA0_LOAD          BIT(3)
72#define SATA1_LOAD          BIT(4)
73#define PCM_LOAD            BIT(5)
74#define I2S_LOAD            BIT(6)
75#define SPI0_LOAD           BIT(7)
76#define SPI1_LOAD           BIT(8)
77#define PCIE0_LOAD          BIT(9)
78#define PCIE1_LOAD          BIT(10)
79#define USB0_LOAD           BIT(11)
80#define USB1_LOAD           BIT(12)
81#define USB1_ROUTE          BIT(13)
82#define SD_LOAD             BIT(14)
83#define UART0_LOAD          BIT(15)
84#define UART1_LOAD          BIT(16)
85#define UART2_LOAD          BIT(17)
86#define MPCI0_LOAD          BIT(18)
87#define MPCI1_LOAD          BIT(19)
88#define MPCI2_LOAD          BIT(20)
89#define MPCI3_LOAD          BIT(21)
90#define FP_BUT_LOAD         BIT(22)
91#define FP_BUT_HEADER_LOAD  BIT(23)
92#define FP_LED_LOAD         BIT(24)
93#define FP_LED_HEADER_LOAD  BIT(25)
94#define FP_TAMPER_LOAD      BIT(26)
95#define HEADER_33V_LOAD     BIT(27)
96#define SATA_POWER_LOAD     BIT(28)
97#define FP_POWER_LOAD       BIT(29)
98#define GPIO_HEADER_LOAD    BIT(30)
99#define GSP_BAT_LOAD        BIT(31)
100
101// Config 2 Bitmap
102#define FAN_LOAD            BIT(0)
103#define SPI_FLASH_LOAD      BIT(1)
104#define NOR_FLASH_LOAD      BIT(2)
105#define GPS_LOAD            BIT(3)
106#define SUPPLY_5V_LOAD      BIT(6)
107#define SUPPLY_33V_LOAD     BIT(7)
108
109struct laguna_board_info {
110        char model[16];
111        u32 config_bitmap;
112        u32 config2_bitmap;
113        u8 nor_flash_size;
114        u8 spi_flash_size;
115};
116
117struct laguna_board_info laguna_info __initdata;
118
119EXPORT_SYMBOL(laguna_info);
120/*
121 * NOR Flash
122 */
123static struct mtd_partition laguna_norflash_partitions[] = {
124        /* Bootloader */
125        {
126                .name = "bootloader",
127                .offset = 0,
128                .size = SZ_256K,
129                .mask_flags = 0, /* force read-only */
130        },
131        /* Bootloader params */
132        {
133                .name = "params",
134                .offset = SZ_256K,
135                .size = SZ_128K,
136                .mask_flags = 0,
137        },
138        /* linux */
139        {
140                .name = "linux",
141                .offset = SZ_256K + SZ_128K,
142                .size = SZ_2M,
143                .mask_flags = 0,
144        },
145        /* Root FS */
146        {
147                .name = "rootfs",
148                .offset = SZ_256K + SZ_128K + SZ_2M,
149                .size = SZ_16M - SZ_256K - SZ_128K - SZ_2M,
150                .mask_flags = 0,
151        },
152        /* ddwrt */
153        {
154                .name = "ddwrt",
155                .offset = SZ_256K + SZ_128K + SZ_2M,
156                .size = SZ_128K,
157                .mask_flags = 0,
158        },
159        /* NVRAM */
160        {
161                .name = "nvram",
162                .offset = SZ_256K + SZ_128K + SZ_2M,
163                .size = SZ_128K,
164                .mask_flags = 0,
165        }
166};
167
168static struct physmap_flash_data laguna_nor_pdata = {
169        .width = 2,
170        .parts = laguna_norflash_partitions,
171        .nr_parts = ARRAY_SIZE(laguna_norflash_partitions),
172};
173
174static struct resource laguna_norflash_resource = {
175        .start = CNS3XXX_FLASH_BASE,
176        .end = CNS3XXX_FLASH_BASE + SZ_128M - 1,
177        .flags = IORESOURCE_MEM | IORESOURCE_MEM_32BIT,
178};
179
180static struct platform_device laguna_norflash_device = {
181        .name = "physmap-flash",
182        .id = 0,
183        .resource = &laguna_norflash_resource,
184        .num_resources = 1,
185        .dev = {
186                .platform_data = &laguna_nor_pdata,
187        },
188};
189
190/*
191 * SPI
192 */
193/* SPI Flash */
194static struct mtd_partition laguna_spiflash_partitions[] = {
195        /* Bootloader */
196        {
197                .name           = "bootloader",
198                .offset         = 0,
199                .size           = SZ_256K,
200        },
201        /* Bootloader params */
202        {
203                .name           = "params",
204                .offset         = SZ_256K,
205                .size           = SZ_256K,
206        },
207        /* linux */
208        {
209                .name = "linux",
210                .offset = SZ_512K,
211                .size = SZ_2M,
212                .mask_flags = 0,
213        },
214        /* FileSystem */
215        {
216                .name           = "rootfs",
217                .offset         = SZ_512K + SZ_2M ,
218                .size           = SZ_16M - SZ_512K - SZ_2M,
219        },
220        /* ddwrt */
221        {
222                .name = "ddwrt",
223                .offset = SZ_512K + SZ_2M,
224                .size = SZ_128K,
225                .mask_flags = 0,
226        },
227        /* NVRAM */
228        {
229                .name = "nvram",
230                .offset = SZ_512K + SZ_2M,
231                .size = SZ_128K,
232                .mask_flags = 0,
233        }
234};
235
236static struct flash_platform_data laguna_spi_pdata = {
237        .parts = laguna_spiflash_partitions,
238        .nr_parts = ARRAY_SIZE(laguna_spiflash_partitions),
239};
240
241static struct spi_board_info __initdata laguna_spi_devices[] = {
242        {
243                .modalias = "m25p80",
244                .platform_data = &laguna_spi_pdata,
245                .max_speed_hz = 50000000,
246                .bus_num = 1,
247                .chip_select = 0,
248        },
249};
250
251static struct platform_device laguna_spi_controller_device = {
252        .name = "cns3xxx_spi",
253};
254
255/*
256 * LED's
257 */
258static struct gpio_led laguna_gpio_leds[] = {
259        {
260                .name = "user1", /* Green Led */
261                .gpio = 115,
262                .active_low = 1,
263        },{
264                .name = "user2", /* Red Led */
265                .gpio = 114,
266                .active_low = 1,
267        },{
268                .name = "pwr1", /* Green Led */
269                .gpio = 116,
270                .active_low = 1,
271        },{
272                .name = "pwr2", /* Yellow Led */
273                .gpio = 117,
274                .active_low = 1,
275        },{
276                .name = "txd1", /* Green Led */
277                .gpio = 118,
278                .active_low = 1,
279        },{
280                .name = "txd2", /* Yellow Led */
281                .gpio = 119,
282                .active_low = 1,
283        },{
284                .name = "rxd1", /* Green Led */
285                .gpio = 120,
286                .active_low = 1,
287        },{
288                .name = "rxd2", /* Yellow Led */
289                .gpio = 121,
290                .active_low = 1,
291        },{
292                .name = "ser1", /* Green Led */
293                .gpio = 122,
294                .active_low = 1,
295        },{
296                .name = "ser2", /* Yellow Led */
297                .gpio = 123,
298                .active_low = 1,
299        },{
300                .name = "enet1", /* Green Led */
301                .gpio = 124,
302                .active_low = 1,
303        },{
304                .name = "enet2", /* Yellow Led */
305                .gpio = 125,
306                .active_low = 1,
307        },{
308                .name = "sig1_1", /* Green Led */
309                .gpio = 126,
310                .active_low = 1,
311        },{
312                .name = "sig1_2", /* Yellow Led */
313                .gpio = 127,
314                .active_low = 1,
315        },{
316                .name = "sig2_1", /* Green Led */
317                .gpio = 128,
318                .active_low = 1,
319        },{
320                .name = "sig2_2", /* Yellow Led */
321                .gpio = 129,
322                .active_low = 1,
323        },{
324                .name = "sig3_1", /* Green Led */
325                .gpio = 130,
326                .active_low = 1,
327        },{
328                .name = "sig3_2", /* Yellow Led */
329                .gpio = 131,
330                .active_low = 1,
331        },{
332                .name = "net1", /*Green Led */
333                .gpio = 109,
334                .active_low = 1,
335        },{
336                .name = "net2", /* Red Led */
337                .gpio = 110,
338                .active_low = 1,
339        },{
340                .name = "mod1", /* Green Led */
341                .gpio = 111,
342                .active_low = 1,
343        },{
344                .name = "mod2", /* Red Led */
345                .gpio = 112,
346                .active_low = 1,
347        },
348};
349
350static struct gpio_led_platform_data laguna_gpio_leds_data = {
351        .num_leds = 22,
352        .leds = laguna_gpio_leds,
353};
354
355static struct platform_device laguna_gpio_leds_device = {
356        .name = "leds-gpio",
357        .id = -1,
358        .dev.platform_data = &laguna_gpio_leds_data,
359};
360
361/*
362 * Ethernet
363 */
364static struct cns3xxx_plat_info laguna_net_data = {
365        .ports = 0,
366        .phy = {
367                0,
368                1,
369                2,
370        },
371};
372
373static struct resource laguna_net_resource[] = {
374        {
375                .name = "eth0_mem",
376                .start = CNS3XXX_SWITCH_BASE,
377                .end = CNS3XXX_SWITCH_BASE + SZ_4K - 1,
378                .flags = IORESOURCE_MEM
379        }, {
380                .name = "eth_rx",
381                .start = IRQ_CNS3XXX_SW_R0RXC,
382                .end = IRQ_CNS3XXX_SW_R0RXC,
383                .flags = IORESOURCE_IRQ
384        }, {
385                .name = "eth_stat",
386                .start = IRQ_CNS3XXX_SW_STATUS,
387                .end = IRQ_CNS3XXX_SW_STATUS,
388                .flags = IORESOURCE_IRQ
389        }
390};
391
392static u64 laguna_net_dmamask = DMA_BIT_MASK(32);
393
394static struct platform_device laguna_net_device = {
395        .name = "cns3xxx_eth",
396        .id = 0,
397        .resource = laguna_net_resource,
398        .num_resources = ARRAY_SIZE(laguna_net_resource),
399        .dev = {
400                .dma_mask = &laguna_net_dmamask,
401                .coherent_dma_mask = DMA_BIT_MASK(32),
402                .platform_data = &laguna_net_data,
403        }
404};
405
406
407
408/*
409 * UART
410 */
411static void __init laguna_early_serial_setup(void)
412{
413#ifdef CONFIG_SERIAL_8250_CONSOLE
414        static struct uart_port laguna_serial_port = {
415                .membase        = (void __iomem *)CNS3XXX_UART0_BASE_VIRT,
416                .mapbase        = CNS3XXX_UART0_BASE,
417                .irq            = IRQ_CNS3XXX_UART0,
418                .iotype         = UPIO_MEM,
419                .flags          = UPF_BOOT_AUTOCONF | UPF_FIXED_TYPE,
420                .regshift       = 2,
421                .uartclk        = 24000000,
422                .line           = 0,
423                .type           = PORT_16550A,
424                .fifosize       = 16,
425        };
426
427        early_serial_setup(&laguna_serial_port);
428#endif
429}
430
431static struct resource laguna_uart_resources[] = {
432        {
433                .start = CNS3XXX_UART0_BASE,
434                .end   = CNS3XXX_UART0_BASE + SZ_4K - 1,
435                .flags    = IORESOURCE_MEM
436        },{
437                .start = CNS3XXX_UART2_BASE,
438                .end   = CNS3XXX_UART2_BASE + SZ_4K - 1,
439                .flags    = IORESOURCE_MEM
440        },{
441                .start = CNS3XXX_UART2_BASE,
442                .end   = CNS3XXX_UART2_BASE + SZ_4K - 1,
443                .flags    = IORESOURCE_MEM
444        },
445};
446
447static struct plat_serial8250_port laguna_uart_data[] = {
448        {
449                .mapbase        = (CNS3XXX_UART0_BASE),
450                .irq            = IRQ_CNS3XXX_UART0,
451                .iotype         = UPIO_MEM,
452                .flags          = UPF_BOOT_AUTOCONF | UPF_FIXED_TYPE | UPF_NO_TXEN_TEST | UPF_IOREMAP,
453                .regshift       = 2,
454                .uartclk        = 24000000,
455                .type           = PORT_16550A,
456        },{
457                .mapbase        = (CNS3XXX_UART1_BASE),
458                .irq            = IRQ_CNS3XXX_UART1,
459                .iotype         = UPIO_MEM,
460                .flags          = UPF_BOOT_AUTOCONF | UPF_FIXED_TYPE | UPF_NO_TXEN_TEST | UPF_IOREMAP,
461                .regshift       = 2,
462                .uartclk        = 24000000,
463                .type           = PORT_16550A,
464        },{
465                .mapbase        = (CNS3XXX_UART2_BASE),
466                .irq            = IRQ_CNS3XXX_UART2,
467                .iotype         = UPIO_MEM,
468                .flags          = UPF_BOOT_AUTOCONF | UPF_FIXED_TYPE | UPF_NO_TXEN_TEST | UPF_IOREMAP,
469                .regshift       = 2,
470                .uartclk        = 24000000,
471                .type           = PORT_16550A,
472        },
473        { },
474};
475
476static struct platform_device laguna_uart = {
477        .name     = "serial8250",
478        .id     = PLAT8250_DEV_PLATFORM,
479        .dev.platform_data  = laguna_uart_data,
480        .num_resources    = 3,
481        .resource   = laguna_uart_resources
482};
483
484/*
485 * USB
486 */
487static struct resource cns3xxx_usb_ehci_resources[] = {
488        [0] = {
489                .start = CNS3XXX_USB_BASE,
490                .end   = CNS3XXX_USB_BASE + SZ_16M - 1,
491                .flags = IORESOURCE_MEM,
492        },
493        [1] = {
494                .start = IRQ_CNS3XXX_USB_EHCI,
495                .flags = IORESOURCE_IRQ,
496        },
497};
498
499static u64 cns3xxx_usb_ehci_dma_mask = DMA_BIT_MASK(32);
500
501static int csn3xxx_usb_power_on(struct platform_device *pdev)
502{
503        /*
504         * EHCI and OHCI share the same clock and power,
505         * resetting twice would cause the 1st controller been reset.
506         * Therefore only do power up  at the first up device, and
507         * power down at the last down device.
508         *
509         * Set USB AHB INCR length to 16
510         */
511        if (atomic_inc_return(&usb_pwr_ref) == 1) {
512                cns3xxx_pwr_power_up(1 << PM_PLL_HM_PD_CTRL_REG_OFFSET_PLL_USB);
513                cns3xxx_pwr_clk_en(1 << PM_CLK_GATE_REG_OFFSET_USB_HOST);
514                cns3xxx_pwr_soft_rst(1 << PM_SOFT_RST_REG_OFFST_USB_HOST);
515                __raw_writel((__raw_readl(MISC_CHIP_CONFIG_REG) | (0X2 << 24)),
516                        MISC_CHIP_CONFIG_REG);
517        }
518
519        return 0;
520}
521
522static void csn3xxx_usb_power_off(struct platform_device *pdev)
523{
524        /*
525         * EHCI and OHCI share the same clock and power,
526         * resetting twice would cause the 1st controller been reset.
527         * Therefore only do power up  at the first up device, and
528         * power down at the last down device.
529         */
530        if (atomic_dec_return(&usb_pwr_ref) == 0)
531                cns3xxx_pwr_clk_dis(1 << PM_CLK_GATE_REG_OFFSET_USB_HOST);
532}
533
534static struct usb_ehci_pdata cns3xxx_usb_ehci_pdata = {
535        .power_on       = csn3xxx_usb_power_on,
536        .power_off      = csn3xxx_usb_power_off,
537};
538
539
540static struct platform_device cns3xxx_usb_ehci_device = {
541        .name          = "ehci-platform",
542        .num_resources = ARRAY_SIZE(cns3xxx_usb_ehci_resources),
543        .resource      = cns3xxx_usb_ehci_resources,
544        .dev           = {
545                .dma_mask          = &cns3xxx_usb_ehci_dma_mask,
546                .coherent_dma_mask = DMA_BIT_MASK(32),
547                .platform_data     = &cns3xxx_usb_ehci_pdata,
548        },
549};
550
551
552static struct resource cns3xxx_usb_ohci_resources[] = {
553        [0] = {
554                .start = CNS3XXX_USB_OHCI_BASE,
555                .end   = CNS3XXX_USB_OHCI_BASE + SZ_16M - 1,
556                .flags = IORESOURCE_MEM,
557        },
558        [1] = {
559                .start = IRQ_CNS3XXX_USB_OHCI,
560                .flags = IORESOURCE_IRQ,
561        },
562};
563
564static u64 cns3xxx_usb_ohci_dma_mask = DMA_BIT_MASK(32);
565
566static struct usb_ohci_pdata cns3xxx_usb_ohci_pdata = {
567        .num_ports      = 1,
568        .power_on       = csn3xxx_usb_power_on,
569        .power_off      = csn3xxx_usb_power_off,
570};
571
572static struct platform_device cns3xxx_usb_ohci_device = {
573        .name          = "ohci-platform",
574        .num_resources = ARRAY_SIZE(cns3xxx_usb_ohci_resources),
575        .resource      = cns3xxx_usb_ohci_resources,
576        .dev           = {
577                .dma_mask          = &cns3xxx_usb_ohci_dma_mask,
578                .coherent_dma_mask = DMA_BIT_MASK(32),
579                .platform_data     = &cns3xxx_usb_ohci_pdata,
580        },
581};
582
583static struct resource cns3xxx_usb_otg_resources[] = {
584        [0] = {
585                .start = CNS3XXX_USBOTG_BASE,
586                .end   = CNS3XXX_USBOTG_BASE + SZ_16M - 1,
587                .flags = IORESOURCE_MEM,
588        },
589        [1] = {
590                .start = IRQ_CNS3XXX_USB_OTG,
591                .flags = IORESOURCE_IRQ,
592        },
593};
594
595static u64 cns3xxx_usb_otg_dma_mask = DMA_BIT_MASK(32);
596
597static struct platform_device cns3xxx_usb_otg_device = {
598        .name          = "dwc_otg",
599        .num_resources = ARRAY_SIZE(cns3xxx_usb_otg_resources),
600        .resource      = cns3xxx_usb_otg_resources,
601        .dev           = {
602                .dma_mask          = &cns3xxx_usb_otg_dma_mask,
603                .coherent_dma_mask = DMA_BIT_MASK(32),
604        },
605};
606
607/*
608 * I2C
609 */
610static struct resource laguna_i2c_resource[] = {
611        {
612                .start    = CNS3XXX_SSP_BASE + 0x20,
613                .end      = 0x7100003f,
614                .flags    = IORESOURCE_MEM,
615        },{
616                .start    = IRQ_CNS3XXX_I2C,
617                .flags    = IORESOURCE_IRQ,
618        },
619};
620
621static struct platform_device laguna_i2c_controller = {
622        .name   = "cns3xxx-i2c",
623        .num_resources  = 2,
624        .resource = laguna_i2c_resource,
625};
626
627static struct memory_accessor *at24_mem_acc;
628
629static void at24_setup(struct memory_accessor *mem_acc, void *context)
630{
631        char buf[16];
632
633        at24_mem_acc = mem_acc;
634
635        /* Read MAC addresses */
636        if (at24_mem_acc->read(at24_mem_acc, buf, 0x100, 6) == 6)
637                memcpy(&laguna_net_data.hwaddr[0], buf, ETH_ALEN);
638        if (at24_mem_acc->read(at24_mem_acc, buf, 0x106, 6) == 6)
639                memcpy(&laguna_net_data.hwaddr[1], buf, ETH_ALEN);
640        if (at24_mem_acc->read(at24_mem_acc, buf, 0x10C, 6) == 6)
641                memcpy(&laguna_net_data.hwaddr[2], buf, ETH_ALEN);
642        if (at24_mem_acc->read(at24_mem_acc, buf, 0x112, 6) == 6)
643                memcpy(&laguna_net_data.hwaddr[3], buf, ETH_ALEN);
644
645        /* Read out Model Information */
646        if (at24_mem_acc->read(at24_mem_acc, buf, 0x130, 16) == 16)
647                memcpy(&laguna_info.model, buf, 16);
648        if (at24_mem_acc->read(at24_mem_acc, buf, 0x140, 1) == 1)
649                memcpy(&laguna_info.nor_flash_size, buf, 1);
650        if (at24_mem_acc->read(at24_mem_acc, buf, 0x141, 1) == 1)
651                memcpy(&laguna_info.spi_flash_size, buf, 1);
652        if (at24_mem_acc->read(at24_mem_acc, buf, 0x142, 4) == 4)
653                memcpy(&laguna_info.config_bitmap, buf, 4);
654        if (at24_mem_acc->read(at24_mem_acc, buf, 0x146, 4) == 4)
655                memcpy(&laguna_info.config2_bitmap, buf, 4);
656};
657
658static struct at24_platform_data laguna_eeprom_info = {
659        .byte_len = 1024,
660        .page_size = 16,
661        .flags = AT24_FLAG_READONLY,
662        .setup = at24_setup,
663};
664
665static struct pca953x_platform_data laguna_pca_data = {
666        .gpio_base = 100,
667};
668
669static struct pca953x_platform_data laguna_pca2_data = {
670        .gpio_base = 116,
671        .irq_base = -1,
672};
673
674static struct i2c_board_info __initdata laguna_i2c_devices[] = {
675        {
676                I2C_BOARD_INFO("pca9555", 0x23),
677                .platform_data = &laguna_pca_data,
678        },{
679                I2C_BOARD_INFO("pca9555", 0x27),
680                .platform_data = &laguna_pca2_data,
681        },{
682                I2C_BOARD_INFO("gsp", 0x29),
683        },{
684                I2C_BOARD_INFO ("24c08",0x50),
685                .platform_data = &laguna_eeprom_info,
686        },{
687                I2C_BOARD_INFO("ds1672", 0x68),
688        },
689};
690
691/*
692 * Watchdog
693 */
694
695static struct resource laguna_watchdog_resources[] = {
696        [0] = {
697                .start  = CNS3XXX_TC11MP_TWD_BASE + 0x100, // CPU0 watchdog
698                .end    = CNS3XXX_TC11MP_TWD_BASE + SZ_4K - 1,
699                .flags  = IORESOURCE_MEM,
700        },
701};
702
703static struct platform_device laguna_watchdog = {
704        .name           = "mpcore_wdt",
705        .id             = -1,
706        .num_resources  = ARRAY_SIZE(laguna_watchdog_resources),
707        .resource       = laguna_watchdog_resources,
708};
709
710
711
712/*
713 * GPS PPS
714 */
715static struct pps_gpio_platform_data laguna_pps_data = {
716        .gpio_pin = 0,
717        .gpio_label = "GPS_PPS",
718        .assert_falling_edge = 0,
719        .capture_clear = 0,
720};
721
722static struct platform_device laguna_pps_device = {
723        .name = "pps-gpio",
724        .id = -1,
725        .dev.platform_data = &laguna_pps_data,
726};
727
728
729static struct platform_device laguna_gpio_dev = {
730        .name = "GPIODEV",
731        .id = -1,
732};
733/*
734 * GPIO
735 */
736
737static struct gpio laguna_gpio_gw2391[] = {
738        {   0, GPIOF_IN           , "*GPS_PPS" },
739        {   1, GPIOF_IN           , "*GSC_IRQ#" },
740        {   2, GPIOF_IN           , "*USB_FAULT#" },
741        {   5, GPIOF_OUT_INIT_LOW , "*USB0_PCI_SEL" },
742        {   6, GPIOF_OUT_INIT_HIGH, "*USB_VBUS_EN" },
743        {   7, GPIOF_OUT_INIT_LOW , "*USB1_PCI_SEL" },
744        {   8, GPIOF_OUT_INIT_HIGH, "*PERST#" },
745        {   9, GPIOF_OUT_INIT_LOW , "*FP_SER_EN#" },
746        { 100, GPIOF_IN           , "*USER_PB#" },
747        { 103, GPIOF_OUT_INIT_HIGH, "*V5_EN" },
748        { 108, GPIOF_IN           , "DIO0" },
749        { 109, GPIOF_IN           , "DIO1" },
750        { 110, GPIOF_IN           , "DIO2" },
751        { 111, GPIOF_IN           , "DIO3" },
752        { 112, GPIOF_IN           , "DIO4" },
753};
754
755static struct gpio laguna_gpio_gw2388[] = {
756        {   0, GPIOF_IN           , "*GPS_PPS" },
757        {   1, GPIOF_IN           , "*GSC_IRQ#" },
758        {   3, GPIOF_IN           , "*USB_FAULT#" },
759        {   6, GPIOF_OUT_INIT_HIGH, "*USB_VBUS_EN" },
760        {   7, GPIOF_OUT_INIT_LOW , "*GSM_SEL0" },
761        {   8, GPIOF_OUT_INIT_LOW , "*GSM_SEL1" },
762        {   9, GPIOF_OUT_INIT_LOW , "*FP_SER_EN" },
763        { 100, GPIOF_OUT_INIT_HIGH, "*USER_PB#" },
764        { 108, GPIOF_IN           , "DIO0" },
765        { 109, GPIOF_IN           , "DIO1" },
766        { 110, GPIOF_IN           , "DIO2" },
767        { 111, GPIOF_IN           , "DIO3" },
768        { 112, GPIOF_IN           , "DIO4" },
769};
770
771static struct gpio laguna_gpio_gw2387[] = {
772        {   0, GPIOF_IN           , "*GPS_PPS" },
773        {   1, GPIOF_IN           , "*GSC_IRQ#" },
774        {   2, GPIOF_IN           , "*USB_FAULT#" },
775        {   5, GPIOF_OUT_INIT_LOW , "*USB_PCI_SEL" },
776        {   6, GPIOF_OUT_INIT_HIGH, "*USB_VBUS_EN" },
777        {   7, GPIOF_OUT_INIT_LOW , "*GSM_SEL0" },
778        {   8, GPIOF_OUT_INIT_LOW , "*GSM_SEL1" },
779        {   9, GPIOF_OUT_INIT_LOW , "*FP_SER_EN" },
780        { 100, GPIOF_IN           , "*USER_PB#" },
781        { 103, GPIOF_OUT_INIT_HIGH, "*V5_EN" },
782        { 108, GPIOF_IN           , "DIO0" },
783        { 109, GPIOF_IN           , "DIO1" },
784        { 110, GPIOF_IN           , "DIO2" },
785        { 111, GPIOF_IN           , "DIO3" },
786        { 112, GPIOF_IN           , "DIO4" },
787        { 113, GPIOF_IN           , "DIO5" },
788};
789
790static struct gpio laguna_gpio_gw2385[] = {
791        {   0, GPIOF_IN           , "*GSC_IRQ#" },
792        {   1, GPIOF_OUT_INIT_HIGH, "*USB_HST_VBUS_EN" },
793        {   2, GPIOF_IN           , "*USB_HST_FAULT#" },
794        {   5, GPIOF_IN           , "*USB_OTG_FAULT#" },
795        {   6, GPIOF_OUT_INIT_LOW , "*USB_HST_PCI_SEL" },
796        {   7, GPIOF_OUT_INIT_LOW , "*GSM_SEL0" },
797        {   8, GPIOF_OUT_INIT_LOW , "*GSM_SEL1" },
798        {   9, GPIOF_OUT_INIT_LOW , "*SER_EN" },
799        {  10, GPIOF_IN,            "*USER_PB#" },
800        {  11, GPIOF_OUT_INIT_HIGH, "*PERST#" },
801        { 100, GPIOF_IN           , "*USER_PB#" },
802        { 103, GPIOF_OUT_INIT_HIGH, "V5_EN" },
803};
804
805static struct gpio laguna_gpio_gw2384[] = {
806        {   0, GPIOF_IN           , "*GSC_IRQ#" },
807        {   1, GPIOF_OUT_INIT_HIGH, "*USB_HST_VBUS_EN" },
808        {   2, GPIOF_IN           , "*USB_HST_FAULT#" },
809        {   5, GPIOF_IN           , "*USB_OTG_FAULT#" },
810        {   6, GPIOF_OUT_INIT_LOW , "*USB_HST_PCI_SEL" },
811        {   7, GPIOF_OUT_INIT_LOW , "*GSM_SEL0" },
812        {   8, GPIOF_OUT_INIT_LOW , "*GSM_SEL1" },
813        {   9, GPIOF_OUT_INIT_LOW , "*FP_SER_EN" },
814        {  12, GPIOF_OUT_INIT_LOW , "J10_DIOLED0" },
815        {  13, GPIOF_OUT_INIT_HIGH, "*I2CMUX_RST#" },
816        {  14, GPIOF_OUT_INIT_LOW , "J10_DIOLED1" },
817        {  15, GPIOF_OUT_INIT_LOW , "J10_DIOLED2" },
818        { 100, GPIOF_IN           , "*USER_PB#" },
819        { 103, GPIOF_OUT_INIT_HIGH, "V5_EN" },
820        { 108, GPIOF_IN           , "J9_DIOGSC0" },
821};
822
823static struct gpio laguna_gpio_gw2383[] = {
824        {   0, GPIOF_IN           , "*GPS_PPS" },
825        {   1, GPIOF_IN           , "*GSC_IRQ#" },
826        {   2, GPIOF_OUT_INIT_HIGH, "*PCIE_RST#" },
827        {   3, GPIOF_IN           , "GPIO0" },
828        {   8, GPIOF_IN           , "GPIO1" },
829        { 100, GPIOF_IN           , "DIO0" },
830        { 101, GPIOF_IN           , "DIO1" },
831        { 108, GPIOF_IN           , "*USER_PB#" },
832};
833
834static struct gpio laguna_gpio_gw2382[] = {
835        {   0, GPIOF_IN           , "*GPS_PPS" },
836        {   1, GPIOF_IN           , "*GSC_IRQ#" },
837        {   2, GPIOF_OUT_INIT_HIGH, "*PCIE_RST#" },
838        {   3, GPIOF_IN           , "GPIO0" },
839        {   4, GPIOF_IN           , "GPIO1" },
840        {   9, GPIOF_OUT_INIT_HIGH, "*USB_VBUS_EN" },
841        {  10, GPIOF_OUT_INIT_HIGH, "*USB_PCI_SEL#" },
842        { 100, GPIOF_IN           , "DIO0" },
843        { 101, GPIOF_IN           , "DIO1" },
844        { 108, GPIOF_IN           , "*USER_PB#" },
845};
846
847static struct gpio laguna_gpio_gw2380[] = {
848        {   0, GPIOF_IN           , "*GPS_PPS" },
849        {   1, GPIOF_IN           , "*GSC_IRQ#" },
850        {   3, GPIOF_IN           , "GPIO0" },
851        {   8, GPIOF_IN           , "GPIO1" },
852        { 100, GPIOF_IN           , "DIO0" },
853        { 101, GPIOF_IN           , "DIO1" },
854        { 102, GPIOF_IN           , "DIO2" },
855        { 103, GPIOF_IN           , "DIO3" },
856        { 108, GPIOF_IN           , "*USER_PB#" },
857};
858
859
860/*
861 * Initialization
862 */
863
864static void __init laguna_init(void)
865{
866        platform_device_register(&laguna_watchdog);
867
868        platform_device_register(&laguna_i2c_controller);
869
870        i2c_register_board_info(0, laguna_i2c_devices,
871                        ARRAY_SIZE(laguna_i2c_devices));
872
873
874        pm_power_off = cns3xxx_power_off;
875}
876
877static struct map_desc laguna_io_desc[] __initdata = {
878        {
879                .virtual        = CNS3XXX_UART0_BASE_VIRT,
880                .pfn            = __phys_to_pfn(CNS3XXX_UART0_BASE),
881                .length         = SZ_4K,
882                .type           = MT_DEVICE,
883        },
884};
885
886
887static int laguna_register_gpio(struct gpio *array, size_t num)
888{
889
890        int i, err, ret;
891
892        ret = 0;
893        for (i = 0; i < num; i++, array++) {
894                const char *label = array->label;
895                if (label[0] == '*')
896                        label++;
897                err = gpio_request_one(array->gpio, array->flags, label);
898                if (err)
899                        ret = err;
900                else {
901                        err = gpio_export(array->gpio, array->label[0] != '*');
902                }
903        }
904        return ret;
905}
906
907 
908#define SPI_MEM_MAP_VALUE(reg_offset)           (*((u32 volatile *)(CNS3XXX_SSP_BASE_VIRT + reg_offset)))
909
910#define SPI_CONFIGURATION_REG                   SPI_MEM_MAP_VALUE(0x40)
911#define SPI_SERVICE_STATUS_REG                  SPI_MEM_MAP_VALUE(0x44)
912#define SPI_BIT_RATE_CONTROL_REG                SPI_MEM_MAP_VALUE(0x48)
913#define SPI_TRANSMIT_CONTROL_REG                SPI_MEM_MAP_VALUE(0x4C)
914#define SPI_TRANSMIT_BUFFER_REG                 SPI_MEM_MAP_VALUE(0x50)
915#define SPI_RECEIVE_CONTROL_REG                 SPI_MEM_MAP_VALUE(0x54)
916#define SPI_RECEIVE_BUFFER_REG                  SPI_MEM_MAP_VALUE(0x58)
917#define SPI_FIFO_TRANSMIT_CONFIG_REG            SPI_MEM_MAP_VALUE(0x5C)
918#define SPI_FIFO_TRANSMIT_CONTROL_REG           SPI_MEM_MAP_VALUE(0x60)
919#define SPI_FIFO_RECEIVE_CONFIG_REG             SPI_MEM_MAP_VALUE(0x64)
920#define SPI_INTERRUPT_STATUS_REG                SPI_MEM_MAP_VALUE(0x68)
921#define SPI_INTERRUPT_ENABLE_REG                SPI_MEM_MAP_VALUE(0x6C)
922
923#define SPI_TRANSMIT_BUFFER_REG_ADDR            (CNS3XXX_SSP_BASE +0x50)
924#define SPI_RECEIVE_BUFFER_REG_ADDR             (CNS3XXX_SSP_BASE +0x58)
925
926
927/* allow disabling of external isolated PCIe IRQs */
928static int cns3xxx_pciextirq = 1;
929static int __init cns3xxx_pciextirq_disable(char *s)
930{
931      cns3xxx_pciextirq = 0;
932      return 1;
933}
934__setup("noextirq", cns3xxx_pciextirq_disable);
935
936static int __init laguna_pcie_init_irq(void)
937{
938        int irqs[] = {
939                IRQ_CNS3XXX_EXTERNAL_PIN0,
940                IRQ_CNS3XXX_EXTERNAL_PIN1,
941                IRQ_CNS3XXX_EXTERNAL_PIN2,
942                154,
943        };
944
945        if (!machine_is_gw2388())
946                return 0;
947
948        /* Verify GPIOB[26:29] == 0001b indicating support for ext irqs */
949        if (cns3xxx_pciextirq) {
950        u32 __iomem *mem = (void __iomem *)(CNS3XXX_GPIOB_BASE_VIRT + 0x0004);
951        u32 reg = __raw_readl(mem);
952        reg >>=16;
953        switch (reg & 0x3c00) {
954        case 0x0400: /* GW2388-4-G (mod) */
955                printk(KERN_INFO "laguna: using isolated PCI interrupts:"
956                       " irq%d/irq%d/irq%d/irq%d\n",
957                       irqs[0], irqs[1], irqs[2], irqs[3]);
958                cns3xxx_pcie_set_irqs(0, irqs);
959                break;
960        case 0x0408: /* GW2388-4-H */
961        case 0x3c00: /* GW2388-4-G */
962        default:
963                printk(KERN_INFO "laguna: using shared PCI interrupts:"
964                       " irq%d/irq%d/irq%d/irq%d\n",
965                       IRQ_CNS3XXX_PCIE0_DEVICE, IRQ_CNS3XXX_PCIE0_DEVICE, IRQ_CNS3XXX_PCIE0_DEVICE, IRQ_CNS3XXX_PCIE0_DEVICE);
966                break; 
967        }
968       
969        }
970        return 0;
971}
972subsys_initcall(laguna_pcie_init_irq);
973
974
975static void __init laguna_map_io(void)
976{
977        cns3xxx_common_init();
978        iotable_init(laguna_io_desc, ARRAY_SIZE(laguna_io_desc));
979        laguna_early_serial_setup();
980}
981
982extern void __init cns3xxx_gpio_init(int gpio_base, int ngpio,
983        u32 base, int irq, int secondary_irq_base);
984
985static int __init laguna_model_setup(void)
986{
987        u32 __iomem *mem;
988        u32 reg;
989
990        printk("Running on Gateworks Laguna %s\n", laguna_info.model);
991
992        cns3xxx_gpio_init( 0, 32, CNS3XXX_GPIOA_BASE_VIRT, IRQ_CNS3XXX_GPIOA,
993                NR_IRQS_CNS3XXX);
994        /*
995         * If pcie external interrupts are supported and desired
996         * configure IRQ types and configure pin function.
997         * Note that cns3xxx_pciextirq is enabled by default, but can be
998         * unset via the 'noextirq' kernel param or by laguna_pcie_init() if
999         * the baseboard model does not support this hardware feature.
1000         */
1001        if (cns3xxx_pciextirq) {
1002                mem = (void __iomem *)(CNS3XXX_MISC_BASE_VIRT + 0x0018);
1003                reg = __raw_readl(mem);
1004                /* GPIO26 is gpio, EXT_INT[0:2] not gpio func */
1005                reg &= ~0x3c000000;
1006                reg |= 0x38000000;
1007                __raw_writel(reg, mem);
1008
1009                cns3xxx_gpio_init(32, 32, CNS3XXX_GPIOB_BASE_VIRT,
1010                                  IRQ_CNS3XXX_GPIOB, NR_IRQS_CNS3XXX + 32);
1011
1012                irq_set_irq_type(154, IRQ_TYPE_LEVEL_LOW);
1013                irq_set_irq_type(93, IRQ_TYPE_LEVEL_HIGH);
1014                irq_set_irq_type(94, IRQ_TYPE_LEVEL_HIGH);
1015                irq_set_irq_type(95, IRQ_TYPE_LEVEL_HIGH);
1016        } else {
1017                cns3xxx_gpio_init(32, 32, CNS3XXX_GPIOB_BASE_VIRT,
1018                                  IRQ_CNS3XXX_GPIOB, NR_IRQS_CNS3XXX + 32);
1019        }
1020
1021
1022        if (strncmp(laguna_info.model, "GW", 2) == 0) {
1023                printk("CONFIG BITMAP = 0x%08X\n",laguna_info.config_bitmap);
1024                if (laguna_info.config_bitmap & ETH0_LOAD)
1025                        laguna_net_data.ports |= BIT(0);
1026                printk(KERN_INFO "detecting ETH\n");
1027                if (strncmp(laguna_info.model, "GW2388", 6) == 0 || strncmp(laguna_info.model, "GW2389", 6) == 0)
1028                {
1029                if (laguna_info.config_bitmap & ETH1_LOAD)
1030                        laguna_net_data.ports |= BIT(1);
1031                if (laguna_info.config_bitmap & ETH2_LOAD)
1032                        laguna_net_data.ports |= BIT(2);
1033                }
1034                printk(KERN_INFO "registering ETH\n");
1035                if (laguna_net_data.ports)
1036                        platform_device_register(&laguna_net_device);
1037
1038                printk(KERN_INFO "registering AHCI\n");
1039                if (laguna_info.config_bitmap & (SATA0_LOAD | SATA1_LOAD))
1040                        cns3xxx_ahci_init();
1041
1042
1043                if (strncmp(laguna_info.model, "GW2380", 6) == 0)
1044                {
1045                printk(KERN_INFO "check USB0\n");
1046                if (laguna_info.config_bitmap & (USB0_LOAD)) {
1047                        printk(KERN_INFO "register USB0\n");
1048                        cns3xxx_pwr_power_up(1 << PM_PLL_HM_PD_CTRL_REG_OFFSET_PLL_USB);
1049
1050                        /* DRVVBUS pins share with GPIOA */
1051                        mem = (void __iomem *)(CNS3XXX_MISC_BASE_VIRT + 0x0014);
1052                        reg = __raw_readl(mem);
1053                        reg |= 0x8;
1054                        __raw_writel(reg, mem);
1055
1056                        /* Enable OTG */
1057                        mem = (void __iomem *)(CNS3XXX_MISC_BASE_VIRT + 0x0808);
1058                        reg = __raw_readl(mem);
1059                        reg &= ~(1 << 10);
1060                        __raw_writel(reg, mem);
1061
1062                        platform_device_register(&cns3xxx_usb_otg_device);
1063                }
1064
1065                printk(KERN_INFO "check USB1\n");
1066                if (laguna_info.config_bitmap & (USB1_LOAD)) {
1067                        printk(KERN_INFO "register USB1\n");
1068                        platform_device_register(&cns3xxx_usb_ehci_device);
1069                        platform_device_register(&cns3xxx_usb_ohci_device);
1070                }
1071                }else{
1072                if (laguna_info.config_bitmap & (USB0_LOAD)) {
1073
1074                        printk(KERN_EMERG "power up USB0\n");
1075                        cns3xxx_pwr_power_up(1 << PM_PLL_HM_PD_CTRL_REG_OFFSET_PLL_USB);
1076
1077                        /* DRVVBUS pins share with GPIOA */
1078                        mem = (void __iomem *)(CNS3XXX_MISC_BASE_VIRT + 0x0014);
1079                        reg = __raw_readl(mem);
1080                        reg |= 0x8;
1081                        __raw_writel(reg, mem);
1082
1083                        /* Enable OTG */
1084                        mem = (void __iomem *)(CNS3XXX_MISC_BASE_VIRT + 0x0808);
1085                        reg = __raw_readl(mem);
1086                        reg &= ~(1 << 10);
1087                        __raw_writel(reg, mem);
1088
1089                        platform_device_register(&cns3xxx_usb_otg_device);
1090                }
1091
1092                if (laguna_info.config_bitmap & (USB1_LOAD)) {
1093                        printk(KERN_EMERG "power up ehci/ohci\n");
1094                        platform_device_register(&cns3xxx_usb_ehci_device);
1095                        platform_device_register(&cns3xxx_usb_ohci_device);
1096                }
1097                }
1098
1099
1100                if (laguna_info.config_bitmap & (SD_LOAD))
1101                {
1102                        printk(KERN_EMERG "init sdhci\n");
1103                        cns3xxx_sdhci_init();
1104                }
1105                printk(KERN_INFO "check UART\n");
1106                if (laguna_info.config_bitmap & (UART0_LOAD))
1107                        laguna_uart.num_resources = 1;
1108                if (laguna_info.config_bitmap & (UART1_LOAD))
1109                        laguna_uart.num_resources = 2;
1110                if (laguna_info.config_bitmap & (UART2_LOAD))
1111                        laguna_uart.num_resources = 3;
1112                printk(KERN_INFO "register %d UART(s) \n",laguna_uart.num_resources);
1113                platform_device_register(&laguna_uart);
1114
1115                printk(KERN_EMERG "notflash size %d\n",laguna_info.nor_flash_size);
1116                if ((laguna_info.config2_bitmap & (NOR_FLASH_LOAD)) && (
1117                strncmp(laguna_info.model, "GW2388", 6) == 0 ||
1118                strncmp(laguna_info.model, "GW2387", 6) == 0 ||
1119                strncmp(laguna_info.model, "GW2389", 6) == 0 ||
1120                strncmp(laguna_info.model, "GW2391", 6) == 0 ||
1121                strncmp(laguna_info.model, "GW2393", 6) == 0)) {
1122                        printk(KERN_EMERG "detecting NOR FLASH\n");
1123//                      if (laguna_info.nor_flash_size < 1 || laguna_info.nor_flash_size > 5)
1124//                          laguna_info.nor_flash_size = 2; //guess default for wrong config
1125                        laguna_norflash_partitions[2].size = SZ_16M - SZ_256K - SZ_128K  - SZ_128K;
1126                        laguna_norflash_resource.end = CNS3XXX_FLASH_BASE + SZ_16M - 1;
1127                        switch (laguna_info.nor_flash_size) {
1128                                case 1:
1129                                        laguna_norflash_partitions[2].size = SZ_8M - SZ_256K - SZ_128K  - SZ_128K;
1130                                        laguna_norflash_resource.end = CNS3XXX_FLASH_BASE + SZ_8M - 1;
1131                                break;
1132                                case 2:
1133                                        laguna_norflash_partitions[2].size = SZ_16M - SZ_256K - SZ_128K  - SZ_128K;
1134                                        laguna_norflash_resource.end = CNS3XXX_FLASH_BASE + SZ_16M - 1;
1135                                break;
1136                                case 3:
1137                                        laguna_norflash_partitions[2].size = SZ_32M - SZ_256K - SZ_128K  - SZ_128K;
1138                                        laguna_norflash_resource.end = CNS3XXX_FLASH_BASE + SZ_32M - 1;
1139                                break;
1140                                case 4:
1141                                        laguna_norflash_partitions[2].size = SZ_64M - SZ_256K - SZ_128K  - SZ_128K;
1142                                        laguna_norflash_resource.end = CNS3XXX_FLASH_BASE + SZ_64M - 1;
1143                                break;
1144                                case 5:
1145                                        laguna_norflash_partitions[2].size = SZ_128M - SZ_256K - SZ_128K  - SZ_128K;
1146                                        laguna_norflash_resource.end = CNS3XXX_FLASH_BASE + SZ_128M - 1;
1147                                break;
1148                        }
1149                        unsigned int flashsize = laguna_norflash_partitions[2].size + SZ_256K + SZ_128K + SZ_128K;
1150                        unsigned char *buf = (unsigned char *)ioremap(laguna_norflash_resource.start,laguna_norflash_resource.end - laguna_norflash_resource.start + 1);
1151                        unsigned int offset=0;
1152                        int tmplen;
1153                        int filesyssize=0;
1154                        int erasesize=0x20000;
1155                        while(offset<laguna_norflash_resource.end)
1156                        {
1157                        if (*((__u32 *) buf) == SQUASHFS_MAGIC)
1158                        {
1159                        printk(KERN_EMERG "found squashfs on %X\n",offset);
1160                        struct squashfs_super_block *sb = (struct squashfs_super_block *) buf;
1161                        filesyssize = sb->bytes_used;
1162                        tmplen = offset + filesyssize;
1163                        tmplen +=  (erasesize - 1);
1164                        tmplen &= ~(erasesize - 1);
1165                        filesyssize = tmplen - offset;
1166                        laguna_norflash_partitions[3].offset = offset;
1167                        laguna_norflash_partitions[3].size = filesyssize;
1168                        laguna_norflash_partitions[4].offset = offset + filesyssize;
1169                        laguna_norflash_partitions[4].size = (flashsize- SZ_128K) - laguna_norflash_partitions[4].offset;
1170                        laguna_norflash_partitions[5].offset = (flashsize - SZ_128K);
1171                        laguna_norflash_partitions[5].size = SZ_128K;
1172                        break;
1173                        }
1174                        buf+=0x1000;
1175                        offset+=0x1000;
1176                        }
1177                        iounmap(buf);
1178                        platform_device_register(&laguna_norflash_device);
1179                }
1180
1181                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)) {
1182                //      printk(KERN_EMERG "detecting SPI FLASH\n");
1183                        SPI_CONFIGURATION_REG = 0x40000000;
1184                        HAL_MISC_ENABLE_SPI_SERIAL_FLASH_BANK_ACCESS();
1185                        laguna_spiflash_partitions[2].size              = SZ_16M - SZ_512K;
1186#if 0
1187                        switch (laguna_info.spi_flash_size) {
1188                                case 1:
1189                                        laguna_spiflash_partitions[2].size              = SZ_4M - SZ_512K;
1190                                break;
1191                                case 2:
1192                                        laguna_spiflash_partitions[2].size              = SZ_8M - SZ_512K;
1193                                break;
1194                                case 3:
1195                                        laguna_spiflash_partitions[2].size              = SZ_16M - SZ_512K;
1196                                break;
1197                                case 4:
1198                                        laguna_spiflash_partitions[2].size              = SZ_32M - SZ_512K;
1199                                break;
1200                                case 5:
1201                                        laguna_spiflash_partitions[2].size              = SZ_64M - SZ_512K;
1202                                break;
1203                        }
1204#endif
1205                        unsigned int flashsize = laguna_spiflash_partitions[2].size + SZ_512K;
1206                        unsigned char *buf = (unsigned char *)ioremap(CNS3XXX_SPI_FLASH_BASE,SZ_16M-1);
1207                //      unsigned char *buf = (unsigned char *)CNS3XXX_SPI_FLASH_BASE;
1208                        unsigned int offset=0;
1209                        int tmplen;
1210                        int filesyssize=0;
1211                        int erasesize=0x40000;
1212                        while(offset<SZ_8M)
1213                        {
1214                        if (*((__u32 *) buf) == SQUASHFS_MAGIC)
1215                        {
1216                        struct squashfs_super_block *sb;
1217                        char *block = vmalloc(0x40000);
1218                        memcpy(block,buf,0x40000);
1219                        sb = (struct squashfs_super_block*)block;
1220                        printk(KERN_EMERG "found squashfs @0x%08X magic=0x%08X\n",offset,*((__u32 *) buf));
1221                        filesyssize = sb->bytes_used;
1222                        vfree(block);
1223                        tmplen = offset + filesyssize;
1224                        tmplen +=  (erasesize - 1);
1225                        tmplen &= ~(erasesize - 1);
1226                        filesyssize = tmplen - offset;
1227                        laguna_spiflash_partitions[3].offset = offset;
1228                        laguna_spiflash_partitions[3].size = filesyssize;
1229                        laguna_spiflash_partitions[4].offset = offset + filesyssize;
1230                        laguna_spiflash_partitions[4].size = (flashsize- SZ_256K) - laguna_spiflash_partitions[4].offset;
1231                        laguna_spiflash_partitions[5].offset = (flashsize - SZ_256K);
1232                        laguna_spiflash_partitions[5].size = SZ_256K;
1233                        break;
1234                        }
1235                        buf+=0x1000;
1236                        offset+=0x1000;
1237                        }
1238                        iounmap(buf);
1239                        HAL_MISC_DISABLE_SPI_SERIAL_FLASH_BANK_ACCESS();
1240
1241                if (strncmp(laguna_info.model, "GW2380", 6) == 0)
1242                        spi_register_board_info(laguna_spi_devices, ARRAY_SIZE(laguna_spi_devices));
1243
1244                }
1245
1246                if (laguna_info.config_bitmap & (SPI0_LOAD | SPI1_LOAD))
1247                {
1248                        platform_device_register(&laguna_spi_controller_device);
1249                }
1250
1251                if (laguna_info.config2_bitmap & GPS_LOAD)
1252                        platform_device_register(&laguna_pps_device);
1253
1254                /*
1255                 *      Do any model specific setup not known by the bitmap by matching
1256                 *  the first 6 characters of the model name
1257                 */
1258
1259
1260                if ( (strncmp(laguna_info.model, "GW2388", 6) == 0)
1261                  || (strncmp(laguna_info.model, "GW2389", 6) == 0) )
1262                {
1263                        // configure GPIO's
1264                        laguna_register_gpio(ARRAY_AND_SIZE(laguna_gpio_gw2388));
1265                        // configure LED's
1266                        laguna_gpio_leds_data.num_leds = 2;
1267                } else if (strncmp(laguna_info.model, "GW2387", 6) == 0) {
1268                        // configure GPIO's
1269                        laguna_register_gpio(ARRAY_AND_SIZE(laguna_gpio_gw2387));
1270                        // configure LED's
1271                        laguna_gpio_leds_data.num_leds = 2;
1272                } else if (strncmp(laguna_info.model, "GW2385", 6) == 0) {
1273                        // configure GPIO's
1274                        laguna_register_gpio(ARRAY_AND_SIZE(laguna_gpio_gw2385));
1275                        // configure LED's
1276                        laguna_gpio_leds[0].gpio = 115;
1277                        laguna_gpio_leds[1].gpio = 12;
1278                        laguna_gpio_leds[1].name = "red";
1279                        laguna_gpio_leds[1].active_low = 0,
1280                        laguna_gpio_leds[2].gpio = 14;
1281                        laguna_gpio_leds[2].name = "green";
1282                        laguna_gpio_leds[2].active_low = 0,
1283                        laguna_gpio_leds[3].gpio = 15;
1284                        laguna_gpio_leds[3].name = "blue";
1285                        laguna_gpio_leds[3].active_low = 0,
1286                        laguna_gpio_leds_data.num_leds = 4;
1287                } else if (strncmp(laguna_info.model, "GW2384", 6) == 0) {
1288                        // configure GPIO's
1289                        laguna_register_gpio(ARRAY_AND_SIZE(laguna_gpio_gw2384));
1290                        // configure LED's
1291                        laguna_gpio_leds_data.num_leds = 1;
1292                } else if (strncmp(laguna_info.model, "GW2383", 6) == 0) {
1293                        // configure GPIO's
1294                        laguna_register_gpio(ARRAY_AND_SIZE(laguna_gpio_gw2383));
1295                        // configure LED's
1296                        laguna_gpio_leds[0].gpio = 107;
1297                        laguna_gpio_leds_data.num_leds = 1;
1298                } else if (strncmp(laguna_info.model, "GW2382", 6) == 0) {
1299                        // configure GPIO's
1300                        laguna_register_gpio(ARRAY_AND_SIZE(laguna_gpio_gw2382));
1301                        // configure LED's
1302                        laguna_gpio_leds[0].gpio = 107;
1303                        laguna_gpio_leds_data.num_leds = 1;
1304                } else if (strncmp(laguna_info.model, "GW2380", 6) == 0) {
1305                        // configure GPIO's
1306                        laguna_register_gpio(ARRAY_AND_SIZE(laguna_gpio_gw2380));
1307                        // configure LED's
1308                        laguna_gpio_leds[0].gpio = 107;
1309                        laguna_gpio_leds[1].gpio = 106;
1310                        laguna_gpio_leds_data.num_leds = 2;
1311                } else if (strncmp(laguna_info.model, "GW2391", 6) == 0 || strncmp(laguna_info.model, "GW2393", 6) == 0) {
1312                        // configure GPIO's
1313                        laguna_register_gpio(ARRAY_AND_SIZE(laguna_gpio_gw2391));
1314                        // configure LED's
1315                        laguna_gpio_leds_data.num_leds = 2;
1316                }
1317                platform_device_register(&laguna_gpio_leds_device);
1318                platform_device_register(&laguna_gpio_dev);
1319        } else {
1320                // Do some defaults here, not sure what yet
1321        }
1322        return 0;
1323}
1324
1325late_initcall(laguna_model_setup);
1326
1327MACHINE_START(GW2388, "Gateworks Corporation Laguna Platform")
1328        .atag_offset    = 0x100,
1329        .smp            = smp_ops(cns3xxx_smp_ops),
1330//      .nr_irqs        = NR_IRQS_CNS3XXX,
1331        .map_io         = laguna_map_io,
1332        .init_irq       = cns3xxx_init_irq,
1333        .init_time      = cns3xxx_timer_init,
1334        .init_machine   = laguna_init,
1335        .init_late      = cns3xxx_pcie_init_late,
1336        .restart        = cns3xxx_restart,
1337MACHINE_END
Note: See TracBrowser for help on using the repository browser.