]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - arch/arm/mach-exynos/common.c
Merge tag 'dt' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
[karo-tx-linux.git] / arch / arm / mach-exynos / common.c
index 4af8284f35974c727887d735c346821802f94ca4..3f257e76bfdefef11d80beb9894c78f762ebd175 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/sched.h>
 #include <linux/serial_core.h>
 #include <linux/of.h>
+#include <linux/of_fdt.h>
 #include <linux/of_irq.h>
 #include <linux/export.h>
 #include <linux/irqdomain.h>
@@ -58,12 +59,14 @@ static const char name_exynos4210[] = "EXYNOS4210";
 static const char name_exynos4212[] = "EXYNOS4212";
 static const char name_exynos4412[] = "EXYNOS4412";
 static const char name_exynos5250[] = "EXYNOS5250";
+static const char name_exynos5440[] = "EXYNOS5440";
 
 static void exynos4_map_io(void);
 static void exynos5_map_io(void);
+static void exynos5440_map_io(void);
 static void exynos4_init_clocks(int xtal);
 static void exynos5_init_clocks(int xtal);
-static void exynos_init_uarts(struct s3c2410_uartcfg *cfg, int no);
+static void exynos4_init_uarts(struct s3c2410_uartcfg *cfg, int no);
 static int exynos_init(void);
 
 static struct cpu_table cpu_ids[] __initdata = {
@@ -72,7 +75,7 @@ static struct cpu_table cpu_ids[] __initdata = {
                .idmask         = EXYNOS4_CPU_MASK,
                .map_io         = exynos4_map_io,
                .init_clocks    = exynos4_init_clocks,
-               .init_uarts     = exynos_init_uarts,
+               .init_uarts     = exynos4_init_uarts,
                .init           = exynos_init,
                .name           = name_exynos4210,
        }, {
@@ -80,7 +83,7 @@ static struct cpu_table cpu_ids[] __initdata = {
                .idmask         = EXYNOS4_CPU_MASK,
                .map_io         = exynos4_map_io,
                .init_clocks    = exynos4_init_clocks,
-               .init_uarts     = exynos_init_uarts,
+               .init_uarts     = exynos4_init_uarts,
                .init           = exynos_init,
                .name           = name_exynos4212,
        }, {
@@ -88,7 +91,7 @@ static struct cpu_table cpu_ids[] __initdata = {
                .idmask         = EXYNOS4_CPU_MASK,
                .map_io         = exynos4_map_io,
                .init_clocks    = exynos4_init_clocks,
-               .init_uarts     = exynos_init_uarts,
+               .init_uarts     = exynos4_init_uarts,
                .init           = exynos_init,
                .name           = name_exynos4412,
        }, {
@@ -96,9 +99,14 @@ static struct cpu_table cpu_ids[] __initdata = {
                .idmask         = EXYNOS5_SOC_MASK,
                .map_io         = exynos5_map_io,
                .init_clocks    = exynos5_init_clocks,
-               .init_uarts     = exynos_init_uarts,
                .init           = exynos_init,
                .name           = name_exynos5250,
+       }, {
+               .idcode         = EXYNOS5440_SOC_ID,
+               .idmask         = EXYNOS5_SOC_MASK,
+               .map_io         = exynos5440_map_io,
+               .init           = exynos_init,
+               .name           = name_exynos5440,
        },
 };
 
@@ -113,6 +121,17 @@ static struct map_desc exynos_iodesc[] __initdata = {
        },
 };
 
+#ifdef CONFIG_ARCH_EXYNOS5
+static struct map_desc exynos5440_iodesc[] __initdata = {
+       {
+               .virtual        = (unsigned long)S5P_VA_CHIPID,
+               .pfn            = __phys_to_pfn(EXYNOS5440_PA_CHIPID),
+               .length         = SZ_4K,
+               .type           = MT_DEVICE,
+       },
+};
+#endif
+
 static struct map_desc exynos4_iodesc[] __initdata = {
        {
                .virtual        = (unsigned long)S3C_VA_SYS,
@@ -256,25 +275,19 @@ static struct map_desc exynos5_iodesc[] __initdata = {
                .pfn            = __phys_to_pfn(EXYNOS5_PA_PMU),
                .length         = SZ_64K,
                .type           = MT_DEVICE,
-       }, {
-               .virtual        = (unsigned long)S5P_VA_COMBINER_BASE,
-               .pfn            = __phys_to_pfn(EXYNOS5_PA_COMBINER),
-               .length         = SZ_4K,
-               .type           = MT_DEVICE,
        }, {
                .virtual        = (unsigned long)S3C_VA_UART,
                .pfn            = __phys_to_pfn(EXYNOS5_PA_UART),
                .length         = SZ_512K,
                .type           = MT_DEVICE,
-       }, {
-               .virtual        = (unsigned long)S5P_VA_GIC_CPU,
-               .pfn            = __phys_to_pfn(EXYNOS5_PA_GIC_CPU),
-               .length         = SZ_8K,
-               .type           = MT_DEVICE,
-       }, {
-               .virtual        = (unsigned long)S5P_VA_GIC_DIST,
-               .pfn            = __phys_to_pfn(EXYNOS5_PA_GIC_DIST),
-               .length         = SZ_4K,
+       },
+};
+
+static struct map_desc exynos5440_iodesc0[] __initdata = {
+       {
+               .virtual        = (unsigned long)S3C_VA_UART,
+               .pfn            = __phys_to_pfn(EXYNOS5440_PA_UART0),
+               .length         = SZ_512K,
                .type           = MT_DEVICE,
        },
 };
@@ -286,11 +299,29 @@ void exynos4_restart(char mode, const char *cmd)
 
 void exynos5_restart(char mode, const char *cmd)
 {
-       __raw_writel(0x1, EXYNOS_SWRESET);
+       u32 val;
+       void __iomem *addr;
+
+       if (of_machine_is_compatible("samsung,exynos5250")) {
+               val = 0x1;
+               addr = EXYNOS_SWRESET;
+       } else if (of_machine_is_compatible("samsung,exynos5440")) {
+               val = (0x10 << 20) | (0x1 << 16);
+               addr = EXYNOS5440_SWRESET;
+       } else {
+               pr_err("%s: cannot support non-DT\n", __func__);
+               return;
+       }
+
+       __raw_writel(val, addr);
 }
 
 void __init exynos_init_late(void)
 {
+       if (of_machine_is_compatible("samsung,exynos5440"))
+               /* to be supported later */
+               return;
+
        exynos_pm_late_initcall();
 }
 
@@ -302,8 +333,20 @@ void __init exynos_init_late(void)
 
 void __init exynos_init_io(struct map_desc *mach_desc, int size)
 {
+       struct map_desc *iodesc = exynos_iodesc;
+       int iodesc_sz = ARRAY_SIZE(exynos_iodesc);
+#if defined(CONFIG_OF) && defined(CONFIG_ARCH_EXYNOS5)
+       unsigned long root = of_get_flat_dt_root();
+
        /* initialize the io descriptors we need for initialization */
-       iotable_init(exynos_iodesc, ARRAY_SIZE(exynos_iodesc));
+       if (of_flat_dt_is_compatible(root, "samsung,exynos5440")) {
+               iodesc = exynos5440_iodesc;
+               iodesc_sz = ARRAY_SIZE(exynos5440_iodesc);
+       }
+#endif
+
+       iotable_init(iodesc, iodesc_sz);
+
        if (mach_desc)
                iotable_init(mach_desc, size);
 
@@ -354,23 +397,6 @@ static void __init exynos4_map_io(void)
 static void __init exynos5_map_io(void)
 {
        iotable_init(exynos5_iodesc, ARRAY_SIZE(exynos5_iodesc));
-
-       s3c_device_i2c0.resource[0].start = EXYNOS5_PA_IIC(0);
-       s3c_device_i2c0.resource[0].end   = EXYNOS5_PA_IIC(0) + SZ_4K - 1;
-       s3c_device_i2c0.resource[1].start = EXYNOS5_IRQ_IIC;
-       s3c_device_i2c0.resource[1].end   = EXYNOS5_IRQ_IIC;
-
-       s3c_sdhci_setname(0, "exynos4-sdhci");
-       s3c_sdhci_setname(1, "exynos4-sdhci");
-       s3c_sdhci_setname(2, "exynos4-sdhci");
-       s3c_sdhci_setname(3, "exynos4-sdhci");
-
-       /* The I2C bus controllers are directly compatible with s3c2440 */
-       s3c_i2c0_setname("s3c2440-i2c");
-       s3c_i2c1_setname("s3c2440-i2c");
-       s3c_i2c2_setname("s3c2440-i2c");
-
-       s3c64xx_spi_setname("exynos4210-spi");
 }
 
 static void __init exynos4_init_clocks(int xtal)
@@ -389,6 +415,11 @@ static void __init exynos4_init_clocks(int xtal)
        exynos4_setup_clocks();
 }
 
+static void __init exynos5440_map_io(void)
+{
+       iotable_init(exynos5440_iodesc0, ARRAY_SIZE(exynos5440_iodesc0));
+}
+
 static void __init exynos5_init_clocks(int xtal)
 {
        printk(KERN_DEBUG "%s: initializing clocks\n", __func__);
@@ -589,7 +620,8 @@ static void __init combiner_init(void __iomem *combiner_base,
 }
 
 #ifdef CONFIG_OF
-int __init combiner_of_init(struct device_node *np, struct device_node *parent)
+static int __init combiner_of_init(struct device_node *np,
+                                  struct device_node *parent)
 {
        void __iomem *combiner_base;
 
@@ -604,8 +636,9 @@ int __init combiner_of_init(struct device_node *np, struct device_node *parent)
        return 0;
 }
 
-static const struct of_device_id exynos4_dt_irq_match[] = {
+static const struct of_device_id exynos_dt_irq_match[] = {
        { .compatible = "arm,cortex-a9-gic", .data = gic_of_init, },
+       { .compatible = "arm,cortex-a15-gic", .data = gic_of_init, },
        { .compatible = "samsung,exynos4210-combiner",
                        .data = combiner_of_init, },
        {},
@@ -622,7 +655,7 @@ void __init exynos4_init_irq(void)
                gic_init_bases(0, IRQ_PPI(0), S5P_VA_GIC_DIST, S5P_VA_GIC_CPU, gic_bank_offset, NULL);
 #ifdef CONFIG_OF
        else
-               of_irq_init(exynos4_dt_irq_match);
+               of_irq_init(exynos_dt_irq_match);
 #endif
 
        if (!of_have_populated_dt())
@@ -639,7 +672,7 @@ void __init exynos4_init_irq(void)
 void __init exynos5_init_irq(void)
 {
 #ifdef CONFIG_OF
-       of_irq_init(exynos4_dt_irq_match);
+       of_irq_init(exynos_dt_irq_match);
 #endif
        /*
         * The parameters of s5p_init_irq() are for VIC init.
@@ -669,7 +702,7 @@ static int __init exynos4_l2x0_cache_init(void)
 {
        int ret;
 
-       if (soc_is_exynos5250())
+       if (soc_is_exynos5250() || soc_is_exynos5440())
                return 0;
 
        ret = l2x0_of_init(L2_AUX_VAL, L2_AUX_MASK);
@@ -727,7 +760,7 @@ static int __init exynos_init(void)
 
 /* uart registration process */
 
-static void __init exynos_init_uarts(struct s3c2410_uartcfg *cfg, int no)
+static void __init exynos4_init_uarts(struct s3c2410_uartcfg *cfg, int no)
 {
        struct s3c2410_uartcfg *tcfg = cfg;
        u32 ucnt;
@@ -735,10 +768,7 @@ static void __init exynos_init_uarts(struct s3c2410_uartcfg *cfg, int no)
        for (ucnt = 0; ucnt < no; ucnt++, tcfg++)
                tcfg->has_fracval = 1;
 
-       if (soc_is_exynos5250())
-               s3c24xx_init_uartdevs("exynos4210-uart", exynos5_uart_resources, cfg, no);
-       else
-               s3c24xx_init_uartdevs("exynos4210-uart", exynos4_uart_resources, cfg, no);
+       s3c24xx_init_uartdevs("exynos4210-uart", exynos4_uart_resources, cfg, no);
 }
 
 static void __iomem *exynos_eint_base;
@@ -970,14 +1000,7 @@ static void exynos_irq_eint0_15(unsigned int irq, struct irq_desc *desc)
        struct irq_chip *chip = irq_get_chip(irq);
 
        chained_irq_enter(chip, desc);
-       chip->irq_mask(&desc->irq_data);
-
-       if (chip->irq_ack)
-               chip->irq_ack(&desc->irq_data);
-
        generic_handle_irq(*irq_data);
-
-       chip->irq_unmask(&desc->irq_data);
        chained_irq_exit(chip, desc);
 }
 
@@ -1013,6 +1036,8 @@ static int __init exynos_init_irq_eint(void)
                }
        }
 #endif
+       if (soc_is_exynos5440())
+               return 0;
 
        if (soc_is_exynos5250())
                exynos_eint_base = ioremap(EXYNOS5_PA_GPIO1, SZ_4K);