]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
ARM: at91: uncompress: autodetect the uart to use
authorJean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Wed, 15 Feb 2012 10:44:40 +0000 (18:44 +0800)
committerNicolas Ferre <nicolas.ferre@atmel.com>
Tue, 17 Apr 2012 09:00:19 +0000 (11:00 +0200)
This will now autodetect the first uart enabled by the bootloader
and will use it for uncompress. This will still assume that the bootloader
configured it (pins and clock).

This also allows to include all soc headers together.

Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Acked-by: Nicolas Ferre <nicolas.ferre@atmel.com>
arch/arm/mach-at91/Kconfig
arch/arm/mach-at91/include/mach/at91rm9200.h
arch/arm/mach-at91/include/mach/at91sam9260.h
arch/arm/mach-at91/include/mach/at91sam9261.h
arch/arm/mach-at91/include/mach/at91sam9263.h
arch/arm/mach-at91/include/mach/at91sam9g45.h
arch/arm/mach-at91/include/mach/at91sam9rl.h
arch/arm/mach-at91/include/mach/at91sam9x5.h
arch/arm/mach-at91/include/mach/hardware.h
arch/arm/mach-at91/include/mach/uncompress.h

index 8acc1649c820364462b102aafa248eaa562f2671..885fdb93618b96dc59b421f094943fd8b042b600 100644 (file)
@@ -9,15 +9,6 @@ config HAVE_AT91_DBGU0
 config HAVE_AT91_DBGU1
        bool
 
-config HAVE_AT91_USART3
-       bool
-
-config HAVE_AT91_USART4
-       bool
-
-config HAVE_AT91_USART5
-       bool
-
 config AT91_SAM9_ALT_RESET
        bool
        default !ARCH_AT91X40
@@ -36,16 +27,12 @@ config ARCH_AT91RM9200
        select CPU_ARM920T
        select GENERIC_CLOCKEVENTS
        select HAVE_AT91_DBGU0
-       select HAVE_AT91_USART3
 
 config ARCH_AT91SAM9260
        bool "AT91SAM9260 or AT91SAM9XE"
        select CPU_ARM926T
        select GENERIC_CLOCKEVENTS
        select HAVE_AT91_DBGU0
-       select HAVE_AT91_USART3
-       select HAVE_AT91_USART4
-       select HAVE_AT91_USART5
        select HAVE_NET_MACB
 
 config ARCH_AT91SAM9261
@@ -74,7 +61,6 @@ config ARCH_AT91SAM9RL
        bool "AT91SAM9RL"
        select CPU_ARM926T
        select GENERIC_CLOCKEVENTS
-       select HAVE_AT91_USART3
        select HAVE_FB_ATMEL
        select HAVE_AT91_DBGU0
 
@@ -83,16 +69,12 @@ config ARCH_AT91SAM9G20
        select CPU_ARM926T
        select GENERIC_CLOCKEVENTS
        select HAVE_AT91_DBGU0
-       select HAVE_AT91_USART3
-       select HAVE_AT91_USART4
-       select HAVE_AT91_USART5
        select HAVE_NET_MACB
 
 config ARCH_AT91SAM9G45
        bool "AT91SAM9G45 or AT91SAM9M10 families"
        select CPU_ARM926T
        select GENERIC_CLOCKEVENTS
-       select HAVE_AT91_USART3
        select HAVE_FB_ATMEL
        select HAVE_NET_MACB
        select HAVE_AT91_DBGU1
@@ -526,41 +508,6 @@ config AT91_TIMER_HZ
          system clock (of at least several MHz), rounding is less of a
          problem so it can be safer to use a decimal values like 100.
 
-choice
-       prompt "Select a UART for early kernel messages"
-
-config AT91_EARLY_DBGU0
-       bool "DBGU on rm9200, 9260/9g20, 9261/9g10, 9rl and 9x5"
-       depends on HAVE_AT91_DBGU0
-
-config AT91_EARLY_DBGU1
-       bool "DBGU on 9263 and 9g45"
-       depends on HAVE_AT91_DBGU1
-
-config AT91_EARLY_USART0
-       bool "USART0"
-
-config AT91_EARLY_USART1
-       bool "USART1"
-
-config AT91_EARLY_USART2
-       bool "USART2"
-       depends on ! ARCH_AT91X40
-
-config AT91_EARLY_USART3
-       bool "USART3"
-       depends on HAVE_AT91_USART3
-
-config AT91_EARLY_USART4
-       bool "USART4"
-       depends on HAVE_AT91_USART4
-
-config AT91_EARLY_USART5
-       bool "USART5"
-       depends on HAVE_AT91_USART5
-
-endchoice
-
 endmenu
 
 endif
index 603e6aac2a4fb9d9a55c6d37b639ff19649e9e81..e67317c677617bd0374446e4646922eb60792ce6 100644 (file)
 #define AT91RM9200_BASE_RTC    0xfffffe00      /* Real-Time Clock */
 #define AT91RM9200_BASE_MC     0xffffff00      /* Memory Controllers */
 
-#define AT91_USART0    AT91RM9200_BASE_US0
-#define AT91_USART1    AT91RM9200_BASE_US1
-#define AT91_USART2    AT91RM9200_BASE_US2
-#define AT91_USART3    AT91RM9200_BASE_US3
-
 /*
  * Internal Memory.
  */
index 08ae9afd00fed48852fe6c62d851cb96683080cc..416c7b6c56d3af85cf34eef90078de512047dbfa 100644 (file)
 #define AT91SAM9260_BASE_WDT   0xfffffd40
 #define AT91SAM9260_BASE_GPBR  0xfffffd50
 
-#define AT91_USART0    AT91SAM9260_BASE_US0
-#define AT91_USART1    AT91SAM9260_BASE_US1
-#define AT91_USART2    AT91SAM9260_BASE_US2
-#define AT91_USART3    AT91SAM9260_BASE_US3
-#define AT91_USART4    AT91SAM9260_BASE_US4
-#define AT91_USART5    AT91SAM9260_BASE_US5
-
 
 /*
  * Internal Memory.
index 44fbdc12ee6247b4581efc51df0883677fd46cbe..a041406d06ee1e0fba30451f3925ed657ec7f315 100644 (file)
 #define AT91SAM9261_BASE_WDT   0xfffffd40
 #define AT91SAM9261_BASE_GPBR  0xfffffd50
 
-#define AT91_USART0    AT91SAM9261_BASE_US0
-#define AT91_USART1    AT91SAM9261_BASE_US1
-#define AT91_USART2    AT91SAM9261_BASE_US2
-
 
 /*
  * Internal Memory.
index d96cbb2e03c49a88f936a6ebc8105089366288b8..d201029d60b386d9de9cefca0f4b03958aaab36d 100644 (file)
 #define AT91SAM9263_BASE_RTT1  0xfffffd50
 #define AT91SAM9263_BASE_GPBR  0xfffffd60
 
-#define AT91_USART0    AT91SAM9263_BASE_US0
-#define AT91_USART1    AT91SAM9263_BASE_US1
-#define AT91_USART2    AT91SAM9263_BASE_US2
-
 #define AT91_SMC       AT91_SMC0
 
 /*
index d052abcff852134fee95d54defa164f66af8b074..3a4da24d59112209613a6cab1ed132103b4c8772 100644 (file)
 #define AT91SAM9G45_BASE_RTC   0xfffffdb0
 #define AT91SAM9G45_BASE_GPBR  0xfffffd60
 
-#define AT91_USART0    AT91SAM9G45_BASE_US0
-#define AT91_USART1    AT91SAM9G45_BASE_US1
-#define AT91_USART2    AT91SAM9G45_BASE_US2
-#define AT91_USART3    AT91SAM9G45_BASE_US3
-
 /*
  * Internal Memory.
  */
index e0073eb10144d87e754c5e261ded43fb908a51dd..a15db56d33fa86154020a3419db2a468a0f4b10f 100644 (file)
 #define AT91SAM9RL_BASE_GPBR   0xfffffd60
 #define AT91SAM9RL_BASE_RTC    0xfffffe00
 
-#define AT91_USART0    AT91SAM9RL_BASE_US0
-#define AT91_USART1    AT91SAM9RL_BASE_US1
-#define AT91_USART2    AT91SAM9RL_BASE_US2
-#define AT91_USART3    AT91SAM9RL_BASE_US3
-
 
 /*
  * Internal Memory.
index 88e43d534cdfeef7f9df38b7c28a34a0546bc436..c75ee19b58d3de69c79e81e312c416fbd6071ef0 100644 (file)
 #define AT91SAM9X5_BASE_USART1 0xf8020000
 #define AT91SAM9X5_BASE_USART2 0xf8024000
 
-/*
- * Base addresses for early serial code (uncompress.h)
- */
-#define AT91_DBGU      AT91_BASE_DBGU0
-#define AT91_USART0    AT91SAM9X5_BASE_USART0
-#define AT91_USART1    AT91SAM9X5_BASE_USART1
-#define AT91_USART2    AT91SAM9X5_BASE_USART2
-
 /*
  * Internal Memory.
  */
index e9e29a6c3868eb6ea462c8df13073915440ac36e..3a01f8ff7e7421e51c7f9fd108562108d289a751 100644 (file)
 /* 9263, 9g45 */
 #define AT91_BASE_DBGU1        0xffffee00
 
-#if defined(CONFIG_ARCH_AT91RM9200)
+#if defined(CONFIG_ARCH_AT91X40)
+#include <mach/at91x40.h>
+#else
 #include <mach/at91rm9200.h>
-#elif defined(CONFIG_ARCH_AT91SAM9260) || defined(CONFIG_ARCH_AT91SAM9G20)
 #include <mach/at91sam9260.h>
-#elif defined(CONFIG_ARCH_AT91SAM9261) || defined(CONFIG_ARCH_AT91SAM9G10)
 #include <mach/at91sam9261.h>
-#elif defined(CONFIG_ARCH_AT91SAM9263)
 #include <mach/at91sam9263.h>
-#elif defined(CONFIG_ARCH_AT91SAM9RL)
 #include <mach/at91sam9rl.h>
-#elif defined(CONFIG_ARCH_AT91SAM9G45)
 #include <mach/at91sam9g45.h>
-#elif defined(CONFIG_ARCH_AT91SAM9X5)
 #include <mach/at91sam9x5.h>
-#elif defined(CONFIG_ARCH_AT91X40)
-#include <mach/at91x40.h>
-#else
-#error "Unsupported AT91 processor"
-#endif
 
-#if !defined(CONFIG_ARCH_AT91X40)
 /*
  * On all at91 except rm9200 and x40 have the System Controller starts
  * at address 0xffffc000 and has a size of 16KiB.
index d985af7c94bd571b42813df87d50490c09ef7f83..6f6118d1576aa8a48189db75e9ad907d1a896e74 100644 (file)
@@ -1,7 +1,8 @@
 /*
  * arch/arm/mach-at91/include/mach/uncompress.h
  *
- *  Copyright (C) 2003 SAN People
+ * Copyright (C) 2003 SAN People
+ * Copyright (C) 2012 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
 #include <linux/atmel_serial.h>
 #include <mach/hardware.h>
 
-#if defined(CONFIG_AT91_EARLY_DBGU0)
-#define UART_OFFSET AT91_BASE_DBGU0
-#elif defined(CONFIG_AT91_EARLY_DBGU1)
-#define UART_OFFSET AT91_BASE_DBGU1
-#elif defined(CONFIG_AT91_EARLY_USART0)
-#define UART_OFFSET AT91_USART0
-#elif defined(CONFIG_AT91_EARLY_USART1)
-#define UART_OFFSET AT91_USART1
-#elif defined(CONFIG_AT91_EARLY_USART2)
-#define UART_OFFSET AT91_USART2
-#elif defined(CONFIG_AT91_EARLY_USART3)
-#define UART_OFFSET AT91_USART3
-#elif defined(CONFIG_AT91_EARLY_USART4)
-#define UART_OFFSET AT91_USART4
-#elif defined(CONFIG_AT91_EARLY_USART5)
-#define UART_OFFSET AT91_USART5
-#endif
+#include <mach/at91_dbgu.h>
+#include <mach/cpu.h>
 
 void __iomem *at91_uart;
 
+#if !defined(CONFIG_ARCH_AT91X40)
+static const u32 uarts_rm9200[] = {
+       AT91_BASE_DBGU0,
+       AT91RM9200_BASE_US0,
+       AT91RM9200_BASE_US1,
+       AT91RM9200_BASE_US2,
+       AT91RM9200_BASE_US3,
+       0,
+};
+
+static const u32 uarts_sam9260[] = {
+       AT91_BASE_DBGU0,
+       AT91SAM9260_BASE_US0,
+       AT91SAM9260_BASE_US1,
+       AT91SAM9260_BASE_US2,
+       AT91SAM9260_BASE_US3,
+       AT91SAM9260_BASE_US4,
+       AT91SAM9260_BASE_US5,
+       0,
+};
+
+static const u32 uarts_sam9261[] = {
+       AT91_BASE_DBGU0,
+       AT91SAM9261_BASE_US0,
+       AT91SAM9261_BASE_US1,
+       AT91SAM9261_BASE_US2,
+       0,
+};
+
+static const u32 uarts_sam9263[] = {
+       AT91_BASE_DBGU1,
+       AT91SAM9263_BASE_US0,
+       AT91SAM9263_BASE_US1,
+       AT91SAM9263_BASE_US2,
+       0,
+};
+
+static const u32 uarts_sam9g45[] = {
+       AT91_BASE_DBGU1,
+       AT91SAM9G45_BASE_US0,
+       AT91SAM9G45_BASE_US1,
+       AT91SAM9G45_BASE_US2,
+       AT91SAM9G45_BASE_US3,
+       0,
+};
+
+static const u32 uarts_sam9rl[] = {
+       AT91_BASE_DBGU0,
+       AT91SAM9RL_BASE_US0,
+       AT91SAM9RL_BASE_US1,
+       AT91SAM9RL_BASE_US2,
+       AT91SAM9RL_BASE_US3,
+       0,
+};
+
+static const u32 uarts_sam9x5[] = {
+       AT91_BASE_DBGU0,
+       AT91SAM9X5_BASE_USART0,
+       AT91SAM9X5_BASE_USART1,
+       AT91SAM9X5_BASE_USART2,
+       0,
+};
+
+static inline const u32* decomp_soc_detect(u32 dbgu_base)
+{
+       u32 cidr, socid;
+
+       cidr = __raw_readl(dbgu_base + AT91_DBGU_CIDR);
+       socid = cidr & ~AT91_CIDR_VERSION;
+
+       switch (socid) {
+       case ARCH_ID_AT91RM9200:
+               return uarts_rm9200;
+
+       case ARCH_ID_AT91SAM9G20:
+       case ARCH_ID_AT91SAM9260:
+               return uarts_sam9260;
+
+       case ARCH_ID_AT91SAM9261:
+               return uarts_sam9261;
+
+       case ARCH_ID_AT91SAM9263:
+               return uarts_sam9263;
+
+       case ARCH_ID_AT91SAM9G45:
+               return uarts_sam9g45;
+
+       case ARCH_ID_AT91SAM9RL64:
+               return uarts_sam9rl;
+
+       case ARCH_ID_AT91SAM9X5:
+               return uarts_sam9x5;
+       }
+
+       /* at91sam9g10 */
+       if ((cidr & ~AT91_CIDR_EXT) == ARCH_ID_AT91SAM9G10) {
+               return uarts_sam9261;
+       }
+       /* at91sam9xe */
+       else if ((cidr & AT91_CIDR_ARCH) == ARCH_FAMILY_AT91SAM9XE) {
+               return uarts_sam9260;
+       }
+
+       return NULL;
+}
+
 static inline void arch_decomp_setup(void)
 {
-#ifdef UART_OFFSET
-       at91_uart = (void __iomem *) UART_OFFSET;       /* physical address */
-#endif
+       int i = 0;
+       const u32* usarts;
+
+       usarts = decomp_soc_detect(AT91_BASE_DBGU0);
+
+       if (!usarts)
+               usarts = decomp_soc_detect(AT91_BASE_DBGU1);
+       if (!usarts) {
+               at91_uart = NULL;
+               return;
+       }
+
+       do {
+               /* physical address */
+               at91_uart = (void __iomem *)usarts[i];
+
+               if (__raw_readl(at91_uart + ATMEL_US_BRGR))
+                       return;
+               i++;
+       } while (usarts[i]);
+
+       at91_uart = NULL;
 }
+#else
+static inline void arch_decomp_setup(void)
+{
+       at91_uart = NULL;
+}
+#endif
+
 /*
  * The following code assumes the serial port has already been
  * initialized by the bootloader.  If you didn't setup a port in
@@ -60,20 +178,22 @@ static inline void arch_decomp_setup(void)
  */
 static void putc(int c)
 {
-#ifdef UART_OFFSET
+       if (!at91_uart)
+               return;
+
        while (!(__raw_readl(at91_uart + ATMEL_US_CSR) & ATMEL_US_TXRDY))
                barrier();
        __raw_writel(c, at91_uart + ATMEL_US_THR);
-#endif
 }
 
 static inline void flush(void)
 {
-#ifdef UART_OFFSET
+       if (!at91_uart)
+               return;
+
        /* wait for transmission to complete */
        while (!(__raw_readl(at91_uart + ATMEL_US_CSR) & ATMEL_US_TXEMPTY))
                barrier();
-#endif
 }
 
 #define arch_decomp_wdog()