diff options
author | William Lai <b04597@freescale.com> | 2009-08-04 11:11:10 +0800 |
---|---|---|
committer | Rob Herring <r.herring@freescale.com> | 2009-08-07 09:47:35 -0500 |
commit | 6118b31c7f41f6a800391a60088e92eb5e2e5ed7 (patch) | |
tree | 71c6411b08b9ea97d9175dcdb65410a93d454dcf | |
parent | ff866679372a4c340c9f873662d6ac8941e0ab7b (diff) |
ENGR00114644-2 MX51 PWM: Correction for the PWM
1. Some field of the the PWM control register is
recommended to be changed when the PWM is disabled.
2. Enable and disable the PWM in the enable and disable
functions repectively, but not in the config function.
3. Right now, the PWM module supports MX51 too.
Signed-off-by: William Lai<b04597@freescale.com>
-rw-r--r-- | arch/arm/plat-mxc/include/mach/hardware.h | 6 | ||||
-rw-r--r-- | arch/arm/plat-mxc/pwm.c | 36 |
2 files changed, 34 insertions, 8 deletions
diff --git a/arch/arm/plat-mxc/include/mach/hardware.h b/arch/arm/plat-mxc/include/mach/hardware.h index 61bea0e55161..57a7a468c8f8 100644 --- a/arch/arm/plat-mxc/include/mach/hardware.h +++ b/arch/arm/plat-mxc/include/mach/hardware.h @@ -112,6 +112,12 @@ static inline int type## _rev (int rev) \ #define cpu_is_mx27() (0) #endif +#define cpu_is_mx2() \ + (cpu_is_mx21() || cpu_is_mx25() || cpu_is_mx27()) +#define cpu_is_mx3() \ + (cpu_is_mx31() || cpu_is_mx35() || cpu_is_mx37()) + + #ifndef __ASSEMBLY__ /* * Create inline functions to test for cpu revision diff --git a/arch/arm/plat-mxc/pwm.c b/arch/arm/plat-mxc/pwm.c index ae34198a79dd..ee43e6a6710e 100644 --- a/arch/arm/plat-mxc/pwm.c +++ b/arch/arm/plat-mxc/pwm.c @@ -6,6 +6,7 @@ * published by the Free Software Foundation. * * Derived from pxa PWM driver by eric miao <eric.miao@marvell.com> + * Copyright 2009 Freescale Semiconductor, Inc. All Rights Reserved. */ #include <linux/module.h> @@ -25,16 +26,21 @@ #define MX1_PWMP 0x08 /* PWM Period Register */ -/* i.MX27, i.MX31, i.MX35 share the same PWM function block: */ +/* i.MX27, i.MX31, i.MX35, i.MX51 share the same PWM function block: */ #define MX3_PWMCR 0x00 /* PWM Control Register */ #define MX3_PWMSAR 0x0C /* PWM Sample Register */ #define MX3_PWMPR 0x10 /* PWM Period Register */ #define MX3_PWMCR_PRESCALER(x) (((x - 1) & 0xFFF) << 4) -#define MX3_PWMCR_CLKSRC_IPG_HIGH (2 << 16) -#define MX3_PWMCR_EN (1 << 0) - +#define MX3_PWMCR_STOPEN (1 << 25) +#define MX3_PWMCR_DOZEEN (1 << 24) +#define MX3_PWMCR_WAITEN (1 << 23) +#define MX3_PWMCR_DBGEN (1 << 22) +#define MX3_PWMCR_CLKSRC_IPG (1 << 16) +#define MX3_PWMCR_CLKSRC_IPG_HIGH (2 << 16) +#define MX3_PWMCR_CLKSRC_IPG_32k (3 << 16) +#define MX3_PWMCR_EN (1 << 0) struct pwm_device { struct list_head node; @@ -55,7 +61,7 @@ int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns) if (pwm == NULL || period_ns == 0 || duty_ns > period_ns) return -EINVAL; - if (cpu_is_mx27() || cpu_is_mx3()) { + if (cpu_is_mx27() || cpu_is_mx3() || cpu_is_mx51()) { unsigned long long c; unsigned long period_cycles, duty_cycles, prescale; c = clk_get_rate(pwm->clk); @@ -72,10 +78,12 @@ int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns) writel(duty_cycles, pwm->mmio_base + MX3_PWMSAR); writel(period_cycles, pwm->mmio_base + MX3_PWMPR); - writel(MX3_PWMCR_PRESCALER(prescale - 1) | - MX3_PWMCR_CLKSRC_IPG_HIGH | MX3_PWMCR_EN, + writel(MX3_PWMCR_PRESCALER(prescale) | + MX3_PWMCR_CLKSRC_IPG_HIGH | + MX3_PWMCR_STOPEN | MX3_PWMCR_DOZEEN | + MX3_PWMCR_WAITEN | MX3_PWMCR_DBGEN, pwm->mmio_base + MX3_PWMCR); - } else if (cpu_is_mx1() || cpu_is_mx21()) { + } else if (cpu_is_mx21()) { /* The PWM subsystem allows for exact frequencies. However, * I cannot connect a scope on my device to the PWM line and * thus cannot provide the program the PWM controller @@ -105,6 +113,7 @@ EXPORT_SYMBOL(pwm_config); int pwm_enable(struct pwm_device *pwm) { + unsigned long reg; int rc = 0; if (!pwm->clk_enabled) { @@ -112,16 +121,27 @@ int pwm_enable(struct pwm_device *pwm) if (!rc) pwm->clk_enabled = 1; } + + reg = readl(pwm->mmio_base + MX3_PWMCR); + reg |= MX3_PWMCR_EN; + writel(reg, pwm->mmio_base + MX3_PWMCR); return rc; } EXPORT_SYMBOL(pwm_enable); void pwm_disable(struct pwm_device *pwm) { + unsigned long reg; + if (pwm->clk_enabled) { clk_disable(pwm->clk); pwm->clk_enabled = 0; } + + reg = readl(pwm->mmio_base + MX3_PWMCR); + reg &= ~MX3_PWMCR_EN; + writel(reg, pwm->mmio_base + MX3_PWMCR); + } EXPORT_SYMBOL(pwm_disable); |