From 68e824f3eb17be38258e341f6a9db046eec311bf Mon Sep 17 00:00:00 2001 From: Nishanth Menon Date: Wed, 15 Jun 2011 14:04:58 -0500 Subject: OMAP4: hwmod: make dss reset static Reset DSS is a public function which makes no sense. make it static Also fixes the following sparse warning: arch/arm/mach-omap2/omap_hwmod_44xx_data.c:1418:5: warning: symbol 'omap44xx_dss_reset' was not declared. Should it be static? as a side effect use kernel standards for function declaration of '{' Signed-off-by: Nishanth Menon --- arch/arm/mach-omap2/omap_hwmod_44xx_data.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'arch/arm') diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index f9fa220..ffa7190 100644 --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c @@ -1110,7 +1110,8 @@ static struct omap_hwmod_class_sysconfig omap44xx_dss_sysc = { .sysc_flags = SYSS_HAS_RESET_STATUS, }; -int omap44xx_dss_reset(struct omap_hwmod *oh) { +static int omap44xx_dss_reset(struct omap_hwmod *oh) +{ omap_hwmod_write(0x0, oh, 0x40); return 0; } -- cgit v1.1 From 20e93f112412967a9850cb9642195c04c46acd62 Mon Sep 17 00:00:00 2001 From: Dima Zavin Date: Mon, 27 Jun 2011 12:55:26 -0700 Subject: HACK: OMAP4: hwmod: disable lcd1/lcd2/tv before reparenting dss clocks HACK: There should be a way to do this without resorting to messing with DISPC registers inside DSS reset func. If we try to reparent the clocks while the LCD/TV is active and in the middle of a DMA, we can get underflow/sync errors that are sometimes unrecoverable. So, disable all the outputs first, then reset DSS clock muxes to all point to PRCM clocks. Based on a patch by Gilles-Arnaud Bleu-Laine Change-Id: I89b39845d76bcb4c522a3b9fa7e95c7ee362c759 Signed-off-by: Dima Zavin --- arch/arm/mach-omap2/omap_hwmod_44xx_data.c | 51 ++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) (limited to 'arch/arm') diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index ffa7190..15a6e8b 100644 --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c @@ -1112,8 +1112,59 @@ static struct omap_hwmod_class_sysconfig omap44xx_dss_sysc = { static int omap44xx_dss_reset(struct omap_hwmod *oh) { +#define DISPC_IRQSTATUS (0x48041018UL) +#define DISPC_CONTROL1 (0x48041040UL) +#define DISPC_CONTROL2 (0x48041238UL) + u32 ctrl1_mask = 0; + u32 ctrl2_mask = 0; + u32 irq_mask = 0; + u32 val; + unsigned long end_wait; + + /* HACK */ + /* If LCD1/LCD2/TV are active, disable them first before + * moving the clock sources back to PRCM. We don't want to change + * the clock source while a DMA is active. + */ + val = omap_readl(DISPC_CONTROL1); + if (val & (1 << 0)) { + /* LCD1 */ + irq_mask |= 1 << 0; + ctrl1_mask |= 1 << 0; + } + if (val & (1 << 1)) { + /* TV/VENC */ + irq_mask |= 1 << 24; + ctrl1_mask |= 1 << 1; + } + val = omap_readl(DISPC_CONTROL2); + if (val & (1 << 0)) { + /* LCD2 */ + irq_mask |= 1 << 22; + ctrl2_mask |= 1 << 0; + } + + /* disable the active controllers */ + omap_writel(omap_readl(DISPC_CONTROL1) & (~ctrl1_mask), DISPC_CONTROL1); + omap_writel(omap_readl(DISPC_CONTROL2) & (~ctrl2_mask), DISPC_CONTROL2); + + omap_writel(irq_mask, DISPC_IRQSTATUS); + + end_wait = jiffies + msecs_to_jiffies(50); + while (((omap_readl(DISPC_CONTROL1) & ctrl1_mask) || + (omap_readl(DISPC_CONTROL2) & ctrl2_mask) || + ((omap_readl(DISPC_IRQSTATUS) & irq_mask) != irq_mask)) && + time_before(jiffies, end_wait)) + cpu_relax(); + WARN_ON((omap_readl(DISPC_CONTROL1) & ctrl1_mask) || + (omap_readl(DISPC_CONTROL2) & ctrl2_mask) || + ((omap_readl(DISPC_IRQSTATUS) & irq_mask) != irq_mask)); + omap_hwmod_write(0x0, oh, 0x40); return 0; +#undef DISPC_IRQSTATUS +#undef DISPC_CONTROL1 +#undef DISPC_CONTROL2 } static struct omap_hwmod_class omap44xx_dss_hwmod_class = { -- cgit v1.1