All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/3] Add SAMA5D2 PWM Support
@ 2021-09-20 23:28 Dan Sneddon
  2021-09-20 23:28 ` [PATCH 1/3] pwm: Add PWM driver for SAMA5D2 Dan Sneddon
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Dan Sneddon @ 2021-09-20 23:28 UTC (permalink / raw)
  To: u-boot; +Cc: Dan Sneddon

Add support for the PWM found on SAMA5D2 SoCs.

Dan Sneddon (3):
  pwm: Add PWM driver for SAMA5D2
  dt-bindings: pwm: pwm-at91: Add PWM bindings for A5D2
  ARM:dts: sama5d2: Add pwm definition

 arch/arm/dts/sama5d2.dtsi                 |   8 +
 doc/device-tree-bindings/pwm/pwm-at91.txt |  16 ++
 drivers/pwm/Kconfig                       |   6 +
 drivers/pwm/Makefile                      |   1 +
 drivers/pwm/pwm-at91.c                    | 207 ++++++++++++++++++++++
 5 files changed, 238 insertions(+)
 create mode 100644 doc/device-tree-bindings/pwm/pwm-at91.txt
 create mode 100644 drivers/pwm/pwm-at91.c

-- 
2.17.1


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 1/3] pwm: Add PWM driver for SAMA5D2
  2021-09-20 23:28 [PATCH 0/3] Add SAMA5D2 PWM Support Dan Sneddon
@ 2021-09-20 23:28 ` Dan Sneddon
  2021-09-20 23:28 ` [PATCH 2/3] dt-bindings: pwm: pwm-at91: Add PWM bindings for A5D2 Dan Sneddon
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Dan Sneddon @ 2021-09-20 23:28 UTC (permalink / raw)
  To: u-boot; +Cc: Dan Sneddon

Add support for the PWM found on the SAMA5D2 family of devices.

Signed-off-by: Dan Sneddon <dan.sneddon@microchip.com>
---
 drivers/pwm/Kconfig    |   6 ++
 drivers/pwm/Makefile   |   1 +
 drivers/pwm/pwm-at91.c | 207 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 214 insertions(+)
 create mode 100644 drivers/pwm/pwm-at91.c

diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
index cf7f4c6840..691bbcd469 100644
--- a/drivers/pwm/Kconfig
+++ b/drivers/pwm/Kconfig
@@ -91,3 +91,9 @@ config PWM_TI_EHRPWM
 	default y
 	help
 	  PWM driver support for the EHRPWM controller found on TI SOCs.
+
+config PWM_AT91
+	bool "Enable support for PWM found on AT91 SoC's"
+	depends on DM_PWM && ARCH_AT91
+	help
+	  Support for PWM hardware on AT91 based SoC.
diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
index 10d244bfb7..6cdcbdb996 100644
--- a/drivers/pwm/Makefile
+++ b/drivers/pwm/Makefile
@@ -21,3 +21,4 @@ obj-$(CONFIG_PWM_SIFIVE)	+= pwm-sifive.o
 obj-$(CONFIG_PWM_TEGRA)		+= tegra_pwm.o
 obj-$(CONFIG_PWM_SUNXI)		+= sunxi_pwm.o
 obj-$(CONFIG_PWM_TI_EHRPWM)	+= pwm-ti-ehrpwm.o
+obj-$(CONFIG_PWM_AT91)		+= pwm-at91.o
diff --git a/drivers/pwm/pwm-at91.c b/drivers/pwm/pwm-at91.c
new file mode 100644
index 0000000000..95597aee55
--- /dev/null
+++ b/drivers/pwm/pwm-at91.c
@@ -0,0 +1,207 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * PWM support for Microchip AT91 architectures.
+ *
+ * Copyright (C) 2021 Microchip Technology Inc. and its subsidiaries
+ *
+ * Author: Dan Sneddon <daniel.sneddon@microchip.com>
+ *
+ * Based on drivers/pwm/pwm-atmel.c from Linux.
+ */
+#include <clk.h>
+#include <common.h>
+#include <div64.h>
+#include <dm.h>
+#include <linux/bitops.h>
+#include <linux/io.h>
+#include <pwm.h>
+
+#define PERIOD_BITS 16
+#define PWM_MAX_PRES 10
+#define NSEC_PER_SEC 1000000000L
+
+#define PWM_ENA 0x04
+#define PWM_CHANNEL_OFFSET 0x20
+#define PWM_CMR 0x200
+#define PWM_CMR_CPRE_MSK GENMASK(3, 0)
+#define PWM_CMR_CPOL BIT(9)
+#define PWM_CDTY 0x204
+#define PWM_CPRD 0x20C
+
+struct at91_pwm_priv {
+	void __iomem *base;
+	struct clk pclk;
+	u32 clkrate;
+};
+
+static int at91_pwm_calculate_cprd_and_pres(struct udevice *dev,
+					    unsigned long clkrate,
+					    uint period_ns, uint duty_ns,
+					    unsigned long *cprd, u32 *pres)
+{
+	u64 cycles = period_ns;
+	int shift;
+
+	/* Calculate the period cycles and prescale value */
+	cycles *= clkrate;
+	do_div(cycles, NSEC_PER_SEC);
+
+	/*
+	 * The register for the period length is period_bits bits wide.
+	 * So for each bit the number of clock cycles is wider divide the input
+	 * clock frequency by two using pres and shift cprd accordingly.
+	 */
+	shift = fls(cycles) - PERIOD_BITS;
+
+	if (shift > PWM_MAX_PRES) {
+		return -EINVAL;
+	} else if (shift > 0) {
+		*pres = shift;
+		cycles >>= *pres;
+	} else {
+		*pres = 0;
+	}
+
+	*cprd = cycles;
+
+	return 0;
+}
+
+static void at91_pwm_calculate_cdty(uint period_ns, uint duty_ns,
+				    unsigned long clkrate, unsigned long cprd,
+				     u32 pres, unsigned long *cdty)
+{
+	u64 cycles = duty_ns;
+
+	cycles *= clkrate;
+	do_div(cycles, NSEC_PER_SEC);
+	cycles >>= pres;
+	*cdty = cprd - cycles;
+}
+
+/**
+ * Returns: channel status after set operation
+ */
+static bool at91_pwm_set(void __iomem *base, uint channel, bool enable)
+{
+	u32 val, cur_status;
+
+	val = ioread32(base + PWM_ENA);
+	cur_status = !!(val & BIT(channel));
+
+	/* if channel is already in that state, do nothing */
+	if (!(enable ^ cur_status))
+		return cur_status;
+
+	if (enable)
+		val |= BIT(channel);
+	else
+		val &= ~(BIT(channel));
+
+	iowrite32(val, base + PWM_ENA);
+
+	return cur_status;
+}
+
+static int at91_pwm_set_enable(struct udevice *dev, uint channel, bool enable)
+{
+	struct at91_pwm_priv *priv = dev_get_priv(dev);
+
+	at91_pwm_set(priv->base, channel, enable);
+
+	return 0;
+}
+
+static int at91_pwm_set_config(struct udevice *dev, uint channel,
+			       uint period_ns, uint duty_ns)
+{
+	struct at91_pwm_priv *priv = dev_get_priv(dev);
+	unsigned long cprd, cdty;
+	u32 pres, val;
+	int channel_enabled;
+	int ret;
+
+	ret = at91_pwm_calculate_cprd_and_pres(dev, priv->clkrate, period_ns,
+					       duty_ns, &cprd, &pres);
+	if (ret)
+		return ret;
+
+	at91_pwm_calculate_cdty(period_ns, duty_ns, priv->clkrate, cprd, pres, &cdty);
+
+	/* disable the channel */
+	channel_enabled = at91_pwm_set(priv->base, channel, false);
+
+	/* It is necessary to preserve CPOL, inside CMR */
+	val = ioread32(priv->base + (channel * PWM_CHANNEL_OFFSET) + PWM_CMR);
+	val = (val & ~PWM_CMR_CPRE_MSK) | (pres & PWM_CMR_CPRE_MSK);
+	iowrite32(val, priv->base + (channel * PWM_CHANNEL_OFFSET) + PWM_CMR);
+
+	iowrite32(cprd, priv->base + (channel * PWM_CHANNEL_OFFSET) + PWM_CPRD);
+
+	iowrite32(cdty, priv->base + (channel * PWM_CHANNEL_OFFSET) + PWM_CDTY);
+
+	/* renable the channel if needed */
+	if (channel_enabled)
+		at91_pwm_set(priv->base, channel, true);
+
+	return 0;
+}
+
+static int at91_pwm_set_invert(struct udevice *dev, uint channel,
+			       bool polarity)
+{
+	struct at91_pwm_priv *priv = dev_get_priv(dev);
+	u32 val;
+
+	val = ioread32(priv->base + (channel * PWM_CHANNEL_OFFSET) + PWM_CMR);
+	if (polarity)
+		val |= PWM_CMR_CPOL;
+	else
+		val &= ~PWM_CMR_CPOL;
+	iowrite32(val, priv->base + (channel * PWM_CHANNEL_OFFSET) + PWM_CMR);
+
+	return 0;
+}
+
+static int at91_pwm_probe(struct udevice *dev)
+{
+	struct at91_pwm_priv *priv = dev_get_priv(dev);
+	int ret;
+
+	priv->base = dev_read_addr_ptr(dev);
+	if (!priv->base)
+		return -EINVAL;
+
+	ret = clk_get_by_index(dev, 0, &priv->pclk);
+	if (ret)
+		return ret;
+
+	/* clocks aren't ref-counted so just enabled them once here */
+	ret = clk_enable(&priv->pclk);
+	if (ret)
+		return ret;
+
+	priv->clkrate = clk_get_rate(&priv->pclk);
+
+	return ret;
+}
+
+static const struct pwm_ops at91_pwm_ops = {
+	.set_config = at91_pwm_set_config,
+	.set_enable = at91_pwm_set_enable,
+	.set_invert = at91_pwm_set_invert,
+};
+
+static const struct udevice_id at91_pwm_of_match[] = {
+	{ .compatible = "atmel,sama5d2-pwm" },
+	{ }
+};
+
+U_BOOT_DRIVER(at91_pwm) = {
+	.name = "at91_pwm",
+	.id = UCLASS_PWM,
+	.of_match = at91_pwm_of_match,
+	.probe = at91_pwm_probe,
+	.priv_auto = sizeof(struct at91_pwm_priv),
+	.ops = &at91_pwm_ops,
+};
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 2/3] dt-bindings: pwm: pwm-at91: Add PWM bindings for A5D2
  2021-09-20 23:28 [PATCH 0/3] Add SAMA5D2 PWM Support Dan Sneddon
  2021-09-20 23:28 ` [PATCH 1/3] pwm: Add PWM driver for SAMA5D2 Dan Sneddon
@ 2021-09-20 23:28 ` Dan Sneddon
  2021-09-20 23:28 ` [PATCH 3/3] ARM:dts: sama5d2: Add pwm definition Dan Sneddon
  2021-10-12 12:59 ` [PATCH 0/3] Add SAMA5D2 PWM Support Eugen.Hristev
  3 siblings, 0 replies; 5+ messages in thread
From: Dan Sneddon @ 2021-09-20 23:28 UTC (permalink / raw)
  To: u-boot; +Cc: Dan Sneddon

Document the bindings needed for the PWM device on the SAMA5D2.

Signed-off-by: Dan Sneddon <dan.sneddon@microchip.com>
---
 doc/device-tree-bindings/pwm/pwm-at91.txt | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)
 create mode 100644 doc/device-tree-bindings/pwm/pwm-at91.txt

diff --git a/doc/device-tree-bindings/pwm/pwm-at91.txt b/doc/device-tree-bindings/pwm/pwm-at91.txt
new file mode 100644
index 0000000000..a03da404f5
--- /dev/null
+++ b/doc/device-tree-bindings/pwm/pwm-at91.txt
@@ -0,0 +1,16 @@
+Microchip AT91 PWM controller for SAMA5D2
+
+Required properties:
+  - compatible: Should be "atmel,sama5d2-pwm"
+  - reg: Physical base address and length of the controller's registers.
+  - clocks: Should contain a clock identifier for the PWM's parent clock.
+  - #pwm-cells: Should be 3.
+
+Example:
+
+pwm0: pwm@f802c000 {
+	compatible = "atmel,sama5d2-pwm";
+	reg = <0xf802c000 0x4000>;
+	clocks = <&pwm_clk>;
+	#pwm-cells = <3>;
+};
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 3/3] ARM:dts: sama5d2: Add pwm definition
  2021-09-20 23:28 [PATCH 0/3] Add SAMA5D2 PWM Support Dan Sneddon
  2021-09-20 23:28 ` [PATCH 1/3] pwm: Add PWM driver for SAMA5D2 Dan Sneddon
  2021-09-20 23:28 ` [PATCH 2/3] dt-bindings: pwm: pwm-at91: Add PWM bindings for A5D2 Dan Sneddon
@ 2021-09-20 23:28 ` Dan Sneddon
  2021-10-12 12:59 ` [PATCH 0/3] Add SAMA5D2 PWM Support Eugen.Hristev
  3 siblings, 0 replies; 5+ messages in thread
From: Dan Sneddon @ 2021-09-20 23:28 UTC (permalink / raw)
  To: u-boot; +Cc: Dan Sneddon

Add the PWM on the SAMA5D2.

Signed-off-by: Dan Sneddon <dan.sneddon@microchip.com>
---
 arch/arm/dts/sama5d2.dtsi | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm/dts/sama5d2.dtsi b/arch/arm/dts/sama5d2.dtsi
index 6fb2cb25f9..ba1b69e629 100644
--- a/arch/arm/dts/sama5d2.dtsi
+++ b/arch/arm/dts/sama5d2.dtsi
@@ -671,6 +671,14 @@
 				status = "disabled";
 			};
 
+			pwm0: pwm@f802c000 {
+				compatible = "atmel,sama5d2-pwm";
+				reg = <0xf802c000 0x4000>;
+				clocks = <&pwm_clk>;
+				#pwm-cells = <3>;
+				status = "disabled";
+			};
+
 			rstc@f8048000 {
 				compatible = "atmel,sama5d3-rstc";
 				reg = <0xf8048000 0x10>;
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH 0/3] Add SAMA5D2 PWM Support
  2021-09-20 23:28 [PATCH 0/3] Add SAMA5D2 PWM Support Dan Sneddon
                   ` (2 preceding siblings ...)
  2021-09-20 23:28 ` [PATCH 3/3] ARM:dts: sama5d2: Add pwm definition Dan Sneddon
@ 2021-10-12 12:59 ` Eugen.Hristev
  3 siblings, 0 replies; 5+ messages in thread
From: Eugen.Hristev @ 2021-10-12 12:59 UTC (permalink / raw)
  To: Dan.Sneddon, u-boot

On 9/21/21 2:28 AM, Dan Sneddon wrote:
> Add support for the PWM found on SAMA5D2 SoCs.
> 
> Dan Sneddon (3):
>    pwm: Add PWM driver for SAMA5D2
>    dt-bindings: pwm: pwm-at91: Add PWM bindings for A5D2
>    ARM:dts: sama5d2: Add pwm definition
> 
>   arch/arm/dts/sama5d2.dtsi                 |   8 +
>   doc/device-tree-bindings/pwm/pwm-at91.txt |  16 ++
>   drivers/pwm/Kconfig                       |   6 +
>   drivers/pwm/Makefile                      |   1 +
>   drivers/pwm/pwm-at91.c                    | 207 ++++++++++++++++++++++
>   5 files changed, 238 insertions(+)
>   create mode 100644 doc/device-tree-bindings/pwm/pwm-at91.txt
>   create mode 100644 drivers/pwm/pwm-at91.c
> 
> --
> 2.17.1
> 

Applied to u-boot-at91/master, thanks !

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2021-10-12 12:59 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-09-20 23:28 [PATCH 0/3] Add SAMA5D2 PWM Support Dan Sneddon
2021-09-20 23:28 ` [PATCH 1/3] pwm: Add PWM driver for SAMA5D2 Dan Sneddon
2021-09-20 23:28 ` [PATCH 2/3] dt-bindings: pwm: pwm-at91: Add PWM bindings for A5D2 Dan Sneddon
2021-09-20 23:28 ` [PATCH 3/3] ARM:dts: sama5d2: Add pwm definition Dan Sneddon
2021-10-12 12:59 ` [PATCH 0/3] Add SAMA5D2 PWM Support Eugen.Hristev

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.