|
@@ -33,421 +33,6 @@
|
|
|
|
|
|
#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;
|
|
|
|