Selaa lähdekoodia

Merge branch 'omap-clock-fixes' into omap-fixes

Tony Lindgren 16 vuotta sitten
vanhempi
commit
535ff672e3

+ 2 - 2
arch/arm/mach-omap1/mcbsp.c

@@ -40,8 +40,8 @@ static void omap1_mcbsp_request(unsigned int id)
 	 */
 	 */
 	if (id == OMAP_MCBSP1 || id == OMAP_MCBSP3) {
 	if (id == OMAP_MCBSP1 || id == OMAP_MCBSP3) {
 		if (dsp_use++ == 0) {
 		if (dsp_use++ == 0) {
-			api_clk = clk_get(NULL, "api_clk");
-			dsp_clk = clk_get(NULL, "dsp_clk");
+			api_clk = clk_get(NULL, "api_ck");
+			dsp_clk = clk_get(NULL, "dsp_ck");
 			if (!IS_ERR(api_clk) && !IS_ERR(dsp_clk)) {
 			if (!IS_ERR(api_clk) && !IS_ERR(dsp_clk)) {
 				clk_enable(api_clk);
 				clk_enable(api_clk);
 				clk_enable(dsp_clk);
 				clk_enable(dsp_clk);

+ 4 - 0
arch/arm/mach-omap2/board-omap3beagle.c

@@ -42,6 +42,7 @@
 #include <mach/nand.h>
 #include <mach/nand.h>
 #include <mach/mux.h>
 #include <mach/mux.h>
 #include <mach/usb.h>
 #include <mach/usb.h>
+#include <mach/timer-gp.h>
 
 
 #include "mmc-twl4030.h"
 #include "mmc-twl4030.h"
 
 
@@ -186,6 +187,9 @@ static void __init omap3_beagle_init_irq(void)
 {
 {
 	omap2_init_common_hw(NULL);
 	omap2_init_common_hw(NULL);
 	omap_init_irq();
 	omap_init_irq();
+#ifdef CONFIG_OMAP_32K_TIMER
+	omap2_gp_clockevent_set_gptimer(12);
+#endif
 	omap_gpio_init();
 	omap_gpio_init();
 }
 }
 
 

+ 7 - 12
arch/arm/mach-omap2/clock24xx.c

@@ -60,12 +60,13 @@ struct omap_clk {
 		},			\
 		},			\
 	}
 	}
 
 
-#define CK_243X	(1 << 0)
-#define CK_242X	(1 << 1)
+#define CK_243X			RATE_IN_243X
+#define CK_242X			RATE_IN_242X
 
 
 static struct omap_clk omap24xx_clks[] = {
 static struct omap_clk omap24xx_clks[] = {
 	/* external root sources */
 	/* external root sources */
 	CLK(NULL,	"func_32k_ck",	&func_32k_ck,	CK_243X | CK_242X),
 	CLK(NULL,	"func_32k_ck",	&func_32k_ck,	CK_243X | CK_242X),
+	CLK(NULL,	"secure_32k_ck", &secure_32k_ck, CK_243X | CK_242X),
 	CLK(NULL,	"osc_ck",	&osc_ck,	CK_243X | CK_242X),
 	CLK(NULL,	"osc_ck",	&osc_ck,	CK_243X | CK_242X),
 	CLK(NULL,	"sys_ck",	&sys_ck,	CK_243X | CK_242X),
 	CLK(NULL,	"sys_ck",	&sys_ck,	CK_243X | CK_242X),
 	CLK(NULL,	"alt_ck",	&alt_ck,	CK_243X | CK_242X),
 	CLK(NULL,	"alt_ck",	&alt_ck,	CK_243X | CK_242X),
@@ -711,7 +712,7 @@ int __init omap2_clk_init(void)
 {
 {
 	struct prcm_config *prcm;
 	struct prcm_config *prcm;
 	struct omap_clk *c;
 	struct omap_clk *c;
-	u32 clkrate, cpu_mask;
+	u32 clkrate;
 
 
 	if (cpu_is_omap242x())
 	if (cpu_is_omap242x())
 		cpu_mask = RATE_IN_242X;
 		cpu_mask = RATE_IN_242X;
@@ -720,20 +721,14 @@ int __init omap2_clk_init(void)
 
 
 	clk_init(&omap2_clk_functions);
 	clk_init(&omap2_clk_functions);
 
 
+	for (c = omap24xx_clks; c < omap24xx_clks + ARRAY_SIZE(omap24xx_clks); c++)
+		clk_init_one(c->lk.clk);
+
 	osc_ck.rate = omap2_osc_clk_recalc(&osc_ck);
 	osc_ck.rate = omap2_osc_clk_recalc(&osc_ck);
 	propagate_rate(&osc_ck);
 	propagate_rate(&osc_ck);
 	sys_ck.rate = omap2_sys_clk_recalc(&sys_ck);
 	sys_ck.rate = omap2_sys_clk_recalc(&sys_ck);
 	propagate_rate(&sys_ck);
 	propagate_rate(&sys_ck);
 
 
-	for (c = omap24xx_clks; c < omap24xx_clks + ARRAY_SIZE(omap24xx_clks); c++)
-		clk_init_one(c->lk.clk);
-
-	cpu_mask = 0;
-	if (cpu_is_omap2420())
-		cpu_mask |= CK_242X;
-	if (cpu_is_omap2430())
-		cpu_mask |= CK_243X;
-
 	for (c = omap24xx_clks; c < omap24xx_clks + ARRAY_SIZE(omap24xx_clks); c++)
 	for (c = omap24xx_clks; c < omap24xx_clks + ARRAY_SIZE(omap24xx_clks); c++)
 		if (c->cpu & cpu_mask) {
 		if (c->cpu & cpu_mask) {
 			clkdev_add(&c->lk);
 			clkdev_add(&c->lk);

+ 9 - 1
arch/arm/mach-omap2/clock24xx.h

@@ -625,6 +625,14 @@ static struct clk func_32k_ck = {
 	.clkdm_name	= "wkup_clkdm",
 	.clkdm_name	= "wkup_clkdm",
 };
 };
 
 
+static struct clk secure_32k_ck = {
+	.name		= "secure_32k_ck",
+	.ops		= &clkops_null,
+	.rate		= 32768,
+	.flags		= RATE_FIXED,
+	.clkdm_name	= "wkup_clkdm",
+};
+
 /* Typical 12/13MHz in standalone mode, will be 26Mhz in chassis mode */
 /* Typical 12/13MHz in standalone mode, will be 26Mhz in chassis mode */
 static struct clk osc_ck = {		/* (*12, *13, 19.2, *26, 38.4)MHz */
 static struct clk osc_ck = {		/* (*12, *13, 19.2, *26, 38.4)MHz */
 	.name		= "osc_ck",
 	.name		= "osc_ck",
@@ -1790,7 +1798,7 @@ static struct clk gpt12_ick = {
 static struct clk gpt12_fck = {
 static struct clk gpt12_fck = {
 	.name		= "gpt12_fck",
 	.name		= "gpt12_fck",
 	.ops		= &clkops_omap2_dflt_wait,
 	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_32k_ck,
+	.parent		= &secure_32k_ck,
 	.clkdm_name	= "core_l4_clkdm",
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
 	.enable_bit	= OMAP24XX_EN_GPT12_SHIFT,
 	.enable_bit	= OMAP24XX_EN_GPT12_SHIFT,

+ 3 - 4
arch/arm/mach-omap2/clock34xx.h

@@ -2052,7 +2052,7 @@ static struct clk dss_ick = {
 
 
 static struct clk cam_mclk = {
 static struct clk cam_mclk = {
 	.name		= "cam_mclk",
 	.name		= "cam_mclk",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_dflt,
 	.parent		= &dpll4_m5x2_ck,
 	.parent		= &dpll4_m5x2_ck,
 	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_CAM_MOD, CM_FCLKEN),
 	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_CAM_MOD, CM_FCLKEN),
 	.enable_bit	= OMAP3430_EN_CAM_SHIFT,
 	.enable_bit	= OMAP3430_EN_CAM_SHIFT,
@@ -2063,7 +2063,7 @@ static struct clk cam_mclk = {
 static struct clk cam_ick = {
 static struct clk cam_ick = {
 	/* Handles both L3 and L4 clocks */
 	/* Handles both L3 and L4 clocks */
 	.name		= "cam_ick",
 	.name		= "cam_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_dflt,
 	.parent		= &l4_ick,
 	.parent		= &l4_ick,
 	.init		= &omap2_init_clk_clkdm,
 	.init		= &omap2_init_clk_clkdm,
 	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_CAM_MOD, CM_ICLKEN),
 	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_CAM_MOD, CM_ICLKEN),
@@ -2074,7 +2074,7 @@ static struct clk cam_ick = {
 
 
 static struct clk csi2_96m_fck = {
 static struct clk csi2_96m_fck = {
 	.name		= "csi2_96m_fck",
 	.name		= "csi2_96m_fck",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_dflt,
 	.parent		= &core_96m_fck,
 	.parent		= &core_96m_fck,
 	.init		= &omap2_init_clk_clkdm,
 	.init		= &omap2_init_clk_clkdm,
 	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_CAM_MOD, CM_FCLKEN),
 	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_CAM_MOD, CM_FCLKEN),
@@ -2901,7 +2901,6 @@ static struct clk sr_l4_ick = {
 
 
 /* SECURE_32K_FCK clocks */
 /* SECURE_32K_FCK clocks */
 
 
-/* XXX This clock no longer exists in 3430 TRM rev F */
 static struct clk gpt12_fck = {
 static struct clk gpt12_fck = {
 	.name		= "gpt12_fck",
 	.name		= "gpt12_fck",
 	.ops		= &clkops_null,
 	.ops		= &clkops_null,

+ 45 - 3
arch/arm/mach-omap2/timer-gp.c

@@ -3,6 +3,8 @@
  *
  *
  * OMAP2 GP timer support.
  * OMAP2 GP timer support.
  *
  *
+ * Copyright (C) 2009 Nokia Corporation
+ *
  * Update to use new clocksource/clockevent layers
  * Update to use new clocksource/clockevent layers
  * Author: Kevin Hilman, MontaVista Software, Inc. <source@mvista.com>
  * Author: Kevin Hilman, MontaVista Software, Inc. <source@mvista.com>
  * Copyright (C) 2007 MontaVista Software, Inc.
  * Copyright (C) 2007 MontaVista Software, Inc.
@@ -36,8 +38,13 @@
 #include <asm/mach/time.h>
 #include <asm/mach/time.h>
 #include <mach/dmtimer.h>
 #include <mach/dmtimer.h>
 
 
+/* MAX_GPTIMER_ID: number of GPTIMERs on the chip */
+#define MAX_GPTIMER_ID		12
+
 static struct omap_dm_timer *gptimer;
 static struct omap_dm_timer *gptimer;
 static struct clock_event_device clockevent_gpt;
 static struct clock_event_device clockevent_gpt;
+static u8 __initdata gptimer_id = 1;
+static u8 __initdata inited;
 
 
 static irqreturn_t omap2_gp_timer_interrupt(int irq, void *dev_id)
 static irqreturn_t omap2_gp_timer_interrupt(int irq, void *dev_id)
 {
 {
@@ -95,20 +102,53 @@ static struct clock_event_device clockevent_gpt = {
 	.set_mode	= omap2_gp_timer_set_mode,
 	.set_mode	= omap2_gp_timer_set_mode,
 };
 };
 
 
+/**
+ * omap2_gp_clockevent_set_gptimer - set which GPTIMER is used for clockevents
+ * @id: GPTIMER to use (1..MAX_GPTIMER_ID)
+ *
+ * Define the GPTIMER that the system should use for the tick timer.
+ * Meant to be called from board-*.c files in the event that GPTIMER1, the
+ * default, is unsuitable.  Returns -EINVAL on error or 0 on success.
+ */
+int __init omap2_gp_clockevent_set_gptimer(u8 id)
+{
+	if (id < 1 || id > MAX_GPTIMER_ID)
+		return -EINVAL;
+
+	BUG_ON(inited);
+
+	gptimer_id = id;
+
+	return 0;
+}
+
 static void __init omap2_gp_clockevent_init(void)
 static void __init omap2_gp_clockevent_init(void)
 {
 {
 	u32 tick_rate;
 	u32 tick_rate;
+	int src;
+
+	inited = 1;
 
 
-	gptimer = omap_dm_timer_request_specific(1);
+	gptimer = omap_dm_timer_request_specific(gptimer_id);
 	BUG_ON(gptimer == NULL);
 	BUG_ON(gptimer == NULL);
 
 
 #if defined(CONFIG_OMAP_32K_TIMER)
 #if defined(CONFIG_OMAP_32K_TIMER)
-	omap_dm_timer_set_source(gptimer, OMAP_TIMER_SRC_32_KHZ);
+	src = OMAP_TIMER_SRC_32_KHZ;
 #else
 #else
-	omap_dm_timer_set_source(gptimer, OMAP_TIMER_SRC_SYS_CLK);
+	src = OMAP_TIMER_SRC_SYS_CLK;
+	WARN(gptimer_id == 12, "WARNING: GPTIMER12 can only use the "
+	     "secure 32KiHz clock source\n");
 #endif
 #endif
+
+	if (gptimer_id != 12)
+		WARN(IS_ERR_VALUE(omap_dm_timer_set_source(gptimer, src)),
+		     "timer-gp: omap_dm_timer_set_source() failed\n");
+
 	tick_rate = clk_get_rate(omap_dm_timer_get_fclk(gptimer));
 	tick_rate = clk_get_rate(omap_dm_timer_get_fclk(gptimer));
 
 
+	pr_info("OMAP clockevent source: GPTIMER%d at %u Hz\n",
+		gptimer_id, tick_rate);
+
 	omap2_gp_timer_irq.dev_id = (void *)gptimer;
 	omap2_gp_timer_irq.dev_id = (void *)gptimer;
 	setup_irq(omap_dm_timer_get_irq(gptimer), &omap2_gp_timer_irq);
 	setup_irq(omap_dm_timer_get_irq(gptimer), &omap2_gp_timer_irq);
 	omap_dm_timer_set_int_enable(gptimer, OMAP_TIMER_INT_OVERFLOW);
 	omap_dm_timer_set_int_enable(gptimer, OMAP_TIMER_INT_OVERFLOW);
@@ -125,6 +165,8 @@ static void __init omap2_gp_clockevent_init(void)
 	clockevents_register_device(&clockevent_gpt);
 	clockevents_register_device(&clockevent_gpt);
 }
 }
 
 
+/* Clocksource code */
+
 #ifdef CONFIG_OMAP_32K_TIMER
 #ifdef CONFIG_OMAP_32K_TIMER
 /* 
 /* 
  * When 32k-timer is enabled, don't use GPTimer for clocksource
  * When 32k-timer is enabled, don't use GPTimer for clocksource

+ 7 - 0
arch/arm/plat-omap/clock.c

@@ -239,6 +239,13 @@ void recalculate_root_clocks(void)
 	}
 	}
 }
 }
 
 
+/**
+ * clk_init_one - initialize any fields in the struct clk before clk init
+ * @clk: struct clk * to initialize
+ *
+ * Initialize any struct clk fields needed before normal clk initialization
+ * can run.  No return value.
+ */
 void clk_init_one(struct clk *clk)
 void clk_init_one(struct clk *clk)
 {
 {
 	INIT_LIST_HEAD(&clk->children);
 	INIT_LIST_HEAD(&clk->children);

+ 17 - 11
arch/arm/plat-omap/dmtimer.c

@@ -238,7 +238,7 @@ static struct omap_dm_timer omap3_dm_timers[] = {
 	{ .phys_base = 0x49040000, .irq = INT_24XX_GPTIMER9 },
 	{ .phys_base = 0x49040000, .irq = INT_24XX_GPTIMER9 },
 	{ .phys_base = 0x48086000, .irq = INT_24XX_GPTIMER10 },
 	{ .phys_base = 0x48086000, .irq = INT_24XX_GPTIMER10 },
 	{ .phys_base = 0x48088000, .irq = INT_24XX_GPTIMER11 },
 	{ .phys_base = 0x48088000, .irq = INT_24XX_GPTIMER11 },
-	{ .phys_base = 0x48304000, .irq = INT_24XX_GPTIMER12 },
+	{ .phys_base = 0x48304000, .irq = INT_34XX_GPT12_IRQ },
 };
 };
 
 
 static const char *omap3_dm_source_names[] __initdata = {
 static const char *omap3_dm_source_names[] __initdata = {
@@ -321,11 +321,9 @@ static void omap_dm_timer_reset(struct omap_dm_timer *timer)
 	l |= 0x2 << 8;   /* Set clock activity to perserve f-clock on idle */
 	l |= 0x2 << 8;   /* Set clock activity to perserve f-clock on idle */
 
 
 	/*
 	/*
-	 * Enable wake-up only for GPT1 on OMAP2 CPUs.
-	 * FIXME: All timers should have wake-up enabled and clear
-	 * PRCM status.
+	 * Enable wake-up on OMAP2 CPUs.
 	 */
 	 */
-	if (cpu_class_is_omap2() && (timer == &dm_timers[0]))
+	if (cpu_class_is_omap2())
 		l |= 1 << 2;
 		l |= 1 << 2;
 	omap_dm_timer_write_reg(timer, OMAP_TIMER_OCP_CFG_REG, l);
 	omap_dm_timer_write_reg(timer, OMAP_TIMER_OCP_CFG_REG, l);
 
 
@@ -511,7 +509,7 @@ EXPORT_SYMBOL_GPL(omap_dm_timer_stop);
 
 
 #ifdef CONFIG_ARCH_OMAP1
 #ifdef CONFIG_ARCH_OMAP1
 
 
-void omap_dm_timer_set_source(struct omap_dm_timer *timer, int source)
+int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source)
 {
 {
 	int n = (timer - dm_timers) << 1;
 	int n = (timer - dm_timers) << 1;
 	u32 l;
 	u32 l;
@@ -519,23 +517,31 @@ void omap_dm_timer_set_source(struct omap_dm_timer *timer, int source)
 	l = omap_readl(MOD_CONF_CTRL_1) & ~(0x03 << n);
 	l = omap_readl(MOD_CONF_CTRL_1) & ~(0x03 << n);
 	l |= source << n;
 	l |= source << n;
 	omap_writel(l, MOD_CONF_CTRL_1);
 	omap_writel(l, MOD_CONF_CTRL_1);
+
+	return 0;
 }
 }
 EXPORT_SYMBOL_GPL(omap_dm_timer_set_source);
 EXPORT_SYMBOL_GPL(omap_dm_timer_set_source);
 
 
 #else
 #else
 
 
-void omap_dm_timer_set_source(struct omap_dm_timer *timer, int source)
+int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source)
 {
 {
+	int ret = -EINVAL;
+
 	if (source < 0 || source >= 3)
 	if (source < 0 || source >= 3)
-		return;
+		return -EINVAL;
 
 
 	clk_disable(timer->fclk);
 	clk_disable(timer->fclk);
-	clk_set_parent(timer->fclk, dm_source_clocks[source]);
+	ret = clk_set_parent(timer->fclk, dm_source_clocks[source]);
 	clk_enable(timer->fclk);
 	clk_enable(timer->fclk);
 
 
-	/* When the functional clock disappears, too quick writes seem to
-	 * cause an abort. */
+	/*
+	 * When the functional clock disappears, too quick writes seem
+	 * to cause an abort. XXX Is this still necessary?
+	 */
 	__delay(150000);
 	__delay(150000);
+
+	return ret;
 }
 }
 EXPORT_SYMBOL_GPL(omap_dm_timer_set_source);
 EXPORT_SYMBOL_GPL(omap_dm_timer_set_source);
 
 

+ 1 - 1
arch/arm/plat-omap/include/mach/dmtimer.h

@@ -64,7 +64,7 @@ void omap_dm_timer_trigger(struct omap_dm_timer *timer);
 void omap_dm_timer_start(struct omap_dm_timer *timer);
 void omap_dm_timer_start(struct omap_dm_timer *timer);
 void omap_dm_timer_stop(struct omap_dm_timer *timer);
 void omap_dm_timer_stop(struct omap_dm_timer *timer);
 
 
-void omap_dm_timer_set_source(struct omap_dm_timer *timer, int source);
+int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source);
 void omap_dm_timer_set_load(struct omap_dm_timer *timer, int autoreload, unsigned int value);
 void omap_dm_timer_set_load(struct omap_dm_timer *timer, int autoreload, unsigned int value);
 void omap_dm_timer_set_load_start(struct omap_dm_timer *timer, int autoreload, unsigned int value);
 void omap_dm_timer_set_load_start(struct omap_dm_timer *timer, int autoreload, unsigned int value);
 void omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable, unsigned int match);
 void omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable, unsigned int match);

+ 17 - 0
arch/arm/plat-omap/include/mach/timer-gp.h

@@ -0,0 +1,17 @@
+/*
+ * OMAP2/3 GPTIMER support.headers
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_TIMER_GP_H
+#define __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_TIMER_GP_H
+
+int __init omap2_gp_clockevent_set_gptimer(u8 id);
+
+#endif
+