From 31c4fa3442570d001f58303dea36d81693bc199c Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Fri, 23 May 2014 16:41:28 +0800 Subject: pwm: imx: set can_sleep flag for imx_pwm MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The .config() hook imx_pwm_config() calls clk APIs like clk_prepare() and clk_get_rate(), which might sleep, so we need to set can_sleep flag on pwm_chip. Signed-off-by: Shawn Guo Acked-by: Uwe Kleine-König Signed-off-by: Thierry Reding --- drivers/pwm/pwm-imx.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/pwm/pwm-imx.c') diff --git a/drivers/pwm/pwm-imx.c b/drivers/pwm/pwm-imx.c index d797c7b84c3..5449d9150d4 100644 --- a/drivers/pwm/pwm-imx.c +++ b/drivers/pwm/pwm-imx.c @@ -262,6 +262,7 @@ static int imx_pwm_probe(struct platform_device *pdev) imx->chip.dev = &pdev->dev; imx->chip.base = -1; imx->chip.npwm = 1; + imx->chip.can_sleep = true; r = platform_get_resource(pdev, IORESOURCE_MEM, 0); imx->mmio_base = devm_ioremap_resource(&pdev->dev, r); -- cgit v1.2.3-70-g09d2 From bd59bdc898623e6c948a9f900250ce7343cf9012 Mon Sep 17 00:00:00 2001 From: Liu Ying Date: Wed, 28 May 2014 18:50:11 +0800 Subject: pwm: imx: Fix the macro MX3_PWMCR_PRESCALER(x) definition MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch adds missing parentheses around the argument of the macro MX3_PWMCR_PRESCALER(x) to avoid any potential macro expansion issue. Reported-by: Lothar Waßmann Cc: Thierry Reding Cc: Sascha Hauer Cc: Shawn Guo Cc: Lothar Waßmann Cc: linux-pwm@vger.kernel.org Cc: linux-arm-kernel@lists.infradead.org Signed-off-by: Liu Ying Acked-by: Shawn Guo Signed-off-by: Thierry Reding --- drivers/pwm/pwm-imx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/pwm/pwm-imx.c') diff --git a/drivers/pwm/pwm-imx.c b/drivers/pwm/pwm-imx.c index 5449d9150d4..183225e41d6 100644 --- a/drivers/pwm/pwm-imx.c +++ b/drivers/pwm/pwm-imx.c @@ -32,7 +32,7 @@ #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_PRESCALER(x) ((((x) - 1) & 0xFFF) << 4) #define MX3_PWMCR_DOZEEN (1 << 24) #define MX3_PWMCR_WAITEN (1 << 23) #define MX3_PWMCR_DBGEN (1 << 22) -- cgit v1.2.3-70-g09d2 From 40f260c2cebb464dda6916055112963f1421a111 Mon Sep 17 00:00:00 2001 From: Liu Ying Date: Wed, 28 May 2014 18:50:12 +0800 Subject: pwm: imx: Cleanup indentation for register definitions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch contains no logic change to cleanup indentation for register definitions only. Cc: Thierry Reding Cc: Sascha Hauer Cc: Shawn Guo Cc: Lothar Waßmann Cc: linux-pwm@vger.kernel.org Cc: linux-arm-kernel@lists.infradead.org Signed-off-by: Liu Ying Acked-by: Shawn Guo Signed-off-by: Thierry Reding --- drivers/pwm/pwm-imx.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'drivers/pwm/pwm-imx.c') diff --git a/drivers/pwm/pwm-imx.c b/drivers/pwm/pwm-imx.c index 183225e41d6..fb68534b098 100644 --- a/drivers/pwm/pwm-imx.c +++ b/drivers/pwm/pwm-imx.c @@ -21,24 +21,24 @@ /* i.MX1 and i.MX21 share the same PWM function block: */ -#define MX1_PWMC 0x00 /* PWM Control Register */ -#define MX1_PWMS 0x04 /* PWM Sample Register */ -#define MX1_PWMP 0x08 /* PWM Period Register */ +#define MX1_PWMC 0x00 /* PWM Control Register */ +#define MX1_PWMS 0x04 /* PWM Sample Register */ +#define MX1_PWMP 0x08 /* PWM Period Register */ -#define MX1_PWMC_EN (1 << 4) +#define MX1_PWMC_EN (1 << 4) /* i.MX27, i.MX31, i.MX35 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_DOZEEN (1 << 24) -#define MX3_PWMCR_WAITEN (1 << 23) +#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_DOZEEN (1 << 24) +#define MX3_PWMCR_WAITEN (1 << 23) #define MX3_PWMCR_DBGEN (1 << 22) -#define MX3_PWMCR_CLKSRC_IPG_HIGH (2 << 16) -#define MX3_PWMCR_CLKSRC_IPG (1 << 16) -#define MX3_PWMCR_EN (1 << 0) +#define MX3_PWMCR_CLKSRC_IPG_HIGH (2 << 16) +#define MX3_PWMCR_CLKSRC_IPG (1 << 16) +#define MX3_PWMCR_EN (1 << 0) struct imx_chip { struct clk *clk_per; -- cgit v1.2.3-70-g09d2 From 137fd45ffec15db14034990ceac890975cae7a32 Mon Sep 17 00:00:00 2001 From: Liu Ying Date: Wed, 28 May 2014 18:50:13 +0800 Subject: pwm: imx: Avoid sample FIFO overflow for i.MX PWM version2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The i.MX PWM version2 is embedded in several i.MX SoCs, such as i.MX27, i.MX51 and i.MX6SL. There is a 4-word (16 bit) sample FIFO in this IP. Each FIFO slot determines the duty period of a PWM waveform in one full cycle. The IP spec mentions that we should not write a fourth sample because the FIFO will become full and triggers a FIFO write error (FWE) which will prevent the PWM from starting once it is enabled. In order to avoid any sample FIFO overflow issue, this patch clears all sample FIFO by doing software reset in the configuration hook when the controller is disabled or waits for a full PWM cycle to get a relinquished FIFO slot when the controller is enabled and the FIFO is fully loaded. The FIFO overflow issue can be reproduced by the following commands on the i.MX6SL EVK platform, assuming we use PWM2 for the debug LED which is driven by the pin HSIC_STROBE and the maximal brightness is 255. echo 0 > /sys/class/leds/user/brightness echo 0 > /sys/class/leds/user/brightness echo 0 > /sys/class/leds/user/brightness echo 0 > /sys/class/leds/user/brightness echo 255 > /sys/class/leds/user/brightness Here, FWE happens (PWMSR register reads 0x58) and the LED can not be lighten. Another way to reproduce the FIFO overflow issue is to run this script: while true; do echo 255 > /sys/class/leds/user/brightness; done Cc: Thierry Reding Cc: Sascha Hauer Cc: Shawn Guo Cc: Lothar Waßmann Cc: linux-pwm@vger.kernel.org Cc: linux-arm-kernel@lists.infradead.org Signed-off-by: Liu Ying Acked-by: Shawn Guo Signed-off-by: Thierry Reding --- drivers/pwm/pwm-imx.c | 45 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 43 insertions(+), 2 deletions(-) (limited to 'drivers/pwm/pwm-imx.c') diff --git a/drivers/pwm/pwm-imx.c b/drivers/pwm/pwm-imx.c index fb68534b098..f8b5f109c1a 100644 --- a/drivers/pwm/pwm-imx.c +++ b/drivers/pwm/pwm-imx.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -30,6 +31,7 @@ /* i.MX27, i.MX31, i.MX35 share the same PWM function block: */ #define MX3_PWMCR 0x00 /* PWM Control Register */ +#define MX3_PWMSR 0x04 /* PWM Status Register */ #define MX3_PWMSAR 0x0C /* PWM Sample Register */ #define MX3_PWMPR 0x10 /* PWM Period Register */ #define MX3_PWMCR_PRESCALER(x) ((((x) - 1) & 0xFFF) << 4) @@ -38,7 +40,12 @@ #define MX3_PWMCR_DBGEN (1 << 22) #define MX3_PWMCR_CLKSRC_IPG_HIGH (2 << 16) #define MX3_PWMCR_CLKSRC_IPG (1 << 16) +#define MX3_PWMCR_SWR (1 << 3) #define MX3_PWMCR_EN (1 << 0) +#define MX3_PWMSR_FIFOAV_4WORDS 0x4 +#define MX3_PWMSR_FIFOAV_MASK 0x7 + +#define MX3_PWM_SWR_LOOP 5 struct imx_chip { struct clk *clk_per; @@ -103,9 +110,43 @@ static int imx_pwm_config_v2(struct pwm_chip *chip, struct pwm_device *pwm, int duty_ns, int period_ns) { struct imx_chip *imx = to_imx_chip(chip); + struct device *dev = chip->dev; unsigned long long c; unsigned long period_cycles, duty_cycles, prescale; - u32 cr; + unsigned int period_ms; + bool enable = test_bit(PWMF_ENABLED, &pwm->flags); + int wait_count = 0, fifoav; + u32 cr, sr; + + /* + * i.MX PWMv2 has a 4-word sample FIFO. + * In order to avoid FIFO overflow issue, we do software reset + * to clear all sample FIFO if the controller is disabled or + * wait for a full PWM cycle to get a relinquished FIFO slot + * when the controller is enabled and the FIFO is fully loaded. + */ + if (enable) { + sr = readl(imx->mmio_base + MX3_PWMSR); + fifoav = sr & MX3_PWMSR_FIFOAV_MASK; + if (fifoav == MX3_PWMSR_FIFOAV_4WORDS) { + period_ms = DIV_ROUND_UP(pwm->period, NSEC_PER_MSEC); + msleep(period_ms); + + sr = readl(imx->mmio_base + MX3_PWMSR); + if (fifoav == (sr & MX3_PWMSR_FIFOAV_MASK)) + dev_warn(dev, "there is no free FIFO slot\n"); + } + } else { + writel(MX3_PWMCR_SWR, imx->mmio_base + MX3_PWMCR); + do { + usleep_range(200, 1000); + cr = readl(imx->mmio_base + MX3_PWMCR); + } while ((cr & MX3_PWMCR_SWR) && + (wait_count++ < MX3_PWM_SWR_LOOP)); + + if (cr & MX3_PWMCR_SWR) + dev_warn(dev, "software reset timeout\n"); + } c = clk_get_rate(imx->clk_per); c = c * period_ns; @@ -135,7 +176,7 @@ static int imx_pwm_config_v2(struct pwm_chip *chip, MX3_PWMCR_DOZEEN | MX3_PWMCR_WAITEN | MX3_PWMCR_DBGEN | MX3_PWMCR_CLKSRC_IPG_HIGH; - if (test_bit(PWMF_ENABLED, &pwm->flags)) + if (enable) cr |= MX3_PWMCR_EN; writel(cr, imx->mmio_base + MX3_PWMCR); -- cgit v1.2.3-70-g09d2