summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWilliam Lai <b04597@freescale.com>2009-08-04 11:11:10 +0800
committerRob Herring <r.herring@freescale.com>2009-08-07 09:47:35 -0500
commit6118b31c7f41f6a800391a60088e92eb5e2e5ed7 (patch)
tree71c6411b08b9ea97d9175dcdb65410a93d454dcf
parentff866679372a4c340c9f873662d6ac8941e0ab7b (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.h6
-rw-r--r--arch/arm/plat-mxc/pwm.c36
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);