From patchwork Fri Sep 25 15:53:26 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Marco Felsch X-Patchwork-Id: 11800155 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 698896CA for ; Fri, 25 Sep 2020 15:55:18 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 3AAFC21D7A for ; Fri, 25 Sep 2020 15:55:18 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="paI730uS" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 3AAFC21D7A Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Message-Id:Date: Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=Abjj9Bf30Lfd8O9pU8PGLTJiJ9RBjAJJ7IPabIsH8r8=; b=paI730uSQI97ucXiqXyDOm2r7 YPxCP3R/Ej2hHl57ADTMypf8N4pjVQK8sNoFUvJOlm/9f8Q77ry2ft4FIxhtzmGw6Ukz81ndDxgY2 gPK6YXpaf5xYQdLHrsB2qfGGyeXM1R+sE1Se3NwqDSHlP1OAGKEtTIouzcspKMo3u7Qg4EXbbwP1f 8PaSTyUhdSPfi2YQ2qWR0ZIEP/I2/cTlpQwG9gIXeSKif0nb4+v30R9Jpi/051VYP79GoTCqBrMlY LD3htmUE6POvEPxhbyhtf1/k4U04srXxYXLat0kIl3auQx4G0aITFC+DgRenZrbLa+7piAvB0X5s8 zWAHjihZQ==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1kLq2u-0003RK-0B; Fri, 25 Sep 2020 15:54:04 +0000 Received: from metis.ext.pengutronix.de ([2001:67c:670:201:290:27ff:fe1d:cc33]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1kLq2b-0003M1-NK for linux-arm-kernel@lists.infradead.org; Fri, 25 Sep 2020 15:53:47 +0000 Received: from dude02.hi.pengutronix.de ([2001:67c:670:100:1d::28]) by metis.ext.pengutronix.de with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1kLq2S-0000oQ-Ki; Fri, 25 Sep 2020 17:53:36 +0200 Received: from mfe by dude02.hi.pengutronix.de with local (Exim 4.92) (envelope-from ) id 1kLq2Q-0008QC-Sy; Fri, 25 Sep 2020 17:53:34 +0200 From: Marco Felsch To: thierry.reding@gmail.com, u.kleine-koenig@pengutronix.de, lee.jones@linaro.org, shawnguo@kernel.org, s.hauer@pengutronix.de, festevam@gmail.com, linux-imx@nxp.com, Anson.Huang@nxp.com, michal.vokac@ysoft.com, l.majewski@majess.pl Subject: [PATCH v2 1/5] pwm: imx27: enable clock unconditional for register access Date: Fri, 25 Sep 2020 17:53:26 +0200 Message-Id: <20200925155330.32301-2-m.felsch@pengutronix.de> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200925155330.32301-1-m.felsch@pengutronix.de> References: <20200925155330.32301-1-m.felsch@pengutronix.de> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 2001:67c:670:100:1d::28 X-SA-Exim-Mail-From: mfe@pengutronix.de X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-arm-kernel@lists.infradead.org X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200925_115345_827614_55496FF0 X-CRM114-Status: GOOD ( 24.54 ) X-Spam-Score: 0.0 (/) X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary: Content analysis details: (0.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.0 SPF_PASS SPF: sender matches SPF record X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: linux-pwm@vger.kernel.org, linux-arm-kernel@lists.infradead.org, kernel@pengutronix.de Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org The current implementation enables the clock if the current PWM state is '!enabled' to ensure the register access and left the clock on if the new state is 'enabled'. Further apply calls don't enable the clock since they relying on the fact the the clock is already running. Change this behaviour since it is not very intuitive. This commit changes this behaviour. Now the clocks are unconditional enabled/disabled before/after the register access. If the PWM should be turned on (state.enabled) we enable the clock again and vice versa if the PWM should be turned off (!state.enabled). Therefore I added the enable member to the driver state struct since the usage of cstate and pwm_get_state() is a layer violation. I removed this violation while on it. Signed-off-by: Marco Felsch Acked-by: Uwe Kleine-König --- v2: - use enable var which can be shared later on - remove cstate and pwm_get_state() layer violation - explicite enable/disable the clock twice if the pwm should be enabled/disabled rather than tracking the clock usage within the pwm_imx27_clk_prepare_enable() state. - rename commit message drivers/pwm/pwm-imx27.c | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/drivers/pwm/pwm-imx27.c b/drivers/pwm/pwm-imx27.c index c50d453552bd..7edac4ac6395 100644 --- a/drivers/pwm/pwm-imx27.c +++ b/drivers/pwm/pwm-imx27.c @@ -91,6 +91,7 @@ struct pwm_imx27_chip { * value to return in that case. */ unsigned int duty_cycle; + bool enabled; }; #define to_pwm_imx27_chip(chip) container_of(chip, struct pwm_imx27_chip, chip) @@ -217,13 +218,14 @@ static int pwm_imx27_apply(struct pwm_chip *chip, struct pwm_device *pwm, { unsigned long period_cycles, duty_cycles, prescale; struct pwm_imx27_chip *imx = to_pwm_imx27_chip(chip); - struct pwm_state cstate; unsigned long long c; unsigned long long clkrate; int ret; u32 cr; - pwm_get_state(pwm, &cstate); + ret = pwm_imx27_clk_prepare_enable(imx); + if (ret) + return ret; clkrate = clk_get_rate(imx->clk_per); c = clkrate * state->period; @@ -251,15 +253,10 @@ static int pwm_imx27_apply(struct pwm_chip *chip, struct pwm_device *pwm, * Wait for a free FIFO slot if the PWM is already enabled, and flush * the FIFO if the PWM was disabled and is about to be enabled. */ - if (cstate.enabled) { + if (imx->enabled) pwm_imx27_wait_fifo_slot(chip, pwm); - } else { - ret = pwm_imx27_clk_prepare_enable(imx); - if (ret) - return ret; - + else pwm_imx27_sw_reset(chip); - } writel(duty_cycles, imx->mmio_base + MX3_PWMSAR); writel(period_cycles, imx->mmio_base + MX3_PWMPR); @@ -284,10 +281,21 @@ static int pwm_imx27_apply(struct pwm_chip *chip, struct pwm_device *pwm, writel(cr, imx->mmio_base + MX3_PWMCR); - if (!state->enabled) - pwm_imx27_clk_disable_unprepare(imx); + if (imx->enabled != state->enabled) { + if (state->enabled) { + ret = pwm_imx27_clk_prepare_enable(imx); + if (ret) + goto out; + } else { + pwm_imx27_clk_disable_unprepare(imx); + } + imx->enabled = state->enabled; + } - return 0; +out: + pwm_imx27_clk_disable_unprepare(imx); + + return ret; } static const struct pwm_ops pwm_imx27_ops = { From patchwork Fri Sep 25 15:53:27 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marco Felsch X-Patchwork-Id: 11800157 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 653986CA for ; Fri, 25 Sep 2020 15:55:26 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 3641421741 for ; Fri, 25 Sep 2020 15:55:26 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="zttoLH7z" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 3641421741 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Message-Id:Date: Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=R2TokF3G1TsRd5r9XPKGTg67lOjlUgJGql56tWbn318=; b=zttoLH7zkkZ+n85e5fHG1uHf6 r3Gd/NScnpHbt4bnYu3D7Dk3SF43leWMpqP6ldnHAAilu0Lymg9BpfsP6o0ls9PNKfTPNSeNJKq1v HbWzMIsQl9DoVKU1EgsT1jVbOvemcnJYNkogesBaxscyqCxHw40rcAU8xs/e7NZpJ8NU9agxE2Z7F N8S9mfD6VGAHEE8PoBppKUQ+C35IILJU2eeUV2lRFZd7juBJvu9YVGDi38NPN5rfWhtCCds8lTyoA wOAnh1tWlCHMMEdku/8cGQ7H8f2Jf8qqRiD6maRSgYc9dgTyWkipF/eFkmfUMY/HeKL9OvOO/C/1g uQbSViTkg==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1kLq33-0003Td-Nb; Fri, 25 Sep 2020 15:54:13 +0000 Received: from metis.ext.pengutronix.de ([2001:67c:670:201:290:27ff:fe1d:cc33]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1kLq2b-0003Lw-Lg for linux-arm-kernel@lists.infradead.org; Fri, 25 Sep 2020 15:53:47 +0000 Received: from dude02.hi.pengutronix.de ([2001:67c:670:100:1d::28]) by metis.ext.pengutronix.de with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1kLq2S-0000oR-Kl; Fri, 25 Sep 2020 17:53:36 +0200 Received: from mfe by dude02.hi.pengutronix.de with local (Exim 4.92) (envelope-from ) id 1kLq2Q-0008QF-TQ; Fri, 25 Sep 2020 17:53:34 +0200 From: Marco Felsch To: thierry.reding@gmail.com, u.kleine-koenig@pengutronix.de, lee.jones@linaro.org, shawnguo@kernel.org, s.hauer@pengutronix.de, festevam@gmail.com, linux-imx@nxp.com, Anson.Huang@nxp.com, michal.vokac@ysoft.com, l.majewski@majess.pl Subject: [PATCH v2 2/5] pwm: imx27: move constant PWMCR register values into probe Date: Fri, 25 Sep 2020 17:53:27 +0200 Message-Id: <20200925155330.32301-3-m.felsch@pengutronix.de> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200925155330.32301-1-m.felsch@pengutronix.de> References: <20200925155330.32301-1-m.felsch@pengutronix.de> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 2001:67c:670:100:1d::28 X-SA-Exim-Mail-From: mfe@pengutronix.de X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-arm-kernel@lists.infradead.org X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200925_115345_794250_7BD1872D X-CRM114-Status: GOOD ( 17.85 ) X-Spam-Score: 0.0 (/) X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary: Content analysis details: (0.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.0 SPF_PASS SPF: sender matches SPF record X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: linux-pwm@vger.kernel.org, linux-arm-kernel@lists.infradead.org, kernel@pengutronix.de Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org The STOPEN, DOZEN, WAITEN, DBGEN and the CLKSRC bit values never change. So it should be safe to move this bit settings into probe() and change only the necessary bits during apply(). Therefore I added the pwm_imx27_update_bits() helper. Signed-off-by: Marco Felsch --- v2: - drop software reset from the logic - fix setting STOPEN, DOZEN, WAITEN and DBGEN bits in case the pwm is already enabled drivers/pwm/pwm-imx27.c | 37 ++++++++++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/drivers/pwm/pwm-imx27.c b/drivers/pwm/pwm-imx27.c index 7edac4ac6395..b761764b8375 100644 --- a/drivers/pwm/pwm-imx27.c +++ b/drivers/pwm/pwm-imx27.c @@ -96,6 +96,16 @@ struct pwm_imx27_chip { #define to_pwm_imx27_chip(chip) container_of(chip, struct pwm_imx27_chip, chip) +static void pwm_imx27_update_bits(void __iomem *reg, u32 mask, u32 val) +{ + u32 tmp; + + tmp = readl(reg); + tmp &= ~mask; + tmp |= val & mask; + return writel(tmp, reg); +} + static int pwm_imx27_clk_prepare_enable(struct pwm_imx27_chip *imx) { int ret; @@ -221,7 +231,7 @@ static int pwm_imx27_apply(struct pwm_chip *chip, struct pwm_device *pwm, unsigned long long c; unsigned long long clkrate; int ret; - u32 cr; + u32 cr, mask; ret = pwm_imx27_clk_prepare_enable(imx); if (ret) @@ -267,10 +277,7 @@ static int pwm_imx27_apply(struct pwm_chip *chip, struct pwm_device *pwm, */ imx->duty_cycle = duty_cycles; - cr = MX3_PWMCR_PRESCALER_SET(prescale) | - MX3_PWMCR_STOPEN | MX3_PWMCR_DOZEN | MX3_PWMCR_WAITEN | - FIELD_PREP(MX3_PWMCR_CLKSRC, MX3_PWMCR_CLKSRC_IPG_HIGH) | - MX3_PWMCR_DBGEN; + cr = MX3_PWMCR_PRESCALER_SET(prescale); if (state->polarity == PWM_POLARITY_INVERSED) cr |= FIELD_PREP(MX3_PWMCR_POUTC, @@ -279,7 +286,9 @@ static int pwm_imx27_apply(struct pwm_chip *chip, struct pwm_device *pwm, if (state->enabled) cr |= MX3_PWMCR_EN; - writel(cr, imx->mmio_base + MX3_PWMCR); + mask = MX3_PWMCR_PRESCALER | MX3_PWMCR_POUTC | MX3_PWMCR_EN; + + pwm_imx27_update_bits(imx->mmio_base + MX3_PWMCR, mask, cr); if (imx->enabled != state->enabled) { if (state->enabled) { @@ -314,7 +323,7 @@ static int pwm_imx27_probe(struct platform_device *pdev) { struct pwm_imx27_chip *imx; int ret; - u32 pwmcr; + u32 pwmcr, mask; imx = devm_kzalloc(&pdev->dev, sizeof(*imx), GFP_KERNEL); if (imx == NULL) @@ -361,10 +370,20 @@ static int pwm_imx27_probe(struct platform_device *pdev) if (ret) return ret; - /* keep clks on if pwm is running */ + mask = MX3_PWMCR_STOPEN | MX3_PWMCR_DOZEN | MX3_PWMCR_WAITEN | + MX3_PWMCR_DBGEN; + pwmcr = MX3_PWMCR_STOPEN | MX3_PWMCR_DOZEN | MX3_PWMCR_WAITEN | + MX3_PWMCR_DBGEN; + pwm_imx27_update_bits(imx->mmio_base + MX3_PWMCR, mask, pwmcr); + + /* keep clks on and clk settings unchanged if pwm is running */ pwmcr = readl(imx->mmio_base + MX3_PWMCR); - if (!(pwmcr & MX3_PWMCR_EN)) + if (!(pwmcr & MX3_PWMCR_EN)) { + mask = MX3_PWMCR_CLKSRC; + pwmcr = FIELD_PREP(MX3_PWMCR_CLKSRC, MX3_PWMCR_CLKSRC_IPG_HIGH); + pwm_imx27_update_bits(imx->mmio_base + MX3_PWMCR, mask, pwmcr); pwm_imx27_clk_disable_unprepare(imx); + } return pwmchip_add(&imx->chip); } From patchwork Fri Sep 25 15:53:28 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marco Felsch X-Patchwork-Id: 11800147 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 50E1292C for ; Fri, 25 Sep 2020 15:54:11 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 2258E21741 for ; Fri, 25 Sep 2020 15:54:11 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="Onu/oiCz" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 2258E21741 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Message-Id:Date: Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=XGPt0UW5CWFUPfjj0IC1Is387XPcbftQTHDod4+EeW4=; b=Onu/oiCzjeP87KWYIhLpQhBfc TDVhR1AhCapM1/o951xpa6NSmfSIayNVqj0HC+yZl+qgS9D9Cvw6F4Gm9AF7EIletqxOfzroWs37o AooTWN15X2BObKqyXDycryOrXmv9v4YUshQZm02UX40G7p0sprPS/wCGEbJKHV94GyiJUoh1DMwZG jIoxZOuynIjm9yNQ1VBKR1x2WM82FBvvU+tyfdITGbwgEB4StyfgciuVRZ9aXyQSaa2ZU1FarP+y6 KoxWj7kEz/k1PIVMmnw+b1yJ9EKFSVBmdwUjNsyx3YpSQVb/dfBPafy1KLTwTvOaiXjOmJWcjFtkZ h8JoukJkw==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1kLq2r-0003Qd-7X; Fri, 25 Sep 2020 15:54:01 +0000 Received: from metis.ext.pengutronix.de ([2001:67c:670:201:290:27ff:fe1d:cc33]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1kLq2b-0003Lz-FV for linux-arm-kernel@lists.infradead.org; Fri, 25 Sep 2020 15:53:47 +0000 Received: from dude02.hi.pengutronix.de ([2001:67c:670:100:1d::28]) by metis.ext.pengutronix.de with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1kLq2S-0000oS-Ke; Fri, 25 Sep 2020 17:53:36 +0200 Received: from mfe by dude02.hi.pengutronix.de with local (Exim 4.92) (envelope-from ) id 1kLq2Q-0008QI-U5; Fri, 25 Sep 2020 17:53:34 +0200 From: Marco Felsch To: thierry.reding@gmail.com, u.kleine-koenig@pengutronix.de, lee.jones@linaro.org, shawnguo@kernel.org, s.hauer@pengutronix.de, festevam@gmail.com, linux-imx@nxp.com, Anson.Huang@nxp.com, michal.vokac@ysoft.com, l.majewski@majess.pl Subject: [PATCH v2 3/5] pwm: imx27: reset the PWM if it is not running Date: Fri, 25 Sep 2020 17:53:28 +0200 Message-Id: <20200925155330.32301-4-m.felsch@pengutronix.de> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200925155330.32301-1-m.felsch@pengutronix.de> References: <20200925155330.32301-1-m.felsch@pengutronix.de> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 2001:67c:670:100:1d::28 X-SA-Exim-Mail-From: mfe@pengutronix.de X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-arm-kernel@lists.infradead.org X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200925_115345_721547_59992FAE X-CRM114-Status: GOOD ( 15.02 ) X-Spam-Score: 0.0 (/) X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary: Content analysis details: (0.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.0 SPF_PASS SPF: sender matches SPF record X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: linux-pwm@vger.kernel.org, linux-arm-kernel@lists.infradead.org, kernel@pengutronix.de Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org Trigger a software reset during probe to clear the FIFO and reset the register values to their default. According the datasheet the DBGEN, STOPEN, DOZEN and WAITEN bits should be untouched by the software reset but this is not the case. Signed-off-by: Marco Felsch --- v2: - new patch drivers/pwm/pwm-imx27.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/drivers/pwm/pwm-imx27.c b/drivers/pwm/pwm-imx27.c index b761764b8375..3b6bcd8d58b7 100644 --- a/drivers/pwm/pwm-imx27.c +++ b/drivers/pwm/pwm-imx27.c @@ -183,10 +183,8 @@ static void pwm_imx27_get_state(struct pwm_chip *chip, pwm_imx27_clk_disable_unprepare(imx); } -static void pwm_imx27_sw_reset(struct pwm_chip *chip) +static void pwm_imx27_sw_reset(struct pwm_imx27_chip *imx, struct device *dev) { - struct pwm_imx27_chip *imx = to_pwm_imx27_chip(chip); - struct device *dev = chip->dev; int wait_count = 0; u32 cr; @@ -266,7 +264,7 @@ static int pwm_imx27_apply(struct pwm_chip *chip, struct pwm_device *pwm, if (imx->enabled) pwm_imx27_wait_fifo_slot(chip, pwm); else - pwm_imx27_sw_reset(chip); + pwm_imx27_sw_reset(imx, chip->dev); writel(duty_cycles, imx->mmio_base + MX3_PWMSAR); writel(period_cycles, imx->mmio_base + MX3_PWMPR); @@ -370,19 +368,23 @@ static int pwm_imx27_probe(struct platform_device *pdev) if (ret) return ret; - mask = MX3_PWMCR_STOPEN | MX3_PWMCR_DOZEN | MX3_PWMCR_WAITEN | - MX3_PWMCR_DBGEN; - pwmcr = MX3_PWMCR_STOPEN | MX3_PWMCR_DOZEN | MX3_PWMCR_WAITEN | - MX3_PWMCR_DBGEN; - pwm_imx27_update_bits(imx->mmio_base + MX3_PWMCR, mask, pwmcr); - /* keep clks on and clk settings unchanged if pwm is running */ pwmcr = readl(imx->mmio_base + MX3_PWMCR); if (!(pwmcr & MX3_PWMCR_EN)) { - mask = MX3_PWMCR_CLKSRC; - pwmcr = FIELD_PREP(MX3_PWMCR_CLKSRC, MX3_PWMCR_CLKSRC_IPG_HIGH); + pwm_imx27_sw_reset(imx, &pdev->dev); + mask = MX3_PWMCR_STOPEN | MX3_PWMCR_DOZEN | MX3_PWMCR_WAITEN | + MX3_PWMCR_DBGEN | MX3_PWMCR_CLKSRC; + pwmcr = MX3_PWMCR_STOPEN | MX3_PWMCR_DOZEN | MX3_PWMCR_WAITEN | + MX3_PWMCR_DBGEN | + FIELD_PREP(MX3_PWMCR_CLKSRC, MX3_PWMCR_CLKSRC_IPG_HIGH); pwm_imx27_update_bits(imx->mmio_base + MX3_PWMCR, mask, pwmcr); pwm_imx27_clk_disable_unprepare(imx); + } else { + mask = MX3_PWMCR_STOPEN | MX3_PWMCR_DOZEN | MX3_PWMCR_WAITEN | + MX3_PWMCR_DBGEN; + pwmcr = MX3_PWMCR_STOPEN | MX3_PWMCR_DOZEN | MX3_PWMCR_WAITEN | + MX3_PWMCR_DBGEN; + pwm_imx27_update_bits(imx->mmio_base + MX3_PWMCR, mask, pwmcr); } return pwmchip_add(&imx->chip); From patchwork Fri Sep 25 15:53:29 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marco Felsch X-Patchwork-Id: 11800149 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 1926A92C for ; Fri, 25 Sep 2020 15:54:20 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id DEF4F21741 for ; Fri, 25 Sep 2020 15:54:19 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="Zpg+1C7T" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org DEF4F21741 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Message-Id:Date: Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=24Qg7w6govQU/Yut6xtFdGmpZlXN/XwiT78ybE0pyfs=; b=Zpg+1C7TMDIl4U1lvL2XD8qkA qQWwKWUt9fxo8y37Nki/2jvwkGVqyWY2BOkKu8JUuyed4Gaks94qzvgOGUVmxd2A2BMiiGfzwaVx6 GKWyLtoc6sgYxrOZC4Ych53WHRZxy5TsSk9cVj6XkdGvoeGEphNAiHdFD9txBlhguSYbA8seYppnY a2GqX5IaeI9s0yJ3+Lt5eFokek3O8M0QxY9S0tmOIJtMUJvCYGCyMEtKYt/LhrNkqiK1c8bs03mUO Y+jrzSBTaA99Vh69khzACQr886873NNLf7MKYhLlO7TKlxrZHu5LF9iQywvbseyDVNnBYpFkox3kS OEh4mFldg==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1kLq2y-0003S2-2P; Fri, 25 Sep 2020 15:54:08 +0000 Received: from metis.ext.pengutronix.de ([2001:67c:670:201:290:27ff:fe1d:cc33]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1kLq2b-0003Lx-CM for linux-arm-kernel@lists.infradead.org; Fri, 25 Sep 2020 15:53:47 +0000 Received: from dude02.hi.pengutronix.de ([2001:67c:670:100:1d::28]) by metis.ext.pengutronix.de with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1kLq2S-0000oT-Kh; Fri, 25 Sep 2020 17:53:36 +0200 Received: from mfe by dude02.hi.pengutronix.de with local (Exim 4.92) (envelope-from ) id 1kLq2Q-0008QL-UW; Fri, 25 Sep 2020 17:53:34 +0200 From: Marco Felsch To: thierry.reding@gmail.com, u.kleine-koenig@pengutronix.de, lee.jones@linaro.org, shawnguo@kernel.org, s.hauer@pengutronix.de, festevam@gmail.com, linux-imx@nxp.com, Anson.Huang@nxp.com, michal.vokac@ysoft.com, l.majewski@majess.pl Subject: [PATCH v2 4/5] pwm: imx27: fix disable state for inverted PWMs Date: Fri, 25 Sep 2020 17:53:29 +0200 Message-Id: <20200925155330.32301-5-m.felsch@pengutronix.de> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200925155330.32301-1-m.felsch@pengutronix.de> References: <20200925155330.32301-1-m.felsch@pengutronix.de> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 2001:67c:670:100:1d::28 X-SA-Exim-Mail-From: mfe@pengutronix.de X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-arm-kernel@lists.infradead.org X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200925_115345_797950_1A4A34B8 X-CRM114-Status: GOOD ( 27.23 ) X-Spam-Score: 0.0 (/) X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary: Content analysis details: (0.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.0 SPF_PASS SPF: sender matches SPF record X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: linux-pwm@vger.kernel.org, linux-arm-kernel@lists.infradead.org, kernel@pengutronix.de Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org Up to now disabling the PWM is done using the PWMCR.EN register bit. Setting this bit to zero results in the output pin driving a low value independent of the polarity setting (PWMCR.POUTC). There is only little documentation about expectations and requirements in the PWM framework but the usual expectation seems to be that disabling a PWM together with setting .duty_cycle = 0 results in the output driving the inactive level. The pwm-bl driver for example uses this setting to disable the backlight and with the pwm-imx27 driver this results in an enabled backlight if the pwm signal is inverted. Keep the PWMCR.EN bit always enabled and simulate a disabled PWM using duty_cycle = 0 to fix this. Furthermore we have to drop the sw-reset from apply() otherwise the PWMCR.EN is cleared too. Therefore the pwm_imx27_wait_fifo_slot() is extended and renamed to guarantee a free FIFO slot and to reflect the new meaning. Signed-off-by: Marco Felsch --- v2: - fix driver remove function - rename pwm_imx27_wait_fifo_slot - pwm_imx27_get_fifo_slot now returns the number of used fifo slots rather than 0 on success (needed for next patch). drivers/pwm/pwm-imx27.c | 78 ++++++++++++++++++++++++++--------------- 1 file changed, 49 insertions(+), 29 deletions(-) diff --git a/drivers/pwm/pwm-imx27.c b/drivers/pwm/pwm-imx27.c index 3b6bcd8d58b7..07c6a263a39c 100644 --- a/drivers/pwm/pwm-imx27.c +++ b/drivers/pwm/pwm-imx27.c @@ -141,12 +141,9 @@ static void pwm_imx27_get_state(struct pwm_chip *chip, if (ret < 0) return; - val = readl(imx->mmio_base + MX3_PWMCR); + state->enabled = imx->enabled; - if (val & MX3_PWMCR_EN) - state->enabled = true; - else - state->enabled = false; + val = readl(imx->mmio_base + MX3_PWMCR); switch (FIELD_GET(MX3_PWMCR_POUTC, val)) { case MX3_PWMCR_POUTC_NORMAL: @@ -169,8 +166,8 @@ static void pwm_imx27_get_state(struct pwm_chip *chip, state->period = DIV_ROUND_UP_ULL(tmp, pwm_clk); /* - * PWMSAR can be read only if PWM is enabled. If the PWM is disabled, - * use the cached value. + * Use the cached value if the PWM is disabled since we are using the + * PWMSAR to disable the PWM (see the notes in pwm_imx27_apply()) */ if (state->enabled) val = readl(imx->mmio_base + MX3_PWMSAR); @@ -199,8 +196,8 @@ static void pwm_imx27_sw_reset(struct pwm_imx27_chip *imx, struct device *dev) dev_warn(dev, "software reset timeout\n"); } -static void pwm_imx27_wait_fifo_slot(struct pwm_chip *chip, - struct pwm_device *pwm) +static int pwm_imx27_get_fifo_slot(struct pwm_chip *chip, + struct pwm_device *pwm) { struct pwm_imx27_chip *imx = to_pwm_imx27_chip(chip); struct device *dev = chip->dev; @@ -216,9 +213,13 @@ static void pwm_imx27_wait_fifo_slot(struct pwm_chip *chip, msleep(period_ms); sr = readl(imx->mmio_base + MX3_PWMSR); - if (fifoav == FIELD_GET(MX3_PWMSR_FIFOAV, sr)) + if (fifoav == FIELD_GET(MX3_PWMSR_FIFOAV, sr)) { dev_warn(dev, "there is no free FIFO slot\n"); + return -EBUSY; + } } + + return fifoav; } static int pwm_imx27_apply(struct pwm_chip *chip, struct pwm_device *pwm, @@ -257,16 +258,25 @@ static int pwm_imx27_apply(struct pwm_chip *chip, struct pwm_device *pwm, else period_cycles = 0; + /* Wait for a free FIFO slot */ + ret = pwm_imx27_get_fifo_slot(chip, pwm); + if (ret < 0) + goto out; + /* - * Wait for a free FIFO slot if the PWM is already enabled, and flush - * the FIFO if the PWM was disabled and is about to be enabled. + * We can't use the enable bit to control the en-/disable squence + * correctly because the output pin is pulled low if setting this bit + * to '0' regardless of the poutc value. Instead we have to use the + * sample register. According the RM: + * A value of zero in the sample register will result in the PWMO output + * signal always being low/high (POUTC = 00 it will be low and + * POUTC = 01 it will be high), and no output waveform will be produced. + * If the value in this register is higher than the PERIOD */ - if (imx->enabled) - pwm_imx27_wait_fifo_slot(chip, pwm); + if (state->enabled) + writel(duty_cycles, imx->mmio_base + MX3_PWMSAR); else - pwm_imx27_sw_reset(imx, chip->dev); - - writel(duty_cycles, imx->mmio_base + MX3_PWMSAR); + writel(0, imx->mmio_base + MX3_PWMSAR); writel(period_cycles, imx->mmio_base + MX3_PWMPR); /* @@ -276,15 +286,10 @@ static int pwm_imx27_apply(struct pwm_chip *chip, struct pwm_device *pwm, imx->duty_cycle = duty_cycles; cr = MX3_PWMCR_PRESCALER_SET(prescale); - if (state->polarity == PWM_POLARITY_INVERSED) - cr |= FIELD_PREP(MX3_PWMCR_POUTC, - MX3_PWMCR_POUTC_INVERTED); - - if (state->enabled) - cr |= MX3_PWMCR_EN; + cr |= FIELD_PREP(MX3_PWMCR_POUTC, MX3_PWMCR_POUTC_INVERTED); - mask = MX3_PWMCR_PRESCALER | MX3_PWMCR_POUTC | MX3_PWMCR_EN; + mask = MX3_PWMCR_PRESCALER | MX3_PWMCR_POUTC; pwm_imx27_update_bits(imx->mmio_base + MX3_PWMCR, mask, cr); @@ -373,10 +378,13 @@ static int pwm_imx27_probe(struct platform_device *pdev) if (!(pwmcr & MX3_PWMCR_EN)) { pwm_imx27_sw_reset(imx, &pdev->dev); mask = MX3_PWMCR_STOPEN | MX3_PWMCR_DOZEN | MX3_PWMCR_WAITEN | - MX3_PWMCR_DBGEN | MX3_PWMCR_CLKSRC; + MX3_PWMCR_DBGEN | MX3_PWMCR_CLKSRC | MX3_PWMCR_POUTC | + MX3_PWMCR_EN; pwmcr = MX3_PWMCR_STOPEN | MX3_PWMCR_DOZEN | MX3_PWMCR_WAITEN | MX3_PWMCR_DBGEN | - FIELD_PREP(MX3_PWMCR_CLKSRC, MX3_PWMCR_CLKSRC_IPG_HIGH); + FIELD_PREP(MX3_PWMCR_CLKSRC, MX3_PWMCR_CLKSRC_IPG_HIGH) | + FIELD_PREP(MX3_PWMCR_POUTC, MX3_PWMCR_POUTC_OFF) | + MX3_PWMCR_EN; pwm_imx27_update_bits(imx->mmio_base + MX3_PWMCR, mask, pwmcr); pwm_imx27_clk_disable_unprepare(imx); } else { @@ -385,6 +393,7 @@ static int pwm_imx27_probe(struct platform_device *pdev) pwmcr = MX3_PWMCR_STOPEN | MX3_PWMCR_DOZEN | MX3_PWMCR_WAITEN | MX3_PWMCR_DBGEN; pwm_imx27_update_bits(imx->mmio_base + MX3_PWMCR, mask, pwmcr); + imx->enabled = true; } return pwmchip_add(&imx->chip); @@ -392,11 +401,22 @@ static int pwm_imx27_probe(struct platform_device *pdev) static int pwm_imx27_remove(struct platform_device *pdev) { - struct pwm_imx27_chip *imx; + struct pwm_imx27_chip *imx = platform_get_drvdata(pdev); + int ret; - imx = platform_get_drvdata(pdev); + ret = pwm_imx27_clk_prepare_enable(imx); + if (ret) + return ret; - return pwmchip_remove(&imx->chip); + ret = pwmchip_remove(&imx->chip); + if (ret) + return ret; + + /* Ensure module is disabled after remove */ + pwm_imx27_update_bits(imx->mmio_base + MX3_PWMCR, MX3_PWMCR_EN, 0); + pwm_imx27_clk_disable_unprepare(imx); + + return 0; } static struct platform_driver imx_pwm_driver = { From patchwork Fri Sep 25 15:53:30 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marco Felsch X-Patchwork-Id: 11800153 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id DB31092C for ; Fri, 25 Sep 2020 15:55:13 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id AE22E21D7A for ; Fri, 25 Sep 2020 15:55:13 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="fUFWXMLx" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org AE22E21D7A Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Message-Id:Date: Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=Fnk2MvoRRO3uTyBhnHvOJIhG/D7mpRGow/xB5sPcsGE=; b=fUFWXMLx9E+iPFVH+SuQzgQ2C Vx19rrg6sIf/r58lg9AR0w+9C11WoHeb6y/qGHpFoFLErZSQqt8wDN9Fc6sNjuGb/lO+hbAvftjiy VjUeKfp3uyp3A364oqNA07pMa7RvEMQ6/ZegWc1A++JL6Bo0UV1rj+BgvdrPSq8GPb62vDghvi5L2 e0LLvPhJVsXwdtvTyITw2tbDIIOJPNpgiV/gZ6oYOTzwEUPl4aPx0iMdlghkQLsOHNiOF29a3ZLH1 ch1AYxzJ4AddrxSaIUibFvj94VyDeLi4A9YxFBYQ/NgOoSLEpM0vbWvPeUJbZu0WNGlAI0EBOMVw0 8XK3IT6lA==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1kLq2e-0003Nv-DX; Fri, 25 Sep 2020 15:53:48 +0000 Received: from metis.ext.pengutronix.de ([2001:67c:670:201:290:27ff:fe1d:cc33]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1kLq2b-0003Ly-9w for linux-arm-kernel@lists.infradead.org; Fri, 25 Sep 2020 15:53:45 +0000 Received: from dude02.hi.pengutronix.de ([2001:67c:670:100:1d::28]) by metis.ext.pengutronix.de with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1kLq2S-0000oU-Kd; Fri, 25 Sep 2020 17:53:36 +0200 Received: from mfe by dude02.hi.pengutronix.de with local (Exim 4.92) (envelope-from ) id 1kLq2Q-0008QO-Uv; Fri, 25 Sep 2020 17:53:34 +0200 From: Marco Felsch To: thierry.reding@gmail.com, u.kleine-koenig@pengutronix.de, lee.jones@linaro.org, shawnguo@kernel.org, s.hauer@pengutronix.de, festevam@gmail.com, linux-imx@nxp.com, Anson.Huang@nxp.com, michal.vokac@ysoft.com, l.majewski@majess.pl Subject: [PATCH v2 5/5] pwm: imx27: wait till the duty cycle is applied Date: Fri, 25 Sep 2020 17:53:30 +0200 Message-Id: <20200925155330.32301-6-m.felsch@pengutronix.de> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200925155330.32301-1-m.felsch@pengutronix.de> References: <20200925155330.32301-1-m.felsch@pengutronix.de> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 2001:67c:670:100:1d::28 X-SA-Exim-Mail-From: mfe@pengutronix.de X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-arm-kernel@lists.infradead.org X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200925_115345_353978_3C8C2B0F X-CRM114-Status: GOOD ( 16.65 ) X-Spam-Score: 0.0 (/) X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary: Content analysis details: (0.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.0 SPF_PASS SPF: sender matches SPF record X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: linux-pwm@vger.kernel.org, linux-arm-kernel@lists.infradead.org, kernel@pengutronix.de Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org Currently the driver don't check if the new state was applied or not. This can cause glitches on the output pin if the new state disables the PWM. In this case the PWM clocks are disabled before the new duty cycle value gets applied. The fix is to wait till the desired duty cycle was applied. Signed-off-by: Marco Felsch --- v2: - new patch drivers/pwm/pwm-imx27.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/drivers/pwm/pwm-imx27.c b/drivers/pwm/pwm-imx27.c index 07c6a263a39c..ffa00bcd81da 100644 --- a/drivers/pwm/pwm-imx27.c +++ b/drivers/pwm/pwm-imx27.c @@ -222,6 +222,26 @@ static int pwm_imx27_get_fifo_slot(struct pwm_chip *chip, return fifoav; } +static int pwm_imx27_wait_till_applied(struct pwm_chip *chip, + struct pwm_device *pwm) +{ + unsigned int attempts = 4; + unsigned int period_ms; + int busy_slots; + + do { + busy_slots = pwm_imx27_get_fifo_slot(chip, pwm); + if (busy_slots == 0) + return 0; + + period_ms = DIV_ROUND_UP(pwm_get_period(pwm), + NSEC_PER_MSEC); + msleep(period_ms); + } while (attempts--); + + return -ETIMEDOUT; +} + static int pwm_imx27_apply(struct pwm_chip *chip, struct pwm_device *pwm, const struct pwm_state *state) { @@ -277,6 +297,11 @@ static int pwm_imx27_apply(struct pwm_chip *chip, struct pwm_device *pwm, writel(duty_cycles, imx->mmio_base + MX3_PWMSAR); else writel(0, imx->mmio_base + MX3_PWMSAR); + + ret = pwm_imx27_wait_till_applied(chip, pwm); + if (ret) + goto out; + writel(period_cycles, imx->mmio_base + MX3_PWMPR); /*