From 995411953604e3c973328dda8c7807e45aca0f2b Mon Sep 17 00:00:00 2001 From: Afzal Mohammed Date: Tue, 13 Dec 2011 10:46:43 -0800 Subject: ARM: OMAP: am33xx: Update common omap platform files This patch updates the common platform files with AM335X device support (AM33XX family). The approach taken in this patch is, AM33XX device will be considered as OMAP3 variant, and a separate SoC class created for AM33XX family of devices with a subclass type for AM335X device, which is newly added device in the family. This means, cpu_is_omap34xx(), cpu_is_am33xx() and cpu_is_am335x() checks will return success on AM335X device. A kernel config option CONFIG_SOC_OMAPAM33XX is added under OMAP3 to include support for AM33XX build. Also, cpu_mask and RATE_IN_XXX flags have crossed 8 bit hence struct clksel_rate.flags, struct prcm_config.flags and cpu_mask are changed to u16 from u8. Signed-off-by: Afzal Mohammed Signed-off-by: Vaibhav Hiremath Cc: Hemant Pedanekar [tony@atomide.com: left out CK_AM33XX for now] Signed-off-by: Tony Lindgren --- arch/arm/plat-omap/include/plat/clock.h | 3 ++- arch/arm/plat-omap/include/plat/cpu.h | 25 +++++++++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) (limited to 'arch/arm/plat-omap/include/plat') diff --git a/arch/arm/plat-omap/include/plat/clock.h b/arch/arm/plat-omap/include/plat/clock.h index eb73ab40e95..bb3e423b731 100644 --- a/arch/arm/plat-omap/include/plat/clock.h +++ b/arch/arm/plat-omap/include/plat/clock.h @@ -59,6 +59,7 @@ struct clkops { #define RATE_IN_4430 (1 << 5) #define RATE_IN_TI816X (1 << 6) #define RATE_IN_4460 (1 << 7) +#define RATE_IN_AM33XX (1 << 8) #define RATE_IN_24XX (RATE_IN_242X | RATE_IN_243X) #define RATE_IN_34XX (RATE_IN_3430ES1 | RATE_IN_3430ES2PLUS) @@ -84,7 +85,7 @@ struct clkops { struct clksel_rate { u32 val; u8 div; - u8 flags; + u16 flags; }; /** diff --git a/arch/arm/plat-omap/include/plat/cpu.h b/arch/arm/plat-omap/include/plat/cpu.h index 408a12f7920..aa52d1e61eb 100644 --- a/arch/arm/plat-omap/include/plat/cpu.h +++ b/arch/arm/plat-omap/include/plat/cpu.h @@ -78,6 +78,14 @@ static inline int is_omap ##class (void) \ return (GET_OMAP_CLASS == (id)) ? 1 : 0; \ } +#define GET_AM_CLASS ((omap_rev() >> 24) & 0xff) + +#define IS_AM_CLASS(class, id) \ +static inline int is_am ##class (void) \ +{ \ + return (GET_AM_CLASS == (id)) ? 1 : 0; \ +} + #define GET_OMAP_SUBCLASS ((omap_rev() >> 20) & 0x0fff) #define IS_OMAP_SUBCLASS(subclass, id) \ @@ -92,12 +100,19 @@ static inline int is_ti ##subclass (void) \ return (GET_OMAP_SUBCLASS == (id)) ? 1 : 0; \ } +#define IS_AM_SUBCLASS(subclass, id) \ +static inline int is_am ##subclass (void) \ +{ \ + return (GET_OMAP_SUBCLASS == (id)) ? 1 : 0; \ +} + IS_OMAP_CLASS(7xx, 0x07) IS_OMAP_CLASS(15xx, 0x15) IS_OMAP_CLASS(16xx, 0x16) IS_OMAP_CLASS(24xx, 0x24) IS_OMAP_CLASS(34xx, 0x34) IS_OMAP_CLASS(44xx, 0x44) +IS_AM_CLASS(33xx, 0x33) IS_OMAP_SUBCLASS(242x, 0x242) IS_OMAP_SUBCLASS(243x, 0x243) @@ -107,6 +122,7 @@ IS_OMAP_SUBCLASS(443x, 0x443) IS_OMAP_SUBCLASS(446x, 0x446) IS_TI_SUBCLASS(816x, 0x816) +IS_AM_SUBCLASS(335x, 0x335) #define cpu_is_omap7xx() 0 #define cpu_is_omap15xx() 0 @@ -117,6 +133,8 @@ IS_TI_SUBCLASS(816x, 0x816) #define cpu_is_omap34xx() 0 #define cpu_is_omap343x() 0 #define cpu_is_ti816x() 0 +#define cpu_is_am33xx() 0 +#define cpu_is_am335x() 0 #define cpu_is_omap44xx() 0 #define cpu_is_omap443x() 0 #define cpu_is_omap446x() 0 @@ -323,6 +341,8 @@ IS_OMAP_TYPE(3517, 0x3517) # undef cpu_is_omap3505 # undef cpu_is_omap3517 # undef cpu_is_ti816x +# undef cpu_is_am33xx +# undef cpu_is_am335x # define cpu_is_omap3430() is_omap3430() # define cpu_is_omap3503() (cpu_is_omap3430() && \ (!omap3_has_iva()) && \ @@ -340,6 +360,8 @@ IS_OMAP_TYPE(3517, 0x3517) # undef cpu_is_omap3630 # define cpu_is_omap3630() is_omap363x() # define cpu_is_ti816x() is_ti816x() +# define cpu_is_am33xx() is_am33xx() +# define cpu_is_am335x() is_am335x() #endif # if defined(CONFIG_ARCH_OMAP4) @@ -386,6 +408,9 @@ IS_OMAP_TYPE(3517, 0x3517) #define TI8168_REV_ES1_0 TI816X_CLASS #define TI8168_REV_ES1_1 (TI816X_CLASS | (0x1 << 8)) +#define AM335X_CLASS 0x33500034 +#define AM335X_REV_ES1_0 AM335X_CLASS + #define OMAP443X_CLASS 0x44300044 #define OMAP4430_REV_ES1_0 (OMAP443X_CLASS | (0x10 << 8)) #define OMAP4430_REV_ES2_0 (OMAP443X_CLASS | (0x20 << 8)) -- cgit v1.2.3-70-g09d2 From 1e6cb146c39cdef1ffc340c13637fce2ba5575be Mon Sep 17 00:00:00 2001 From: Afzal Mohammed Date: Tue, 13 Dec 2011 10:46:43 -0800 Subject: ARM: OMAP: am33xx: Update common OMAP machine specific sources This patch updates the common machine specific source files for support for AM33XX/AM335x with cpu type, macros for identification of AM33XX/AM335X device. Signed-off-by: Afzal Mohammed Signed-off-by: Vaibhav Hiremath Reviewed-by: Kevin Hilman Tested-by: Kevin Hilman [tony@atomide.com: updated for map_io and common.h changes, dropped CK_AM33XX] Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/clock3xxx_data.c | 2 ++ arch/arm/mach-omap2/common.c | 21 +++++++++++++++++++++ arch/arm/mach-omap2/common.h | 10 ++++++++++ arch/arm/mach-omap2/id.c | 6 ++++++ arch/arm/mach-omap2/io.c | 24 ++++++++++++++++++++++++ arch/arm/mach-omap2/serial.c | 4 ++-- arch/arm/plat-omap/Makefile | 1 - arch/arm/plat-omap/include/plat/am33xx.h | 25 +++++++++++++++++++++++++ arch/arm/plat-omap/include/plat/hardware.h | 1 + arch/arm/plat-omap/include/plat/io.h | 12 ++++++++++++ arch/arm/plat-omap/include/plat/omap34xx.h | 2 ++ 11 files changed, 105 insertions(+), 3 deletions(-) create mode 100644 arch/arm/plat-omap/include/plat/am33xx.h (limited to 'arch/arm/plat-omap/include/plat') diff --git a/arch/arm/mach-omap2/clock3xxx_data.c b/arch/arm/mach-omap2/clock3xxx_data.c index 5d0064a4fb5..3d56d8a2b86 100644 --- a/arch/arm/mach-omap2/clock3xxx_data.c +++ b/arch/arm/mach-omap2/clock3xxx_data.c @@ -3517,6 +3517,8 @@ int __init omap3xxx_clk_init(void) } else if (cpu_is_ti816x()) { cpu_mask = RATE_IN_TI816X; cpu_clkflg = CK_TI816X; + } else if (cpu_is_am33xx()) { + cpu_mask = RATE_IN_AM33XX; } else if (cpu_is_omap34xx()) { if (omap_rev() == OMAP3430_REV_ES1_0) { cpu_mask = RATE_IN_3430ES1; diff --git a/arch/arm/mach-omap2/common.c b/arch/arm/mach-omap2/common.c index 684b8a7cd40..c900dcb6f1f 100644 --- a/arch/arm/mach-omap2/common.c +++ b/arch/arm/mach-omap2/common.c @@ -128,6 +128,27 @@ void __init omap2_set_globals_ti816x(void) { __omap2_set_globals(&ti816x_globals); } + +#define AM33XX_TAP_BASE (AM33XX_CTRL_BASE + \ + TI816X_CONTROL_DEVICE_ID - 0x204) + +static struct omap_globals am33xx_globals = { + .class = AM335X_CLASS, + .tap = AM33XX_L4_WK_IO_ADDRESS(AM33XX_TAP_BASE), + .ctrl = AM33XX_L4_WK_IO_ADDRESS(AM33XX_CTRL_BASE), + .prm = AM33XX_L4_WK_IO_ADDRESS(AM33XX_PRCM_BASE), + .cm = AM33XX_L4_WK_IO_ADDRESS(AM33XX_PRCM_BASE), +}; + +void __init omap2_set_globals_am33xx(void) +{ + __omap2_set_globals(&am33xx_globals); +} + +void __init am33xx_map_io(void) +{ + omapam33xx_map_common_io(); +} #endif #if defined(CONFIG_ARCH_OMAP4) diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h index 012bac7d56a..9b733e343bf 100644 --- a/arch/arm/mach-omap2/common.h +++ b/arch/arm/mach-omap2/common.h @@ -60,6 +60,14 @@ static inline void omapti816x_map_common_io(void) } #endif +#ifdef CONFIG_SOC_OMAPAM33XX +extern void omapam33xx_map_common_io(void); +#else +static inline void omapam33xx_map_common_io(void) +{ +} +#endif + #ifdef CONFIG_ARCH_OMAP4 extern void omap44xx_map_common_io(void); #else @@ -107,6 +115,7 @@ void omap2_set_globals_243x(void); void omap2_set_globals_3xxx(void); void omap2_set_globals_443x(void); void omap2_set_globals_ti816x(void); +void omap2_set_globals_am33xx(void); /* These get called from omap2_set_globals_xxxx(), do not call these */ void omap2_set_globals_tap(struct omap_globals *); @@ -117,6 +126,7 @@ void omap2_set_globals_prcm(struct omap_globals *); void omap242x_map_io(void); void omap243x_map_io(void); void omap3_map_io(void); +void am33xx_map_io(void); void omap4_map_io(void); /** diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c index 27ad722df63..7ab09f76460 100644 --- a/arch/arm/mach-omap2/id.c +++ b/arch/arm/mach-omap2/id.c @@ -340,6 +340,10 @@ static void __init omap3_check_revision(const char **cpu_rev) break; } break; + case 0xb944: + omap_revision = AM335X_REV_ES1_0; + *cpu_rev = "1.0"; + break; default: /* Unknown default to latest silicon rev as default */ omap_revision = OMAP3630_REV_ES1_2; @@ -432,6 +436,8 @@ static void __init omap3_cpuinfo(const char *cpu_rev) cpu_name = (omap3_has_sgx()) ? "AM3517" : "AM3505"; } else if (cpu_is_ti816x()) { cpu_name = "TI816X"; + } else if (cpu_is_am335x()) { + cpu_name = "AM335X"; } else if (omap3_has_iva() && omap3_has_sgx()) { /* OMAP3430, OMAP3525, OMAP3515, OMAP3503 devices */ cpu_name = "OMAP3430/3530"; diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c index 3f565dd2ea8..088d2ba60ef 100644 --- a/arch/arm/mach-omap2/io.c +++ b/arch/arm/mach-omap2/io.c @@ -178,12 +178,29 @@ static struct map_desc omap34xx_io_desc[] __initdata = { #ifdef CONFIG_SOC_OMAPTI816X static struct map_desc omapti816x_io_desc[] __initdata = { + { + .virtual = L4_34XX_VIRT, + .pfn = __phys_to_pfn(L4_34XX_PHYS), + .length = L4_34XX_SIZE, + .type = MT_DEVICE + } +}; +#endif + +#ifdef CONFIG_SOC_OMAPAM33XX +static struct map_desc omapam33xx_io_desc[] __initdata = { { .virtual = L4_34XX_VIRT, .pfn = __phys_to_pfn(L4_34XX_PHYS), .length = L4_34XX_SIZE, .type = MT_DEVICE }, + { + .virtual = L4_WK_AM33XX_VIRT, + .pfn = __phys_to_pfn(L4_WK_AM33XX_PHYS), + .length = L4_WK_AM33XX_SIZE, + .type = MT_DEVICE + } }; #endif @@ -270,6 +287,13 @@ void __init omapti816x_map_common_io(void) } #endif +#ifdef CONFIG_SOC_OMAPAM33XX +void __init omapam33xx_map_common_io(void) +{ + iotable_init(omapam33xx_io_desc, ARRAY_SIZE(omapam33xx_io_desc)); +} +#endif + #ifdef CONFIG_ARCH_OMAP4 void __init omap44xx_map_common_io(void) { diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c index 42c326732a2..9770c7624aa 100644 --- a/arch/arm/mach-omap2/serial.c +++ b/arch/arm/mach-omap2/serial.c @@ -464,7 +464,7 @@ static void omap_uart_idle_init(struct omap_uart_state *uart) mod_timer(&uart->timer, jiffies + uart->timeout); omap_uart_smart_idle_enable(uart, 0); - if (cpu_is_omap34xx() && !cpu_is_ti816x()) { + if (cpu_is_omap34xx() && !(cpu_is_ti816x() || cpu_is_am33xx())) { u32 mod = (uart->num > 1) ? OMAP3430_PER_MOD : CORE_MOD; u32 wk_mask = 0; u32 padconf = 0; @@ -828,7 +828,7 @@ void __init omap_serial_init_port(struct omap_board_data *bdata) } /* Enable the MDR1 errata for OMAP3 */ - if (cpu_is_omap34xx() && !cpu_is_ti816x()) + if (cpu_is_omap34xx() && !(cpu_is_ti816x() || cpu_is_am33xx())) uart->errata |= UART_ERRATA_i202_MDR1_ACCESS; } diff --git a/arch/arm/plat-omap/Makefile b/arch/arm/plat-omap/Makefile index 3df04d944e4..9a584614e7e 100644 --- a/arch/arm/plat-omap/Makefile +++ b/arch/arm/plat-omap/Makefile @@ -19,7 +19,6 @@ obj-$(CONFIG_ARCH_OMAP4) += omap_device.o obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o -obj-$(CONFIG_CPU_FREQ) += cpu-omap.o obj-$(CONFIG_OMAP_DM_TIMER) += dmtimer.o obj-$(CONFIG_OMAP_DEBUG_DEVICES) += debug-devices.o obj-$(CONFIG_OMAP_DEBUG_LEDS) += debug-leds.o diff --git a/arch/arm/plat-omap/include/plat/am33xx.h b/arch/arm/plat-omap/include/plat/am33xx.h new file mode 100644 index 00000000000..06c19bb7bca --- /dev/null +++ b/arch/arm/plat-omap/include/plat/am33xx.h @@ -0,0 +1,25 @@ +/* + * This file contains the address info for various AM33XX modules. + * + * Copyright (C) 2011 Texas Instruments, Inc. - http://www.ti.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 the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __ASM_ARCH_AM33XX_H +#define __ASM_ARCH_AM33XX_H + +#define L4_SLOW_AM33XX_BASE 0x48000000 + +#define AM33XX_SCM_BASE 0x44E10000 +#define AM33XX_CTRL_BASE AM33XX_SCM_BASE +#define AM33XX_PRCM_BASE 0x44E00000 + +#endif /* __ASM_ARCH_AM33XX_H */ diff --git a/arch/arm/plat-omap/include/plat/hardware.h b/arch/arm/plat-omap/include/plat/hardware.h index e87efe1499b..e6521e120d9 100644 --- a/arch/arm/plat-omap/include/plat/hardware.h +++ b/arch/arm/plat-omap/include/plat/hardware.h @@ -287,5 +287,6 @@ #include #include #include +#include #endif /* __ASM_ARCH_OMAP_HARDWARE_H */ diff --git a/arch/arm/plat-omap/include/plat/io.h b/arch/arm/plat-omap/include/plat/io.h index 1234944a4da..0696bae1818 100644 --- a/arch/arm/plat-omap/include/plat/io.h +++ b/arch/arm/plat-omap/include/plat/io.h @@ -73,6 +73,9 @@ #define OMAP4_L3_IO_OFFSET 0xb4000000 #define OMAP4_L3_IO_ADDRESS(pa) IOMEM((pa) + OMAP4_L3_IO_OFFSET) /* L3 */ +#define AM33XX_L4_WK_IO_OFFSET 0xb5000000 +#define AM33XX_L4_WK_IO_ADDRESS(pa) IOMEM((pa) + AM33XX_L4_WK_IO_OFFSET) + #define OMAP4_L3_PER_IO_OFFSET 0xb1100000 #define OMAP4_L3_PER_IO_ADDRESS(pa) IOMEM((pa) + OMAP4_L3_PER_IO_OFFSET) @@ -153,6 +156,15 @@ #define L4_34XX_VIRT (L4_34XX_PHYS + OMAP2_L4_IO_OFFSET) #define L4_34XX_SIZE SZ_4M /* 1MB of 128MB used, want 1MB sect */ +/* + * ---------------------------------------------------------------------------- + * AM33XX specific IO mapping + * ---------------------------------------------------------------------------- + */ +#define L4_WK_AM33XX_PHYS L4_WK_AM33XX_BASE +#define L4_WK_AM33XX_VIRT (L4_WK_AM33XX_PHYS + AM33XX_L4_WK_IO_OFFSET) +#define L4_WK_AM33XX_SIZE SZ_4M /* 1MB of 128MB used, want 1MB sect */ + /* * Need to look at the Size 4M for L4. * VPOM3430 was not working for Int controller diff --git a/arch/arm/plat-omap/include/plat/omap34xx.h b/arch/arm/plat-omap/include/plat/omap34xx.h index b9e85886b9d..0d818acf391 100644 --- a/arch/arm/plat-omap/include/plat/omap34xx.h +++ b/arch/arm/plat-omap/include/plat/omap34xx.h @@ -35,6 +35,8 @@ #define L4_EMU_34XX_BASE 0x54000000 #define L3_34XX_BASE 0x68000000 +#define L4_WK_AM33XX_BASE 0x44C00000 + #define OMAP3430_32KSYNCT_BASE 0x48320000 #define OMAP3430_CM_BASE 0x48004800 #define OMAP3430_PRM_BASE 0x48306800 -- cgit v1.2.3-70-g09d2 From 55035c1524b5b48ac7d267167c4895f7831897ad Mon Sep 17 00:00:00 2001 From: David Anders Date: Tue, 13 Dec 2011 10:46:44 -0800 Subject: ARM: OMAP: id: add chip id recognition for omap4430 es2.3 allow for the omap4430 es2.3 revision to be recognized in the omap4_check_revision() function. most aspects of all omap4430 es2.x versions are identical, however a number of small variations such as default pullup or pulldown resistor configurations vary between revisions. detailed information on silicon errata for omap4430 revisions can be found at http://focus.ti.com/pdfs/wtbu/swpz009D.pdf Signed-off-by: David Anders Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/id.c | 7 +++++-- arch/arm/plat-omap/include/plat/cpu.h | 1 + 2 files changed, 6 insertions(+), 2 deletions(-) (limited to 'arch/arm/plat-omap/include/plat') diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c index 7ab09f76460..5bb4ee18564 100644 --- a/arch/arm/mach-omap2/id.c +++ b/arch/arm/mach-omap2/id.c @@ -393,8 +393,11 @@ static void __init omap4_check_revision(void) omap_revision = OMAP4430_REV_ES2_1; break; case 4: - default: omap_revision = OMAP4430_REV_ES2_2; + break; + case 6: + default: + omap_revision = OMAP4430_REV_ES2_3; } break; case 0xb94e: @@ -407,7 +410,7 @@ static void __init omap4_check_revision(void) break; default: /* Unknown default to latest silicon rev as default */ - omap_revision = OMAP4430_REV_ES2_2; + omap_revision = OMAP4430_REV_ES2_3; } pr_info("OMAP%04x ES%d.%d\n", omap_rev() >> 16, diff --git a/arch/arm/plat-omap/include/plat/cpu.h b/arch/arm/plat-omap/include/plat/cpu.h index aa52d1e61eb..e5baa3cde90 100644 --- a/arch/arm/plat-omap/include/plat/cpu.h +++ b/arch/arm/plat-omap/include/plat/cpu.h @@ -416,6 +416,7 @@ IS_OMAP_TYPE(3517, 0x3517) #define OMAP4430_REV_ES2_0 (OMAP443X_CLASS | (0x20 << 8)) #define OMAP4430_REV_ES2_1 (OMAP443X_CLASS | (0x21 << 8)) #define OMAP4430_REV_ES2_2 (OMAP443X_CLASS | (0x22 << 8)) +#define OMAP4430_REV_ES2_3 (OMAP443X_CLASS | (0x23 << 8)) #define OMAP446X_CLASS 0x44600044 #define OMAP4460_REV_ES1_0 (OMAP446X_CLASS | (0x10 << 8)) -- cgit v1.2.3-70-g09d2 From ec023e46f7e86acb04fef5bdd1e9465f5fc39894 Mon Sep 17 00:00:00 2001 From: Leonid Iziumtsev Date: Tue, 13 Dec 2011 10:46:44 -0800 Subject: ARM: OMAP: ID: Chip detection for OMAP4470 Add support for detection of the next chip in the OMAP4 family: OMAP4470 ES1.0 For more details on OMAP4470, visit: http://focus.ti.com/general/docs/wtbu/wtbuproductcontent.tsp?templateId=6123&navigationId=12869&contentId=123362 Signed-off-by: Leonid Iziumtsev Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/id.c | 10 +++++++++- arch/arm/plat-omap/include/plat/cpu.h | 8 ++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) (limited to 'arch/arm/plat-omap/include/plat') diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c index 5bb4ee18564..439afe7acdc 100644 --- a/arch/arm/mach-omap2/id.c +++ b/arch/arm/mach-omap2/id.c @@ -371,7 +371,7 @@ static void __init omap4_check_revision(void) * Few initial 4430 ES2.0 samples IDCODE is same as ES1.0 * Use ARM register to detect the correct ES version */ - if (!rev && (hawkeye != 0xb94e)) { + if (!rev && (hawkeye != 0xb94e) && (hawkeye != 0xb975)) { idcode = read_cpuid(CPUID_ID); rev = (idcode & 0xf) - 1; } @@ -408,6 +408,14 @@ static void __init omap4_check_revision(void) break; } break; + case 0xb975: + switch (rev) { + case 0: + default: + omap_revision = OMAP4470_REV_ES1_0; + break; + } + break; default: /* Unknown default to latest silicon rev as default */ omap_revision = OMAP4430_REV_ES2_3; diff --git a/arch/arm/plat-omap/include/plat/cpu.h b/arch/arm/plat-omap/include/plat/cpu.h index e5baa3cde90..34fc9136b1a 100644 --- a/arch/arm/plat-omap/include/plat/cpu.h +++ b/arch/arm/plat-omap/include/plat/cpu.h @@ -69,6 +69,7 @@ unsigned int omap_rev(void); * cpu_is_omap343x(): True for OMAP3430 * cpu_is_omap443x(): True for OMAP4430 * cpu_is_omap446x(): True for OMAP4460 + * cpu_is_omap447x(): True for OMAP4470 */ #define GET_OMAP_CLASS (omap_rev() & 0xff) @@ -120,6 +121,7 @@ IS_OMAP_SUBCLASS(343x, 0x343) IS_OMAP_SUBCLASS(363x, 0x363) IS_OMAP_SUBCLASS(443x, 0x443) IS_OMAP_SUBCLASS(446x, 0x446) +IS_OMAP_SUBCLASS(447x, 0x447) IS_TI_SUBCLASS(816x, 0x816) IS_AM_SUBCLASS(335x, 0x335) @@ -138,6 +140,7 @@ IS_AM_SUBCLASS(335x, 0x335) #define cpu_is_omap44xx() 0 #define cpu_is_omap443x() 0 #define cpu_is_omap446x() 0 +#define cpu_is_omap447x() 0 #if defined(MULTI_OMAP1) # if defined(CONFIG_ARCH_OMAP730) @@ -368,9 +371,11 @@ IS_OMAP_TYPE(3517, 0x3517) # undef cpu_is_omap44xx # undef cpu_is_omap443x # undef cpu_is_omap446x +# undef cpu_is_omap447x # define cpu_is_omap44xx() is_omap44xx() # define cpu_is_omap443x() is_omap443x() # define cpu_is_omap446x() is_omap446x() +# define cpu_is_omap447x() is_omap447x() # endif /* Macros to detect if we have OMAP1 or OMAP2 */ @@ -421,6 +426,9 @@ IS_OMAP_TYPE(3517, 0x3517) #define OMAP446X_CLASS 0x44600044 #define OMAP4460_REV_ES1_0 (OMAP446X_CLASS | (0x10 << 8)) +#define OMAP447X_CLASS 0x44700044 +#define OMAP4470_REV_ES1_0 (OMAP447X_CLASS | (0x10 << 8)) + void omap2_check_revision(void); /* -- cgit v1.2.3-70-g09d2 From a920360f038e976e7a86b002e209402da20e9147 Mon Sep 17 00:00:00 2001 From: Hemant Pedanekar Date: Tue, 13 Dec 2011 10:46:44 -0800 Subject: ARM: OMAP: TI81XX: Prepare for addition of TI814X support This patch updates existing macros, functions used for TI816X, to enable addition of other SoCs belonging to TI81XX family (e.g., TI814X). The approach taken is to use TI81XX/ti81xx for code/data going to be common across all TI81XX devices. cpu_is_ti81xx() is introduced to handle code common across TI81XX devices. In addition, ti8168_evm_map_io() is now replaced with ti81xx_map_io() and moved in mach-omap2/common.c as same will be used for TI814X and is not board specific. Signed-off-by: Hemant Pedanekar Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/Kconfig | 6 +++--- arch/arm/mach-omap2/board-ti8168evm.c | 11 +++------- arch/arm/mach-omap2/clock3xxx_data.c | 2 +- arch/arm/mach-omap2/common.c | 29 +++++++++++++++----------- arch/arm/mach-omap2/common.h | 13 ++++++------ arch/arm/mach-omap2/control.h | 8 +++---- arch/arm/mach-omap2/id.c | 8 +++---- arch/arm/mach-omap2/include/mach/debug-macro.S | 12 +++++------ arch/arm/mach-omap2/io.c | 14 ++++++------- arch/arm/mach-omap2/irq.c | 2 +- arch/arm/mach-omap2/serial.c | 6 +++--- arch/arm/plat-omap/include/plat/cpu.h | 13 ++++++++++++ arch/arm/plat-omap/include/plat/hardware.h | 2 +- arch/arm/plat-omap/include/plat/serial.h | 14 ++++++------- arch/arm/plat-omap/include/plat/ti816x.h | 27 ------------------------ arch/arm/plat-omap/include/plat/ti81xx.h | 27 ++++++++++++++++++++++++ arch/arm/plat-omap/include/plat/uncompress.h | 8 +++---- 17 files changed, 108 insertions(+), 94 deletions(-) delete mode 100644 arch/arm/plat-omap/include/plat/ti816x.h create mode 100644 arch/arm/plat-omap/include/plat/ti81xx.h (limited to 'arch/arm/plat-omap/include/plat') diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index ccdd442ca12..f475954c3b9 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig @@ -76,8 +76,8 @@ config SOC_OMAP3430 default y select ARCH_OMAP_OTG -config SOC_OMAPTI816X - bool "TI816X support" +config SOC_OMAPTI81XX + bool "TI81XX support" depends on ARCH_OMAP3 default y @@ -319,7 +319,7 @@ config MACH_OMAP_3630SDP config MACH_TI8168EVM bool "TI8168 Evaluation Module" - depends on SOC_OMAPTI816X + depends on SOC_OMAPTI81XX default y config MACH_OMAP_4430SDP diff --git a/arch/arm/mach-omap2/board-ti8168evm.c b/arch/arm/mach-omap2/board-ti8168evm.c index 8402b39b284..b236fcc023a 100644 --- a/arch/arm/mach-omap2/board-ti8168evm.c +++ b/arch/arm/mach-omap2/board-ti8168evm.c @@ -35,17 +35,12 @@ static void __init ti8168_evm_init(void) omap_board_config_size = ARRAY_SIZE(ti8168_evm_config); } -static void __init ti8168_evm_map_io(void) -{ - omapti816x_map_common_io(); -} - MACHINE_START(TI8168EVM, "ti8168evm") /* Maintainer: Texas Instruments */ .atag_offset = 0x100, - .map_io = ti8168_evm_map_io, - .init_early = ti816x_init_early, - .init_irq = ti816x_init_irq, + .map_io = ti81xx_map_io, + .init_early = ti81xx_init_early, + .init_irq = ti81xx_init_irq, .timer = &omap3_timer, .init_machine = ti8168_evm_init, MACHINE_END diff --git a/arch/arm/mach-omap2/clock3xxx_data.c b/arch/arm/mach-omap2/clock3xxx_data.c index 3d56d8a2b86..be0fa34e550 100644 --- a/arch/arm/mach-omap2/clock3xxx_data.c +++ b/arch/arm/mach-omap2/clock3xxx_data.c @@ -3602,7 +3602,7 @@ int __init omap3xxx_clk_init(void) * Lock DPLL5 -- here only until other device init code can * handle this */ - if (!cpu_is_ti816x() && (omap_rev() >= OMAP3430_REV_ES2_0)) + if (!cpu_is_ti81xx() && (omap_rev() >= OMAP3430_REV_ES2_0)) omap3_clk_lock_dpll5(); /* Avoid sleeping during omap3_core_dpll_m2_set_rate() */ diff --git a/arch/arm/mach-omap2/common.c b/arch/arm/mach-omap2/common.c index c900dcb6f1f..aaf421178c9 100644 --- a/arch/arm/mach-omap2/common.c +++ b/arch/arm/mach-omap2/common.c @@ -110,27 +110,32 @@ void __init omap3_map_io(void) /* * Adjust TAP register base such that omap3_check_revision accesses the correct - * TI816X register for checking device ID (it adds 0x204 to tap base while - * TI816X DEVICE ID register is at offset 0x600 from control base). + * TI81XX register for checking device ID (it adds 0x204 to tap base while + * TI81XX DEVICE ID register is at offset 0x600 from control base). */ -#define TI816X_TAP_BASE (TI816X_CTRL_BASE + \ - TI816X_CONTROL_DEVICE_ID - 0x204) +#define TI81XX_TAP_BASE (TI81XX_CTRL_BASE + \ + TI81XX_CONTROL_DEVICE_ID - 0x204) -static struct omap_globals ti816x_globals = { +static struct omap_globals ti81xx_globals = { .class = OMAP343X_CLASS, - .tap = OMAP2_L4_IO_ADDRESS(TI816X_TAP_BASE), - .ctrl = OMAP2_L4_IO_ADDRESS(TI816X_CTRL_BASE), - .prm = OMAP2_L4_IO_ADDRESS(TI816X_PRCM_BASE), - .cm = OMAP2_L4_IO_ADDRESS(TI816X_PRCM_BASE), + .tap = OMAP2_L4_IO_ADDRESS(TI81XX_TAP_BASE), + .ctrl = OMAP2_L4_IO_ADDRESS(TI81XX_CTRL_BASE), + .prm = OMAP2_L4_IO_ADDRESS(TI81XX_PRCM_BASE), + .cm = OMAP2_L4_IO_ADDRESS(TI81XX_PRCM_BASE), }; -void __init omap2_set_globals_ti816x(void) +void __init omap2_set_globals_ti81xx(void) { - __omap2_set_globals(&ti816x_globals); + __omap2_set_globals(&ti81xx_globals); +} + +void __init ti81xx_map_io(void) +{ + omapti81xx_map_common_io(); } #define AM33XX_TAP_BASE (AM33XX_CTRL_BASE + \ - TI816X_CONTROL_DEVICE_ID - 0x204) + TI81XX_CONTROL_DEVICE_ID - 0x204) static struct omap_globals am33xx_globals = { .class = AM335X_CLASS, diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h index 9b733e343bf..4b2b416fafe 100644 --- a/arch/arm/mach-omap2/common.h +++ b/arch/arm/mach-omap2/common.h @@ -52,10 +52,10 @@ static inline void omap34xx_map_common_io(void) } #endif -#ifdef CONFIG_SOC_OMAPTI816X -extern void omapti816x_map_common_io(void); +#ifdef CONFIG_SOC_OMAPTI81XX +extern void omapti81xx_map_common_io(void); #else -static inline void omapti816x_map_common_io(void) +static inline void omapti81xx_map_common_io(void) { } #endif @@ -90,7 +90,7 @@ void omap35xx_init_early(void); void omap3630_init_early(void); void omap3_init_early(void); /* Do not use this one */ void am35xx_init_early(void); -void ti816x_init_early(void); +void ti81xx_init_early(void); void omap4430_init_early(void); /* @@ -114,7 +114,7 @@ void omap2_set_globals_242x(void); void omap2_set_globals_243x(void); void omap2_set_globals_3xxx(void); void omap2_set_globals_443x(void); -void omap2_set_globals_ti816x(void); +void omap2_set_globals_ti81xx(void); void omap2_set_globals_am33xx(void); /* These get called from omap2_set_globals_xxxx(), do not call these */ @@ -128,6 +128,7 @@ void omap243x_map_io(void); void omap3_map_io(void); void am33xx_map_io(void); void omap4_map_io(void); +void ti81xx_map_io(void); /** * omap_test_timeout - busy-loop, testing a condition @@ -156,7 +157,7 @@ extern struct device *omap4_get_dsp_device(void); void omap2_init_irq(void); void omap3_init_irq(void); -void ti816x_init_irq(void); +void ti81xx_init_irq(void); extern int omap_irq_pending(void); void omap_intc_save_context(void); void omap_intc_restore_context(void); diff --git a/arch/arm/mach-omap2/control.h b/arch/arm/mach-omap2/control.h index d4ef75d5a38..0ba68d3764b 100644 --- a/arch/arm/mach-omap2/control.h +++ b/arch/arm/mach-omap2/control.h @@ -52,8 +52,8 @@ #define OMAP343X_CONTROL_PADCONFS_WKUP 0xa00 #define OMAP343X_CONTROL_GENERAL_WKUP 0xa60 -/* TI816X spefic control submodules */ -#define TI816X_CONTROL_DEVCONF 0x600 +/* TI81XX spefic control submodules */ +#define TI81XX_CONTROL_DEVCONF 0x600 /* Control register offsets - read/write with omap_ctrl_{read,write}{bwl}() */ @@ -244,8 +244,8 @@ #define OMAP3_PADCONF_SAD2D_MSTANDBY 0x250 #define OMAP3_PADCONF_SAD2D_IDLEACK 0x254 -/* TI816X CONTROL_DEVCONF register offsets */ -#define TI816X_CONTROL_DEVICE_ID (TI816X_CONTROL_DEVCONF + 0x000) +/* TI81XX CONTROL_DEVCONF register offsets */ +#define TI81XX_CONTROL_DEVICE_ID (TI81XX_CONTROL_DEVCONF + 0x000) /* * REVISIT: This list of registers is not comprehensive - there are more diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c index 439afe7acdc..1dc68e64d7e 100644 --- a/arch/arm/mach-omap2/id.c +++ b/arch/arm/mach-omap2/id.c @@ -226,7 +226,7 @@ static void __init omap4_check_features(void) } } -static void __init ti816x_check_features(void) +static void __init ti81xx_check_features(void) { omap_features = OMAP3_HAS_NEON; } @@ -489,11 +489,11 @@ void __init omap2_check_revision(void) } else if (cpu_is_omap34xx()) { omap3_check_revision(&cpu_rev); - /* TI816X doesn't have feature register */ - if (!cpu_is_ti816x()) + /* TI81XX doesn't have feature register */ + if (!cpu_is_ti81xx()) omap3_check_features(); else - ti816x_check_features(); + ti81xx_check_features(); omap3_cpuinfo(cpu_rev); return; diff --git a/arch/arm/mach-omap2/include/mach/debug-macro.S b/arch/arm/mach-omap2/include/mach/debug-macro.S index 13f98e59cfe..cdfc2a1f0e7 100644 --- a/arch/arm/mach-omap2/include/mach/debug-macro.S +++ b/arch/arm/mach-omap2/include/mach/debug-macro.S @@ -66,11 +66,11 @@ omap_uart_lsr: .word 0 beq 34f @ configure OMAP3UART4 cmp \rp, #OMAP4UART4 @ only on 44xx beq 44f @ configure OMAP4UART4 - cmp \rp, #TI816XUART1 @ ti816x UART offsets different + cmp \rp, #TI81XXUART1 @ ti81Xx UART offsets different beq 81f @ configure UART1 - cmp \rp, #TI816XUART2 @ ti816x UART offsets different + cmp \rp, #TI81XXUART2 @ ti81Xx UART offsets different beq 82f @ configure UART2 - cmp \rp, #TI816XUART3 @ ti816x UART offsets different + cmp \rp, #TI81XXUART3 @ ti81Xx UART offsets different beq 83f @ configure UART3 cmp \rp, #ZOOM_UART @ only on zoom2/3 beq 95f @ configure ZOOM_UART @@ -94,11 +94,11 @@ omap_uart_lsr: .word 0 b 98f 44: mov \rp, #UART_OFFSET(OMAP4_UART4_BASE) b 98f -81: mov \rp, #UART_OFFSET(TI816X_UART1_BASE) +81: mov \rp, #UART_OFFSET(TI81XX_UART1_BASE) b 98f -82: mov \rp, #UART_OFFSET(TI816X_UART2_BASE) +82: mov \rp, #UART_OFFSET(TI81XX_UART2_BASE) b 98f -83: mov \rp, #UART_OFFSET(TI816X_UART3_BASE) +83: mov \rp, #UART_OFFSET(TI81XX_UART3_BASE) b 98f 95: ldr \rp, =ZOOM_UART_BASE diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c index 088d2ba60ef..73d617f0dc4 100644 --- a/arch/arm/mach-omap2/io.c +++ b/arch/arm/mach-omap2/io.c @@ -176,8 +176,8 @@ static struct map_desc omap34xx_io_desc[] __initdata = { }; #endif -#ifdef CONFIG_SOC_OMAPTI816X -static struct map_desc omapti816x_io_desc[] __initdata = { +#ifdef CONFIG_SOC_OMAPTI81XX +static struct map_desc omapti81xx_io_desc[] __initdata = { { .virtual = L4_34XX_VIRT, .pfn = __phys_to_pfn(L4_34XX_PHYS), @@ -280,10 +280,10 @@ void __init omap34xx_map_common_io(void) } #endif -#ifdef CONFIG_SOC_OMAPTI816X -void __init omapti816x_map_common_io(void) +#ifdef CONFIG_SOC_OMAPTI81XX +void __init omapti81xx_map_common_io(void) { - iotable_init(omapti816x_io_desc, ARRAY_SIZE(omapti816x_io_desc)); + iotable_init(omapti81xx_io_desc, ARRAY_SIZE(omapti81xx_io_desc)); } #endif @@ -442,9 +442,9 @@ void __init am35xx_init_early(void) omap3_init_early(); } -void __init ti816x_init_early(void) +void __init ti81xx_init_early(void) { - omap2_set_globals_ti816x(); + omap2_set_globals_ti81xx(); omap_common_init_early(); omap3xxx_voltagedomains_init(); omap3xxx_powerdomains_init(); diff --git a/arch/arm/mach-omap2/irq.c b/arch/arm/mach-omap2/irq.c index 42b1d659191..1fef061f792 100644 --- a/arch/arm/mach-omap2/irq.c +++ b/arch/arm/mach-omap2/irq.c @@ -193,7 +193,7 @@ void __init omap3_init_irq(void) omap_init_irq(OMAP34XX_IC_BASE, 96); } -void __init ti816x_init_irq(void) +void __init ti81xx_init_irq(void) { omap_init_irq(OMAP34XX_IC_BASE, 128); } diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c index 9770c7624aa..d0f009cbfb5 100644 --- a/arch/arm/mach-omap2/serial.c +++ b/arch/arm/mach-omap2/serial.c @@ -464,7 +464,7 @@ static void omap_uart_idle_init(struct omap_uart_state *uart) mod_timer(&uart->timer, jiffies + uart->timeout); omap_uart_smart_idle_enable(uart, 0); - if (cpu_is_omap34xx() && !(cpu_is_ti816x() || cpu_is_am33xx())) { + if (cpu_is_omap34xx() && !(cpu_is_ti81xx() || cpu_is_am33xx())) { u32 mod = (uart->num > 1) ? OMAP3430_PER_MOD : CORE_MOD; u32 wk_mask = 0; u32 padconf = 0; @@ -746,7 +746,7 @@ void __init omap_serial_init_port(struct omap_board_data *bdata) */ uart->regshift = p->regshift; uart->membase = p->membase; - if (cpu_is_omap44xx() || cpu_is_ti816x()) + if (cpu_is_omap44xx() || cpu_is_ti81xx()) uart->errata |= UART_ERRATA_FIFO_FULL_ABORT; else if ((serial_read_reg(uart, UART_OMAP_MVER) & 0xFF) >= UART_OMAP_NO_EMPTY_FIFO_READ_IP_REV) @@ -828,7 +828,7 @@ void __init omap_serial_init_port(struct omap_board_data *bdata) } /* Enable the MDR1 errata for OMAP3 */ - if (cpu_is_omap34xx() && !(cpu_is_ti816x() || cpu_is_am33xx())) + if (cpu_is_omap34xx() && !(cpu_is_ti81xx() || cpu_is_am33xx())) uart->errata |= UART_ERRATA_i202_MDR1_ACCESS; } diff --git a/arch/arm/plat-omap/include/plat/cpu.h b/arch/arm/plat-omap/include/plat/cpu.h index 34fc9136b1a..5f7aa4981da 100644 --- a/arch/arm/plat-omap/include/plat/cpu.h +++ b/arch/arm/plat-omap/include/plat/cpu.h @@ -87,6 +87,14 @@ static inline int is_am ##class (void) \ return (GET_AM_CLASS == (id)) ? 1 : 0; \ } +#define GET_TI_CLASS ((omap_rev() >> 24) & 0xff) + +#define IS_TI_CLASS(class, id) \ +static inline int is_ti ##class (void) \ +{ \ + return (GET_TI_CLASS == (id)) ? 1 : 0; \ +} + #define GET_OMAP_SUBCLASS ((omap_rev() >> 20) & 0x0fff) #define IS_OMAP_SUBCLASS(subclass, id) \ @@ -115,6 +123,8 @@ IS_OMAP_CLASS(34xx, 0x34) IS_OMAP_CLASS(44xx, 0x44) IS_AM_CLASS(33xx, 0x33) +IS_TI_CLASS(81xx, 0x81) + IS_OMAP_SUBCLASS(242x, 0x242) IS_OMAP_SUBCLASS(243x, 0x243) IS_OMAP_SUBCLASS(343x, 0x343) @@ -134,6 +144,7 @@ IS_AM_SUBCLASS(335x, 0x335) #define cpu_is_omap243x() 0 #define cpu_is_omap34xx() 0 #define cpu_is_omap343x() 0 +#define cpu_is_ti81xx() 0 #define cpu_is_ti816x() 0 #define cpu_is_am33xx() 0 #define cpu_is_am335x() 0 @@ -343,6 +354,7 @@ IS_OMAP_TYPE(3517, 0x3517) # undef cpu_is_omap3530 # undef cpu_is_omap3505 # undef cpu_is_omap3517 +# undef cpu_is_ti81xx # undef cpu_is_ti816x # undef cpu_is_am33xx # undef cpu_is_am335x @@ -362,6 +374,7 @@ IS_OMAP_TYPE(3517, 0x3517) !omap3_has_sgx()) # undef cpu_is_omap3630 # define cpu_is_omap3630() is_omap363x() +# define cpu_is_ti81xx() is_ti81xx() # define cpu_is_ti816x() is_ti816x() # define cpu_is_am33xx() is_am33xx() # define cpu_is_am335x() is_am335x() diff --git a/arch/arm/plat-omap/include/plat/hardware.h b/arch/arm/plat-omap/include/plat/hardware.h index e6521e120d9..e897978371c 100644 --- a/arch/arm/plat-omap/include/plat/hardware.h +++ b/arch/arm/plat-omap/include/plat/hardware.h @@ -286,7 +286,7 @@ #include #include #include -#include +#include #include #endif /* __ASM_ARCH_OMAP_HARDWARE_H */ diff --git a/arch/arm/plat-omap/include/plat/serial.h b/arch/arm/plat-omap/include/plat/serial.h index 1ab9fd6abe6..6975ee3f521 100644 --- a/arch/arm/plat-omap/include/plat/serial.h +++ b/arch/arm/plat-omap/include/plat/serial.h @@ -51,10 +51,10 @@ #define OMAP4_UART3_BASE 0x48020000 #define OMAP4_UART4_BASE 0x4806e000 -/* TI816X serial ports */ -#define TI816X_UART1_BASE 0x48020000 -#define TI816X_UART2_BASE 0x48022000 -#define TI816X_UART3_BASE 0x48024000 +/* TI81XX serial ports */ +#define TI81XX_UART1_BASE 0x48020000 +#define TI81XX_UART2_BASE 0x48022000 +#define TI81XX_UART3_BASE 0x48024000 /* AM3505/3517 UART4 */ #define AM35XX_UART4_BASE 0x4809E000 /* Only on AM3505/3517 */ @@ -89,9 +89,9 @@ #define OMAP4UART2 OMAP2UART2 #define OMAP4UART3 43 #define OMAP4UART4 44 -#define TI816XUART1 81 -#define TI816XUART2 82 -#define TI816XUART3 83 +#define TI81XXUART1 81 +#define TI81XXUART2 82 +#define TI81XXUART3 83 #define ZOOM_UART 95 /* Only on zoom2/3 */ /* This is only used by 8250.c for omap1510 */ diff --git a/arch/arm/plat-omap/include/plat/ti816x.h b/arch/arm/plat-omap/include/plat/ti816x.h deleted file mode 100644 index 50510f5dda1..00000000000 --- a/arch/arm/plat-omap/include/plat/ti816x.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * This file contains the address data for various TI816X modules. - * - * Copyright (C) 2010 Texas Instruments, Inc. - http://www.ti.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 the Free Software Foundation version 2. - * - * This program is distributed "as is" WITHOUT ANY WARRANTY of any - * kind, whether express or implied; without even the implied warranty - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#ifndef __ASM_ARCH_TI816X_H -#define __ASM_ARCH_TI816X_H - -#define L4_SLOW_TI816X_BASE 0x48000000 - -#define TI816X_SCM_BASE 0x48140000 -#define TI816X_CTRL_BASE TI816X_SCM_BASE -#define TI816X_PRCM_BASE 0x48180000 - -#define TI816X_ARM_INTC_BASE 0x48200000 - -#endif /* __ASM_ARCH_TI816X_H */ diff --git a/arch/arm/plat-omap/include/plat/ti81xx.h b/arch/arm/plat-omap/include/plat/ti81xx.h new file mode 100644 index 00000000000..8f9843f7842 --- /dev/null +++ b/arch/arm/plat-omap/include/plat/ti81xx.h @@ -0,0 +1,27 @@ +/* + * This file contains the address data for various TI81XX modules. + * + * Copyright (C) 2010 Texas Instruments, Inc. - http://www.ti.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 the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __ASM_ARCH_TI81XX_H +#define __ASM_ARCH_TI81XX_H + +#define L4_SLOW_TI81XX_BASE 0x48000000 + +#define TI81XX_SCM_BASE 0x48140000 +#define TI81XX_CTRL_BASE TI81XX_SCM_BASE +#define TI81XX_PRCM_BASE 0x48180000 + +#define TI81XX_ARM_INTC_BASE 0x48200000 + +#endif /* __ASM_ARCH_TI81XX_H */ diff --git a/arch/arm/plat-omap/include/plat/uncompress.h b/arch/arm/plat-omap/include/plat/uncompress.h index 2f472e989ec..7fbc361946b 100644 --- a/arch/arm/plat-omap/include/plat/uncompress.h +++ b/arch/arm/plat-omap/include/plat/uncompress.h @@ -99,9 +99,9 @@ static inline void flush(void) #define DEBUG_LL_ZOOM(mach) \ _DEBUG_LL_ENTRY(mach, ZOOM_UART_BASE, ZOOM_PORT_SHIFT, ZOOM_UART) -#define DEBUG_LL_TI816X(p, mach) \ - _DEBUG_LL_ENTRY(mach, TI816X_UART##p##_BASE, OMAP_PORT_SHIFT, \ - TI816XUART##p) +#define DEBUG_LL_TI81XX(p, mach) \ + _DEBUG_LL_ENTRY(mach, TI81XX_UART##p##_BASE, OMAP_PORT_SHIFT, \ + TI81XXUART##p) static inline void __arch_decomp_setup(unsigned long arch_id) { @@ -177,7 +177,7 @@ static inline void __arch_decomp_setup(unsigned long arch_id) DEBUG_LL_ZOOM(omap_zoom3); /* TI8168 base boards using UART3 */ - DEBUG_LL_TI816X(3, ti8168evm); + DEBUG_LL_TI81XX(3, ti8168evm); } while (0); } -- cgit v1.2.3-70-g09d2 From 4390f5b2cb1f568c1d4b3e5bbf57158f6809627a Mon Sep 17 00:00:00 2001 From: Hemant Pedanekar Date: Tue, 13 Dec 2011 10:46:45 -0800 Subject: ARM: OMAP: TI814X: Add cpu type macros and detection support This patch adds cpu type, macros for identification of TI814X device. Signed-off-by: Hemant Pedanekar [tony@atomide.com: left out CK_TI814X for now] Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/clock3xxx_data.c | 2 ++ arch/arm/mach-omap2/id.c | 21 +++++++++++++++++++++ arch/arm/plat-omap/include/plat/clock.h | 1 + arch/arm/plat-omap/include/plat/cpu.h | 9 +++++++++ 4 files changed, 33 insertions(+) (limited to 'arch/arm/plat-omap/include/plat') diff --git a/arch/arm/mach-omap2/clock3xxx_data.c b/arch/arm/mach-omap2/clock3xxx_data.c index be0fa34e550..60424f41156 100644 --- a/arch/arm/mach-omap2/clock3xxx_data.c +++ b/arch/arm/mach-omap2/clock3xxx_data.c @@ -3519,6 +3519,8 @@ int __init omap3xxx_clk_init(void) cpu_clkflg = CK_TI816X; } else if (cpu_is_am33xx()) { cpu_mask = RATE_IN_AM33XX; + } else if (cpu_is_ti814x()) { + cpu_mask = RATE_IN_TI814X; } else if (cpu_is_omap34xx()) { if (omap_rev() == OMAP3430_REV_ES1_0) { cpu_mask = RATE_IN_3430ES1; diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c index 1dc68e64d7e..6c5826605ea 100644 --- a/arch/arm/mach-omap2/id.c +++ b/arch/arm/mach-omap2/id.c @@ -343,6 +343,25 @@ static void __init omap3_check_revision(const char **cpu_rev) case 0xb944: omap_revision = AM335X_REV_ES1_0; *cpu_rev = "1.0"; + case 0xb8f2: + switch (rev) { + case 0: + /* FALLTHROUGH */ + case 1: + omap_revision = TI8148_REV_ES1_0; + *cpu_rev = "1.0"; + break; + case 2: + omap_revision = TI8148_REV_ES2_0; + *cpu_rev = "2.0"; + break; + case 3: + /* FALLTHROUGH */ + default: + omap_revision = TI8148_REV_ES2_1; + *cpu_rev = "2.1"; + break; + } break; default: /* Unknown default to latest silicon rev as default */ @@ -449,6 +468,8 @@ static void __init omap3_cpuinfo(const char *cpu_rev) cpu_name = "TI816X"; } else if (cpu_is_am335x()) { cpu_name = "AM335X"; + } else if (cpu_is_ti814x()) { + cpu_name = "TI814X"; } else if (omap3_has_iva() && omap3_has_sgx()) { /* OMAP3430, OMAP3525, OMAP3515, OMAP3503 devices */ cpu_name = "OMAP3430/3530"; diff --git a/arch/arm/plat-omap/include/plat/clock.h b/arch/arm/plat-omap/include/plat/clock.h index bb3e423b731..240a7b9fd94 100644 --- a/arch/arm/plat-omap/include/plat/clock.h +++ b/arch/arm/plat-omap/include/plat/clock.h @@ -60,6 +60,7 @@ struct clkops { #define RATE_IN_TI816X (1 << 6) #define RATE_IN_4460 (1 << 7) #define RATE_IN_AM33XX (1 << 8) +#define RATE_IN_TI814X (1 << 9) #define RATE_IN_24XX (RATE_IN_242X | RATE_IN_243X) #define RATE_IN_34XX (RATE_IN_3430ES1 | RATE_IN_3430ES2PLUS) diff --git a/arch/arm/plat-omap/include/plat/cpu.h b/arch/arm/plat-omap/include/plat/cpu.h index 5f7aa4981da..6b51086fce1 100644 --- a/arch/arm/plat-omap/include/plat/cpu.h +++ b/arch/arm/plat-omap/include/plat/cpu.h @@ -134,6 +134,7 @@ IS_OMAP_SUBCLASS(446x, 0x446) IS_OMAP_SUBCLASS(447x, 0x447) IS_TI_SUBCLASS(816x, 0x816) +IS_TI_SUBCLASS(814x, 0x814) IS_AM_SUBCLASS(335x, 0x335) #define cpu_is_omap7xx() 0 @@ -146,6 +147,7 @@ IS_AM_SUBCLASS(335x, 0x335) #define cpu_is_omap343x() 0 #define cpu_is_ti81xx() 0 #define cpu_is_ti816x() 0 +#define cpu_is_ti814x() 0 #define cpu_is_am33xx() 0 #define cpu_is_am335x() 0 #define cpu_is_omap44xx() 0 @@ -356,6 +358,7 @@ IS_OMAP_TYPE(3517, 0x3517) # undef cpu_is_omap3517 # undef cpu_is_ti81xx # undef cpu_is_ti816x +# undef cpu_is_ti814x # undef cpu_is_am33xx # undef cpu_is_am335x # define cpu_is_omap3430() is_omap3430() @@ -376,6 +379,7 @@ IS_OMAP_TYPE(3517, 0x3517) # define cpu_is_omap3630() is_omap363x() # define cpu_is_ti81xx() is_ti81xx() # define cpu_is_ti816x() is_ti816x() +# define cpu_is_ti814x() is_ti814x() # define cpu_is_am33xx() is_am33xx() # define cpu_is_am335x() is_am335x() #endif @@ -426,6 +430,11 @@ IS_OMAP_TYPE(3517, 0x3517) #define TI8168_REV_ES1_0 TI816X_CLASS #define TI8168_REV_ES1_1 (TI816X_CLASS | (0x1 << 8)) +#define TI814X_CLASS 0x81400034 +#define TI8148_REV_ES1_0 TI814X_CLASS +#define TI8148_REV_ES2_0 (TI814X_CLASS | (0x1 << 8)) +#define TI8148_REV_ES2_1 (TI814X_CLASS | (0x2 << 8)) + #define AM335X_CLASS 0x33500034 #define AM335X_REV_ES1_0 AM335X_CLASS -- cgit v1.2.3-70-g09d2 From 8384c9749f8c31c6e1e64a63c8d50af7863ce657 Mon Sep 17 00:00:00 2001 From: "Govindraj.R" Date: Wed, 9 Nov 2011 17:22:30 +0530 Subject: ARM: OMAP2+: UART: cleanup + remove uart pm specific API In preparation to UART runtime conversion remove uart specific calls from pm24xx/34xx files and their definition from serial.c These func calls will no more be used with upcoming uart runtime design. 1.) omap_uart_prepare_suspend :- can be taken care with driver suspend hooks. 2.) omap_uart_enable_irqs :- Used to enable/disable uart irq's in suspend path from PM code, this is removed as same is handled by uart_suspend_port/uart_resume_port in omap-serial driver which will do an port_shutdown on suspend freeing irq and port_startup on resume enabling back irq. 3.) Remove prepare_idle/resume_idle calls used to gate uart clocks. UART clocks can be gated within driver using runtime funcs and be woken up using irq_chaining from omap_prm driver. 4.) Remove console_locking from idle path as clock gating is done withing driver itself with runtime API. Remove is_suspending check used to acquire console_lock. Signed-off-by: Govindraj.R Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/pm24xx.c | 18 --------- arch/arm/mach-omap2/pm34xx.c | 32 ---------------- arch/arm/mach-omap2/serial.c | 65 -------------------------------- arch/arm/plat-omap/include/plat/serial.h | 4 -- 4 files changed, 119 deletions(-) (limited to 'arch/arm/plat-omap/include/plat') diff --git a/arch/arm/mach-omap2/pm24xx.c b/arch/arm/mach-omap2/pm24xx.c index ef8595c8029..22af2f2fdbf 100644 --- a/arch/arm/mach-omap2/pm24xx.c +++ b/arch/arm/mach-omap2/pm24xx.c @@ -30,7 +30,6 @@ #include #include #include -#include #include #include @@ -127,27 +126,11 @@ static void omap2_enter_full_retention(void) if (omap_irq_pending()) goto no_sleep; - /* Block console output in case it is on one of the OMAP UARTs */ - if (!is_suspending()) - if (!console_trylock()) - goto no_sleep; - - omap_uart_prepare_idle(0); - omap_uart_prepare_idle(1); - omap_uart_prepare_idle(2); - /* Jump to SRAM suspend code */ omap2_sram_suspend(sdrc_read_reg(SDRC_DLLA_CTRL), OMAP_SDRC_REGADDR(SDRC_DLLA_CTRL), OMAP_SDRC_REGADDR(SDRC_POWER)); - omap_uart_resume_idle(2); - omap_uart_resume_idle(1); - omap_uart_resume_idle(0); - - if (!is_suspending()) - console_unlock(); - no_sleep: omap2_gpio_resume_after_idle(); @@ -291,7 +274,6 @@ static int omap2_pm_suspend(void) mir1 = omap_readl(0x480fe0a4); omap_writel(1 << 5, 0x480fe0ac); - omap_uart_prepare_suspend(); omap2_enter_full_retention(); omap_writel(mir1, 0x480fe0a4); diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index fa637dfdda5..4feee45ef06 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include @@ -54,15 +53,6 @@ #ifdef CONFIG_SUSPEND static suspend_state_t suspend_state = PM_SUSPEND_ON; -static inline bool is_suspending(void) -{ - return (suspend_state != PM_SUSPEND_ON) && console_suspend_enabled; -} -#else -static inline bool is_suspending(void) -{ - return false; -} #endif /* pm34xx errata defined in pm.h */ @@ -376,20 +366,11 @@ void omap_sram_idle(void) omap3_enable_io_chain(); } - /* Block console output in case it is on one of the OMAP UARTs */ - if (!is_suspending()) - if (per_next_state < PWRDM_POWER_ON || - core_next_state < PWRDM_POWER_ON) - if (!console_trylock()) - goto console_still_active; - pwrdm_pre_transition(); /* PER */ if (per_next_state < PWRDM_POWER_ON) { per_going_off = (per_next_state == PWRDM_POWER_OFF) ? 1 : 0; - omap_uart_prepare_idle(2); - omap_uart_prepare_idle(3); omap2_gpio_prepare_for_idle(per_going_off); if (per_next_state == PWRDM_POWER_OFF) omap3_per_save_context(); @@ -397,8 +378,6 @@ void omap_sram_idle(void) /* CORE */ if (core_next_state < PWRDM_POWER_ON) { - omap_uart_prepare_idle(0); - omap_uart_prepare_idle(1); if (core_next_state == PWRDM_POWER_OFF) { omap3_core_save_context(); omap3_cm_save_context(); @@ -447,8 +426,6 @@ void omap_sram_idle(void) omap3_sram_restore_context(); omap2_sms_restore_context(); } - omap_uart_resume_idle(0); - omap_uart_resume_idle(1); if (core_next_state == PWRDM_POWER_OFF) omap2_prm_clear_mod_reg_bits(OMAP3430_AUTO_OFF_MASK, OMAP3430_GR_MOD, @@ -464,14 +441,8 @@ void omap_sram_idle(void) omap2_gpio_resume_after_idle(); if (per_prev_state == PWRDM_POWER_OFF) omap3_per_restore_context(); - omap_uart_resume_idle(2); - omap_uart_resume_idle(3); } - if (!is_suspending()) - console_unlock(); - -console_still_active: /* Disable IO-PAD and IO-CHAIN wakeup */ if (omap3_has_io_wakeup() && (per_next_state < PWRDM_POWER_ON || @@ -533,7 +504,6 @@ static int omap3_pm_suspend(void) goto restore; } - omap_uart_prepare_suspend(); omap3_intc_suspend(); omap_sram_idle(); @@ -580,14 +550,12 @@ static int omap3_pm_begin(suspend_state_t state) { disable_hlt(); suspend_state = state; - omap_uart_enable_irqs(0); return 0; } static void omap3_pm_end(void) { suspend_state = PM_SUSPEND_ON; - omap_uart_enable_irqs(1); enable_hlt(); return; } diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c index d0f009cbfb5..6378a2a5d6b 100644 --- a/arch/arm/mach-omap2/serial.c +++ b/arch/arm/mach-omap2/serial.c @@ -367,51 +367,6 @@ static void omap_uart_idle_timer(unsigned long data) omap_uart_allow_sleep(uart); } -void omap_uart_prepare_idle(int num) -{ - struct omap_uart_state *uart; - - list_for_each_entry(uart, &uart_list, node) { - if (num == uart->num && uart->can_sleep) { - omap_uart_disable_clocks(uart); - return; - } - } -} - -void omap_uart_resume_idle(int num) -{ - struct omap_uart_state *uart; - - list_for_each_entry(uart, &uart_list, node) { - if (num == uart->num && uart->can_sleep) { - omap_uart_enable_clocks(uart); - - /* Check for IO pad wakeup */ - if (cpu_is_omap34xx() && uart->padconf) { - u16 p = omap_ctrl_readw(uart->padconf); - - if (p & OMAP3_PADCONF_WAKEUPEVENT0) - omap_uart_block_sleep(uart); - } - - /* Check for normal UART wakeup */ - if (__raw_readl(uart->wk_st) & uart->wk_mask) - omap_uart_block_sleep(uart); - return; - } - } -} - -void omap_uart_prepare_suspend(void) -{ - struct omap_uart_state *uart; - - list_for_each_entry(uart, &uart_list, node) { - omap_uart_allow_sleep(uart); - } -} - int omap_uart_can_sleep(void) { struct omap_uart_state *uart; @@ -530,26 +485,6 @@ static void omap_uart_idle_init(struct omap_uart_state *uart) WARN_ON(ret); } -void omap_uart_enable_irqs(int enable) -{ - int ret; - struct omap_uart_state *uart; - - list_for_each_entry(uart, &uart_list, node) { - if (enable) { - pm_runtime_put_sync(&uart->pdev->dev); - ret = request_threaded_irq(uart->irq, NULL, - omap_uart_interrupt, - IRQF_SHARED, - "serial idle", - (void *)uart); - } else { - pm_runtime_get_noresume(&uart->pdev->dev); - free_irq(uart->irq, (void *)uart); - } - } -} - static ssize_t sleep_timeout_show(struct device *dev, struct device_attribute *attr, char *buf) diff --git a/arch/arm/plat-omap/include/plat/serial.h b/arch/arm/plat-omap/include/plat/serial.h index 6975ee3f521..73d990780da 100644 --- a/arch/arm/plat-omap/include/plat/serial.h +++ b/arch/arm/plat-omap/include/plat/serial.h @@ -111,10 +111,6 @@ extern void omap_serial_init(void); extern void omap_serial_init_port(struct omap_board_data *bdata); extern int omap_uart_can_sleep(void); extern void omap_uart_check_wakeup(void); -extern void omap_uart_prepare_suspend(void); -extern void omap_uart_prepare_idle(int num); -extern void omap_uart_resume_idle(int num); -extern void omap_uart_enable_irqs(int enable); #endif #endif -- cgit v1.2.3-70-g09d2 From 273558b3a0399e368d99da5b3daf1c0e11b93e06 Mon Sep 17 00:00:00 2001 From: "Govindraj.R" Date: Tue, 13 Sep 2011 14:01:01 +0530 Subject: ARM: OMAP2+: UART: Cleanup part of clock gating mechanism for uart Currently we use a shared irq handler to identify uart activity and then trigger a timer. By default the timeout value is zero and can be set or modified from sysfs. If there was no uart activity for the period set through sysfs, the timer will expire and call timer handler this will set a flag can_sleep using which decision to gate uart clocks can be taken. Since the clock gating mechanism is outside the uart driver, we currently use this mechanism. In preparation to runtime implementation for omap-serial driver we can cleanup this mechanism and use runtime API's to gate uart clocks. Removes the following: * timer related info from local uart_state struct * the code used to set timeout value from sysfs. * irqflags used to set shared irq handler. * un-used function omap_uart_check_wakeup. Signed-off-by: Govindraj.R Acked-by: Greg Kroah-Hartman (for drivers/tty changes) Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/serial.c | 118 +------------------------- arch/arm/plat-omap/include/plat/omap-serial.h | 1 - arch/arm/plat-omap/include/plat/serial.h | 1 - drivers/tty/serial/omap-serial.c | 1 - 4 files changed, 2 insertions(+), 119 deletions(-) (limited to 'arch/arm/plat-omap/include/plat') diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c index e027bc99251..5bdbc42e42a 100644 --- a/arch/arm/mach-omap2/serial.c +++ b/arch/arm/mach-omap2/serial.c @@ -58,8 +58,6 @@ struct omap_uart_state { int num; int can_sleep; - struct timer_list timer; - u32 timeout; void __iomem *wk_st; void __iomem *wk_en; @@ -67,13 +65,9 @@ struct omap_uart_state { u32 padconf; u32 dma_enabled; - struct clk *ick; - struct clk *fck; int clocked; - int irq; int regshift; - int irqflags; void __iomem *membase; resource_size_t mapbase; @@ -331,32 +325,6 @@ static void omap_uart_block_sleep(struct omap_uart_state *uart) omap_uart_smart_idle_enable(uart, 0); uart->can_sleep = 0; - if (uart->timeout) - mod_timer(&uart->timer, jiffies + uart->timeout); - else - del_timer(&uart->timer); -} - -static void omap_uart_allow_sleep(struct omap_uart_state *uart) -{ - if (device_may_wakeup(&uart->pdev->dev)) - omap_uart_enable_wakeup(uart); - else - omap_uart_disable_wakeup(uart); - - if (!uart->clocked) - return; - - omap_uart_smart_idle_enable(uart, 1); - uart->can_sleep = 1; - del_timer(&uart->timer); -} - -static void omap_uart_idle_timer(unsigned long data) -{ - struct omap_uart_state *uart = (struct omap_uart_state *)data; - - omap_uart_allow_sleep(uart); } int omap_uart_can_sleep(void) @@ -380,35 +348,11 @@ int omap_uart_can_sleep(void) return can_sleep; } -/** - * omap_uart_interrupt() - * - * This handler is used only to detect that *any* UART interrupt has - * occurred. It does _nothing_ to handle the interrupt. Rather, - * any UART interrupt will trigger the inactivity timer so the - * UART will not idle or sleep for its timeout period. - * - **/ -/* static int first_interrupt; */ -static irqreturn_t omap_uart_interrupt(int irq, void *dev_id) -{ - struct omap_uart_state *uart = dev_id; - - omap_uart_block_sleep(uart); - - return IRQ_NONE; -} - static void omap_uart_idle_init(struct omap_uart_state *uart) { int ret; uart->can_sleep = 0; - uart->timeout = DEFAULT_TIMEOUT; - setup_timer(&uart->timer, omap_uart_idle_timer, - (unsigned long) uart); - if (uart->timeout) - mod_timer(&uart->timer, jiffies + uart->timeout); omap_uart_smart_idle_enable(uart, 0); if (cpu_is_omap34xx() && !(cpu_is_ti81xx() || cpu_is_am33xx())) { @@ -470,51 +414,8 @@ static void omap_uart_idle_init(struct omap_uart_state *uart) uart->wk_mask = 0; uart->padconf = 0; } - - uart->irqflags |= IRQF_SHARED; - ret = request_threaded_irq(uart->irq, NULL, omap_uart_interrupt, - IRQF_SHARED, "serial idle", (void *)uart); - WARN_ON(ret); -} - -static ssize_t sleep_timeout_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct platform_device *pdev = to_platform_device(dev); - struct omap_device *odev = to_omap_device(pdev); - struct omap_uart_state *uart = odev->hwmods[0]->dev_attr; - - return sprintf(buf, "%u\n", uart->timeout / HZ); } -static ssize_t sleep_timeout_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t n) -{ - struct platform_device *pdev = to_platform_device(dev); - struct omap_device *odev = to_omap_device(pdev); - struct omap_uart_state *uart = odev->hwmods[0]->dev_attr; - unsigned int value; - - if (sscanf(buf, "%u", &value) != 1) { - dev_err(dev, "sleep_timeout_store: Invalid value\n"); - return -EINVAL; - } - - uart->timeout = value * HZ; - if (uart->timeout) - mod_timer(&uart->timer, jiffies + uart->timeout); - else - /* A zero value means disable timeout feature */ - omap_uart_block_sleep(uart); - - return n; -} - -static DEVICE_ATTR(sleep_timeout, 0644, sleep_timeout_show, - sleep_timeout_store); -#define DEV_CREATE_FILE(dev, attr) WARN_ON(device_create_file(dev, attr)) #else static inline void omap_uart_idle_init(struct omap_uart_state *uart) {} static void omap_uart_block_sleep(struct omap_uart_state *uart) @@ -522,7 +423,6 @@ static void omap_uart_block_sleep(struct omap_uart_state *uart) /* Needed to enable UART clocks when built without CONFIG_PM */ omap_uart_enable_clocks(uart); } -#define DEV_CREATE_FILE(dev, attr) #endif /* CONFIG_PM */ static int __init omap_serial_early_init(void) @@ -606,8 +506,7 @@ void __init omap_serial_init_port(struct omap_board_data *bdata) omap_up.uartclk = OMAP24XX_BASE_BAUD * 16; omap_up.mapbase = oh->slaves[0]->addr->pa_start; omap_up.membase = omap_hwmod_get_mpu_rt_va(oh); - omap_up.irqflags = IRQF_SHARED; - omap_up.flags = UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ; + omap_up.flags = UPF_BOOT_AUTOCONF; pdata = &omap_up; pdata_size = sizeof(struct omap_uart_port_info); @@ -623,7 +522,6 @@ void __init omap_serial_init_port(struct omap_board_data *bdata) omap_device_disable_idle_on_suspend(pdev); oh->mux = omap_hwmod_mux_init(bdata->pads, bdata->pads_cnt); - uart->irq = oh->mpu_irqs[0].irq; uart->regshift = 2; uart->mapbase = oh->slaves[0]->addr->pa_start; uart->membase = omap_hwmod_get_mpu_rt_va(oh); @@ -646,24 +544,12 @@ void __init omap_serial_init_port(struct omap_board_data *bdata) omap_hwmod_enable_wakeup(uart->oh); omap_device_idle(uart->pdev); - /* - * Need to block sleep long enough for interrupt driven - * driver to start. Console driver is in polling mode - * so device needs to be kept enabled while polling driver - * is in use. - */ - if (uart->timeout) - uart->timeout = (30 * HZ); omap_uart_block_sleep(uart); - uart->timeout = DEFAULT_TIMEOUT; - console_unlock(); if ((cpu_is_omap34xx() && uart->padconf) || - (uart->wk_en && uart->wk_mask)) { + (uart->wk_en && uart->wk_mask)) device_init_wakeup(&pdev->dev, true); - DEV_CREATE_FILE(&pdev->dev, &dev_attr_sleep_timeout); - } /* Enable the MDR1 errata for OMAP3 */ if (cpu_is_omap34xx() && !(cpu_is_ti81xx() || cpu_is_am33xx())) diff --git a/arch/arm/plat-omap/include/plat/omap-serial.h b/arch/arm/plat-omap/include/plat/omap-serial.h index 2682043f5a5..307cd6f1582 100644 --- a/arch/arm/plat-omap/include/plat/omap-serial.h +++ b/arch/arm/plat-omap/include/plat/omap-serial.h @@ -61,7 +61,6 @@ struct omap_uart_port_info { unsigned int uartclk; /* UART clock rate */ void __iomem *membase; /* ioremap cookie or NULL */ resource_size_t mapbase; /* resource base */ - unsigned long irqflags; /* request_irq flags */ upf_t flags; /* UPF_* flags */ }; diff --git a/arch/arm/plat-omap/include/plat/serial.h b/arch/arm/plat-omap/include/plat/serial.h index 73d990780da..152500b558a 100644 --- a/arch/arm/plat-omap/include/plat/serial.h +++ b/arch/arm/plat-omap/include/plat/serial.h @@ -110,7 +110,6 @@ struct omap_board_data; extern void omap_serial_init(void); extern void omap_serial_init_port(struct omap_board_data *bdata); extern int omap_uart_can_sleep(void); -extern void omap_uart_check_wakeup(void); #endif #endif diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index 5e713d3ef1f..be368cf70f3 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c @@ -1278,7 +1278,6 @@ static int serial_omap_probe(struct platform_device *pdev) up->port.membase = omap_up_info->membase; up->port.mapbase = omap_up_info->mapbase; up->port.flags = omap_up_info->flags; - up->port.irqflags = omap_up_info->irqflags; up->port.uartclk = omap_up_info->uartclk; up->uart_dma.uart_base = mem->start; -- cgit v1.2.3-70-g09d2 From edd70ad757e9b336116433e6e62de79ae1dfef54 Mon Sep 17 00:00:00 2001 From: "Govindraj.R" Date: Tue, 11 Oct 2011 14:55:41 +0530 Subject: ARM: OMAP2+: UART: Remove mapbase/membase fields from pdata. The mapbase (start_address), membase(io_remap cookie) part of pdata struct omap_uart_port_info are removed as this should be derived within driver. Signed-off-by: Govindraj.R Acked-by: Greg Kroah-Hartman (for drivers/tty changes) Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/serial.c | 2 -- arch/arm/plat-omap/include/plat/omap-serial.h | 2 -- drivers/tty/serial/omap-serial.c | 10 ++++++++-- 3 files changed, 8 insertions(+), 6 deletions(-) (limited to 'arch/arm/plat-omap/include/plat') diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c index 77feaab7805..2456cfdad78 100644 --- a/arch/arm/mach-omap2/serial.c +++ b/arch/arm/mach-omap2/serial.c @@ -605,8 +605,6 @@ void __init omap_serial_init_port(struct omap_board_data *bdata) omap_up.dma_enabled = uart->dma_enabled; omap_up.uartclk = OMAP24XX_BASE_BAUD * 16; - omap_up.mapbase = oh->slaves[0]->addr->pa_start; - omap_up.membase = omap_hwmod_get_mpu_rt_va(oh); omap_up.flags = UPF_BOOT_AUTOCONF; pdata = &omap_up; diff --git a/arch/arm/plat-omap/include/plat/omap-serial.h b/arch/arm/plat-omap/include/plat/omap-serial.h index 307cd6f1582..db9bda97876 100644 --- a/arch/arm/plat-omap/include/plat/omap-serial.h +++ b/arch/arm/plat-omap/include/plat/omap-serial.h @@ -59,8 +59,6 @@ struct omap_uart_port_info { bool dma_enabled; /* To specify DMA Mode */ unsigned int uartclk; /* UART clock rate */ - void __iomem *membase; /* ioremap cookie or NULL */ - resource_size_t mapbase; /* resource base */ upf_t flags; /* UPF_* flags */ }; diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index be368cf70f3..31f0cbf73c1 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c @@ -1275,8 +1275,14 @@ static int serial_omap_probe(struct platform_device *pdev) up->port.ops = &serial_omap_pops; up->port.line = pdev->id; - up->port.membase = omap_up_info->membase; - up->port.mapbase = omap_up_info->mapbase; + up->port.mapbase = mem->start; + up->port.membase = ioremap(mem->start, resource_size(mem)); + if (!up->port.membase) { + dev_err(&pdev->dev, "can't ioremap UART\n"); + ret = -ENOMEM; + goto err; + } + up->port.flags = omap_up_info->flags; up->port.uartclk = omap_up_info->uartclk; up->uart_dma.uart_base = mem->start; -- cgit v1.2.3-70-g09d2 From c538d20c7f437e56c5301357c492230d1d6d1b80 Mon Sep 17 00:00:00 2001 From: "Govindraj.R" Date: Mon, 7 Nov 2011 18:57:03 +0530 Subject: ARM: OMAP2+: UART: Ensure all reg values configured are available from port structure Add missing uart regs to uart_port structure which can be used in context restore. Store dll, dlh, mdr1, scr, efr, lcr, mcr reg values into uart_port structure while configuring individual port in termios function. Signed-off-by: Govindraj.R Acked-by: Greg Kroah-Hartman (for drivers/tty changes) Signed-off-by: Kevin Hilman --- arch/arm/plat-omap/include/plat/omap-serial.h | 4 +++ drivers/tty/serial/omap-serial.c | 43 ++++++++++++++++----------- 2 files changed, 30 insertions(+), 17 deletions(-) (limited to 'arch/arm/plat-omap/include/plat') diff --git a/arch/arm/plat-omap/include/plat/omap-serial.h b/arch/arm/plat-omap/include/plat/omap-serial.h index db9bda97876..70e7738dd3a 100644 --- a/arch/arm/plat-omap/include/plat/omap-serial.h +++ b/arch/arm/plat-omap/include/plat/omap-serial.h @@ -97,6 +97,10 @@ struct uart_omap_port { unsigned char mcr; unsigned char fcr; unsigned char efr; + unsigned char dll; + unsigned char dlh; + unsigned char mdr1; + unsigned char scr; int use_dma; /* diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index a834e913a6e..5327ff0b008 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c @@ -466,8 +466,9 @@ static void serial_omap_set_mctrl(struct uart_port *port, unsigned int mctrl) mcr |= UART_MCR_LOOP; pm_runtime_get_sync(&up->pdev->dev); - mcr |= up->mcr; - serial_out(up, UART_MCR, mcr); + up->mcr = serial_in(up, UART_MCR); + up->mcr |= mcr; + serial_out(up, UART_MCR, up->mcr); pm_runtime_put(&up->pdev->dev); } @@ -616,8 +617,6 @@ static inline void serial_omap_configure_xonxoff (struct uart_omap_port *up, struct ktermios *termios) { - unsigned char efr = 0; - up->lcr = serial_in(up, UART_LCR); serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); up->efr = serial_in(up, UART_EFR); @@ -627,8 +626,7 @@ serial_omap_configure_xonxoff serial_out(up, UART_XOFF1, termios->c_cc[VSTOP]); /* clear SW control mode bits */ - efr = up->efr; - efr &= OMAP_UART_SW_CLR; + up->efr &= OMAP_UART_SW_CLR; /* * IXON Flag: @@ -636,7 +634,7 @@ serial_omap_configure_xonxoff * Transmit XON1, XOFF1 */ if (termios->c_iflag & IXON) - efr |= OMAP_UART_SW_TX; + up->efr |= OMAP_UART_SW_TX; /* * IXOFF Flag: @@ -644,7 +642,7 @@ serial_omap_configure_xonxoff * Receiver compares XON1, XOFF1. */ if (termios->c_iflag & IXOFF) - efr |= OMAP_UART_SW_RX; + up->efr |= OMAP_UART_SW_RX; serial_out(up, UART_EFR, up->efr | UART_EFR_ECB); serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); @@ -667,7 +665,7 @@ serial_omap_configure_xonxoff * load the new software flow control mode IXON or IXOFF * and restore the UARTi.EFR_REG[4] ENHANCED_EN value. */ - serial_out(up, UART_EFR, efr | UART_EFR_SCD); + serial_out(up, UART_EFR, up->efr | UART_EFR_SCD); serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); serial_out(up, UART_MCR, up->mcr & ~UART_MCR_TCRTLR); @@ -714,6 +712,10 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios, baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/13); quot = serial_omap_get_divisor(port, baud); + up->dll = quot & 0xff; + up->dlh = quot >> 8; + up->mdr1 = UART_OMAP_MDR1_DISABLE; + up->fcr = UART_FCR_R_TRIG_01 | UART_FCR_T_TRIG_01 | UART_FCR_ENABLE_FIFO; if (up->use_dma) @@ -767,6 +769,7 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios, up->ier |= UART_IER_MSI; serial_out(up, UART_IER, up->ier); serial_out(up, UART_LCR, cval); /* reset DLAB */ + up->lcr = cval; /* FIFOs and DMA Settings */ @@ -793,17 +796,18 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios, if (up->use_dma) { serial_out(up, UART_TI752_TLR, 0); - serial_out(up, UART_OMAP_SCR, - (UART_FCR_TRIGGER_4 | UART_FCR_TRIGGER_8)); + up->scr |= (UART_FCR_TRIGGER_4 | UART_FCR_TRIGGER_8); } + serial_out(up, UART_OMAP_SCR, up->scr); + serial_out(up, UART_EFR, up->efr); serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); serial_out(up, UART_MCR, up->mcr); /* Protocol, Baud Rate, and Interrupt Settings */ - serial_out(up, UART_OMAP_MDR1, UART_OMAP_MDR1_DISABLE); + serial_out(up, UART_OMAP_MDR1, up->mdr1); serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); up->efr = serial_in(up, UART_EFR); @@ -813,8 +817,8 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios, serial_out(up, UART_IER, 0); serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); - serial_out(up, UART_DLL, quot & 0xff); /* LS of divisor */ - serial_out(up, UART_DLM, quot >> 8); /* MS of divisor */ + serial_out(up, UART_DLL, up->dll); /* LS of divisor */ + serial_out(up, UART_DLM, up->dlh); /* MS of divisor */ serial_out(up, UART_LCR, 0); serial_out(up, UART_IER, up->ier); @@ -824,9 +828,11 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios, serial_out(up, UART_LCR, cval); if (baud > 230400 && baud != 3000000) - serial_out(up, UART_OMAP_MDR1, UART_OMAP_MDR1_13X_MODE); + up->mdr1 = UART_OMAP_MDR1_13X_MODE; else - serial_out(up, UART_OMAP_MDR1, UART_OMAP_MDR1_16X_MODE); + up->mdr1 = UART_OMAP_MDR1_16X_MODE; + + serial_out(up, UART_OMAP_MDR1, up->mdr1); /* Hardware Flow Control Configuration */ @@ -1416,15 +1422,18 @@ static void serial_omap_restore_context(struct uart_omap_port *up) serial_out(up, UART_LCR, 0x0); /* Operational mode */ serial_out(up, UART_IER, 0x0); serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); /* Config B mode */ + serial_out(up, UART_DLL, up->dll); + serial_out(up, UART_DLM, up->dlh); serial_out(up, UART_LCR, 0x0); /* Operational mode */ serial_out(up, UART_IER, up->ier); serial_out(up, UART_FCR, up->fcr); serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); serial_out(up, UART_MCR, up->mcr); serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); /* Config B mode */ + serial_out(up, UART_OMAP_SCR, up->scr); serial_out(up, UART_EFR, up->efr); serial_out(up, UART_LCR, up->lcr); - serial_out(up, UART_OMAP_MDR1, UART_OMAP_MDR1_16X_MODE); + serial_out(up, UART_OMAP_MDR1, up->mdr1); } #ifdef CONFIG_PM_RUNTIME -- cgit v1.2.3-70-g09d2 From 32212897eeb8c2b2b3c74dbd44d842963084d808 Mon Sep 17 00:00:00 2001 From: "Govindraj.R" Date: Mon, 7 Nov 2011 18:58:55 +0530 Subject: ARM: OMAP2+: UART: Remove uart reset function. Remove the uart reset function which is configuring the TX empty irq which can now be handled within omap-serial driver. Signed-off-by: Govindraj.R Acked-by: Greg Kroah-Hartman (for drivers/tty changes) Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/serial.c | 14 -------------- arch/arm/plat-omap/include/plat/omap-serial.h | 2 ++ drivers/tty/serial/omap-serial.c | 1 + 3 files changed, 3 insertions(+), 14 deletions(-) (limited to 'arch/arm/plat-omap/include/plat') diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c index 64b0d11ddc4..b3f3284bf6b 100644 --- a/arch/arm/mach-omap2/serial.c +++ b/arch/arm/mach-omap2/serial.c @@ -74,19 +74,6 @@ struct omap_uart_state { static LIST_HEAD(uart_list); static u8 num_uarts; -/* - * 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 inline void __init omap_uart_reset(struct omap_uart_state *uart) -{ - serial_write_reg(uart, UART_OMAP_MDR1, UART_OMAP_MDR1_DISABLE); - serial_write_reg(uart, UART_OMAP_SCR, 0x08); - serial_write_reg(uart, UART_OMAP_MDR1, UART_OMAP_MDR1_16X_MODE); -} - #if defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP3) /* @@ -521,7 +508,6 @@ void __init omap_serial_init_port(struct omap_board_data *bdata) omap_device_enable(uart->pdev); omap_uart_idle_init(uart); - omap_uart_reset(uart); omap_hwmod_enable_wakeup(uart->oh); omap_device_idle(uart->pdev); diff --git a/arch/arm/plat-omap/include/plat/omap-serial.h b/arch/arm/plat-omap/include/plat/omap-serial.h index 70e7738dd3a..5b913c71cd7 100644 --- a/arch/arm/plat-omap/include/plat/omap-serial.h +++ b/arch/arm/plat-omap/include/plat/omap-serial.h @@ -33,6 +33,8 @@ #define OMAP_MODE13X_SPEED 230400 +#define OMAP_UART_SCR_TX_EMPTY 0x08 + /* WER = 0x7F * Enable module level wakeup in WER reg */ diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index 5327ff0b008..f5a5ed67682 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c @@ -770,6 +770,7 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios, serial_out(up, UART_IER, up->ier); serial_out(up, UART_LCR, cval); /* reset DLAB */ up->lcr = cval; + up->scr = OMAP_UART_SCR_TX_EMPTY; /* FIFOs and DMA Settings */ -- cgit v1.2.3-70-g09d2 From ec3bebc6ec64aac23500e6b8ef5c0aaaeda735cf Mon Sep 17 00:00:00 2001 From: "Govindraj.R" Date: Tue, 11 Oct 2011 19:11:27 +0530 Subject: ARM: OMAP2+: UART: Get context loss count to context restore Avoid unconditional context restore every time we gate uart clocks. Check whether context loss happened based on which we can context restore uart regs from uart_port structure. Signed-off-by: Govindraj.R Acked-by: Greg Kroah-Hartman (for drivers/tty changes) Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/serial.c | 2 ++ arch/arm/plat-omap/include/plat/omap-serial.h | 3 +++ drivers/tty/serial/omap-serial.c | 20 ++++++++++++++++++-- 3 files changed, 23 insertions(+), 2 deletions(-) (limited to 'arch/arm/plat-omap/include/plat') diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c index b3f3284bf6b..78ca7e8fc10 100644 --- a/arch/arm/mach-omap2/serial.c +++ b/arch/arm/mach-omap2/serial.c @@ -33,6 +33,7 @@ #include #include #include +#include #include "prm2xxx_3xxx.h" #include "pm.h" @@ -478,6 +479,7 @@ void __init omap_serial_init_port(struct omap_board_data *bdata) omap_up.dma_enabled = uart->dma_enabled; omap_up.uartclk = OMAP24XX_BASE_BAUD * 16; omap_up.flags = UPF_BOOT_AUTOCONF; + omap_up.get_context_loss_count = omap_pm_get_dev_context_loss_count; pdata = &omap_up; pdata_size = sizeof(struct omap_uart_port_info); diff --git a/arch/arm/plat-omap/include/plat/omap-serial.h b/arch/arm/plat-omap/include/plat/omap-serial.h index 5b913c71cd7..348c9ead6ed 100644 --- a/arch/arm/plat-omap/include/plat/omap-serial.h +++ b/arch/arm/plat-omap/include/plat/omap-serial.h @@ -62,6 +62,8 @@ struct omap_uart_port_info { bool dma_enabled; /* To specify DMA Mode */ unsigned int uartclk; /* UART clock rate */ upf_t flags; /* UPF_* flags */ + + int (*get_context_loss_count)(struct device *); }; struct uart_omap_dma { @@ -114,6 +116,7 @@ struct uart_omap_port { unsigned char msr_saved_flags; char name[20]; unsigned long port_activity; + u32 context_loss_cnt; }; #endif /* __OMAP_SERIAL_H__ */ diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index f5a5ed67682..ea4c24aa8c8 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c @@ -1440,15 +1440,31 @@ static void serial_omap_restore_context(struct uart_omap_port *up) #ifdef CONFIG_PM_RUNTIME static int serial_omap_runtime_suspend(struct device *dev) { + struct uart_omap_port *up = dev_get_drvdata(dev); + struct omap_uart_port_info *pdata = dev->platform_data; + + if (!up) + return -EINVAL; + + if (pdata->get_context_loss_count) + up->context_loss_cnt = pdata->get_context_loss_count(dev); + return 0; } static int serial_omap_runtime_resume(struct device *dev) { struct uart_omap_port *up = dev_get_drvdata(dev); + struct omap_uart_port_info *pdata = dev->platform_data; - if (up) - serial_omap_restore_context(up); + if (up) { + if (pdata->get_context_loss_count) { + u32 loss_cnt = pdata->get_context_loss_count(dev); + + if (up->context_loss_cnt != loss_cnt) + serial_omap_restore_context(up); + } + } return 0; } -- cgit v1.2.3-70-g09d2 From 94734749af794c080f6af6ac3ce8c1c13ee2dbbd Mon Sep 17 00:00:00 2001 From: "Govindraj.R" Date: Mon, 7 Nov 2011 19:00:33 +0530 Subject: ARM: OMAP2+: UART: Move errata handling from serial.c to omap-serial Move the errata handling mechanism from serial.c to omap-serial file and utilise the same func in driver file. Errata i202, i291 are moved to be handled with omap-serial Moving the errata macro from serial.c file to driver header file as from on errata will be handled in driver file itself. Corrected errata id from chapter reference 2.15 to errata id i291. Removed errata and dma_enabled fields from omap_uart_state struct as they are no more needed with errata handling done within omap-serial. Signed-off-by: Govindraj.R Acked-by: Alan Cox Acked-by: Greg Kroah-Hartman Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/serial.c | 101 ++++++++------------------ arch/arm/plat-omap/include/plat/omap-serial.h | 7 ++ drivers/tty/serial/omap-serial.c | 68 ++++++++++++++++- 3 files changed, 102 insertions(+), 74 deletions(-) (limited to 'arch/arm/plat-omap/include/plat') diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c index 78ca7e8fc10..77a25cb1dcc 100644 --- a/arch/arm/mach-omap2/serial.c +++ b/arch/arm/mach-omap2/serial.c @@ -42,8 +42,6 @@ #include "control.h" #include "mux.h" -#define UART_ERRATA_i202_MDR1_ACCESS (0x1 << 1) - /* * NOTE: By default the serial timeout is disabled as it causes lost characters * over the serial ports. This means that the UART clocks will stay on until @@ -61,59 +59,17 @@ struct omap_uart_state { void __iomem *wk_st; void __iomem *wk_en; u32 wk_mask; - u32 dma_enabled; int clocked; struct list_head node; struct omap_hwmod *oh; struct platform_device *pdev; - - u32 errata; }; static LIST_HEAD(uart_list); static u8 num_uarts; -#if defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP3) - -/* - * Work Around for Errata i202 (3430 - 1.12, 3630 - 1.6) - * The access to uart register after MDR1 Access - * causes UART to corrupt data. - * - * Need a delay = - * 5 L4 clock cycles + 5 UART functional clock cycle (@48MHz = ~0.2uS) - * give 10 times as much - */ -static void omap_uart_mdr1_errataset(struct omap_uart_state *uart, u8 mdr1_val, - u8 fcr_val) -{ - u8 timeout = 255; - - serial_write_reg(uart, UART_OMAP_MDR1, mdr1_val); - udelay(2); - serial_write_reg(uart, UART_FCR, fcr_val | UART_FCR_CLEAR_XMIT | - UART_FCR_CLEAR_RCVR); - /* - * Wait for FIFO to empty: when empty, RX_FIFO_E bit is 0 and - * TX_FIFO_E bit is 1. - */ - while (UART_LSR_THRE != (serial_read_reg(uart, UART_LSR) & - (UART_LSR_THRE | UART_LSR_DR))) { - timeout--; - if (!timeout) { - /* Should *never* happen. we warn and carry on */ - dev_crit(&uart->pdev->dev, "Errata i202: timedout %x\n", - serial_read_reg(uart, UART_LSR)); - break; - } - udelay(1); - } -} - -#endif /* CONFIG_PM && CONFIG_ARCH_OMAP3 */ - static inline void omap_uart_enable_clocks(struct omap_uart_state *uart) { if (uart->clocked) @@ -156,27 +112,6 @@ static void omap_uart_disable_wakeup(struct omap_uart_state *uart) } } -static void omap_uart_smart_idle_enable(struct omap_uart_state *uart, - int enable) -{ - u8 idlemode; - - if (enable) { - /** - * Errata 2.15: [UART]:Cannot Acknowledge Idle Requests - * in Smartidle Mode When Configured for DMA Operations. - */ - if (uart->dma_enabled) - idlemode = HWMOD_IDLEMODE_FORCE; - else - idlemode = HWMOD_IDLEMODE_SMART; - } else { - idlemode = HWMOD_IDLEMODE_NO; - } - - omap_hwmod_set_slave_idlemode(uart->oh, idlemode); -} - static void omap_uart_block_sleep(struct omap_uart_state *uart) { omap_uart_enable_clocks(uart); @@ -267,7 +202,28 @@ static void omap_uart_idle_init(struct omap_uart_state *uart) } } +/* + * Errata i291: [UART]:Cannot Acknowledge Idle Requests + * in Smartidle Mode When Configured for DMA Operations. + * WA: configure uart in force idle mode. + */ +static void omap_uart_set_noidle(struct platform_device *pdev) +{ + struct omap_device *od = to_omap_device(pdev); + + omap_hwmod_set_slave_idlemode(od->hwmods[0], HWMOD_IDLEMODE_NO); +} + +static void omap_uart_set_forceidle(struct platform_device *pdev) +{ + struct omap_device *od = to_omap_device(pdev); + + omap_hwmod_set_slave_idlemode(od->hwmods[0], HWMOD_IDLEMODE_FORCE); +} + #else +static void omap_uart_set_noidle(struct platform_device *pdev) {} +static void omap_uart_set_forceidle(struct platform_device *pdev) {} static void omap_uart_block_sleep(struct omap_uart_state *uart) { /* Needed to enable UART clocks when built without CONFIG_PM */ @@ -473,13 +429,22 @@ void __init omap_serial_init_port(struct omap_board_data *bdata) break; oh = uart->oh; - uart->dma_enabled = 0; name = DRIVER_NAME; omap_up.dma_enabled = uart->dma_enabled; omap_up.uartclk = OMAP24XX_BASE_BAUD * 16; omap_up.flags = UPF_BOOT_AUTOCONF; omap_up.get_context_loss_count = omap_pm_get_dev_context_loss_count; + omap_up.set_forceidle = omap_uart_set_forceidle; + omap_up.set_noidle = omap_uart_set_noidle; + + /* Enable the MDR1 Errata i202 for OMAP2430/3xxx/44xx */ + if (!cpu_is_omap2420() && !cpu_is_ti816x()) + omap_up.errata |= UART_ERRATA_i202_MDR1_ACCESS; + + /* Enable DMA Mode Force Idle Errata i291 for omap34xx/3630 */ + if (cpu_is_omap34xx() || cpu_is_omap3630()) + omap_up.errata |= UART_ERRATA_i291_DMA_FORCEIDLE; pdata = &omap_up; pdata_size = sizeof(struct omap_uart_port_info); @@ -519,10 +484,6 @@ void __init omap_serial_init_port(struct omap_board_data *bdata) if (((cpu_is_omap34xx() || cpu_is_omap44xx()) && bdata->pads) || (pdata->wk_en && pdata->wk_mask)) device_init_wakeup(&pdev->dev, true); - - /* Enable the MDR1 errata for OMAP3 */ - if (cpu_is_omap34xx() && !(cpu_is_ti81xx() || cpu_is_am33xx())) - uart->errata |= UART_ERRATA_i202_MDR1_ACCESS; } /** diff --git a/arch/arm/plat-omap/include/plat/omap-serial.h b/arch/arm/plat-omap/include/plat/omap-serial.h index 348c9ead6ed..842b429cfea 100644 --- a/arch/arm/plat-omap/include/plat/omap-serial.h +++ b/arch/arm/plat-omap/include/plat/omap-serial.h @@ -58,12 +58,18 @@ #define MSR_SAVE_FLAGS UART_MSR_ANY_DELTA +#define UART_ERRATA_i202_MDR1_ACCESS BIT(0) +#define UART_ERRATA_i291_DMA_FORCEIDLE BIT(1) + struct omap_uart_port_info { bool dma_enabled; /* To specify DMA Mode */ unsigned int uartclk; /* UART clock rate */ upf_t flags; /* UPF_* flags */ + u32 errata; int (*get_context_loss_count)(struct device *); + void (*set_forceidle)(struct platform_device *); + void (*set_noidle)(struct platform_device *); }; struct uart_omap_dma { @@ -117,6 +123,7 @@ struct uart_omap_port { char name[20]; unsigned long port_activity; u32 context_loss_cnt; + u32 errata; }; #endif /* __OMAP_SERIAL_H__ */ diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index ea4c24aa8c8..764ac779569 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c @@ -51,6 +51,7 @@ static struct uart_omap_port *ui[OMAP_MAX_HSUART_PORTS]; static void uart_tx_dma_callback(int lch, u16 ch_status, void *data); static void serial_omap_rx_timeout(unsigned long uart_no); static int serial_omap_start_rxdma(struct uart_omap_port *up); +static void serial_omap_mdr1_errataset(struct uart_omap_port *up, u8 mdr1); static inline unsigned int serial_in(struct uart_omap_port *up, int offset) { @@ -808,7 +809,11 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios, /* Protocol, Baud Rate, and Interrupt Settings */ - serial_out(up, UART_OMAP_MDR1, up->mdr1); + if (up->errata & UART_ERRATA_i202_MDR1_ACCESS) + serial_omap_mdr1_errataset(up, up->mdr1); + else + serial_out(up, UART_OMAP_MDR1, up->mdr1); + serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); up->efr = serial_in(up, UART_EFR); @@ -833,7 +838,10 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios, else up->mdr1 = UART_OMAP_MDR1_16X_MODE; - serial_out(up, UART_OMAP_MDR1, up->mdr1); + if (up->errata & UART_ERRATA_i202_MDR1_ACCESS) + serial_omap_mdr1_errataset(up, up->mdr1); + else + serial_out(up, UART_OMAP_MDR1, up->mdr1); /* Hardware Flow Control Configuration */ @@ -1362,6 +1370,7 @@ static int serial_omap_probe(struct platform_device *pdev) up->port.flags = omap_up_info->flags; up->port.uartclk = omap_up_info->uartclk; up->uart_dma.uart_base = mem->start; + up->errata = omap_up_info->errata; if (omap_up_info->dma_enabled) { up->uart_dma.uart_dma_tx = dma_tx->start; @@ -1415,9 +1424,47 @@ static int serial_omap_remove(struct platform_device *dev) return 0; } +/* + * Work Around for Errata i202 (2430, 3430, 3630, 4430 and 4460) + * The access to uart register after MDR1 Access + * causes UART to corrupt data. + * + * Need a delay = + * 5 L4 clock cycles + 5 UART functional clock cycle (@48MHz = ~0.2uS) + * give 10 times as much + */ +static void serial_omap_mdr1_errataset(struct uart_omap_port *up, u8 mdr1) +{ + u8 timeout = 255; + + serial_out(up, UART_OMAP_MDR1, mdr1); + udelay(2); + serial_out(up, UART_FCR, up->fcr | UART_FCR_CLEAR_XMIT | + UART_FCR_CLEAR_RCVR); + /* + * Wait for FIFO to empty: when empty, RX_FIFO_E bit is 0 and + * TX_FIFO_E bit is 1. + */ + while (UART_LSR_THRE != (serial_in(up, UART_LSR) & + (UART_LSR_THRE | UART_LSR_DR))) { + timeout--; + if (!timeout) { + /* Should *never* happen. we warn and carry on */ + dev_crit(&up->pdev->dev, "Errata i202: timedout %x\n", + serial_in(up, UART_LSR)); + break; + } + udelay(1); + } +} + static void serial_omap_restore_context(struct uart_omap_port *up) { - serial_out(up, UART_OMAP_MDR1, UART_OMAP_MDR1_DISABLE); + if (up->errata & UART_ERRATA_i202_MDR1_ACCESS) + serial_omap_mdr1_errataset(up, UART_OMAP_MDR1_DISABLE); + else + serial_out(up, UART_OMAP_MDR1, UART_OMAP_MDR1_DISABLE); + serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); /* Config B mode */ serial_out(up, UART_EFR, UART_EFR_ECB); serial_out(up, UART_LCR, 0x0); /* Operational mode */ @@ -1434,7 +1481,10 @@ static void serial_omap_restore_context(struct uart_omap_port *up) serial_out(up, UART_OMAP_SCR, up->scr); serial_out(up, UART_EFR, up->efr); serial_out(up, UART_LCR, up->lcr); - serial_out(up, UART_OMAP_MDR1, up->mdr1); + if (up->errata & UART_ERRATA_i202_MDR1_ACCESS) + serial_omap_mdr1_errataset(up, up->mdr1); + else + serial_out(up, UART_OMAP_MDR1, up->mdr1); } #ifdef CONFIG_PM_RUNTIME @@ -1449,6 +1499,11 @@ static int serial_omap_runtime_suspend(struct device *dev) if (pdata->get_context_loss_count) up->context_loss_cnt = pdata->get_context_loss_count(dev); + /* Errata i291 */ + if (up->use_dma && pdata->set_forceidle && + (up->errata & UART_ERRATA_i291_DMA_FORCEIDLE)) + pdata->set_forceidle(up->pdev); + return 0; } @@ -1464,6 +1519,11 @@ static int serial_omap_runtime_resume(struct device *dev) if (up->context_loss_cnt != loss_cnt) serial_omap_restore_context(up); } + + /* Errata i291 */ + if (up->use_dma && pdata->set_noidle && + (up->errata & UART_ERRATA_i291_DMA_FORCEIDLE)) + pdata->set_noidle(up->pdev); } return 0; -- cgit v1.2.3-70-g09d2 From 62f3ec5fbd5fddce62b7a71adc04723a5eb903da Mon Sep 17 00:00:00 2001 From: "Govindraj.R" Date: Thu, 13 Oct 2011 14:11:09 +0530 Subject: ARM: OMAP2+: UART: Add wakeup mechanism for omap-uarts From the runtime callbacks enable hwmod wakeups for uart which will internally enable io-pad wakeups for uarts if they have rx-pad pins set as wakeup capabale. Use the io-ring wakeup mechanism after uart clock gating and leave the PM_WKST set for uart to default reset values cleanup the code in serial.c which was handling PM_WKST reg. Irq_chaing(PRM_DRIVER) is used to wakeup uart after uart clocks are gated using pad wakeup mechanism. Signed-off-by: Govindraj.R Acked-by: Greg Kroah-Hartman (for drivers/tty changes) Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/serial.c | 96 ++++----------------------- arch/arm/plat-omap/include/plat/omap-serial.h | 2 + drivers/tty/serial/omap-serial.c | 15 +++++ 3 files changed, 29 insertions(+), 84 deletions(-) (limited to 'arch/arm/plat-omap/include/plat') diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c index 77a25cb1dcc..aa6f7f05a1e 100644 --- a/arch/arm/mach-omap2/serial.c +++ b/arch/arm/mach-omap2/serial.c @@ -56,10 +56,6 @@ struct omap_uart_state { int num; int can_sleep; - void __iomem *wk_st; - void __iomem *wk_en; - u32 wk_mask; - int clocked; struct list_head node; @@ -92,26 +88,6 @@ static inline void omap_uart_disable_clocks(struct omap_uart_state *uart) omap_device_idle(uart->pdev); } -static void omap_uart_enable_wakeup(struct omap_uart_state *uart) -{ - /* Set wake-enable bit */ - if (uart->wk_en && uart->wk_mask) { - u32 v = __raw_readl(uart->wk_en); - v |= uart->wk_mask; - __raw_writel(v, uart->wk_en); - } -} - -static void omap_uart_disable_wakeup(struct omap_uart_state *uart) -{ - /* Clear wake-enable bit */ - if (uart->wk_en && uart->wk_mask) { - u32 v = __raw_readl(uart->wk_en); - v &= ~uart->wk_mask; - __raw_writel(v, uart->wk_en); - } -} - static void omap_uart_block_sleep(struct omap_uart_state *uart) { omap_uart_enable_clocks(uart); @@ -141,65 +117,17 @@ int omap_uart_can_sleep(void) return can_sleep; } -static void omap_uart_idle_init(struct omap_uart_state *uart) +static void omap_uart_enable_wakeup(struct platform_device *pdev, bool enable) { - int ret; - - uart->can_sleep = 0; - omap_uart_smart_idle_enable(uart, 0); + struct omap_device *od = to_omap_device(pdev); - if (cpu_is_omap34xx() && !(cpu_is_ti81xx() || cpu_is_am33xx())) { - u32 mod = (uart->num > 1) ? OMAP3430_PER_MOD : CORE_MOD; - u32 wk_mask = 0; + if (!od) + return; - /* XXX These PRM accesses do not belong here */ - uart->wk_en = OMAP34XX_PRM_REGADDR(mod, PM_WKEN1); - uart->wk_st = OMAP34XX_PRM_REGADDR(mod, PM_WKST1); - switch (uart->num) { - case 0: - wk_mask = OMAP3430_ST_UART1_MASK; - break; - case 1: - wk_mask = OMAP3430_ST_UART2_MASK; - break; - case 2: - wk_mask = OMAP3430_ST_UART3_MASK; - break; - case 3: - wk_mask = OMAP3630_ST_UART4_MASK; - break; - } - uart->wk_mask = wk_mask; - } else if (cpu_is_omap24xx()) { - u32 wk_mask = 0; - u32 wk_en = PM_WKEN1, wk_st = PM_WKST1; - - switch (uart->num) { - case 0: - wk_mask = OMAP24XX_ST_UART1_MASK; - break; - case 1: - wk_mask = OMAP24XX_ST_UART2_MASK; - break; - case 2: - wk_en = OMAP24XX_PM_WKEN2; - wk_st = OMAP24XX_PM_WKST2; - wk_mask = OMAP24XX_ST_UART3_MASK; - break; - } - uart->wk_mask = wk_mask; - if (cpu_is_omap2430()) { - uart->wk_en = OMAP2430_PRM_REGADDR(CORE_MOD, wk_en); - uart->wk_st = OMAP2430_PRM_REGADDR(CORE_MOD, wk_st); - } else if (cpu_is_omap2420()) { - uart->wk_en = OMAP2420_PRM_REGADDR(CORE_MOD, wk_en); - uart->wk_st = OMAP2420_PRM_REGADDR(CORE_MOD, wk_st); - } - } else { - uart->wk_en = NULL; - uart->wk_st = NULL; - uart->wk_mask = 0; - } + if (enable) + omap_hwmod_enable_wakeup(od->hwmods[0]); + else + omap_hwmod_disable_wakeup(od->hwmods[0]); } /* @@ -222,6 +150,8 @@ static void omap_uart_set_forceidle(struct platform_device *pdev) } #else +static void omap_uart_enable_wakeup(struct platform_device *pdev, bool enable) +{} static void omap_uart_set_noidle(struct platform_device *pdev) {} static void omap_uart_set_forceidle(struct platform_device *pdev) {} static void omap_uart_block_sleep(struct omap_uart_state *uart) @@ -437,6 +367,7 @@ void __init omap_serial_init_port(struct omap_board_data *bdata) omap_up.get_context_loss_count = omap_pm_get_dev_context_loss_count; omap_up.set_forceidle = omap_uart_set_forceidle; omap_up.set_noidle = omap_uart_set_noidle; + omap_up.enable_wakeup = omap_uart_enable_wakeup; /* Enable the MDR1 Errata i202 for OMAP2430/3xxx/44xx */ if (!cpu_is_omap2420() && !cpu_is_ti816x()) @@ -474,15 +405,12 @@ void __init omap_serial_init_port(struct omap_board_data *bdata) omap_hwmod_idle(uart->oh); omap_device_enable(uart->pdev); - omap_uart_idle_init(uart); - omap_hwmod_enable_wakeup(uart->oh); omap_device_idle(uart->pdev); omap_uart_block_sleep(uart); console_unlock(); - if (((cpu_is_omap34xx() || cpu_is_omap44xx()) && bdata->pads) || - (pdata->wk_en && pdata->wk_mask)) + if ((cpu_is_omap34xx() || cpu_is_omap44xx()) && bdata->pads) device_init_wakeup(&pdev->dev, true); } diff --git a/arch/arm/plat-omap/include/plat/omap-serial.h b/arch/arm/plat-omap/include/plat/omap-serial.h index 842b429cfea..39709ecfd58 100644 --- a/arch/arm/plat-omap/include/plat/omap-serial.h +++ b/arch/arm/plat-omap/include/plat/omap-serial.h @@ -70,6 +70,7 @@ struct omap_uart_port_info { int (*get_context_loss_count)(struct device *); void (*set_forceidle)(struct platform_device *); void (*set_noidle)(struct platform_device *); + void (*enable_wakeup)(struct platform_device *, bool); }; struct uart_omap_dma { @@ -124,6 +125,7 @@ struct uart_omap_port { unsigned long port_activity; u32 context_loss_cnt; u32 errata; + u8 wakeups_enabled; }; #endif /* __OMAP_SERIAL_H__ */ diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index 764ac779569..45a25a01c44 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c @@ -1496,9 +1496,24 @@ static int serial_omap_runtime_suspend(struct device *dev) if (!up) return -EINVAL; + if (!pdata->enable_wakeup) + return 0; + if (pdata->get_context_loss_count) up->context_loss_cnt = pdata->get_context_loss_count(dev); + if (device_may_wakeup(dev)) { + if (!up->wakeups_enabled) { + pdata->enable_wakeup(up->pdev, true); + up->wakeups_enabled = true; + } + } else { + if (up->wakeups_enabled) { + pdata->enable_wakeup(up->pdev, false); + up->wakeups_enabled = false; + } + } + /* Errata i291 */ if (up->use_dma && pdata->set_forceidle && (up->errata & UART_ERRATA_i291_DMA_FORCEIDLE)) -- cgit v1.2.3-70-g09d2 From c86845db77ce220f77e6645b18800744684946ac Mon Sep 17 00:00:00 2001 From: Deepak K Date: Wed, 9 Nov 2011 17:33:38 +0530 Subject: ARM: OMAP2+: UART: Allow UART parameters to be configured from board file. The following UART parameters are defined within the UART driver: 1). Whether the UART uses DMA (dma_enabled), by default set to 0 2). The size of dma buffer (set to 4096 bytes) 3). The time after which the dma should stop if no more data is received. 4). The auto suspend delay that will be passed for pm_runtime_autosuspend where uart will be disabled after timeout Different UARTs may be used for different purpose such as the console, for interfacing bluetooth chip, for interfacing to a modem chip, etc. Therefore, it is necessary to be able to customize the above settings for a given board on a per UART basis. This change allows these parameters to be configured from the board file and allows the parameters to be configured for each UART independently. If a board does not define its own custom parameters for the UARTs, then use the default parameters in the structure "omap_serial_default_info". The default parameters are defined to be the same as the current settings in the UART driver to avoid breaking the UART for any cuurnelty supported boards. By default, make all boards use the default UART parameters. Signed-off-by: Deepak K Signed-off-by: Jon Hunter Signed-off-by: Govindraj.R Acked-by: Greg Kroah-Hartman (for drivers/tty changes) Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/board-n8x0.c | 6 +-- arch/arm/mach-omap2/serial.c | 56 +++++++++++++++++++++------ arch/arm/plat-omap/include/plat/omap-serial.h | 7 +++- arch/arm/plat-omap/include/plat/serial.h | 5 ++- drivers/tty/serial/omap-serial.c | 8 ++-- 5 files changed, 60 insertions(+), 22 deletions(-) (limited to 'arch/arm/plat-omap/include/plat') diff --git a/arch/arm/mach-omap2/board-n8x0.c b/arch/arm/mach-omap2/board-n8x0.c index bebd3d84365..118f38c4b37 100644 --- a/arch/arm/mach-omap2/board-n8x0.c +++ b/arch/arm/mach-omap2/board-n8x0.c @@ -644,15 +644,15 @@ static inline void board_serial_init(void) bdata.pads_cnt = 0; bdata.id = 0; - omap_serial_init_port(&bdata); + omap_serial_init_port(&bdata, NULL); bdata.id = 1; - omap_serial_init_port(&bdata); + omap_serial_init_port(&bdata, NULL); bdata.id = 2; bdata.pads = serial2_pads; bdata.pads_cnt = ARRAY_SIZE(serial2_pads); - omap_serial_init_port(&bdata); + omap_serial_init_port(&bdata, NULL); } #else diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c index f94394fe5b1..5b1b36a45e9 100644 --- a/arch/arm/mach-omap2/serial.c +++ b/arch/arm/mach-omap2/serial.c @@ -43,12 +43,12 @@ #include "mux.h" /* - * NOTE: By default the serial timeout is disabled as it causes lost characters - * over the serial ports. This means that the UART clocks will stay on until - * disabled via sysfs. This also causes that any deeper omap sleep states are - * blocked. + * NOTE: By default the serial auto_suspend timeout is disabled as it causes + * lost characters over the serial ports. This means that the UART clocks will + * stay on until power/autosuspend_delay is set for the uart from sysfs. + * This also causes that any deeper omap sleep states are blocked. */ -#define DEFAULT_TIMEOUT 0 +#define DEFAULT_AUTOSUSPEND_DELAY -1 #define MAX_UART_HWMOD_NAME_LEN 16 @@ -64,6 +64,18 @@ struct omap_uart_state { static LIST_HEAD(uart_list); static u8 num_uarts; +#define DEFAULT_RXDMA_TIMEOUT 1 /* RX DMA polling rate (us) */ +#define DEFAULT_RXDMA_BUFSIZE 4096 /* RX DMA buffer size */ + +static struct omap_uart_port_info omap_serial_default_info[] __initdata = { + { + .dma_enabled = false, + .dma_rx_buf_size = DEFAULT_RXDMA_BUFSIZE, + .dma_rx_timeout = DEFAULT_RXDMA_TIMEOUT, + .autosuspend_timeout = DEFAULT_AUTOSUSPEND_DELAY, + }, +}; + #ifdef CONFIG_PM int omap_uart_can_sleep(void) @@ -294,6 +306,7 @@ core_initcall(omap_serial_early_init); /** * omap_serial_init_port() - initialize single serial port * @bdata: port specific board data pointer + * @info: platform specific data pointer * * This function initialies serial driver for given port only. * Platforms can call this function instead of omap_serial_init() @@ -302,7 +315,8 @@ core_initcall(omap_serial_early_init); * Don't mix calls to omap_serial_init_port() and omap_serial_init(), * use only one of the two. */ -void __init omap_serial_init_port(struct omap_board_data *bdata) +void __init omap_serial_init_port(struct omap_board_data *bdata, + struct omap_uart_port_info *info) { struct omap_uart_state *uart; struct omap_hwmod *oh; @@ -322,17 +336,22 @@ void __init omap_serial_init_port(struct omap_board_data *bdata) list_for_each_entry(uart, &uart_list, node) if (bdata->id == uart->num) break; + if (!info) + info = omap_serial_default_info; oh = uart->oh; name = DRIVER_NAME; - omap_up.dma_enabled = uart->dma_enabled; + omap_up.dma_enabled = info->dma_enabled; omap_up.uartclk = OMAP24XX_BASE_BAUD * 16; omap_up.flags = UPF_BOOT_AUTOCONF; omap_up.get_context_loss_count = omap_pm_get_dev_context_loss_count; omap_up.set_forceidle = omap_uart_set_forceidle; omap_up.set_noidle = omap_uart_set_noidle; omap_up.enable_wakeup = omap_uart_enable_wakeup; + omap_up.dma_rx_buf_size = info->dma_rx_buf_size; + omap_up.dma_rx_timeout = info->dma_rx_timeout; + omap_up.autosuspend_timeout = info->autosuspend_timeout; /* Enable the MDR1 Errata i202 for OMAP2430/3xxx/44xx */ if (!cpu_is_omap2420() && !cpu_is_ti816x()) @@ -379,13 +398,14 @@ void __init omap_serial_init_port(struct omap_board_data *bdata) } /** - * omap_serial_init() - initialize all supported serial ports + * omap_serial_board_init() - initialize all supported serial ports + * @info: platform specific data pointer * * Initializes all available UARTs as serial ports. Platforms * can call this function when they want to have default behaviour * for serial ports (e.g initialize them all as serial ports). */ -void __init omap_serial_init(void) +void __init omap_serial_board_init(struct omap_uart_port_info *info) { struct omap_uart_state *uart; struct omap_board_data bdata; @@ -399,7 +419,21 @@ void __init omap_serial_init(void) if (cpu_is_omap44xx() || cpu_is_omap34xx()) omap_serial_fill_default_pads(&bdata); - omap_serial_init_port(&bdata); - + if (!info) + omap_serial_init_port(&bdata, NULL); + else + omap_serial_init_port(&bdata, &info[uart->num]); } } + +/** + * omap_serial_init() - initialize all supported serial ports + * + * Initializes all available UARTs. + * Platforms can call this function when they want to have default behaviour + * for serial ports (e.g initialize them all as serial ports). + */ +void __init omap_serial_init(void) +{ + omap_serial_board_init(NULL); +} diff --git a/arch/arm/plat-omap/include/plat/omap-serial.h b/arch/arm/plat-omap/include/plat/omap-serial.h index 39709ecfd58..a740a6c0e10 100644 --- a/arch/arm/plat-omap/include/plat/omap-serial.h +++ b/arch/arm/plat-omap/include/plat/omap-serial.h @@ -66,6 +66,9 @@ struct omap_uart_port_info { unsigned int uartclk; /* UART clock rate */ upf_t flags; /* UPF_* flags */ u32 errata; + unsigned int dma_rx_buf_size; + unsigned int dma_rx_timeout; + unsigned int autosuspend_timeout; int (*get_context_loss_count)(struct device *); void (*set_forceidle)(struct platform_device *); @@ -94,8 +97,8 @@ struct uart_omap_dma { spinlock_t rx_lock; /* timer to poll activity on rx dma */ struct timer_list rx_timer; - int rx_buf_size; - int rx_timeout; + unsigned int rx_buf_size; + unsigned int rx_timeout; }; struct uart_omap_port { diff --git a/arch/arm/plat-omap/include/plat/serial.h b/arch/arm/plat-omap/include/plat/serial.h index 152500b558a..38b3e38df2a 100644 --- a/arch/arm/plat-omap/include/plat/serial.h +++ b/arch/arm/plat-omap/include/plat/serial.h @@ -106,10 +106,13 @@ #ifndef __ASSEMBLER__ struct omap_board_data; +struct omap_uart_port_info; extern void omap_serial_init(void); -extern void omap_serial_init_port(struct omap_board_data *bdata); extern int omap_uart_can_sleep(void); +extern void omap_serial_board_init(struct omap_uart_port_info *platform_data); +extern void omap_serial_init_port(struct omap_board_data *bdata, + struct omap_uart_port_info *platform_data); #endif #endif diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index 45a25a01c44..d60e001cf60 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c @@ -43,8 +43,6 @@ #include #include -#define OMAP_UART_AUTOSUSPEND_DELAY -1 - static struct uart_omap_port *ui[OMAP_MAX_HSUART_PORTS]; /* Forward declaration of functions */ @@ -1376,8 +1374,8 @@ static int serial_omap_probe(struct platform_device *pdev) up->uart_dma.uart_dma_tx = dma_tx->start; up->uart_dma.uart_dma_rx = dma_rx->start; up->use_dma = 1; - up->uart_dma.rx_buf_size = 4096; - up->uart_dma.rx_timeout = 2; + up->uart_dma.rx_buf_size = omap_up_info->dma_rx_buf_size; + up->uart_dma.rx_timeout = omap_up_info->dma_rx_timeout; spin_lock_init(&(up->uart_dma.tx_lock)); spin_lock_init(&(up->uart_dma.rx_lock)); up->uart_dma.tx_dma_channel = OMAP_UART_DMA_CH_FREE; @@ -1386,7 +1384,7 @@ static int serial_omap_probe(struct platform_device *pdev) pm_runtime_use_autosuspend(&pdev->dev); pm_runtime_set_autosuspend_delay(&pdev->dev, - OMAP_UART_AUTOSUSPEND_DELAY); + omap_up_info->autosuspend_timeout); pm_runtime_irq_safe(&pdev->dev); pm_runtime_enable(&pdev->dev); -- cgit v1.2.3-70-g09d2 From a9e210e0b7a344c0e44aa6bf6888176bbc635c42 Mon Sep 17 00:00:00 2001 From: Jon Hunter Date: Wed, 9 Nov 2011 17:34:49 +0530 Subject: ARM: OMAP2+: UART: Make the RX_TIMEOUT for DMA configurable for each UART When using DMA there are two timeouts defined. The first timeout, rx_timeout, is really a polling rate in which software polls the DMA status to see if the DMA has finished. This is necessary for the RX side because we do not know how much data we will receive. The secound timeout, RX_TIMEOUT, is a timeout after which the DMA will be stopped if no more data is received. To make this clearer, rename rx_timeout as rx_poll_rate and rename the function serial_omap_rx_timeout() to serial_omap_rxdma_poll(). The OMAP-Serial driver defines an RX_TIMEOUT of 3 seconds that is used to indicate when the DMA for UART can be stopped if no more data is received. The value is a global definition that is applied to all instances of the UART. Each UART may be used for a different purpose and so the timeout required may differ. Make this value configurable for each UART so that this value can be optimised for power savings. Signed-off-by: Jon Hunter Signed-off-by: Govindraj.R Acked-by: Greg Kroah-Hartman (for drivers/tty changes) Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/serial.c | 5 ++++- arch/arm/plat-omap/include/plat/omap-serial.h | 3 ++- drivers/tty/serial/omap-serial.c | 15 ++++++++------- 3 files changed, 14 insertions(+), 9 deletions(-) (limited to 'arch/arm/plat-omap/include/plat') diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c index 5b1b36a45e9..5dd92894503 100644 --- a/arch/arm/mach-omap2/serial.c +++ b/arch/arm/mach-omap2/serial.c @@ -64,13 +64,15 @@ struct omap_uart_state { static LIST_HEAD(uart_list); static u8 num_uarts; -#define DEFAULT_RXDMA_TIMEOUT 1 /* RX DMA polling rate (us) */ +#define DEFAULT_RXDMA_POLLRATE 1 /* RX DMA polling rate (us) */ #define DEFAULT_RXDMA_BUFSIZE 4096 /* RX DMA buffer size */ +#define DEFAULT_RXDMA_TIMEOUT (3 * HZ)/* RX DMA timeout (jiffies) */ static struct omap_uart_port_info omap_serial_default_info[] __initdata = { { .dma_enabled = false, .dma_rx_buf_size = DEFAULT_RXDMA_BUFSIZE, + .dma_rx_poll_rate = DEFAULT_RXDMA_POLLRATE, .dma_rx_timeout = DEFAULT_RXDMA_TIMEOUT, .autosuspend_timeout = DEFAULT_AUTOSUSPEND_DELAY, }, @@ -351,6 +353,7 @@ void __init omap_serial_init_port(struct omap_board_data *bdata, omap_up.enable_wakeup = omap_uart_enable_wakeup; omap_up.dma_rx_buf_size = info->dma_rx_buf_size; omap_up.dma_rx_timeout = info->dma_rx_timeout; + omap_up.dma_rx_poll_rate = info->dma_rx_poll_rate; omap_up.autosuspend_timeout = info->autosuspend_timeout; /* Enable the MDR1 Errata i202 for OMAP2430/3xxx/44xx */ diff --git a/arch/arm/plat-omap/include/plat/omap-serial.h b/arch/arm/plat-omap/include/plat/omap-serial.h index a740a6c0e10..ea63b2bc761 100644 --- a/arch/arm/plat-omap/include/plat/omap-serial.h +++ b/arch/arm/plat-omap/include/plat/omap-serial.h @@ -53,7 +53,6 @@ #define OMAP_UART_DMA_CH_FREE -1 -#define RX_TIMEOUT (3 * HZ) #define OMAP_MAX_HSUART_PORTS 4 #define MSR_SAVE_FLAGS UART_MSR_ANY_DELTA @@ -69,6 +68,7 @@ struct omap_uart_port_info { unsigned int dma_rx_buf_size; unsigned int dma_rx_timeout; unsigned int autosuspend_timeout; + unsigned int dma_rx_poll_rate; int (*get_context_loss_count)(struct device *); void (*set_forceidle)(struct platform_device *); @@ -98,6 +98,7 @@ struct uart_omap_dma { /* timer to poll activity on rx dma */ struct timer_list rx_timer; unsigned int rx_buf_size; + unsigned int rx_poll_rate; unsigned int rx_timeout; }; diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index d60e001cf60..e1eaa66c047 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c @@ -47,7 +47,7 @@ static struct uart_omap_port *ui[OMAP_MAX_HSUART_PORTS]; /* Forward declaration of functions */ static void uart_tx_dma_callback(int lch, u16 ch_status, void *data); -static void serial_omap_rx_timeout(unsigned long uart_no); +static void serial_omap_rxdma_poll(unsigned long uart_no); static int serial_omap_start_rxdma(struct uart_omap_port *up); static void serial_omap_mdr1_errataset(struct uart_omap_port *up, u8 mdr1); @@ -542,7 +542,7 @@ static int serial_omap_startup(struct uart_port *port) (dma_addr_t *)&(up->uart_dma.tx_buf_dma_phys), 0); init_timer(&(up->uart_dma.rx_timer)); - up->uart_dma.rx_timer.function = serial_omap_rx_timeout; + up->uart_dma.rx_timer.function = serial_omap_rxdma_poll; up->uart_dma.rx_timer.data = up->pdev->id; /* Currently the buffer size is 4KB. Can increase it */ up->uart_dma.rx_buf = dma_alloc_coherent(NULL, @@ -1160,7 +1160,7 @@ static int serial_omap_resume(struct device *dev) } #endif -static void serial_omap_rx_timeout(unsigned long uart_no) +static void serial_omap_rxdma_poll(unsigned long uart_no) { struct uart_omap_port *up = ui[uart_no]; unsigned int curr_dma_pos, curr_transmitted_size; @@ -1170,9 +1170,9 @@ static void serial_omap_rx_timeout(unsigned long uart_no) if ((curr_dma_pos == up->uart_dma.prev_rx_dma_pos) || (curr_dma_pos == 0)) { if (jiffies_to_msecs(jiffies - up->port_activity) < - RX_TIMEOUT) { + up->uart_dma.rx_timeout) { mod_timer(&up->uart_dma.rx_timer, jiffies + - usecs_to_jiffies(up->uart_dma.rx_timeout)); + usecs_to_jiffies(up->uart_dma.rx_poll_rate)); } else { serial_omap_stop_rxdma(up); up->ier |= (UART_IER_RDI | UART_IER_RLSI); @@ -1201,7 +1201,7 @@ static void serial_omap_rx_timeout(unsigned long uart_no) } } else { mod_timer(&up->uart_dma.rx_timer, jiffies + - usecs_to_jiffies(up->uart_dma.rx_timeout)); + usecs_to_jiffies(up->uart_dma.rx_poll_rate)); } up->port_activity = jiffies; } @@ -1240,7 +1240,7 @@ static int serial_omap_start_rxdma(struct uart_omap_port *up) /* FIXME: Cache maintenance needed here? */ omap_start_dma(up->uart_dma.rx_dma_channel); mod_timer(&up->uart_dma.rx_timer, jiffies + - usecs_to_jiffies(up->uart_dma.rx_timeout)); + usecs_to_jiffies(up->uart_dma.rx_poll_rate)); up->uart_dma.rx_dma_used = true; return ret; } @@ -1376,6 +1376,7 @@ static int serial_omap_probe(struct platform_device *pdev) up->use_dma = 1; up->uart_dma.rx_buf_size = omap_up_info->dma_rx_buf_size; up->uart_dma.rx_timeout = omap_up_info->dma_rx_timeout; + up->uart_dma.rx_poll_rate = omap_up_info->dma_rx_poll_rate; spin_lock_init(&(up->uart_dma.tx_lock)); spin_lock_init(&(up->uart_dma.rx_lock)); up->uart_dma.tx_dma_channel = OMAP_UART_DMA_CH_FREE; -- cgit v1.2.3-70-g09d2 From 2fd149645eb46d26130d7070c6de037dddf34880 Mon Sep 17 00:00:00 2001 From: "Govindraj.R" Date: Wed, 9 Nov 2011 17:41:21 +0530 Subject: ARM: OMAP2+: UART: Remove omap_uart_can_sleep and add pm_qos Omap_uart_can_sleep function blocks system wide low power state until uart is active remove this func and add qos requests to prevent MPU from transitioning. Keep qos request to default value which will allow MPU to transition and while uart baud rate is available calculate the latency value from the baudrate and use the same to hold constraint while uart clocks are enabled, and if uart is auto-idled the constraint is updated with default constraint value allowing MPU to transition. Qos requests are blocking notifier calls so put these requests to work queue, also the driver uses irq_safe version of runtime API's and callbacks can be called in interrupt disabled context. So to avoid warn on slow path warning while using qos update API's from runtime callbacks use the qos_work_queue. During bootup the runtime_resume call backs might not be called and runtime callback gets called only after uart is idled by setting the autosuspend timeout. So qos_request from runtime resume callback might not activated during boot if uart baudrate is calculated during bootup for console uart, so schedule the qos_work queue once we calc_latency while configuring the uart port. Flush and complete any pending qos jobs in work queue while suspending. Signed-off-by: Govindraj.R Acked-by: Greg Kroah-Hartman (for drivers/tty changes) Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/cpuidle34xx.c | 6 ----- arch/arm/mach-omap2/pm24xx.c | 2 -- arch/arm/mach-omap2/pm34xx.c | 11 -------- arch/arm/mach-omap2/serial.c | 22 ---------------- arch/arm/plat-omap/include/plat/omap-serial.h | 6 +++++ drivers/tty/serial/omap-serial.c | 36 ++++++++++++++++++++++++++- 6 files changed, 41 insertions(+), 42 deletions(-) (limited to 'arch/arm/plat-omap/include/plat') diff --git a/arch/arm/mach-omap2/cpuidle34xx.c b/arch/arm/mach-omap2/cpuidle34xx.c index e20332f4abd..3a9d2b883b3 100644 --- a/arch/arm/mach-omap2/cpuidle34xx.c +++ b/arch/arm/mach-omap2/cpuidle34xx.c @@ -30,7 +30,6 @@ #include #include "powerdomain.h" #include "clockdomain.h" -#include #include "pm.h" #include "control.h" @@ -245,11 +244,6 @@ static int omap3_enter_idle_bm(struct cpuidle_device *dev, struct omap3_idle_statedata *cx; int ret; - if (!omap3_can_sleep()) { - new_state_idx = drv->safe_state_index; - goto select_state; - } - /* * Prevent idle completely if CAM is active. * CAM does not have wakeup capability in OMAP3. diff --git a/arch/arm/mach-omap2/pm24xx.c b/arch/arm/mach-omap2/pm24xx.c index 22af2f2fdbf..b8822f8b289 100644 --- a/arch/arm/mach-omap2/pm24xx.c +++ b/arch/arm/mach-omap2/pm24xx.c @@ -222,8 +222,6 @@ static int omap2_can_sleep(void) { if (omap2_fclks_active()) return 0; - if (!omap_uart_can_sleep()) - return 0; if (osc_ck->usecount > 1) return 0; if (omap_dma_running()) diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index 4feee45ef06..4ee5f4eb04e 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -35,7 +35,6 @@ #include #include "clockdomain.h" #include "powerdomain.h" -#include #include #include #include @@ -456,21 +455,11 @@ void omap_sram_idle(void) clkdm_allow_idle(mpu_pwrdm->pwrdm_clkdms[0]); } -int omap3_can_sleep(void) -{ - if (!omap_uart_can_sleep()) - return 0; - return 1; -} - static void omap3_pm_idle(void) { local_irq_disable(); local_fiq_disable(); - if (!omap3_can_sleep()) - goto out; - if (omap_irq_pending() || need_resched()) goto out; diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c index c909770eacd..247d89478f2 100644 --- a/arch/arm/mach-omap2/serial.c +++ b/arch/arm/mach-omap2/serial.c @@ -82,28 +82,6 @@ static struct omap_uart_port_info omap_serial_default_info[] __initdata = { }; #ifdef CONFIG_PM - -int omap_uart_can_sleep(void) -{ - struct omap_uart_state *uart; - int can_sleep = 1; - - list_for_each_entry(uart, &uart_list, node) { - if (!uart->clocked) - continue; - - if (!uart->can_sleep) { - can_sleep = 0; - continue; - } - - /* This UART can now safely sleep. */ - omap_uart_allow_sleep(uart); - } - - return can_sleep; -} - static void omap_uart_enable_wakeup(struct platform_device *pdev, bool enable) { struct omap_device *od = to_omap_device(pdev); diff --git a/arch/arm/plat-omap/include/plat/omap-serial.h b/arch/arm/plat-omap/include/plat/omap-serial.h index ea63b2bc761..9ff444469f3 100644 --- a/arch/arm/plat-omap/include/plat/omap-serial.h +++ b/arch/arm/plat-omap/include/plat/omap-serial.h @@ -19,6 +19,7 @@ #include #include +#include #include @@ -130,6 +131,11 @@ struct uart_omap_port { u32 context_loss_cnt; u32 errata; u8 wakeups_enabled; + + struct pm_qos_request pm_qos_request; + u32 latency; + u32 calc_latency; + struct work_struct qos_work; }; #endif /* __OMAP_SERIAL_H__ */ diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index e1eaa66c047..f3ff0ca377c 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c @@ -51,6 +51,8 @@ static void serial_omap_rxdma_poll(unsigned long uart_no); static int serial_omap_start_rxdma(struct uart_omap_port *up); static void serial_omap_mdr1_errataset(struct uart_omap_port *up, u8 mdr1); +static struct workqueue_struct *serial_omap_uart_wq; + static inline unsigned int serial_in(struct uart_omap_port *up, int offset) { offset <<= up->port.regshift; @@ -671,6 +673,14 @@ serial_omap_configure_xonxoff serial_out(up, UART_LCR, up->lcr); } +static void serial_omap_uart_qos_work(struct work_struct *work) +{ + struct uart_omap_port *up = container_of(work, struct uart_omap_port, + qos_work); + + pm_qos_update_request(&up->pm_qos_request, up->latency); +} + static void serial_omap_set_termios(struct uart_port *port, struct ktermios *termios, struct ktermios *old) @@ -711,6 +721,12 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios, baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/13); quot = serial_omap_get_divisor(port, baud); + /* calculate wakeup latency constraint */ + up->calc_latency = (1000000 * up->port.fifosize) / + (1000 * baud / 8); + up->latency = up->calc_latency; + schedule_work(&up->qos_work); + up->dll = quot & 0xff; up->dlh = quot >> 8; up->mdr1 = UART_OMAP_MDR1_DISABLE; @@ -1145,8 +1161,11 @@ static int serial_omap_suspend(struct device *dev) { struct uart_omap_port *up = dev_get_drvdata(dev); - if (up) + if (up) { uart_suspend_port(&serial_omap_reg, &up->port); + flush_work_sync(&up->qos_work); + } + return 0; } @@ -1383,6 +1402,13 @@ static int serial_omap_probe(struct platform_device *pdev) up->uart_dma.rx_dma_channel = OMAP_UART_DMA_CH_FREE; } + up->latency = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE; + up->calc_latency = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE; + pm_qos_add_request(&up->pm_qos_request, + PM_QOS_CPU_DMA_LATENCY, up->latency); + serial_omap_uart_wq = create_singlethread_workqueue(up->name); + INIT_WORK(&up->qos_work, serial_omap_uart_qos_work); + pm_runtime_use_autosuspend(&pdev->dev); pm_runtime_set_autosuspend_delay(&pdev->dev, omap_up_info->autosuspend_timeout); @@ -1416,6 +1442,8 @@ static int serial_omap_remove(struct platform_device *dev) if (up) { pm_runtime_disable(&up->pdev->dev); uart_remove_one_port(&serial_omap_reg, &up->port); + pm_qos_remove_request(&up->pm_qos_request); + kfree(up); } @@ -1518,6 +1546,9 @@ static int serial_omap_runtime_suspend(struct device *dev) (up->errata & UART_ERRATA_i291_DMA_FORCEIDLE)) pdata->set_forceidle(up->pdev); + up->latency = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE; + schedule_work(&up->qos_work); + return 0; } @@ -1538,6 +1569,9 @@ static int serial_omap_runtime_resume(struct device *dev) if (up->use_dma && pdata->set_noidle && (up->errata & UART_ERRATA_i291_DMA_FORCEIDLE)) pdata->set_noidle(up->pdev); + + up->latency = up->calc_latency; + schedule_work(&up->qos_work); } return 0; -- cgit v1.2.3-70-g09d2