2018-06-08 19:25:03

by Shenwei Wang

[permalink] [raw]
Subject: [PATCH v2 1/4] pwm: fsl-ftm: Added a dedicated IP interface clock

The current driver assumes that the ftm_sys clock works as
one of the clock sources for the IP block as well as the IP
interface clock. This assumption does not apply any more on
the latest i.MX8x SoC family. On i.MX8x SoCs, a dedicated IP
interface clock is introduced and it must be enabled before
accessing any FTM registers. Moreover, the clock can not be
used as the source clock for the FTM IP block. This patch
introduces the ipg_clk as the dedicated IP interface clock
and by default it is the same as the ftm_sys clock if not
specified.

Signed-off-by: Shenwei Wang <[email protected]>
---
drivers/pwm/pwm-fsl-ftm.c | 22 ++++++++++++++++------
1 file changed, 16 insertions(+), 6 deletions(-)

diff --git a/drivers/pwm/pwm-fsl-ftm.c b/drivers/pwm/pwm-fsl-ftm.c
index 557b4ea..df0a1c0 100644
--- a/drivers/pwm/pwm-fsl-ftm.c
+++ b/drivers/pwm/pwm-fsl-ftm.c
@@ -87,6 +87,7 @@ struct fsl_pwm_chip {

int period_ns;

+ struct clk *ipg_clk;
struct clk *clk[FSL_PWM_CLK_MAX];
};

@@ -99,14 +100,14 @@ static int fsl_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
{
struct fsl_pwm_chip *fpc = to_fsl_chip(chip);

- return clk_prepare_enable(fpc->clk[FSL_PWM_CLK_SYS]);
+ return clk_prepare_enable(fpc->ipg_clk);
}

static void fsl_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm)
{
struct fsl_pwm_chip *fpc = to_fsl_chip(chip);

- clk_disable_unprepare(fpc->clk[FSL_PWM_CLK_SYS]);
+ clk_disable_unprepare(fpc->ipg_clk);
}

static int fsl_pwm_calculate_default_ps(struct fsl_pwm_chip *fpc,
@@ -363,7 +364,7 @@ static int fsl_pwm_init(struct fsl_pwm_chip *fpc)
{
int ret;

- ret = clk_prepare_enable(fpc->clk[FSL_PWM_CLK_SYS]);
+ ret = clk_prepare_enable(fpc->ipg_clk);
if (ret)
return ret;

@@ -371,7 +372,7 @@ static int fsl_pwm_init(struct fsl_pwm_chip *fpc)
regmap_write(fpc->regmap, FTM_OUTINIT, 0x00);
regmap_write(fpc->regmap, FTM_OUTMASK, 0xFF);

- clk_disable_unprepare(fpc->clk[FSL_PWM_CLK_SYS]);
+ clk_disable_unprepare(fpc->ipg_clk);

return 0;
}
@@ -441,6 +442,15 @@ static int fsl_pwm_probe(struct platform_device *pdev)
if (IS_ERR(fpc->clk[FSL_PWM_CLK_CNTEN]))
return PTR_ERR(fpc->clk[FSL_PWM_CLK_CNTEN]);

+ /* ipg_clk is the interface clock for the IP.
+ * If not provided, use the ftm_sys clock as
+ * the default
+ */
+ fpc->ipg_clk = devm_clk_get(&pdev->dev, "ipg");
+ if (IS_ERR(fpc->ipg_clk))
+ fpc->ipg_clk = fpc->clk[FSL_PWM_CLK_SYS];
+
+
fpc->chip.ops = &fsl_pwm_ops;
fpc->chip.of_xlate = of_pwm_xlate_with_flags;
fpc->chip.of_pwm_n_cells = 3;
@@ -480,7 +490,7 @@ static int fsl_pwm_suspend(struct device *dev)
if (!test_bit(PWMF_REQUESTED, &pwm->flags))
continue;

- clk_disable_unprepare(fpc->clk[FSL_PWM_CLK_SYS]);
+ clk_disable_unprepare(fpc->ipg_clk);

if (!pwm_is_enabled(pwm))
continue;
@@ -503,7 +513,7 @@ static int fsl_pwm_resume(struct device *dev)
if (!test_bit(PWMF_REQUESTED, &pwm->flags))
continue;

- clk_prepare_enable(fpc->clk[FSL_PWM_CLK_SYS]);
+ clk_prepare_enable(fpc->ipg_clk);

if (!pwm_is_enabled(pwm))
continue;
--
2.9.2



2018-06-08 19:24:31

by Shenwei Wang

[permalink] [raw]
Subject: [PATCH v2 2/4] pwm: fsl-ftm: Added the support of per-compatible data

On the i.MX8x SoC family, an additional PWM enable bit is
added for each PWM channel in the register FTM_SC[23:16].
It supports 8 channels. Bit16 is for channel 0, and bit23
is for channel 7. As the IP version information can not
be obtained via any of the FTM registers, a property of
"has_enable_bits" is added via per-compatible data structure.

Signed-off-by: Shenwei Wang <[email protected]>
---
drivers/pwm/pwm-fsl-ftm.c | 32 ++++++++++++++++++++++++++++++--
1 file changed, 30 insertions(+), 2 deletions(-)

diff --git a/drivers/pwm/pwm-fsl-ftm.c b/drivers/pwm/pwm-fsl-ftm.c
index df0a1c0..e4c76da 100644
--- a/drivers/pwm/pwm-fsl-ftm.c
+++ b/drivers/pwm/pwm-fsl-ftm.c
@@ -15,6 +15,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/mutex.h>
+#include <linux/of_device.h>
#include <linux/of_address.h>
#include <linux/platform_device.h>
#include <linux/pm.h>
@@ -75,6 +76,10 @@ enum fsl_pwm_clk {
FSL_PWM_CLK_MAX
};

+struct fsl_ftm_soc {
+ bool has_enable_bits;
+};
+
struct fsl_pwm_chip {
struct pwm_chip chip;

@@ -89,6 +94,8 @@ struct fsl_pwm_chip {

struct clk *ipg_clk;
struct clk *clk[FSL_PWM_CLK_MAX];
+
+ const struct fsl_ftm_soc *soc;
};

static inline struct fsl_pwm_chip *to_fsl_chip(struct pwm_chip *chip)
@@ -98,15 +105,31 @@ static inline struct fsl_pwm_chip *to_fsl_chip(struct pwm_chip *chip)

static int fsl_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
{
+ int ret;
struct fsl_pwm_chip *fpc = to_fsl_chip(chip);

- return clk_prepare_enable(fpc->ipg_clk);
+ ret = clk_prepare_enable(fpc->ipg_clk);
+
+ if ((!ret) && (fpc->soc->has_enable_bits)) {
+ mutex_lock(&fpc->lock);
+ regmap_update_bits(fpc->regmap, FTM_SC,
+ BIT(pwm->hwpwm + 16), BIT(pwm->hwpwm + 16));
+ mutex_unlock(&fpc->lock);
+ }
+
+ return ret;
}

static void fsl_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm)
{
struct fsl_pwm_chip *fpc = to_fsl_chip(chip);

+ if (fpc->soc->has_enable_bits) {
+ mutex_lock(&fpc->lock);
+ regmap_update_bits(fpc->regmap, FTM_SC, BIT(pwm->hwpwm + 16), 0);
+ mutex_unlock(&fpc->lock);
+ }
+
clk_disable_unprepare(fpc->ipg_clk);
}

@@ -409,6 +432,7 @@ static int fsl_pwm_probe(struct platform_device *pdev)

mutex_init(&fpc->lock);

+ fpc->soc = of_device_get_match_data(&pdev->dev);
fpc->chip.dev = &pdev->dev;

res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -534,8 +558,12 @@ static const struct dev_pm_ops fsl_pwm_pm_ops = {
SET_SYSTEM_SLEEP_PM_OPS(fsl_pwm_suspend, fsl_pwm_resume)
};

+static const struct fsl_ftm_soc vf610_ftm_pwm = {
+ .has_enable_bits = false,
+};
+
static const struct of_device_id fsl_pwm_dt_ids[] = {
- { .compatible = "fsl,vf610-ftm-pwm", },
+ { .compatible = "fsl,vf610-ftm-pwm", .data = &vf610_ftm_pwm },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, fsl_pwm_dt_ids);
--
2.9.2


2018-06-08 19:25:13

by Shenwei Wang

[permalink] [raw]
Subject: [PATCH v2 3/4] pwm: fsl-ftm: Enable support for the new SoC i.mx8qm

Enabled the support for the new SoC i.mx8qm by adding the
compatible string of "fsl,imx8qm-ftm-pwm" and its
per-compatible data with setting "has_enable_bits" to "true".

Signed-off-by: Shenwei Wang <[email protected]>
---
drivers/pwm/pwm-fsl-ftm.c | 5 +++++
1 file changed, 5 insertions(+)

diff --git a/drivers/pwm/pwm-fsl-ftm.c b/drivers/pwm/pwm-fsl-ftm.c
index e4c76da..28b87ec 100644
--- a/drivers/pwm/pwm-fsl-ftm.c
+++ b/drivers/pwm/pwm-fsl-ftm.c
@@ -562,8 +562,13 @@ static const struct fsl_ftm_soc vf610_ftm_pwm = {
.has_enable_bits = false,
};

+static const struct fsl_ftm_soc imx8qm_ftm_pwm = {
+ .has_enable_bits = true,
+};
+
static const struct of_device_id fsl_pwm_dt_ids[] = {
{ .compatible = "fsl,vf610-ftm-pwm", .data = &vf610_ftm_pwm },
+ { .compatible = "fsl,imx8qm-ftm-pwm", .data = &imx8qm_ftm_pwm },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, fsl_pwm_dt_ids);
--
2.9.2


2018-06-08 19:25:34

by Shenwei Wang

[permalink] [raw]
Subject: [PATCH v2 4/4] dt-bindings: pwm: fsl-ftm: Add compatible string for i.MX8QM

i.MX8QM integrates a new version of FTM IP block. It adds eight
PWM enable bits in FTM_SC register.
Add a new compatible string of "fsl,imx8qm-ftm-pwm" for i.MX8QM
to differentiate it from the previous SoCs.

Signed-off-by: Shenwei Wang <[email protected]>
---
Documentation/devicetree/bindings/pwm/pwm-fsl-ftm.txt | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/pwm/pwm-fsl-ftm.txt b/Documentation/devicetree/bindings/pwm/pwm-fsl-ftm.txt
index 3899d6a..576ad00 100644
--- a/Documentation/devicetree/bindings/pwm/pwm-fsl-ftm.txt
+++ b/Documentation/devicetree/bindings/pwm/pwm-fsl-ftm.txt
@@ -16,7 +16,10 @@ modes in device tree.


Required properties:
-- compatible: Should be "fsl,vf610-ftm-pwm".
+- compatible : should be "fsl,<soc>-ftm-pwm" and one of the following
+ compatible strings:
+ - "fsl,vf610-ftm-pwm" for PWM compatible with the one integrated on VF610
+ - "fsl,imx8qm-ftm-pwm" for PWM compatible with the one integrated on i.MX8QM
- reg: Physical base address and length of the controller's registers
- #pwm-cells: Should be 3. See pwm.txt in this directory for a description of
the cells format.
--
2.9.2


2018-06-26 15:06:18

by Shenwei Wang

[permalink] [raw]
Subject: RE: [PATCH v2 1/4] pwm: fsl-ftm: Added a dedicated IP interface clock

Ping.

Shenwei

-----Original Message-----
From: Shenwei Wang
Sent: Friday, June 8, 2018 2:23 PM
To: [email protected]
Cc: [email protected]; dl-linux-imx <[email protected]>; [email protected]; Shenwei Wang <[email protected]>
Subject: [PATCH v2 1/4] pwm: fsl-ftm: Added a dedicated IP interface clock

The current driver assumes that the ftm_sys clock works as one of the clock sources for the IP block as well as the IP interface clock. This assumption does not apply any more on the latest i.MX8x SoC family. On i.MX8x SoCs, a dedicated IP interface clock is introduced and it must be enabled before accessing any FTM registers. Moreover, the clock can not be used as the source clock for the FTM IP block. This patch introduces the ipg_clk as the dedicated IP interface clock and by default it is the same as the ftm_sys clock if not specified.

Signed-off-by: Shenwei Wang <[email protected]>
---
drivers/pwm/pwm-fsl-ftm.c | 22 ++++++++++++++++------
1 file changed, 16 insertions(+), 6 deletions(-)

diff --git a/drivers/pwm/pwm-fsl-ftm.c b/drivers/pwm/pwm-fsl-ftm.c index 557b4ea..df0a1c0 100644
--- a/drivers/pwm/pwm-fsl-ftm.c
+++ b/drivers/pwm/pwm-fsl-ftm.c
@@ -87,6 +87,7 @@ struct fsl_pwm_chip {

int period_ns;

+ struct clk *ipg_clk;
struct clk *clk[FSL_PWM_CLK_MAX];
};

@@ -99,14 +100,14 @@ static int fsl_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm) {
struct fsl_pwm_chip *fpc = to_fsl_chip(chip);

- return clk_prepare_enable(fpc->clk[FSL_PWM_CLK_SYS]);
+ return clk_prepare_enable(fpc->ipg_clk);
}

static void fsl_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm) {
struct fsl_pwm_chip *fpc = to_fsl_chip(chip);

- clk_disable_unprepare(fpc->clk[FSL_PWM_CLK_SYS]);
+ clk_disable_unprepare(fpc->ipg_clk);
}

static int fsl_pwm_calculate_default_ps(struct fsl_pwm_chip *fpc, @@ -363,7 +364,7 @@ static int fsl_pwm_init(struct fsl_pwm_chip *fpc) {
int ret;

- ret = clk_prepare_enable(fpc->clk[FSL_PWM_CLK_SYS]);
+ ret = clk_prepare_enable(fpc->ipg_clk);
if (ret)
return ret;

@@ -371,7 +372,7 @@ static int fsl_pwm_init(struct fsl_pwm_chip *fpc)
regmap_write(fpc->regmap, FTM_OUTINIT, 0x00);
regmap_write(fpc->regmap, FTM_OUTMASK, 0xFF);

- clk_disable_unprepare(fpc->clk[FSL_PWM_CLK_SYS]);
+ clk_disable_unprepare(fpc->ipg_clk);

return 0;
}
@@ -441,6 +442,15 @@ static int fsl_pwm_probe(struct platform_device *pdev)
if (IS_ERR(fpc->clk[FSL_PWM_CLK_CNTEN]))
return PTR_ERR(fpc->clk[FSL_PWM_CLK_CNTEN]);

+ /* ipg_clk is the interface clock for the IP.
+ * If not provided, use the ftm_sys clock as
+ * the default
+ */
+ fpc->ipg_clk = devm_clk_get(&pdev->dev, "ipg");
+ if (IS_ERR(fpc->ipg_clk))
+ fpc->ipg_clk = fpc->clk[FSL_PWM_CLK_SYS];
+
+
fpc->chip.ops = &fsl_pwm_ops;
fpc->chip.of_xlate = of_pwm_xlate_with_flags;
fpc->chip.of_pwm_n_cells = 3;
@@ -480,7 +490,7 @@ static int fsl_pwm_suspend(struct device *dev)
if (!test_bit(PWMF_REQUESTED, &pwm->flags))
continue;

- clk_disable_unprepare(fpc->clk[FSL_PWM_CLK_SYS]);
+ clk_disable_unprepare(fpc->ipg_clk);

if (!pwm_is_enabled(pwm))
continue;
@@ -503,7 +513,7 @@ static int fsl_pwm_resume(struct device *dev)
if (!test_bit(PWMF_REQUESTED, &pwm->flags))
continue;

- clk_prepare_enable(fpc->clk[FSL_PWM_CLK_SYS]);
+ clk_prepare_enable(fpc->ipg_clk);

if (!pwm_is_enabled(pwm))
continue;
--
2.9.2


2018-07-06 14:26:30

by Shenwei Wang

[permalink] [raw]
Subject: RE: [PATCH v2 1/4] pwm: fsl-ftm: Added a dedicated IP interface clock

2nd ping.

Regards,
Shenwei

-----Original Message-----
From: Shenwei Wang
Sent: Tuesday, June 26, 2018 10:03 AM
To: [email protected]
Cc: [email protected]; dl-linux-imx <[email protected]>; [email protected]
Subject: RE: [PATCH v2 1/4] pwm: fsl-ftm: Added a dedicated IP interface clock

Ping.

Shenwei

-----Original Message-----
From: Shenwei Wang
Sent: Friday, June 8, 2018 2:23 PM
To: [email protected]
Cc: [email protected]; dl-linux-imx <[email protected]>; [email protected]; Shenwei Wang <[email protected]>
Subject: [PATCH v2 1/4] pwm: fsl-ftm: Added a dedicated IP interface clock

The current driver assumes that the ftm_sys clock works as one of the clock sources for the IP block as well as the IP interface clock. This assumption does not apply any more on the latest i.MX8x SoC family. On i.MX8x SoCs, a dedicated IP interface clock is introduced and it must be enabled before accessing any FTM registers. Moreover, the clock can not be used as the source clock for the FTM IP block. This patch introduces the ipg_clk as the dedicated IP interface clock and by default it is the same as the ftm_sys clock if not specified.

Signed-off-by: Shenwei Wang <[email protected]>
---
drivers/pwm/pwm-fsl-ftm.c | 22 ++++++++++++++++------
1 file changed, 16 insertions(+), 6 deletions(-)

diff --git a/drivers/pwm/pwm-fsl-ftm.c b/drivers/pwm/pwm-fsl-ftm.c index 557b4ea..df0a1c0 100644
--- a/drivers/pwm/pwm-fsl-ftm.c
+++ b/drivers/pwm/pwm-fsl-ftm.c
@@ -87,6 +87,7 @@ struct fsl_pwm_chip {

int period_ns;

+ struct clk *ipg_clk;
struct clk *clk[FSL_PWM_CLK_MAX];
};

@@ -99,14 +100,14 @@ static int fsl_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm) {
struct fsl_pwm_chip *fpc = to_fsl_chip(chip);

- return clk_prepare_enable(fpc->clk[FSL_PWM_CLK_SYS]);
+ return clk_prepare_enable(fpc->ipg_clk);
}

static void fsl_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm) {
struct fsl_pwm_chip *fpc = to_fsl_chip(chip);

- clk_disable_unprepare(fpc->clk[FSL_PWM_CLK_SYS]);
+ clk_disable_unprepare(fpc->ipg_clk);
}

static int fsl_pwm_calculate_default_ps(struct fsl_pwm_chip *fpc, @@ -363,7 +364,7 @@ static int fsl_pwm_init(struct fsl_pwm_chip *fpc) {
int ret;

- ret = clk_prepare_enable(fpc->clk[FSL_PWM_CLK_SYS]);
+ ret = clk_prepare_enable(fpc->ipg_clk);
if (ret)
return ret;

@@ -371,7 +372,7 @@ static int fsl_pwm_init(struct fsl_pwm_chip *fpc)
regmap_write(fpc->regmap, FTM_OUTINIT, 0x00);
regmap_write(fpc->regmap, FTM_OUTMASK, 0xFF);

- clk_disable_unprepare(fpc->clk[FSL_PWM_CLK_SYS]);
+ clk_disable_unprepare(fpc->ipg_clk);

return 0;
}
@@ -441,6 +442,15 @@ static int fsl_pwm_probe(struct platform_device *pdev)
if (IS_ERR(fpc->clk[FSL_PWM_CLK_CNTEN]))
return PTR_ERR(fpc->clk[FSL_PWM_CLK_CNTEN]);

+ /* ipg_clk is the interface clock for the IP.
+ * If not provided, use the ftm_sys clock as
+ * the default
+ */
+ fpc->ipg_clk = devm_clk_get(&pdev->dev, "ipg");
+ if (IS_ERR(fpc->ipg_clk))
+ fpc->ipg_clk = fpc->clk[FSL_PWM_CLK_SYS];
+
+
fpc->chip.ops = &fsl_pwm_ops;
fpc->chip.of_xlate = of_pwm_xlate_with_flags;
fpc->chip.of_pwm_n_cells = 3;
@@ -480,7 +490,7 @@ static int fsl_pwm_suspend(struct device *dev)
if (!test_bit(PWMF_REQUESTED, &pwm->flags))
continue;

- clk_disable_unprepare(fpc->clk[FSL_PWM_CLK_SYS]);
+ clk_disable_unprepare(fpc->ipg_clk);

if (!pwm_is_enabled(pwm))
continue;
@@ -503,7 +513,7 @@ static int fsl_pwm_resume(struct device *dev)
if (!test_bit(PWMF_REQUESTED, &pwm->flags))
continue;

- clk_prepare_enable(fpc->clk[FSL_PWM_CLK_SYS]);
+ clk_prepare_enable(fpc->ipg_clk);

if (!pwm_is_enabled(pwm))
continue;
--
2.9.2


2018-07-09 17:11:09

by Thierry Reding

[permalink] [raw]
Subject: Re: [PATCH v2 1/4] pwm: fsl-ftm: Added a dedicated IP interface clock

On Fri, Jun 08, 2018 at 02:22:34PM -0500, [email protected] wrote:
> The current driver assumes that the ftm_sys clock works as
> one of the clock sources for the IP block as well as the IP
> interface clock. This assumption does not apply any more on
> the latest i.MX8x SoC family. On i.MX8x SoCs, a dedicated IP
> interface clock is introduced and it must be enabled before
> accessing any FTM registers. Moreover, the clock can not be
> used as the source clock for the FTM IP block. This patch
> introduces the ipg_clk as the dedicated IP interface clock
> and by default it is the same as the ftm_sys clock if not
> specified.
>
> Signed-off-by: Shenwei Wang <[email protected]>
> ---
> drivers/pwm/pwm-fsl-ftm.c | 22 ++++++++++++++++------
> 1 file changed, 16 insertions(+), 6 deletions(-)

Applied, thanks.

Thierry


Attachments:
(No filename) (854.00 B)
signature.asc (849.00 B)
Download all attachments

2018-07-09 19:03:30

by Shenwei Wang

[permalink] [raw]
Subject: RE: [PATCH v2 1/4] pwm: fsl-ftm: Added a dedicated IP interface clock

Thank you, Thierry.
Have you also reviewed and accepted the other 3 patches in this serial?

Regards,
Shenwei

-----Original Message-----
From: Thierry Reding [mailto:[email protected]]
Sent: Monday, July 9, 2018 12:09 PM
To: Shenwei Wang <[email protected]>
Cc: [email protected]; dl-linux-imx <[email protected]>; [email protected]
Subject: Re: [PATCH v2 1/4] pwm: fsl-ftm: Added a dedicated IP interface clock

On Fri, Jun 08, 2018 at 02:22:34PM -0500, [email protected] wrote:
> The current driver assumes that the ftm_sys clock works as one of the
> clock sources for the IP block as well as the IP interface clock. This
> assumption does not apply any more on the latest i.MX8x SoC family. On
> i.MX8x SoCs, a dedicated IP interface clock is introduced and it must
> be enabled before accessing any FTM registers. Moreover, the clock can
> not be used as the source clock for the FTM IP block. This patch
> introduces the ipg_clk as the dedicated IP interface clock and by
> default it is the same as the ftm_sys clock if not specified.
>
> Signed-off-by: Shenwei Wang <[email protected]>
> ---
> drivers/pwm/pwm-fsl-ftm.c | 22 ++++++++++++++++------
> 1 file changed, 16 insertions(+), 6 deletions(-)

Applied, thanks.

Thierry