vserver 1.9.3
[linux-2.6.git] / arch / arm / mach-omap / common.c
index 2ff74d1..17d82a7 100644 (file)
 #include <asm/arch/board.h>
 #include <asm/io.h>
 
+/*
+ * ----------------------------------------------------------------------------
+ * OMAP revision check
+ *
+ * Since we use the cpu_is_omapnnnn() macros, there's a chance that a board
+ * switches to an updated core. We want to print out the OMAP revision early.
+ *
+ * We use the system_serial registers for the revision information so we
+ * can see it in /proc/cpuinfo.
+ *
+ * If the OMAP detection gets more complicated, we may want to expand this
+ * to store the OMAP version and replace the current cpu_is_omapnnnn() macros.
+ *
+ * ----------------------------------------------------------------------------
+ */
+static void __init omap_check_revision(void)
+{
+       system_serial_high = omap_readl(OMAP_ID_BASE);
+       system_serial_low = OMAP_ID_REG;
+       system_rev = (OMAP_ID_REG >> ID_SHIFT) & ID_MASK;
+
+       printk("OMAP revision: %d.%d (0x%08x) id: 0x%08x detected as OMAP-",
+              (system_serial_high >> 20) & 0xf,
+              (system_serial_high >> 16) & 0xf,
+              system_serial_high, system_serial_low);
+
+       switch (system_rev) {
+       case OMAP_ID_730:
+               printk("730\n");
+               system_rev = 0x730;
+               break;
+       case OMAP_ID_1510:
+               printk("1510\n");
+               system_rev = 0x1510;
+               break;
+       case OMAP_ID_1610:
+               printk("1610\n");
+               system_rev = 0x1610;
+               break;
+       case OMAP_ID_1710:
+               printk("1710\n");
+               system_rev = 0x1710;
+               break;
+       case OMAP_ID_5912:
+               printk("5912/1611B\n");
+               system_rev = 0x5912;
+               break;
+       default:
+               printk("unknown, please add support!\n");
+       }
+}
+
 /*
  * ----------------------------------------------------------------------------
  * OMAP I/O mapping
@@ -52,7 +104,7 @@ static struct map_desc omap1510_io_desc[] __initdata = {
 };
 #endif
 
-#ifdef CONFIG_ARCH_OMAP1610
+#if defined(CONFIG_ARCH_OMAP1610) || defined(CONFIG_ARCH_OMAP1710)
 static struct map_desc omap1610_io_desc[] __initdata = {
  { OMAP1610_DSP_BASE,    OMAP1610_DSP_START,    OMAP1610_DSP_SIZE,    MT_DEVICE },
  { OMAP1610_DSPREG_BASE, OMAP1610_DSPREG_START, OMAP1610_DSPREG_SIZE, MT_DEVICE },
@@ -64,7 +116,13 @@ static struct map_desc omap1610_io_desc[] __initdata = {
 static struct map_desc omap5912_io_desc[] __initdata = {
  { OMAP5912_DSP_BASE,    OMAP5912_DSP_START,    OMAP5912_DSP_SIZE,    MT_DEVICE },
  { OMAP5912_DSPREG_BASE, OMAP5912_DSPREG_START, OMAP5912_DSPREG_SIZE, MT_DEVICE },
- { OMAP5912_SRAM_BASE,   OMAP5912_SRAM_START,   OMAP5912_SRAM_SIZE,   MT_DEVICE }
+/*
+ * The OMAP5912 has 250kByte internal SRAM. Because the mapping is baseed on page
+ * size (4kByte), it seems that the last 2kByte (=0x800) of the 250kByte are not mapped.
+ * Add additional 2kByte (0x800) so that the last page is mapped and the last 2kByte
+ * can be used.
+ */
+ { OMAP5912_SRAM_BASE,   OMAP5912_SRAM_START,   OMAP5912_SRAM_SIZE + 0x800,   MT_DEVICE }
 };
 #endif
 
@@ -77,6 +135,7 @@ static void __init _omap_map_io(void)
        /* We have to initialize the IO space mapping before we can run
         * cpu_is_omapxxx() macros. */
        iotable_init(omap_io_desc, ARRAY_SIZE(omap_io_desc));
+       omap_check_revision();
 
 #ifdef CONFIG_ARCH_OMAP730
        if (cpu_is_omap730()) {
@@ -88,8 +147,8 @@ static void __init _omap_map_io(void)
                iotable_init(omap1510_io_desc, ARRAY_SIZE(omap1510_io_desc));
        }
 #endif
-#ifdef CONFIG_ARCH_OMAP1610
-       if (cpu_is_omap1610()) {
+#if defined(CONFIG_ARCH_OMAP1610) || defined(CONFIG_ARCH_OMAP1710)
+       if (cpu_is_omap1610() || cpu_is_omap1710()) {
                iotable_init(omap1610_io_desc, ARRAY_SIZE(omap1610_io_desc));
        }
 #endif
@@ -102,8 +161,8 @@ static void __init _omap_map_io(void)
        /* REVISIT: Refer to OMAP5910 Errata, Advisory SYS_1: "Timeout Abort
         * on a Posted Write in the TIPB Bridge".
         */
-       omap_writew(0x0, MPU_PUBLIC_TIPB_CNTL_REG);
-       omap_writew(0x0, MPU_PRIVATE_TIPB_CNTL_REG);
+       omap_writew(0x0, MPU_PUBLIC_TIPB_CNTL);
+       omap_writew(0x0, MPU_PRIVATE_TIPB_CNTL);
 
        /* Must init clocks early to assure that timer interrupt works
         */
@@ -122,13 +181,18 @@ void omap_map_io(void)
 extern int omap_bootloader_tag_len;
 extern u8 omap_bootloader_tag[];
 
-const void *__omap_get_per_info(u16 tag, size_t len)
+struct omap_board_config_kernel *omap_board_config;
+int omap_board_config_size = 0;
+
+const void *__omap_get_config(u16 tag, size_t len)
 {
-       struct omap_board_info_entry *info = NULL;
+       struct omap_board_config_entry *info = NULL;
+       struct omap_board_config_kernel *kinfo = NULL;
+       int i;
 
 #ifdef CONFIG_OMAP_BOOT_TAG
        if (omap_bootloader_tag_len > 4)
-               info = (struct omap_board_info_entry *) omap_bootloader_tag;
+               info = (struct omap_board_config_entry *) omap_bootloader_tag;
        while (info != NULL) {
                u8 *next;
 
@@ -139,26 +203,38 @@ const void *__omap_get_per_info(u16 tag, size_t len)
                if (next >= omap_bootloader_tag + omap_bootloader_tag_len)
                        info = NULL;
                else
-                       info = (struct omap_board_info_entry *) next;
+                       info = (struct omap_board_config_entry *) next;
+       }
+       if (info != NULL) {
+               /* Check the length as a lame attempt to check for
+                * binary inconsistancy. */
+               if (info->len != len) {
+                       printk(KERN_ERR "OMAP peripheral config: Length mismatch with tag %x (want %d, got %d)\n",
+                              tag, len, info->len);
+                       return NULL;
+               }
+               return info->data;
        }
 #endif
-       if (info == NULL)
-               return NULL;
-       if (info->len != len) {
-               printk(KERN_ERR "OMAP per_info: Length mismatch with tag %x (want %d, got %d)\n",
-                      tag, len, info->len);
-               return NULL;
+       /* Try to find the config from the board-specific structures
+        * in the kernel. */
+       for (i = 0; i < omap_board_config_size; i++) {
+               if (omap_board_config[i].tag == tag) {
+                       kinfo = &omap_board_config[i];
+                       break;
+               }
        }
-
-       return info->data;
+       if (kinfo == NULL)
+               return NULL;
+       return kinfo->data;
 }
-EXPORT_SYMBOL(__omap_get_per_info);
+EXPORT_SYMBOL(__omap_get_config);
 
 static int __init omap_add_serial_console(void)
 {
-       const struct omap_uart_info *info;
+       const struct omap_uart_config *info;
 
-       info = omap_get_per_info(OMAP_TAG_UART, struct omap_uart_info);
+       info = omap_get_config(OMAP_TAG_UART, struct omap_uart_config);
        if (info != NULL && info->console_uart) {
                static char speed[11], *opt = NULL;