arm: tegra: fuse: replace globals with functions
[linux-3.10.git] / arch / arm / mach-shmobile / board-bonito.c
index d78008b..70d992c 100644 (file)
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
+#include <linux/pinctrl/machine.h>
 #include <linux/platform_device.h>
 #include <linux/gpio.h>
+#include <linux/regulator/fixed.h>
+#include <linux/regulator/machine.h>
+#include <linux/smsc911x.h>
+#include <linux/videodev2.h>
 #include <mach/common.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
@@ -33,6 +38,8 @@
 #include <asm/mach/time.h>
 #include <asm/hardware/cache-l2x0.h>
 #include <mach/r8a7740.h>
+#include <mach/irqs.h>
+#include <video/sh_mobile_lcdc.h>
 
 /*
  * CS  Address         device                  note
  */
 
 /*
+ * LCDC0 (CN3/CN4/CN7)
+ *
+ * S38.1 = OFF
+ * S38.2 = OFF
+ */
+
+/* Dummy supplies, where voltage doesn't matter */
+static struct regulator_consumer_supply dummy_supplies[] = {
+       REGULATOR_SUPPLY("vddvario", "smsc911x"),
+       REGULATOR_SUPPLY("vdd33a", "smsc911x"),
+};
+
+/*
  * FPGA
  */
+#define IRQSR0         0x0020
+#define IRQSR1         0x0022
+#define IRQMR0         0x0030
+#define IRQMR1         0x0032
 #define BUSSWMR1       0x0070
 #define BUSSWMR2       0x0072
 #define BUSSWMR3       0x0074
 #define BUSSWMR4       0x0076
 
+#define LCDCR          0x10B4
+#define DEVRSTCR1      0x10D0
+#define DEVRSTCR2      0x10D2
 #define A1MDSR         0x10E0
 #define BVERR          0x1100
+
+/* FPGA IRQ */
+#define FPGA_IRQ_BASE          (512)
+#define FPGA_IRQ0              (FPGA_IRQ_BASE)
+#define FPGA_IRQ1              (FPGA_IRQ_BASE + 16)
+#define FPGA_ETH_IRQ           (FPGA_IRQ0 + 15)
 static u16 bonito_fpga_read(u32 offset)
 {
-       return __raw_readw(0xf0003000 + offset);
+       return __raw_readw(IOMEM(0xf0003000) + offset);
 }
 
 static void bonito_fpga_write(u32 offset, u16 val)
 {
-       __raw_writew(val, 0xf0003000 + offset);
+       __raw_writew(val, IOMEM(0xf0003000) + offset);
+}
+
+static void bonito_fpga_irq_disable(struct irq_data *data)
+{
+       unsigned int irq = data->irq;
+       u32 addr = (irq < 1016) ? IRQMR0 : IRQMR1;
+       int shift = irq % 16;
+
+       bonito_fpga_write(addr, bonito_fpga_read(addr) | (1 << shift));
+}
+
+static void bonito_fpga_irq_enable(struct irq_data *data)
+{
+       unsigned int irq = data->irq;
+       u32 addr = (irq < 1016) ? IRQMR0 : IRQMR1;
+       int shift = irq % 16;
+
+       bonito_fpga_write(addr, bonito_fpga_read(addr) & ~(1 << shift));
+}
+
+static struct irq_chip bonito_fpga_irq_chip __read_mostly = {
+       .name           = "bonito FPGA",
+       .irq_mask       = bonito_fpga_irq_disable,
+       .irq_unmask     = bonito_fpga_irq_enable,
+};
+
+static void bonito_fpga_irq_demux(unsigned int irq, struct irq_desc *desc)
+{
+       u32 val =  bonito_fpga_read(IRQSR1) << 16 |
+                  bonito_fpga_read(IRQSR0);
+       u32 mask = bonito_fpga_read(IRQMR1) << 16 |
+                  bonito_fpga_read(IRQMR0);
+
+       int i;
+
+       val &= ~mask;
+
+       for (i = 0; i < 32; i++) {
+               if (!(val & (1 << i)))
+                       continue;
+
+               generic_handle_irq(FPGA_IRQ_BASE + i);
+       }
+}
+
+static void bonito_fpga_init(void)
+{
+       int i;
+
+       bonito_fpga_write(IRQMR0, 0xffff); /* mask all */
+       bonito_fpga_write(IRQMR1, 0xffff); /* mask all */
+
+       /* Device reset */
+       bonito_fpga_write(DEVRSTCR1,
+                  (1 << 2));   /* Eth */
+
+       /* FPGA irq require special handling */
+       for (i = FPGA_IRQ_BASE; i < FPGA_IRQ_BASE + 32; i++) {
+               irq_set_chip_and_handler_name(i, &bonito_fpga_irq_chip,
+                                             handle_level_irq, "level");
+               set_irq_flags(i, IRQF_VALID); /* yuck */
+       }
+
+       irq_set_chained_handler(evt2irq(0x0340), bonito_fpga_irq_demux);
+       irq_set_irq_type(evt2irq(0x0340), IRQ_TYPE_LEVEL_LOW);
 }
 
 /*
@@ -135,6 +233,104 @@ static int __init pmic_init(void)
 device_initcall(pmic_init);
 
 /*
+ * LCDC0
+ */
+static const struct fb_videomode lcdc0_mode = {
+       .name           = "WVGA Panel",
+       .xres           = 800,
+       .yres           = 480,
+       .left_margin    = 88,
+       .right_margin   = 40,
+       .hsync_len      = 128,
+       .upper_margin   = 20,
+       .lower_margin   = 5,
+       .vsync_len      = 5,
+       .sync           = 0,
+};
+
+static struct sh_mobile_lcdc_info lcdc0_info = {
+       .clock_source   = LCDC_CLK_BUS,
+       .ch[0] = {
+               .chan                   = LCDC_CHAN_MAINLCD,
+               .fourcc = V4L2_PIX_FMT_RGB565,
+               .interface_type         = RGB24,
+               .clock_divider          = 5,
+               .flags                  = 0,
+               .lcd_modes              = &lcdc0_mode,
+               .num_modes              = 1,
+               .panel_cfg = {
+                       .width  = 152,
+                       .height = 91,
+               },
+       },
+};
+
+static struct resource lcdc0_resources[] = {
+       [0] = {
+               .name   = "LCDC0",
+               .start  = 0xfe940000,
+               .end    = 0xfe943fff,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = intcs_evt2irq(0x0580),
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device lcdc0_device = {
+       .name           = "sh_mobile_lcdc_fb",
+       .id             = 0,
+       .resource       = lcdc0_resources,
+       .num_resources  = ARRAY_SIZE(lcdc0_resources),
+       .dev    = {
+               .platform_data  = &lcdc0_info,
+               .coherent_dma_mask = ~0,
+       },
+};
+
+static const struct pinctrl_map lcdc0_pinctrl_map[] = {
+       /* LCD0 */
+       PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_lcdc_fb.0", "pfc-r8a7740",
+                                 "lcd0_data24_1", "lcd0"),
+       PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_lcdc_fb.0", "pfc-r8a7740",
+                                 "lcd0_lclk_1", "lcd0"),
+       PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_lcdc_fb.0", "pfc-r8a7740",
+                                 "lcd0_sync", "lcd0"),
+};
+
+/*
+ * SMSC 9221
+ */
+static struct resource smsc_resources[] = {
+       [0] = {
+               .start          = 0x18010000,
+               .end            = 0x18011000 - 1,
+               .flags          = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start          = FPGA_ETH_IRQ,
+               .flags          = IORESOURCE_IRQ,
+       },
+};
+
+static struct smsc911x_platform_config smsc_platdata = {
+       .flags          = SMSC911X_USE_16BIT,
+       .phy_interface  = PHY_INTERFACE_MODE_MII,
+       .irq_polarity   = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+       .irq_type       = SMSC911X_IRQ_TYPE_PUSH_PULL,
+};
+
+static struct platform_device smsc_device = {
+       .name           = "smsc911x",
+       .dev  = {
+               .platform_data = &smsc_platdata,
+       },
+       .resource       = smsc_resources,
+       .num_resources  = ARRAY_SIZE(smsc_resources),
+};
+
+/*
  * core board devices
  */
 static struct platform_device *bonito_core_devices[] __initdata = {
@@ -144,34 +340,14 @@ static struct platform_device *bonito_core_devices[] __initdata = {
  * base board devices
  */
 static struct platform_device *bonito_base_devices[] __initdata = {
+       &lcdc0_device,
+       &smsc_device,
 };
 
 /*
  * map I/O
  */
 static struct map_desc bonito_io_desc[] __initdata = {
-        /*
-         * for CPGA/INTC/PFC
-         * 0xe6000000-0xefffffff -> 0xe6000000-0xefffffff
-         */
-       {
-               .virtual        = 0xe6000000,
-               .pfn            = __phys_to_pfn(0xe6000000),
-               .length         = 160 << 20,
-               .type           = MT_DEVICE_NONSHARED
-       },
-#ifdef CONFIG_CACHE_L2X0
-       /*
-        * for l2x0_init()
-        * 0xf0100000-0xf0101000 -> 0xf0002000-0xf0003000
-        */
-       {
-               .virtual        = 0xf0002000,
-               .pfn            = __phys_to_pfn(0xf0100000),
-               .length         = PAGE_SIZE,
-               .type           = MT_DEVICE_NONSHARED
-       },
-#endif
        /*
         * for FPGA (0x1800000-0x19ffffff)
         * 0x18000000-0x18002000 -> 0xf0003000-0xf0005000
@@ -186,11 +362,8 @@ static struct map_desc bonito_io_desc[] __initdata = {
 
 static void __init bonito_map_io(void)
 {
+       r8a7740_map_io();
        iotable_init(bonito_io_desc, ARRAY_SIZE(bonito_io_desc));
-
-       /* setup early devices and console here as well */
-       r8a7740_add_early_devices();
-       shmobile_setup_console();
 }
 
 /*
@@ -199,11 +372,17 @@ static void __init bonito_map_io(void)
 #define BIT_ON(sw, bit)                (sw & (1 << bit))
 #define BIT_OFF(sw, bit)       (!(sw & (1 << bit)))
 
+#define VCCQ1CR                IOMEM(0xE6058140)
+#define VCCQ1LCDCR     IOMEM(0xE6058186)
+
 static void __init bonito_init(void)
 {
        u16 val;
 
+       regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies));
+
        r8a7740_pinmux_init();
+       bonito_fpga_init();
 
        pmic_settings = pmic_do_2A;
 
@@ -213,7 +392,7 @@ static void __init bonito_init(void)
 
 #ifdef CONFIG_CACHE_L2X0
        /* Early BRESP enable, Shared attribute override enable, 32K*8way */
-       l2x0_init(__io(0xf0002000), 0x40440000, 0x82000fff);
+       l2x0_init(IOMEM(0xf0002000), 0x40440000, 0x82000fff);
 #endif
 
        r8a7740_add_standard_devices();
@@ -224,9 +403,8 @@ static void __init bonito_init(void)
        /*
         * base board settings
         */
-       gpio_request(GPIO_PORT176, NULL);
-       gpio_direction_input(GPIO_PORT176);
-       if (!gpio_get_value(GPIO_PORT176)) {
+       gpio_request_one(176, GPIOF_IN, NULL);
+       if (!gpio_get_value(176)) {
                u16 bsw2;
                u16 bsw3;
                u16 bsw4;
@@ -258,12 +436,32 @@ static void __init bonito_init(void)
                        gpio_request(GPIO_FN_SCIFA5_RXD_PORT92, NULL);
                }
 
+               /*
+                * LCDC0 (CN3)
+                */
+               if (BIT_ON(bsw2, 3) &&  /* S38.1 = OFF */
+                   BIT_ON(bsw2, 2)) {  /* S38.2 = OFF */
+                       pinctrl_register_mappings(lcdc0_pinctrl_map,
+                                                 ARRAY_SIZE(lcdc0_pinctrl_map));
+                       gpio_request(GPIO_FN_LCDC0_SELECT, NULL);
+
+                       gpio_request_one(61, GPIOF_OUT_INIT_HIGH,
+                                        NULL); /* LCDDON */
+
+                       /* backlight on */
+                       bonito_fpga_write(LCDCR, 1);
+
+                       /*  drivability Max */
+                       __raw_writew(0x00FF , VCCQ1LCDCR);
+                       __raw_writew(0xFFFF , VCCQ1CR);
+               }
+
                platform_add_devices(bonito_base_devices,
                                     ARRAY_SIZE(bonito_base_devices));
        }
 }
 
-static void __init bonito_timer_init(void)
+static void __init bonito_earlytimer_init(void)
 {
        u16 val;
        u8 md_ck = 0;
@@ -278,17 +476,20 @@ static void __init bonito_timer_init(void)
                md_ck |= MD_CK0;
 
        r8a7740_clock_init(md_ck);
-       shmobile_timer.init();
+       shmobile_earlytimer_init();
 }
 
-struct sys_timer bonito_timer = {
-       .init   = bonito_timer_init,
-};
+static void __init bonito_add_early_devices(void)
+{
+       r8a7740_add_early_devices();
+}
 
 MACHINE_START(BONITO, "bonito")
        .map_io         = bonito_map_io,
+       .init_early     = bonito_add_early_devices,
        .init_irq       = r8a7740_init_irq,
        .handle_irq     = shmobile_handle_irq_intc,
        .init_machine   = bonito_init,
-       .timer          = &bonito_timer,
+       .init_late      = shmobile_init_late,
+       .init_time      = bonito_earlytimer_init,
 MACHINE_END