ARM: EXYNOS: add support uart for EXYNOS4 and EXYNOS5
authorKukjin Kim <kgene.kim@samsung.com>
Fri, 10 Feb 2012 02:57:53 +0000 (11:57 +0900)
committerKukjin Kim <kgene.kim@samsung.com>
Wed, 14 Mar 2012 09:13:05 +0000 (02:13 -0700)
Actually, the base address of uart is different between EXYNOS4
and EXYNOS5 and this patch enables to support uart for EXYNOS4
and EXYNOS5 SoCs at runtime.

Signed-off-by: Kukjin Kim <kgene.kim@samsung.com>
arch/arm/mach-exynos/Makefile
arch/arm/mach-exynos/common.c
arch/arm/mach-exynos/dev-uart.c [new file with mode: 0644]
arch/arm/mach-exynos/include/mach/debug-macro.S
arch/arm/mach-exynos/include/mach/irqs.h
arch/arm/mach-exynos/include/mach/map.h
arch/arm/mach-exynos/include/mach/uncompress.h
arch/arm/plat-s5p/Kconfig
arch/arm/plat-s5p/Makefile
arch/arm/plat-samsung/include/plat/devs.h
arch/arm/plat-samsung/include/plat/uncompress.h

index 2117f0257ef3fdc2ead0d46d92b23400d887f951..f8a377076ff1ecd3ff13cf35b4bb0990e926b4c5 100644 (file)
@@ -44,6 +44,7 @@ obj-$(CONFIG_MACH_EXYNOS4_DT)         += mach-exynos4-dt.o
 
 # device support
 
+obj-y                                  += dev-uart.o
 obj-$(CONFIG_ARCH_EXYNOS4)             += dev-audio.o
 obj-$(CONFIG_EXYNOS4_DEV_AHCI)         += dev-ahci.o
 obj-$(CONFIG_EXYNOS4_DEV_PD)           += dev-pd.o
index 02eed29c1580a19de1e56363131159af5d9add3d..4a82cf0071c3d55bded98e4da367d79ec17dcb36 100644 (file)
@@ -477,7 +477,10 @@ static void __init exynos_init_uarts(struct s3c2410_uartcfg *cfg, int no)
        for (ucnt = 0; ucnt < no; ucnt++, tcfg++)
                tcfg->has_fracval = 1;
 
-       s3c24xx_init_uartdevs("exynos4210-uart", s5p_uart_resources, cfg, no);
+       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);
 }
 
 static DEFINE_SPINLOCK(eint_lock);
diff --git a/arch/arm/mach-exynos/dev-uart.c b/arch/arm/mach-exynos/dev-uart.c
new file mode 100644 (file)
index 0000000..2e85c02
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * Base EXYNOS UART resource and device definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/ioport.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/irq.h>
+#include <mach/hardware.h>
+#include <mach/map.h>
+
+#include <plat/devs.h>
+
+#define EXYNOS_UART_RESOURCE(_series, _nr)     \
+static struct resource exynos##_series##_uart##_nr##_resource[] = {    \
+       [0] = DEFINE_RES_MEM(EXYNOS##_series##_PA_UART##_nr, EXYNOS##_series##_SZ_UART),        \
+       [1] = DEFINE_RES_IRQ(EXYNOS##_series##_IRQ_UART##_nr),  \
+};
+
+EXYNOS_UART_RESOURCE(4, 0)
+EXYNOS_UART_RESOURCE(4, 1)
+EXYNOS_UART_RESOURCE(4, 2)
+EXYNOS_UART_RESOURCE(4, 3)
+
+struct s3c24xx_uart_resources exynos4_uart_resources[] __initdata = {
+       [0] = {
+               .resources      = exynos4_uart0_resource,
+               .nr_resources   = ARRAY_SIZE(exynos4_uart0_resource),
+       },
+       [1] = {
+               .resources      = exynos4_uart1_resource,
+               .nr_resources   = ARRAY_SIZE(exynos4_uart1_resource),
+       },
+       [2] = {
+               .resources      = exynos4_uart2_resource,
+               .nr_resources   = ARRAY_SIZE(exynos4_uart2_resource),
+       },
+       [3] = {
+               .resources      = exynos4_uart3_resource,
+               .nr_resources   = ARRAY_SIZE(exynos4_uart3_resource),
+       },
+};
+
+EXYNOS_UART_RESOURCE(5, 0)
+EXYNOS_UART_RESOURCE(5, 1)
+EXYNOS_UART_RESOURCE(5, 2)
+EXYNOS_UART_RESOURCE(5, 3)
+
+struct s3c24xx_uart_resources exynos5_uart_resources[] __initdata = {
+       [0] = {
+               .resources      = exynos5_uart0_resource,
+               .nr_resources   = ARRAY_SIZE(exynos5_uart0_resource),
+       },
+       [1] = {
+               .resources      = exynos5_uart1_resource,
+               .nr_resources   = ARRAY_SIZE(exynos5_uart0_resource),
+       },
+       [2] = {
+               .resources      = exynos5_uart2_resource,
+               .nr_resources   = ARRAY_SIZE(exynos5_uart2_resource),
+       },
+       [3] = {
+               .resources      = exynos5_uart3_resource,
+               .nr_resources   = ARRAY_SIZE(exynos5_uart3_resource),
+       },
+};
index 6cacf16a67a6e2e4bab156f6dfeffedd04f7746e..6c857ff0b5d84670f65287230801a7bf2cf5d974 100644 (file)
         */
 
        .macro addruart, rp, rv, tmp
-               ldr     \rp, = S3C_PA_UART
-               ldr     \rv, = S3C_VA_UART
+               mov     \rp, #0x10000000
+               ldr     \rp, [\rp, #0x0]
+               and     \rp, \rp, #0xf00000
+               teq     \rp, #0x500000          @@ EXYNOS5
+               ldreq   \rp, =EXYNOS5_PA_UART
+               movne   \rp, #EXYNOS4_PA_UART   @@ EXYNOS4
+               ldr     \rv, =S3C_VA_UART
 #if CONFIG_DEBUG_S3C_UART != 0
                add     \rp, \rp, #(0x10000 * CONFIG_DEBUG_S3C_UART)
                add     \rv, \rv, #(0x10000 * CONFIG_DEBUG_S3C_UART)
index 1d401c957835f666e9c86980efca8935d1f570b1..f78070ee79f062f0a9a86fa015d47ce3bba47dfd 100644 (file)
 /* Set the default NR_IRQS */
 #define NR_IRQS                        (IRQ_TIMER_BASE + IRQ_TIMER_COUNT)
 
+#define EXYNOS4_IRQ_UART0              IRQ_SPI(52)
+#define EXYNOS4_IRQ_UART1              IRQ_SPI(53)
+#define EXYNOS4_IRQ_UART2              IRQ_SPI(54)
+#define EXYNOS4_IRQ_UART3              IRQ_SPI(55)
+#define EXYNOS4_IRQ_UART4              IRQ_SPI(56)
+
+#define EXYNOS5_IRQ_UART0              IRQ_SPI(51)
+#define EXYNOS5_IRQ_UART1              IRQ_SPI(52)
+#define EXYNOS5_IRQ_UART2              IRQ_SPI(53)
+#define EXYNOS5_IRQ_UART3              IRQ_SPI(54)
+#define EXYNOS5_IRQ_UART4              IRQ_SPI(55)
+
 #endif /* __ASM_ARCH_IRQS_H */
index 2ad4e9cfe49802af6ef0cce2241b07d6324a14b7..ea513c626b1223bafdc7b085973bae6e7a398323 100644 (file)
 #define S3C_PA_IIC7                    EXYNOS4_PA_IIC(7)
 #define S3C_PA_RTC                     EXYNOS4_PA_RTC
 #define S3C_PA_WDT                     EXYNOS4_PA_WATCHDOG
-#define S3C_PA_UART                    EXYNOS4_PA_UART
 #define S3C_PA_SPI0                    EXYNOS4_PA_SPI0
 #define S3C_PA_SPI1                    EXYNOS4_PA_SPI1
 #define S3C_PA_SPI2                    EXYNOS4_PA_SPI2
 
 /* Compatibility UART */
 
-#define S3C_VA_UARTx(x)                        (S3C_VA_UART + ((x) * S3C_UART_OFFSET))
+#define EXYNOS4_PA_UART0               0x13800000
+#define EXYNOS4_PA_UART1               0x13810000
+#define EXYNOS4_PA_UART2               0x13820000
+#define EXYNOS4_PA_UART3               0x13830000
+#define EXYNOS4_SZ_UART                        SZ_256
 
-#define S5P_PA_UART(x)                 (EXYNOS4_PA_UART + ((x) * S3C_UART_OFFSET))
-#define S5P_PA_UART0                   S5P_PA_UART(0)
-#define S5P_PA_UART1                   S5P_PA_UART(1)
-#define S5P_PA_UART2                   S5P_PA_UART(2)
-#define S5P_PA_UART3                   S5P_PA_UART(3)
-#define S5P_PA_UART4                   S5P_PA_UART(4)
+#define EXYNOS5_PA_UART0               0x12C00000
+#define EXYNOS5_PA_UART1               0x12C10000
+#define EXYNOS5_PA_UART2               0x12C20000
+#define EXYNOS5_PA_UART3               0x12C30000
+#define EXYNOS5_SZ_UART                        SZ_256
 
-#define S5P_SZ_UART                    SZ_256
+#define S3C_VA_UARTx(x)                        (S3C_VA_UART + ((x) * S3C_UART_OFFSET))
 
 #endif /* __ASM_ARCH_MAP_H */
index 21d97bcd9acb4b09c9ac75033edb120faf701cf2..493f4f365ddfe65a8ceab62908bc2ff6725a1ef1 100644 (file)
@@ -1,9 +1,8 @@
-/* linux/arch/arm/mach-exynos4/include/mach/uncompress.h
- *
- * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+/*
+ * Copyright (c) 2010-2012 Samsung Electronics Co., Ltd.
  *             http://www.samsung.com
  *
- * EXYNOS4 - uncompress code
+ * EXYNOS - uncompress code
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
 #ifndef __ASM_ARCH_UNCOMPRESS_H
 #define __ASM_ARCH_UNCOMPRESS_H __FILE__
 
+#include <asm/mach-types.h>
+
 #include <mach/map.h>
+
+volatile u8 *uart_base;
+
 #include <plat/uncompress.h>
 
 static void arch_detect_cpu(void)
 {
-       /* we do not need to do any cpu detection here at the moment. */
+       if (machine_is_smdk5250())
+               uart_base = (volatile u8 *)EXYNOS5_PA_UART + (S3C_UART_OFFSET * CONFIG_S3C_LOWLEVEL_UART_PORT);
+       else
+               uart_base = (volatile u8 *)EXYNOS4_PA_UART + (S3C_UART_OFFSET * CONFIG_S3C_LOWLEVEL_UART_PORT);
 
        /*
         * For preventing FIFO overrun or infinite loop of UART console,
index 8167ce66188c65c19f6d9efda34b718f7acf7c0b..10e235cc7c93a8268a98050df9af7065aacda52e 100644 (file)
@@ -40,6 +40,10 @@ config S5P_HRT
        help
          Use the High Resolution timer support
 
+config S5P_DEV_UART
+       def_bool y
+       depends on (ARCH_S5P64X0 || ARCH_S5PC100 || ARCH_S5PV210)
+
 config S5P_PM
        bool
        help
index 30d8c3016e6b910d3fc5c92c967a4ee2b973e6a7..4bd8241366594c1dd4e47fad5b0c4ac8ad5cdbbf 100644 (file)
@@ -12,7 +12,6 @@ obj-                          :=
 
 # Core files
 
-obj-y                          += dev-uart.o
 obj-y                          += clock.o
 obj-y                          += irq.o
 obj-$(CONFIG_S5P_EXT_INT)      += irq-eint.o
@@ -23,5 +22,7 @@ obj-$(CONFIG_S5P_SLEEP)               += sleep.o
 obj-$(CONFIG_S5P_HRT)          += s5p-time.o
 
 # devices
+
+obj-$(CONFIG_S5P_DEV_UART)     += dev-uart.o
 obj-$(CONFIG_S5P_DEV_MFC)      += dev-mfc.o
 obj-$(CONFIG_S5P_SETUP_MIPIPHY)        += setup-mipiphy.o
index 4214ea0ff8fe36ffb6d64d8372d2d8248b889b76..32cc67e6be1330ef16cba3935543d82c47a7040b 100644 (file)
@@ -26,6 +26,8 @@ struct s3c24xx_uart_resources {
 extern struct s3c24xx_uart_resources s3c2410_uart_resources[];
 extern struct s3c24xx_uart_resources s3c64xx_uart_resources[];
 extern struct s3c24xx_uart_resources s5p_uart_resources[];
+extern struct s3c24xx_uart_resources exynos4_uart_resources[];
+extern struct s3c24xx_uart_resources exynos5_uart_resources[];
 
 extern struct platform_device *s3c24xx_uart_devs[];
 extern struct platform_device *s3c24xx_uart_src[];
index ee48e12a1e7216ba356e5e160b650f6332904f3d..7e068d182c3ddbb8b0bd50f5b84e490742c296df 100644 (file)
@@ -37,7 +37,9 @@ static void arch_detect_cpu(void);
 /* how many bytes we allow into the FIFO at a time in FIFO mode */
 #define FIFO_MAX        (14)
 
+#ifdef S3C_PA_UART
 #define uart_base S3C_PA_UART + (S3C_UART_OFFSET * CONFIG_S3C_LOWLEVEL_UART_PORT)
+#endif
 
 static __inline__ void
 uart_wr(unsigned int reg, unsigned int val)