[PATCH] ARM: 2801/1: OMAP update 6/11: Split OMAP1 common code into id, io and serial
authorTony Lindgren <tony@atomide.com>
Sun, 10 Jul 2005 18:58:12 +0000 (19:58 +0100)
committerRussell King <rmk+kernel@arm.linux.org.uk>
Sun, 10 Jul 2005 18:58:12 +0000 (19:58 +0100)
Patch from Tony Lindgren

This patch by Juha Yrjölä and other OMAP developers splits
OMAP1 specific common code into OMAP1 id, io, and serial
code in mach-omap1 directory.

Signed-off-by: Tony Lindgren <tony@atomide.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
arch/arm/mach-omap/common.c
arch/arm/mach-omap/common.h
arch/arm/mach-omap1/id.c [new file with mode: 0644]
arch/arm/mach-omap1/io.c [new file with mode: 0644]
arch/arm/mach-omap1/serial.c [new file with mode: 0644]

index 265cde48586f033a58d174f0f467097708d006df..b6a5b39e7e88dc8c3744b356bf2845f477929586 100644 (file)
 
 #include "clock.h"
 
-#define DEBUG 1
-
-struct omap_id {
-       u16     jtag_id;        /* Used to determine OMAP type */
-       u8      die_rev;        /* Processor revision */
-       u32     omap_id;        /* OMAP revision */
-       u32     type;           /* Cpu id bits [31:08], cpu class bits [07:00] */
-};
-
-/* Register values to detect the OMAP version */
-static struct omap_id omap_ids[] __initdata = {
-       { .jtag_id = 0x355f, .die_rev = 0x0, .omap_id = 0x03320000, .type = 0x07300100},
-       { .jtag_id = 0xb55f, .die_rev = 0x0, .omap_id = 0x03320000, .type = 0x07300300},
-       { .jtag_id = 0xb470, .die_rev = 0x0, .omap_id = 0x03310100, .type = 0x15100000},
-       { .jtag_id = 0xb576, .die_rev = 0x0, .omap_id = 0x03320000, .type = 0x16100000},
-       { .jtag_id = 0xb576, .die_rev = 0x2, .omap_id = 0x03320100, .type = 0x16110000},
-       { .jtag_id = 0xb576, .die_rev = 0x3, .omap_id = 0x03320100, .type = 0x16100c00},
-       { .jtag_id = 0xb576, .die_rev = 0x0, .omap_id = 0x03320200, .type = 0x16100d00},
-       { .jtag_id = 0xb613, .die_rev = 0x0, .omap_id = 0x03320300, .type = 0x1610ef00},
-       { .jtag_id = 0xb613, .die_rev = 0x0, .omap_id = 0x03320300, .type = 0x1610ef00},
-       { .jtag_id = 0xb576, .die_rev = 0x1, .omap_id = 0x03320100, .type = 0x16110000},
-       { .jtag_id = 0xb58c, .die_rev = 0x2, .omap_id = 0x03320200, .type = 0x16110b00},
-       { .jtag_id = 0xb58c, .die_rev = 0x3, .omap_id = 0x03320200, .type = 0x16110c00},
-       { .jtag_id = 0xb65f, .die_rev = 0x0, .omap_id = 0x03320400, .type = 0x16212300},
-       { .jtag_id = 0xb65f, .die_rev = 0x1, .omap_id = 0x03320400, .type = 0x16212300},
-       { .jtag_id = 0xb65f, .die_rev = 0x1, .omap_id = 0x03320500, .type = 0x16212300},
-       { .jtag_id = 0xb5f7, .die_rev = 0x0, .omap_id = 0x03330000, .type = 0x17100000},
-       { .jtag_id = 0xb5f7, .die_rev = 0x1, .omap_id = 0x03330100, .type = 0x17100000},
-       { .jtag_id = 0xb5f7, .die_rev = 0x2, .omap_id = 0x03330100, .type = 0x17100000},
-};
-
-/*
- * Get OMAP type from PROD_ID.
- * 1710 has the PROD_ID in bits 15:00, not in 16:01 as documented in TRM.
- * 1510 PROD_ID is empty, and 1610 PROD_ID does not make sense.
- * Undocumented register in TEST BLOCK is used as fallback; This seems to
- * work on 1510, 1610 & 1710. The official way hopefully will work in future
- * processors.
- */
-static u16 __init omap_get_jtag_id(void)
-{
-       u32 prod_id, omap_id;
-
-       prod_id = omap_readl(OMAP_PRODUCTION_ID_1);
-       omap_id = omap_readl(OMAP32_ID_1);
-
-       /* Check for unusable OMAP_PRODUCTION_ID_1 on 1611B/5912 and 730 */
-       if (((prod_id >> 20) == 0) || (prod_id == omap_id))
-               prod_id = 0;
-       else
-               prod_id &= 0xffff;
-
-       if (prod_id)
-               return prod_id;
-
-       /* Use OMAP32_ID_1 as fallback */
-       prod_id = ((omap_id >> 12) & 0xffff);
-
-       return prod_id;
-}
-
-/*
- * Get OMAP revision from DIE_REV.
- * Early 1710 processors may have broken OMAP_DIE_ID, it contains PROD_ID.
- * Undocumented register in the TEST BLOCK is used as fallback.
- * REVISIT: This does not seem to work on 1510
- */
-static u8 __init omap_get_die_rev(void)
-{
-       u32 die_rev;
-
-       die_rev = omap_readl(OMAP_DIE_ID_1);
-
-       /* Check for broken OMAP_DIE_ID on early 1710 */
-       if (((die_rev >> 12) & 0xffff) == omap_get_jtag_id())
-               die_rev = 0;
-
-       die_rev = (die_rev >> 17) & 0xf;
-       if (die_rev)
-               return die_rev;
-
-       die_rev = (omap_readl(OMAP32_ID_1) >> 28) & 0xf;
-
-       return die_rev;
-}
-
-static void __init omap_check_revision(void)
-{
-       int i;
-       u16 jtag_id;
-       u8 die_rev;
-       u32 omap_id;
-       u8 cpu_type;
-
-       jtag_id = omap_get_jtag_id();
-       die_rev = omap_get_die_rev();
-       omap_id = omap_readl(OMAP32_ID_0);
-
-#ifdef DEBUG
-       printk("OMAP_DIE_ID_0: 0x%08x\n", omap_readl(OMAP_DIE_ID_0));
-       printk("OMAP_DIE_ID_1: 0x%08x DIE_REV: %i\n",
-               omap_readl(OMAP_DIE_ID_1),
-              (omap_readl(OMAP_DIE_ID_1) >> 17) & 0xf);
-       printk("OMAP_PRODUCTION_ID_0: 0x%08x\n", omap_readl(OMAP_PRODUCTION_ID_0));
-       printk("OMAP_PRODUCTION_ID_1: 0x%08x JTAG_ID: 0x%04x\n",
-               omap_readl(OMAP_PRODUCTION_ID_1),
-               omap_readl(OMAP_PRODUCTION_ID_1) & 0xffff);
-       printk("OMAP32_ID_0: 0x%08x\n", omap_readl(OMAP32_ID_0));
-       printk("OMAP32_ID_1: 0x%08x\n", omap_readl(OMAP32_ID_1));
-       printk("JTAG_ID: 0x%04x DIE_REV: %i\n", jtag_id, die_rev);
-#endif
-
-       system_serial_high = omap_readl(OMAP_DIE_ID_0);
-       system_serial_low = omap_readl(OMAP_DIE_ID_1);
-
-       /* First check only the major version in a safe way */
-       for (i = 0; i < ARRAY_SIZE(omap_ids); i++) {
-               if (jtag_id == (omap_ids[i].jtag_id)) {
-                       system_rev = omap_ids[i].type;
-                       break;
-               }
-       }
-
-       /* Check if we can find the die revision */
-       for (i = 0; i < ARRAY_SIZE(omap_ids); i++) {
-               if (jtag_id == omap_ids[i].jtag_id && die_rev == omap_ids[i].die_rev) {
-                       system_rev = omap_ids[i].type;
-                       break;
-               }
-       }
-
-       /* Finally check also the omap_id */
-       for (i = 0; i < ARRAY_SIZE(omap_ids); i++) {
-               if (jtag_id == omap_ids[i].jtag_id
-                   && die_rev == omap_ids[i].die_rev
-                   && omap_id == omap_ids[i].omap_id) {
-                       system_rev = omap_ids[i].type;
-                       break;
-               }
-       }
-
-       /* Add the cpu class info (7xx, 15xx, 16xx, 24xx) */
-       cpu_type = system_rev >> 24;
-
-       switch (cpu_type) {
-       case 0x07:
-               system_rev |= 0x07;
-               break;
-       case 0x15:
-               system_rev |= 0x15;
-               break;
-       case 0x16:
-       case 0x17:
-               system_rev |= 0x16;
-               break;
-       case 0x24:
-               system_rev |= 0x24;
-               break;
-       default:
-               printk("Unknown OMAP cpu type: 0x%02x\n", cpu_type);
-       }
-
-       printk("OMAP%04x", system_rev >> 16);
-       if ((system_rev >> 8) & 0xff)
-               printk("%x", (system_rev >> 8) & 0xff);
-       printk(" revision %i handled as %02xxx id: %08x%08x\n",
-              die_rev, system_rev & 0xff, system_serial_low,
-              system_serial_high);
-}
-
-/*
- * ----------------------------------------------------------------------------
- * OMAP I/O mapping
- *
- * The machine specific code may provide the extra mapping besides the
- * default mapping provided here.
- * ----------------------------------------------------------------------------
- */
-
-static struct map_desc omap_io_desc[] __initdata = {
- { IO_VIRT,            IO_PHYS,             IO_SIZE,              MT_DEVICE },
-};
-
-#ifdef CONFIG_ARCH_OMAP730
-static struct map_desc omap730_io_desc[] __initdata = {
- { OMAP730_DSP_BASE,    OMAP730_DSP_START,    OMAP730_DSP_SIZE,    MT_DEVICE },
- { OMAP730_DSPREG_BASE, OMAP730_DSPREG_START, OMAP730_DSPREG_SIZE, MT_DEVICE },
- { OMAP730_SRAM_BASE,   OMAP730_SRAM_START,   OMAP730_SRAM_SIZE,   MT_DEVICE }
-};
-#endif
-
-#ifdef CONFIG_ARCH_OMAP1510
-static struct map_desc omap1510_io_desc[] __initdata = {
- { OMAP1510_DSP_BASE,    OMAP1510_DSP_START,    OMAP1510_DSP_SIZE,    MT_DEVICE },
- { OMAP1510_DSPREG_BASE, OMAP1510_DSPREG_START, OMAP1510_DSPREG_SIZE, MT_DEVICE },
- { OMAP1510_SRAM_BASE,   OMAP1510_SRAM_START,   OMAP1510_SRAM_SIZE,   MT_DEVICE }
-};
-#endif
-
-#if defined(CONFIG_ARCH_OMAP16XX)
-static struct map_desc omap1610_io_desc[] __initdata = {
- { OMAP16XX_DSP_BASE,    OMAP16XX_DSP_START,    OMAP16XX_DSP_SIZE,    MT_DEVICE },
- { OMAP16XX_DSPREG_BASE, OMAP16XX_DSPREG_START, OMAP16XX_DSPREG_SIZE, MT_DEVICE },
- { OMAP16XX_SRAM_BASE,   OMAP16XX_SRAM_START,   OMAP1610_SRAM_SIZE,   MT_DEVICE }
-};
-
-static struct map_desc omap5912_io_desc[] __initdata = {
- { OMAP16XX_DSP_BASE,    OMAP16XX_DSP_START,    OMAP16XX_DSP_SIZE,    MT_DEVICE },
- { OMAP16XX_DSPREG_BASE, OMAP16XX_DSPREG_START, OMAP16XX_DSPREG_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.
- */
- { OMAP16XX_SRAM_BASE,   OMAP16XX_SRAM_START,   OMAP5912_SRAM_SIZE + 0x800,   MT_DEVICE }
-};
-#endif
-
-static int initialized = 0;
-
-static void __init _omap_map_io(void)
-{
-       initialized = 1;
-
-       /* 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()) {
-               iotable_init(omap730_io_desc, ARRAY_SIZE(omap730_io_desc));
-       }
-#endif
-#ifdef CONFIG_ARCH_OMAP1510
-       if (cpu_is_omap1510()) {
-               iotable_init(omap1510_io_desc, ARRAY_SIZE(omap1510_io_desc));
-       }
-#endif
-#if defined(CONFIG_ARCH_OMAP16XX)
-       if (cpu_is_omap1610() || cpu_is_omap1710()) {
-               iotable_init(omap1610_io_desc, ARRAY_SIZE(omap1610_io_desc));
-       }
-       if (cpu_is_omap5912()) {
-               iotable_init(omap5912_io_desc, ARRAY_SIZE(omap5912_io_desc));
-       }
-#endif
-
-       /* 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);
-       omap_writew(0x0, MPU_PRIVATE_TIPB_CNTL);
-
-       /* Must init clocks early to assure that timer interrupt works
-        */
-       clk_init();
-}
-
-/*
- * This should only get called from board specific init
- */
-void omap_map_io(void)
-{
-       if (!initialized)
-               _omap_map_io();
-}
-
-static inline unsigned int omap_serial_in(struct plat_serial8250_port *up,
-                                         int offset)
-{
-       offset <<= up->regshift;
-       return (unsigned int)__raw_readb(up->membase + offset);
-}
-
-static inline void omap_serial_outp(struct plat_serial8250_port *p, int offset,
-                                   int value)
-{
-       offset <<= p->regshift;
-       __raw_writeb(value, p->membase + offset);
-}
-
-/*
- * Internal UARTs need to be initialized for the 8250 autoconfig to work
- * properly. Note that the TX watermark initialization may not be needed
- * once the 8250.c watermark handling code is merged.
- */
-static void __init omap_serial_reset(struct plat_serial8250_port *p)
-{
-       omap_serial_outp(p, UART_OMAP_MDR1, 0x07);      /* disable UART */
-       omap_serial_outp(p, UART_OMAP_SCR, 0x08);       /* TX watermark */
-       omap_serial_outp(p, UART_OMAP_MDR1, 0x00);      /* enable UART */
-
-       if (!cpu_is_omap1510()) {
-               omap_serial_outp(p, UART_OMAP_SYSC, 0x01);
-               while (!(omap_serial_in(p, UART_OMAP_SYSC) & 0x01));
-       }
-}
-
-static struct plat_serial8250_port serial_platform_data[] = {
-       {
-               .membase        = (char*)IO_ADDRESS(OMAP_UART1_BASE),
-               .mapbase        = (unsigned long)OMAP_UART1_BASE,
-               .irq            = INT_UART1,
-               .flags          = UPF_BOOT_AUTOCONF,
-               .iotype         = UPIO_MEM,
-               .regshift       = 2,
-               .uartclk        = OMAP16XX_BASE_BAUD * 16,
-       },
-       {
-               .membase        = (char*)IO_ADDRESS(OMAP_UART2_BASE),
-               .mapbase        = (unsigned long)OMAP_UART2_BASE,
-               .irq            = INT_UART2,
-               .flags          = UPF_BOOT_AUTOCONF,
-               .iotype         = UPIO_MEM,
-               .regshift       = 2,
-               .uartclk        = OMAP16XX_BASE_BAUD * 16,
-       },
-       {
-               .membase        = (char*)IO_ADDRESS(OMAP_UART3_BASE),
-               .mapbase        = (unsigned long)OMAP_UART3_BASE,
-               .irq            = INT_UART3,
-               .flags          = UPF_BOOT_AUTOCONF,
-               .iotype         = UPIO_MEM,
-               .regshift       = 2,
-               .uartclk        = OMAP16XX_BASE_BAUD * 16,
-       },
-       { },
-};
-
-static struct platform_device serial_device = {
-       .name                   = "serial8250",
-       .id                     = 0,
-       .dev                    = {
-               .platform_data  = serial_platform_data,
-       },
-};
-
-/*
- * Note that on Innovator-1510 UART2 pins conflict with USB2.
- * By default UART2 does not work on Innovator-1510 if you have
- * USB OHCI enabled. To use UART2, you must disable USB2 first.
- */
-void __init omap_serial_init(int ports[OMAP_MAX_NR_PORTS])
-{
-       int i;
-
-       if (cpu_is_omap730()) {
-               serial_platform_data[0].regshift = 0;
-               serial_platform_data[1].regshift = 0;
-               serial_platform_data[0].irq = INT_730_UART_MODEM_1;
-               serial_platform_data[1].irq = INT_730_UART_MODEM_IRDA_2;
-       }
-
-       if (cpu_is_omap1510()) {
-               serial_platform_data[0].uartclk = OMAP1510_BASE_BAUD * 16;
-               serial_platform_data[1].uartclk = OMAP1510_BASE_BAUD * 16;
-               serial_platform_data[2].uartclk = OMAP1510_BASE_BAUD * 16;
-       }
-
-       for (i = 0; i < OMAP_MAX_NR_PORTS; i++) {
-               unsigned char reg;
-
-               if (ports[i] == 0) {
-                       serial_platform_data[i].membase = 0;
-                       serial_platform_data[i].mapbase = 0;
-                       continue;
-               }
-
-               switch (i) {
-               case 0:
-                       if (cpu_is_omap1510()) {
-                               omap_cfg_reg(UART1_TX);
-                               omap_cfg_reg(UART1_RTS);
-                               if (machine_is_omap_innovator()) {
-                                       reg = fpga_read(OMAP1510_FPGA_POWER);
-                                       reg |= OMAP1510_FPGA_PCR_COM1_EN;
-                                       fpga_write(reg, OMAP1510_FPGA_POWER);
-                                       udelay(10);
-                               }
-                       }
-                       break;
-               case 1:
-                       if (cpu_is_omap1510()) {
-                               omap_cfg_reg(UART2_TX);
-                               omap_cfg_reg(UART2_RTS);
-                               if (machine_is_omap_innovator()) {
-                                       reg = fpga_read(OMAP1510_FPGA_POWER);
-                                       reg |= OMAP1510_FPGA_PCR_COM2_EN;
-                                       fpga_write(reg, OMAP1510_FPGA_POWER);
-                                       udelay(10);
-                               }
-                       }
-                       break;
-               case 2:
-                       if (cpu_is_omap1510()) {
-                               omap_cfg_reg(UART3_TX);
-                               omap_cfg_reg(UART3_RX);
-                       }
-                       if (cpu_is_omap1710()) {
-                               clk_enable(clk_get(0, "uart3_ck"));
-                       }
-                       break;
-               }
-               omap_serial_reset(&serial_platform_data[i]);
-       }
-}
-
-static int __init omap_init(void)
-{
-       return platform_device_register(&serial_device);
-}
-arch_initcall(omap_init);
-
 #define NO_LENGTH_CHECK 0xffffffff
 
 extern int omap_bootloader_tag_len;
@@ -532,9 +117,10 @@ EXPORT_SYMBOL(omap_get_var_config);
 
 static int __init omap_add_serial_console(void)
 {
-       const struct omap_uart_config *info;
+       const struct omap_serial_console_config *info;
 
-       info = omap_get_config(OMAP_TAG_UART, struct omap_uart_config);
+       info = omap_get_config(OMAP_TAG_SERIAL_CONSOLE,
+                              struct omap_serial_console_config);
        if (info != NULL && info->console_uart) {
                static char speed[11], *opt = NULL;
 
index 9f62858c0df4afc59df9407a8d31e3f212883f99..bb257344f52d379d40d7cf5b2f94bbf2e947459b 100644 (file)
@@ -29,7 +29,7 @@
 
 struct sys_timer;
 
-extern void omap_map_io(void);
+extern void omap_map_common_io(void);
 extern struct sys_timer omap_timer;
 extern void omap_serial_init(int ports[]);
 
diff --git a/arch/arm/mach-omap1/id.c b/arch/arm/mach-omap1/id.c
new file mode 100644 (file)
index 0000000..986c3b7
--- /dev/null
@@ -0,0 +1,188 @@
+/*
+ * linux/arch/arm/mach-omap1/id.c
+ *
+ * OMAP1 CPU identification code
+ *
+ * Copyright (C) 2004 Nokia Corporation
+ * Written by Tony Lindgren <tony@atomide.com>
+ *
+ * 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/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/io.h>
+
+struct omap_id {
+       u16     jtag_id;        /* Used to determine OMAP type */
+       u8      die_rev;        /* Processor revision */
+       u32     omap_id;        /* OMAP revision */
+       u32     type;           /* Cpu id bits [31:08], cpu class bits [07:00] */
+};
+
+/* Register values to detect the OMAP version */
+static struct omap_id omap_ids[] __initdata = {
+       { .jtag_id = 0x355f, .die_rev = 0x0, .omap_id = 0x03320000, .type = 0x07300100},
+       { .jtag_id = 0xb55f, .die_rev = 0x0, .omap_id = 0x03320000, .type = 0x07300300},
+       { .jtag_id = 0xb470, .die_rev = 0x0, .omap_id = 0x03310100, .type = 0x15100000},
+       { .jtag_id = 0xb576, .die_rev = 0x0, .omap_id = 0x03320000, .type = 0x16100000},
+       { .jtag_id = 0xb576, .die_rev = 0x2, .omap_id = 0x03320100, .type = 0x16110000},
+       { .jtag_id = 0xb576, .die_rev = 0x3, .omap_id = 0x03320100, .type = 0x16100c00},
+       { .jtag_id = 0xb576, .die_rev = 0x0, .omap_id = 0x03320200, .type = 0x16100d00},
+       { .jtag_id = 0xb613, .die_rev = 0x0, .omap_id = 0x03320300, .type = 0x1610ef00},
+       { .jtag_id = 0xb613, .die_rev = 0x0, .omap_id = 0x03320300, .type = 0x1610ef00},
+       { .jtag_id = 0xb576, .die_rev = 0x1, .omap_id = 0x03320100, .type = 0x16110000},
+       { .jtag_id = 0xb58c, .die_rev = 0x2, .omap_id = 0x03320200, .type = 0x16110b00},
+       { .jtag_id = 0xb58c, .die_rev = 0x3, .omap_id = 0x03320200, .type = 0x16110c00},
+       { .jtag_id = 0xb65f, .die_rev = 0x0, .omap_id = 0x03320400, .type = 0x16212300},
+       { .jtag_id = 0xb65f, .die_rev = 0x1, .omap_id = 0x03320400, .type = 0x16212300},
+       { .jtag_id = 0xb65f, .die_rev = 0x1, .omap_id = 0x03320500, .type = 0x16212300},
+       { .jtag_id = 0xb5f7, .die_rev = 0x0, .omap_id = 0x03330000, .type = 0x17100000},
+       { .jtag_id = 0xb5f7, .die_rev = 0x1, .omap_id = 0x03330100, .type = 0x17100000},
+       { .jtag_id = 0xb5f7, .die_rev = 0x2, .omap_id = 0x03330100, .type = 0x17100000},
+};
+
+/*
+ * Get OMAP type from PROD_ID.
+ * 1710 has the PROD_ID in bits 15:00, not in 16:01 as documented in TRM.
+ * 1510 PROD_ID is empty, and 1610 PROD_ID does not make sense.
+ * Undocumented register in TEST BLOCK is used as fallback; This seems to
+ * work on 1510, 1610 & 1710. The official way hopefully will work in future
+ * processors.
+ */
+static u16 __init omap_get_jtag_id(void)
+{
+       u32 prod_id, omap_id;
+
+       prod_id = omap_readl(OMAP_PRODUCTION_ID_1);
+       omap_id = omap_readl(OMAP32_ID_1);
+
+       /* Check for unusable OMAP_PRODUCTION_ID_1 on 1611B/5912 and 730 */
+       if (((prod_id >> 20) == 0) || (prod_id == omap_id))
+               prod_id = 0;
+       else
+               prod_id &= 0xffff;
+
+       if (prod_id)
+               return prod_id;
+
+       /* Use OMAP32_ID_1 as fallback */
+       prod_id = ((omap_id >> 12) & 0xffff);
+
+       return prod_id;
+}
+
+/*
+ * Get OMAP revision from DIE_REV.
+ * Early 1710 processors may have broken OMAP_DIE_ID, it contains PROD_ID.
+ * Undocumented register in the TEST BLOCK is used as fallback.
+ * REVISIT: This does not seem to work on 1510
+ */
+static u8 __init omap_get_die_rev(void)
+{
+       u32 die_rev;
+
+       die_rev = omap_readl(OMAP_DIE_ID_1);
+
+       /* Check for broken OMAP_DIE_ID on early 1710 */
+       if (((die_rev >> 12) & 0xffff) == omap_get_jtag_id())
+               die_rev = 0;
+
+       die_rev = (die_rev >> 17) & 0xf;
+       if (die_rev)
+               return die_rev;
+
+       die_rev = (omap_readl(OMAP32_ID_1) >> 28) & 0xf;
+
+       return die_rev;
+}
+
+void __init omap_check_revision(void)
+{
+       int i;
+       u16 jtag_id;
+       u8 die_rev;
+       u32 omap_id;
+       u8 cpu_type;
+
+       jtag_id = omap_get_jtag_id();
+       die_rev = omap_get_die_rev();
+       omap_id = omap_readl(OMAP32_ID_0);
+
+#ifdef DEBUG
+       printk("OMAP_DIE_ID_0: 0x%08x\n", omap_readl(OMAP_DIE_ID_0));
+       printk("OMAP_DIE_ID_1: 0x%08x DIE_REV: %i\n",
+               omap_readl(OMAP_DIE_ID_1),
+              (omap_readl(OMAP_DIE_ID_1) >> 17) & 0xf);
+       printk("OMAP_PRODUCTION_ID_0: 0x%08x\n", omap_readl(OMAP_PRODUCTION_ID_0));
+       printk("OMAP_PRODUCTION_ID_1: 0x%08x JTAG_ID: 0x%04x\n",
+               omap_readl(OMAP_PRODUCTION_ID_1),
+               omap_readl(OMAP_PRODUCTION_ID_1) & 0xffff);
+       printk("OMAP32_ID_0: 0x%08x\n", omap_readl(OMAP32_ID_0));
+       printk("OMAP32_ID_1: 0x%08x\n", omap_readl(OMAP32_ID_1));
+       printk("JTAG_ID: 0x%04x DIE_REV: %i\n", jtag_id, die_rev);
+#endif
+
+       system_serial_high = omap_readl(OMAP_DIE_ID_0);
+       system_serial_low = omap_readl(OMAP_DIE_ID_1);
+
+       /* First check only the major version in a safe way */
+       for (i = 0; i < ARRAY_SIZE(omap_ids); i++) {
+               if (jtag_id == (omap_ids[i].jtag_id)) {
+                       system_rev = omap_ids[i].type;
+                       break;
+               }
+       }
+
+       /* Check if we can find the die revision */
+       for (i = 0; i < ARRAY_SIZE(omap_ids); i++) {
+               if (jtag_id == omap_ids[i].jtag_id && die_rev == omap_ids[i].die_rev) {
+                       system_rev = omap_ids[i].type;
+                       break;
+               }
+       }
+
+       /* Finally check also the omap_id */
+       for (i = 0; i < ARRAY_SIZE(omap_ids); i++) {
+               if (jtag_id == omap_ids[i].jtag_id
+                   && die_rev == omap_ids[i].die_rev
+                   && omap_id == omap_ids[i].omap_id) {
+                       system_rev = omap_ids[i].type;
+                       break;
+               }
+       }
+
+       /* Add the cpu class info (7xx, 15xx, 16xx, 24xx) */
+       cpu_type = system_rev >> 24;
+
+       switch (cpu_type) {
+       case 0x07:
+               system_rev |= 0x07;
+               break;
+       case 0x15:
+               system_rev |= 0x15;
+               break;
+       case 0x16:
+       case 0x17:
+               system_rev |= 0x16;
+               break;
+       case 0x24:
+               system_rev |= 0x24;
+               break;
+       default:
+               printk("Unknown OMAP cpu type: 0x%02x\n", cpu_type);
+       }
+
+       printk("OMAP%04x", system_rev >> 16);
+       if ((system_rev >> 8) & 0xff)
+               printk("%x", (system_rev >> 8) & 0xff);
+       printk(" revision %i handled as %02xxx id: %08x%08x\n",
+              die_rev, system_rev & 0xff, system_serial_low,
+              system_serial_high);
+}
+
diff --git a/arch/arm/mach-omap1/io.c b/arch/arm/mach-omap1/io.c
new file mode 100644 (file)
index 0000000..8587b33
--- /dev/null
@@ -0,0 +1,116 @@
+/*
+ * linux/arch/arm/mach-omap1/io.c
+ *
+ * OMAP1 I/O mapping 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
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/mach/map.h>
+#include <asm/io.h>
+#include <asm/arch/tc.h>
+
+#include "../clock.h"
+
+extern void omap_check_revision(void);
+
+/*
+ * The machine specific code may provide the extra mapping besides the
+ * default mapping provided here.
+ */
+static struct map_desc omap_io_desc[] __initdata = {
+ { IO_VIRT,            IO_PHYS,             IO_SIZE,              MT_DEVICE },
+};
+
+#ifdef CONFIG_ARCH_OMAP730
+static struct map_desc omap730_io_desc[] __initdata = {
+ { OMAP730_DSP_BASE,    OMAP730_DSP_START,    OMAP730_DSP_SIZE,    MT_DEVICE },
+ { OMAP730_DSPREG_BASE, OMAP730_DSPREG_START, OMAP730_DSPREG_SIZE, MT_DEVICE },
+ { OMAP730_SRAM_BASE,   OMAP730_SRAM_START,   OMAP730_SRAM_SIZE,   MT_DEVICE }
+};
+#endif
+
+#ifdef CONFIG_ARCH_OMAP1510
+static struct map_desc omap1510_io_desc[] __initdata = {
+ { OMAP1510_DSP_BASE,    OMAP1510_DSP_START,    OMAP1510_DSP_SIZE,    MT_DEVICE },
+ { OMAP1510_DSPREG_BASE, OMAP1510_DSPREG_START, OMAP1510_DSPREG_SIZE, MT_DEVICE },
+ { OMAP1510_SRAM_BASE,   OMAP1510_SRAM_START,   OMAP1510_SRAM_SIZE,   MT_DEVICE }
+};
+#endif
+
+#if defined(CONFIG_ARCH_OMAP16XX)
+static struct map_desc omap1610_io_desc[] __initdata = {
+ { OMAP16XX_DSP_BASE,    OMAP16XX_DSP_START,    OMAP16XX_DSP_SIZE,    MT_DEVICE },
+ { OMAP16XX_DSPREG_BASE, OMAP16XX_DSPREG_START, OMAP16XX_DSPREG_SIZE, MT_DEVICE },
+ { OMAP16XX_SRAM_BASE,   OMAP16XX_SRAM_START,   OMAP1610_SRAM_SIZE,   MT_DEVICE }
+};
+
+static struct map_desc omap5912_io_desc[] __initdata = {
+ { OMAP16XX_DSP_BASE,    OMAP16XX_DSP_START,    OMAP16XX_DSP_SIZE,    MT_DEVICE },
+ { OMAP16XX_DSPREG_BASE, OMAP16XX_DSPREG_START, OMAP16XX_DSPREG_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.
+ */
+ { OMAP16XX_SRAM_BASE,   OMAP16XX_SRAM_START,   OMAP5912_SRAM_SIZE + 0x800,   MT_DEVICE }
+};
+#endif
+
+static int initialized = 0;
+
+static void __init _omap_map_io(void)
+{
+       initialized = 1;
+
+       /* 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()) {
+               iotable_init(omap730_io_desc, ARRAY_SIZE(omap730_io_desc));
+       }
+#endif
+#ifdef CONFIG_ARCH_OMAP1510
+       if (cpu_is_omap1510()) {
+               iotable_init(omap1510_io_desc, ARRAY_SIZE(omap1510_io_desc));
+       }
+#endif
+#if defined(CONFIG_ARCH_OMAP16XX)
+       if (cpu_is_omap1610() || cpu_is_omap1710()) {
+               iotable_init(omap1610_io_desc, ARRAY_SIZE(omap1610_io_desc));
+       }
+       if (cpu_is_omap5912()) {
+               iotable_init(omap5912_io_desc, ARRAY_SIZE(omap5912_io_desc));
+       }
+#endif
+
+       /* 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);
+       omap_writew(0x0, MPU_PRIVATE_TIPB_CNTL);
+
+       /* Must init clocks early to assure that timer interrupt works
+        */
+       clk_init();
+}
+
+/*
+ * This should only get called from board specific init
+ */
+void omap_map_common_io(void)
+{
+       if (!initialized)
+               _omap_map_io();
+}
diff --git a/arch/arm/mach-omap1/serial.c b/arch/arm/mach-omap1/serial.c
new file mode 100644 (file)
index 0000000..214e5d1
--- /dev/null
@@ -0,0 +1,200 @@
+/*
+ * linux/arch/arm/mach-omap1/id.c
+ *
+ * OMAP1 CPU identification 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
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/serial.h>
+#include <linux/tty.h>
+#include <linux/serial_8250.h>
+#include <linux/serial_reg.h>
+
+#include <asm/io.h>
+#include <asm/mach-types.h>
+#include <asm/hardware/clock.h>
+
+#include <asm/arch/board.h>
+#include <asm/arch/mux.h>
+#include <asm/arch/fpga.h>
+
+static struct clk * uart1_ck = NULL;
+static struct clk * uart2_ck = NULL;
+static struct clk * uart3_ck = NULL;
+
+static inline unsigned int omap_serial_in(struct plat_serial8250_port *up,
+                                         int offset)
+{
+       offset <<= up->regshift;
+       return (unsigned int)__raw_readb(up->membase + offset);
+}
+
+static inline void omap_serial_outp(struct plat_serial8250_port *p, int offset,
+                                   int value)
+{
+       offset <<= p->regshift;
+       __raw_writeb(value, p->membase + offset);
+}
+
+/*
+ * Internal UARTs need to be initialized for the 8250 autoconfig to work
+ * properly. Note that the TX watermark initialization may not be needed
+ * once the 8250.c watermark handling code is merged.
+ */
+static void __init omap_serial_reset(struct plat_serial8250_port *p)
+{
+       omap_serial_outp(p, UART_OMAP_MDR1, 0x07);      /* disable UART */
+       omap_serial_outp(p, UART_OMAP_SCR, 0x08);       /* TX watermark */
+       omap_serial_outp(p, UART_OMAP_MDR1, 0x00);      /* enable UART */
+
+       if (!cpu_is_omap1510()) {
+               omap_serial_outp(p, UART_OMAP_SYSC, 0x01);
+               while (!(omap_serial_in(p, UART_OMAP_SYSC) & 0x01));
+       }
+}
+
+static struct plat_serial8250_port serial_platform_data[] = {
+       {
+               .membase        = (char*)IO_ADDRESS(OMAP_UART1_BASE),
+               .mapbase        = (unsigned long)OMAP_UART1_BASE,
+               .irq            = INT_UART1,
+               .flags          = UPF_BOOT_AUTOCONF,
+               .iotype         = UPIO_MEM,
+               .regshift       = 2,
+               .uartclk        = OMAP16XX_BASE_BAUD * 16,
+       },
+       {
+               .membase        = (char*)IO_ADDRESS(OMAP_UART2_BASE),
+               .mapbase        = (unsigned long)OMAP_UART2_BASE,
+               .irq            = INT_UART2,
+               .flags          = UPF_BOOT_AUTOCONF,
+               .iotype         = UPIO_MEM,
+               .regshift       = 2,
+               .uartclk        = OMAP16XX_BASE_BAUD * 16,
+       },
+       {
+               .membase        = (char*)IO_ADDRESS(OMAP_UART3_BASE),
+               .mapbase        = (unsigned long)OMAP_UART3_BASE,
+               .irq            = INT_UART3,
+               .flags          = UPF_BOOT_AUTOCONF,
+               .iotype         = UPIO_MEM,
+               .regshift       = 2,
+               .uartclk        = OMAP16XX_BASE_BAUD * 16,
+       },
+       { },
+};
+
+static struct platform_device serial_device = {
+       .name                   = "serial8250",
+       .id                     = 0,
+       .dev                    = {
+               .platform_data  = serial_platform_data,
+       },
+};
+
+/*
+ * Note that on Innovator-1510 UART2 pins conflict with USB2.
+ * By default UART2 does not work on Innovator-1510 if you have
+ * USB OHCI enabled. To use UART2, you must disable USB2 first.
+ */
+void __init omap_serial_init(int ports[OMAP_MAX_NR_PORTS])
+{
+       int i;
+
+       if (cpu_is_omap730()) {
+               serial_platform_data[0].regshift = 0;
+               serial_platform_data[1].regshift = 0;
+               serial_platform_data[0].irq = INT_730_UART_MODEM_1;
+               serial_platform_data[1].irq = INT_730_UART_MODEM_IRDA_2;
+       }
+
+       if (cpu_is_omap1510()) {
+               serial_platform_data[0].uartclk = OMAP1510_BASE_BAUD * 16;
+               serial_platform_data[1].uartclk = OMAP1510_BASE_BAUD * 16;
+               serial_platform_data[2].uartclk = OMAP1510_BASE_BAUD * 16;
+       }
+
+       for (i = 0; i < OMAP_MAX_NR_PORTS; i++) {
+               unsigned char reg;
+
+               if (ports[i] == 0) {
+                       serial_platform_data[i].membase = NULL;
+                       serial_platform_data[i].mapbase = 0;
+                       continue;
+               }
+
+               switch (i) {
+               case 0:
+                       uart1_ck = clk_get(NULL, "uart1_ck");
+                       if (IS_ERR(uart1_ck))
+                               printk("Could not get uart1_ck\n");
+                       else {
+                               clk_use(uart1_ck);
+                               if (cpu_is_omap1510())
+                                       clk_set_rate(uart1_ck, 12000000);
+                       }
+                       if (cpu_is_omap1510()) {
+                               omap_cfg_reg(UART1_TX);
+                               omap_cfg_reg(UART1_RTS);
+                               if (machine_is_omap_innovator()) {
+                                       reg = fpga_read(OMAP1510_FPGA_POWER);
+                                       reg |= OMAP1510_FPGA_PCR_COM1_EN;
+                                       fpga_write(reg, OMAP1510_FPGA_POWER);
+                                       udelay(10);
+                               }
+                       }
+                       break;
+               case 1:
+                       uart2_ck = clk_get(NULL, "uart2_ck");
+                       if (IS_ERR(uart2_ck))
+                               printk("Could not get uart2_ck\n");
+                       else {
+                               clk_use(uart2_ck);
+                               if (cpu_is_omap1510())
+                                       clk_set_rate(uart2_ck, 12000000);
+                               else
+                                       clk_set_rate(uart2_ck, 48000000);
+                       }
+                       if (cpu_is_omap1510()) {
+                               omap_cfg_reg(UART2_TX);
+                               omap_cfg_reg(UART2_RTS);
+                               if (machine_is_omap_innovator()) {
+                                       reg = fpga_read(OMAP1510_FPGA_POWER);
+                                       reg |= OMAP1510_FPGA_PCR_COM2_EN;
+                                       fpga_write(reg, OMAP1510_FPGA_POWER);
+                                       udelay(10);
+                               }
+                       }
+                       break;
+               case 2:
+                       uart3_ck = clk_get(NULL, "uart3_ck");
+                       if (IS_ERR(uart3_ck))
+                               printk("Could not get uart3_ck\n");
+                       else {
+                               clk_use(uart3_ck);
+                               if (cpu_is_omap1510())
+                                       clk_set_rate(uart3_ck, 12000000);
+                       }
+                       if (cpu_is_omap1510()) {
+                               omap_cfg_reg(UART3_TX);
+                               omap_cfg_reg(UART3_RX);
+                       }
+                       break;
+               }
+               omap_serial_reset(&serial_platform_data[i]);
+       }
+}
+
+static int __init omap_init(void)
+{
+       return platform_device_register(&serial_device);
+}
+arch_initcall(omap_init);