linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC 00/11] Add generic MFD i.MX mix and audiomix support
@ 2020-03-03  9:03 Abel Vesa
  2020-03-03  9:03 ` [RFC 01/11] mfd: Add i.MX generic mix support Abel Vesa
                   ` (11 more replies)
  0 siblings, 12 replies; 31+ messages in thread
From: Abel Vesa @ 2020-03-03  9:03 UTC (permalink / raw)
  To: Rob Herring, Shawn Guo, Sascha Hauer, Fabio Estevam,
	Mike Turquette, Stephen Boyd, Lee Jones, Anson Huang,
	Leonard Crestez, Peng Fan, Jacky Bai
  Cc: NXP Linux Team, devicetree, linux-arm-kernel,
	Linux Kernel Mailing List, linux-clk, Abel Vesa

The i.MX8MP has some new IPs called mixes. They are formed usually by some
GPRs that can be split into different functionalities. The first example
here is the audiomix which has dedicated registers that can be registered
as a clock controller and some other registers that can be registered as
a reset controller, plus some dedicated ones that will be registered as
syscon and used by each dedicated audio IP.

More mixes to be following the same structure are to come, like hdmimix,
dispmix and mediamix. They will all be populated and registered by the MFD
imx-mix generic driver.

Abel Vesa (11):
  mfd: Add i.MX generic mix support
  arm64: dts: imx8mp: Add AIPS 4 and 5
  arm64: dts: imx8mp: Add audiomix node
  clk: imx: Add gate shared for i.MX8MP audiomix
  clk: imx: pll14xx: Add the device as argument when registering
  clk: imx: Add helpers for passing the device as argument
  dt-bindings: clocks: imx8mp: Add ids for audiomix clocks
  clk: imx: Add audiomix clock controller support
  arm64: dts: imx8mp: Add audiomix clock controller node
  reset: imx: Add audiomix reset controller support
  arm64: dts: imx8mp: Add audiomix reset controller node

 arch/arm64/boot/dts/freescale/imx8mp.dtsi      |  37 ++++
 drivers/clk/imx/Makefile                       |   2 +-
 drivers/clk/imx/clk-audiomix.c                 | 237 +++++++++++++++++++++++++
 drivers/clk/imx/clk-gate-shared.c              | 111 ++++++++++++
 drivers/clk/imx/clk-pll14xx.c                  |   6 +-
 drivers/clk/imx/clk.h                          |  46 ++++-
 drivers/mfd/Kconfig                            |  11 ++
 drivers/mfd/Makefile                           |   1 +
 drivers/mfd/imx-mix.c                          |  48 +++++
 drivers/reset/Kconfig                          |   7 +
 drivers/reset/Makefile                         |   1 +
 drivers/reset/reset-imx-audiomix.c             | 122 +++++++++++++
 include/dt-bindings/clock/imx8mp-clock.h       |  62 +++++++
 include/dt-bindings/reset/imx-audiomix-reset.h |  15 ++
 14 files changed, 699 insertions(+), 7 deletions(-)
 create mode 100644 drivers/clk/imx/clk-audiomix.c
 create mode 100644 drivers/clk/imx/clk-gate-shared.c
 create mode 100644 drivers/mfd/imx-mix.c
 create mode 100644 drivers/reset/reset-imx-audiomix.c
 create mode 100644 include/dt-bindings/reset/imx-audiomix-reset.h

-- 
2.7.4


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

* [RFC 01/11] mfd: Add i.MX generic mix support
  2020-03-03  9:03 [RFC 00/11] Add generic MFD i.MX mix and audiomix support Abel Vesa
@ 2020-03-03  9:03 ` Abel Vesa
  2020-03-26 11:03   ` Lee Jones
  2020-03-03  9:03 ` [RFC 02/11] arm64: dts: imx8mp: Add AIPS 4 and 5 Abel Vesa
                   ` (10 subsequent siblings)
  11 siblings, 1 reply; 31+ messages in thread
From: Abel Vesa @ 2020-03-03  9:03 UTC (permalink / raw)
  To: Rob Herring, Shawn Guo, Sascha Hauer, Fabio Estevam,
	Mike Turquette, Stephen Boyd, Lee Jones, Anson Huang,
	Leonard Crestez, Peng Fan, Jacky Bai
  Cc: NXP Linux Team, devicetree, linux-arm-kernel,
	Linux Kernel Mailing List, linux-clk, Abel Vesa

Some of the i.MX SoCs have a IP for interfacing the dedicated IPs with
clocks, resets and interrupts, plus some other specific control registers.
To allow the functionality to be split between drivers, this MFD driver is
added that has only two purposes: register the devices and map the entire
register addresses. Everything else is left to the dedicated drivers that will
bind to the registered devices.

Signed-off-by: Abel Vesa <abel.vesa@nxp.com>
---
 drivers/mfd/Kconfig   | 11 +++++++++++
 drivers/mfd/Makefile  |  1 +
 drivers/mfd/imx-mix.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 60 insertions(+)
 create mode 100644 drivers/mfd/imx-mix.c

diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 3c547ed..3c89288 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -460,6 +460,17 @@ config MFD_MX25_TSADC
 	  i.MX25 processors. They consist of a conversion queue for general
 	  purpose ADC and a queue for Touchscreens.
 
+config MFD_IMX_MIX
+	tristate "NXP i.MX Generic Mix Control Driver"
+	depends on OF || COMPILE_TEST
+	help
+	  Enable generic mixes support. On some i.MX platforms, there are
+	  devices that are a mix of multiple functionalities like reset
+	  controllers, clock controllers and some others. In order to split
+	  those functionalities between the right drivers, this MFD populates
+	  with virtual devices based on what's found in the devicetree node,
+	  leaving the rest of the behavior control to the dedicated driver.
+
 config MFD_HI6421_PMIC
 	tristate "HiSilicon Hi6421 PMU/Codec IC"
 	depends on OF
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index f935d10..5b2ae5d 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -113,6 +113,7 @@ obj-$(CONFIG_MFD_TWL4030_AUDIO)	+= twl4030-audio.o
 obj-$(CONFIG_TWL6040_CORE)	+= twl6040.o
 
 obj-$(CONFIG_MFD_MX25_TSADC)	+= fsl-imx25-tsadc.o
+obj-$(CONFIG_MFD_IMX_MIX)	+= imx-mix.o
 
 obj-$(CONFIG_MFD_MC13XXX)	+= mc13xxx-core.o
 obj-$(CONFIG_MFD_MC13XXX_SPI)	+= mc13xxx-spi.o
diff --git a/drivers/mfd/imx-mix.c b/drivers/mfd/imx-mix.c
new file mode 100644
index 00000000..d3f8c71
--- /dev/null
+++ b/drivers/mfd/imx-mix.c
@@ -0,0 +1,48 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2019 NXP.
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/spinlock.h>
+#include <linux/types.h>
+#include <linux/platform_device.h>
+#include <linux/of_platform.h>
+
+#include <linux/mfd/core.h>
+
+static int imx_audiomix_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct resource *res;
+	void __iomem *base;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	base = devm_ioremap_resource(dev, res);
+	if (IS_ERR(base))
+		return PTR_ERR(base);
+
+	dev_set_drvdata(dev, base);
+
+	return devm_of_platform_populate(dev);
+}
+
+static const struct of_device_id imx_audiomix_of_match[] = {
+	{ .compatible = "fsl,imx8mp-audiomix" },
+	{ /* Sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, imx_audiomix_of_match);
+
+static struct platform_driver imx_audiomix_driver = {
+	.probe = imx_audiomix_probe,
+	.driver = {
+		.name = "imx-audiomix",
+		.of_match_table = of_match_ptr(imx_audiomix_of_match),
+	},
+};
+module_platform_driver(imx_audiomix_driver);
-- 
2.7.4


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

* [RFC 02/11] arm64: dts: imx8mp: Add AIPS 4 and 5
  2020-03-03  9:03 [RFC 00/11] Add generic MFD i.MX mix and audiomix support Abel Vesa
  2020-03-03  9:03 ` [RFC 01/11] mfd: Add i.MX generic mix support Abel Vesa
@ 2020-03-03  9:03 ` Abel Vesa
  2020-03-13  7:44   ` Peng Fan
  2020-03-03  9:03 ` [RFC 03/11] arm64: dts: imx8mp: Add audiomix node Abel Vesa
                   ` (9 subsequent siblings)
  11 siblings, 1 reply; 31+ messages in thread
From: Abel Vesa @ 2020-03-03  9:03 UTC (permalink / raw)
  To: Rob Herring, Shawn Guo, Sascha Hauer, Fabio Estevam,
	Mike Turquette, Stephen Boyd, Lee Jones, Anson Huang,
	Leonard Crestez, Peng Fan, Jacky Bai
  Cc: NXP Linux Team, devicetree, linux-arm-kernel,
	Linux Kernel Mailing List, linux-clk, Abel Vesa

There are 5 AIPS maps in total, according to the RM. Add the missing ones here.

Signed-off-by: Abel Vesa <abel.vesa@nxp.com>
---
 arch/arm64/boot/dts/freescale/imx8mp.dtsi | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
index 71b0c8f..a997ca7 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
@@ -603,6 +603,22 @@
 			};
 		};
 
+		aips4: bus@32c00000 {
+			compatible = "simple-bus";
+			reg = <0x32c00000 0x400000>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges;
+		};
+
+		aips5: bus@30c00000 {
+			compatible = "simple-bus";
+			reg = <0x30c00000 0x400000>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges;
+		};
+
 		gic: interrupt-controller@38800000 {
 			compatible = "arm,gic-v3";
 			reg = <0x38800000 0x10000>,
-- 
2.7.4


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

* [RFC 03/11] arm64: dts: imx8mp: Add audiomix node
  2020-03-03  9:03 [RFC 00/11] Add generic MFD i.MX mix and audiomix support Abel Vesa
  2020-03-03  9:03 ` [RFC 01/11] mfd: Add i.MX generic mix support Abel Vesa
  2020-03-03  9:03 ` [RFC 02/11] arm64: dts: imx8mp: Add AIPS 4 and 5 Abel Vesa
@ 2020-03-03  9:03 ` Abel Vesa
  2020-03-03  9:03 ` [RFC 04/11] clk: imx: Add gate shared for i.MX8MP audiomix Abel Vesa
                   ` (8 subsequent siblings)
  11 siblings, 0 replies; 31+ messages in thread
From: Abel Vesa @ 2020-03-03  9:03 UTC (permalink / raw)
  To: Rob Herring, Shawn Guo, Sascha Hauer, Fabio Estevam,
	Mike Turquette, Stephen Boyd, Lee Jones, Anson Huang,
	Leonard Crestez, Peng Fan, Jacky Bai
  Cc: NXP Linux Team, devicetree, linux-arm-kernel,
	Linux Kernel Mailing List, linux-clk, Abel Vesa

Audiomix is a mix of multiple functionalities controlled by the audio IPs.
In order to split the functionality between the rightfull drivers, it
will be probled by the imx-mix MFD driver.

Signed-off-by: Abel Vesa <abel.vesa@nxp.com>
---
 arch/arm64/boot/dts/freescale/imx8mp.dtsi | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
index a997ca7..77d2901e 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
@@ -617,6 +617,11 @@
 			#address-cells = <1>;
 			#size-cells = <1>;
 			ranges;
+
+			audiomix: audiomix@30e20000 {
+				compatible = "fsl,imx8mp-audiomix";
+				reg = <0x30e20000 0x10000>;
+			};
 		};
 
 		gic: interrupt-controller@38800000 {
-- 
2.7.4


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

* [RFC 04/11] clk: imx: Add gate shared for i.MX8MP audiomix
  2020-03-03  9:03 [RFC 00/11] Add generic MFD i.MX mix and audiomix support Abel Vesa
                   ` (2 preceding siblings ...)
  2020-03-03  9:03 ` [RFC 03/11] arm64: dts: imx8mp: Add audiomix node Abel Vesa
@ 2020-03-03  9:03 ` Abel Vesa
  2020-03-13  7:47   ` Peng Fan
  2020-03-03  9:03 ` [RFC 05/11] clk: imx: pll14xx: Add the device as argument when registering Abel Vesa
                   ` (7 subsequent siblings)
  11 siblings, 1 reply; 31+ messages in thread
From: Abel Vesa @ 2020-03-03  9:03 UTC (permalink / raw)
  To: Rob Herring, Shawn Guo, Sascha Hauer, Fabio Estevam,
	Mike Turquette, Stephen Boyd, Lee Jones, Anson Huang,
	Leonard Crestez, Peng Fan, Jacky Bai
  Cc: NXP Linux Team, devicetree, linux-arm-kernel,
	Linux Kernel Mailing List, linux-clk, Abel Vesa

The newer i.MX platform use some gates that have a shared control bit
between them.

Signed-off-by: Abel Vesa <abel.vesa@nxp.com>
---
 drivers/clk/imx/Makefile          |   2 +-
 drivers/clk/imx/clk-gate-shared.c | 111 ++++++++++++++++++++++++++++++++++++++
 drivers/clk/imx/clk.h             |   4 ++
 3 files changed, 116 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/imx/clk-gate-shared.c

diff --git a/drivers/clk/imx/Makefile b/drivers/clk/imx/Makefile
index 928f874c..799a8ef 100644
--- a/drivers/clk/imx/Makefile
+++ b/drivers/clk/imx/Makefile
@@ -27,7 +27,7 @@ obj-$(CONFIG_MXC_CLK_SCU) += \
 
 obj-$(CONFIG_CLK_IMX8MM) += clk-imx8mm.o
 obj-$(CONFIG_CLK_IMX8MN) += clk-imx8mn.o
-obj-$(CONFIG_CLK_IMX8MP) += clk-imx8mp.o
+obj-$(CONFIG_CLK_IMX8MP) += clk-imx8mp.o clk-gate-shared.o
 obj-$(CONFIG_CLK_IMX8MQ) += clk-imx8mq.o
 obj-$(CONFIG_CLK_IMX8QXP) += clk-imx8qxp.o clk-imx8qxp-lpcg.o
 
diff --git a/drivers/clk/imx/clk-gate-shared.c b/drivers/clk/imx/clk-gate-shared.c
new file mode 100644
index 00000000..961a0e3
--- /dev/null
+++ b/drivers/clk/imx/clk-gate-shared.c
@@ -0,0 +1,111 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2019 NXP.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include "clk.h"
+
+/**
+ * struct clk_gate_shared - i.MX specific gate clock having the gate flag
+ * shared with other gate clocks
+ */
+struct clk_gate_shared {
+	struct clk_gate	gate;
+	spinlock_t	*lock;
+	unsigned int	*share_count;
+};
+
+static int clk_gate_shared_enable(struct clk_hw *hw)
+{
+	struct clk_gate *gate = to_clk_gate(hw);
+	struct clk_gate_shared *shgate = container_of(gate,
+					struct clk_gate_shared, gate);
+	unsigned long flags = 0;
+	int ret = 0;
+
+	spin_lock_irqsave(shgate->lock, flags);
+
+	if (shgate->share_count && (*shgate->share_count)++ > 0)
+		goto out;
+
+	ret = clk_gate_ops.enable(hw);
+out:
+	spin_unlock_irqrestore(shgate->lock, flags);
+
+	return ret;
+}
+
+static void clk_gate_shared_disable(struct clk_hw *hw)
+{
+	struct clk_gate *gate = to_clk_gate(hw);
+	struct clk_gate_shared *shgate = container_of(gate,
+					struct clk_gate_shared, gate);
+	unsigned long flags = 0;
+
+	spin_lock_irqsave(shgate->lock, flags);
+
+	if (shgate->share_count) {
+		if (WARN_ON(*shgate->share_count == 0))
+			goto out;
+		else if (--(*shgate->share_count) > 0)
+			goto out;
+	}
+
+	clk_gate_ops.disable(hw);
+out:
+	spin_unlock_irqrestore(shgate->lock, flags);
+}
+
+static int clk_gate_shared_is_enabled(struct clk_hw *hw)
+{
+	return clk_gate_ops.is_enabled(hw);
+}
+
+static const struct clk_ops clk_gate_shared_ops = {
+	.enable = clk_gate_shared_enable,
+	.disable = clk_gate_shared_disable,
+	.is_enabled = clk_gate_shared_is_enabled,
+};
+
+struct clk_hw *imx_dev_clk_hw_gate_shared(struct device *dev, const char *name,
+				const char *parent, void __iomem *reg,
+				u8 shift, unsigned int *share_count)
+{
+	struct clk_gate_shared *shgate;
+	struct clk_gate *gate;
+	struct clk_hw *hw;
+	struct clk_init_data init;
+	int ret;
+
+	shgate = kzalloc(sizeof(*shgate), GFP_KERNEL);
+	if (!shgate)
+		return ERR_PTR(-ENOMEM);
+	gate = &shgate->gate;
+
+	init.name = name;
+	init.ops = &clk_gate_shared_ops;
+	init.flags = CLK_OPS_PARENT_ENABLE;
+	init.parent_names = parent ? &parent : NULL;
+	init.num_parents = parent ? 1 : 0;
+
+	gate->reg = reg;
+	gate->bit_idx = shift;
+	gate->lock = NULL;
+	gate->hw.init = &init;
+	shgate->lock = &imx_ccm_lock;
+	shgate->share_count = share_count;
+
+	hw = &gate->hw;
+
+	ret = clk_hw_register(NULL, hw);
+	if (ret) {
+		kfree(shgate);
+		return ERR_PTR(ret);
+	}
+
+	return hw;
+}
diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h
index f074dd8..51d6c26 100644
--- a/drivers/clk/imx/clk.h
+++ b/drivers/clk/imx/clk.h
@@ -151,6 +151,10 @@ struct clk_hw *imx_clk_hw_sscg_pll(const char *name,
 				void __iomem *base,
 				unsigned long flags);
 
+struct clk_hw *imx_dev_clk_hw_gate_shared(struct device *dev, const char *name,
+				const char *parent, void __iomem *reg,
+				u8 shift, unsigned int *share_count);
+
 enum imx_pllv3_type {
 	IMX_PLLV3_GENERIC,
 	IMX_PLLV3_SYS,
-- 
2.7.4


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

* [RFC 05/11] clk: imx: pll14xx: Add the device as argument when registering
  2020-03-03  9:03 [RFC 00/11] Add generic MFD i.MX mix and audiomix support Abel Vesa
                   ` (3 preceding siblings ...)
  2020-03-03  9:03 ` [RFC 04/11] clk: imx: Add gate shared for i.MX8MP audiomix Abel Vesa
@ 2020-03-03  9:03 ` Abel Vesa
  2020-03-13  7:50   ` Peng Fan
  2020-03-21  0:46   ` Stephen Boyd
  2020-03-03  9:03 ` [RFC 06/11] clk: imx: Add helpers for passing the device as argument Abel Vesa
                   ` (6 subsequent siblings)
  11 siblings, 2 replies; 31+ messages in thread
From: Abel Vesa @ 2020-03-03  9:03 UTC (permalink / raw)
  To: Rob Herring, Shawn Guo, Sascha Hauer, Fabio Estevam,
	Mike Turquette, Stephen Boyd, Lee Jones, Anson Huang,
	Leonard Crestez, Peng Fan, Jacky Bai
  Cc: NXP Linux Team, devicetree, linux-arm-kernel,
	Linux Kernel Mailing List, linux-clk, Abel Vesa

In order to allow runtime PM, the device needs to be passed on
to the register function. Audiomix clock controller, used on
i.MX8MP and future platforms, registers a pll14xx and has runtime
PM support.

Signed-off-by: Abel Vesa <abel.vesa@nxp.com>
---
 drivers/clk/imx/clk-pll14xx.c |  6 +++---
 drivers/clk/imx/clk.h         | 13 ++++++++++---
 2 files changed, 13 insertions(+), 6 deletions(-)

diff --git a/drivers/clk/imx/clk-pll14xx.c b/drivers/clk/imx/clk-pll14xx.c
index a83bbbe..2fbc28c 100644
--- a/drivers/clk/imx/clk-pll14xx.c
+++ b/drivers/clk/imx/clk-pll14xx.c
@@ -378,9 +378,9 @@ static const struct clk_ops clk_pll1443x_ops = {
 	.set_rate	= clk_pll1443x_set_rate,
 };
 
-struct clk_hw *imx_clk_hw_pll14xx(const char *name, const char *parent_name,
-				  void __iomem *base,
-				  const struct imx_pll14xx_clk *pll_clk)
+struct clk_hw *imx_dev_clk_hw_pll14xx(struct device *dev, const char *name,
+                            const char *parent_name, void __iomem *base,
+                            const struct imx_pll14xx_clk *pll_clk)
 {
 	struct clk_pll14xx *pll;
 	struct clk_hw *hw;
diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h
index 51d6c26..cb28f06 100644
--- a/drivers/clk/imx/clk.h
+++ b/drivers/clk/imx/clk.h
@@ -131,9 +131,9 @@ struct clk *imx_clk_pll14xx(const char *name, const char *parent_name,
 #define imx_clk_pll14xx(name, parent_name, base, pll_clk) \
 	to_clk(imx_clk_hw_pll14xx(name, parent_name, base, pll_clk))
 
-struct clk_hw *imx_clk_hw_pll14xx(const char *name, const char *parent_name,
-				  void __iomem *base,
-				  const struct imx_pll14xx_clk *pll_clk);
+struct clk_hw *imx_dev_clk_hw_pll14xx(struct device *dev, const char *name,
+                            const char *parent_name, void __iomem *base,
+                            const struct imx_pll14xx_clk *pll_clk);
 
 struct clk_hw *imx_clk_hw_pllv1(enum imx_pllv1_type type, const char *name,
 		const char *parent, void __iomem *base);
@@ -244,6 +244,13 @@ static inline struct clk *to_clk(struct clk_hw *hw)
 	return hw->clk;
 }
 
+static inline struct clk_hw *imx_clk_hw_pll14xx(const char *name, const char *parent_name,
+				  void __iomem *base,
+				  const struct imx_pll14xx_clk *pll_clk)
+{
+	return imx_dev_clk_hw_pll14xx(NULL, name, parent_name, base, pll_clk);
+}
+
 static inline struct clk_hw *imx_clk_hw_fixed(const char *name, int rate)
 {
 	return clk_hw_register_fixed_rate(NULL, name, NULL, 0, rate);
-- 
2.7.4


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

* [RFC 06/11] clk: imx: Add helpers for passing the device as argument
  2020-03-03  9:03 [RFC 00/11] Add generic MFD i.MX mix and audiomix support Abel Vesa
                   ` (4 preceding siblings ...)
  2020-03-03  9:03 ` [RFC 05/11] clk: imx: pll14xx: Add the device as argument when registering Abel Vesa
@ 2020-03-03  9:03 ` Abel Vesa
  2020-03-13  7:58   ` Peng Fan
  2020-03-21  0:46   ` Stephen Boyd
  2020-03-03  9:03 ` [RFC 07/11] dt-bindings: clocks: imx8mp: Add ids for audiomix clocks Abel Vesa
                   ` (5 subsequent siblings)
  11 siblings, 2 replies; 31+ messages in thread
From: Abel Vesa @ 2020-03-03  9:03 UTC (permalink / raw)
  To: Rob Herring, Shawn Guo, Sascha Hauer, Fabio Estevam,
	Mike Turquette, Stephen Boyd, Lee Jones, Anson Huang,
	Leonard Crestez, Peng Fan, Jacky Bai
  Cc: NXP Linux Team, devicetree, linux-arm-kernel,
	Linux Kernel Mailing List, linux-clk, Abel Vesa

All the imx clocks that need to be registered by the audiomix need to pass
on the device so that the runtime PM support could work properly.

Signed-off-by: Abel Vesa <abel.vesa@nxp.com>
---
 drivers/clk/imx/clk.h | 29 +++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)

diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h
index cb28f06..42960a9 100644
--- a/drivers/clk/imx/clk.h
+++ b/drivers/clk/imx/clk.h
@@ -321,6 +321,13 @@ static inline struct clk_hw *imx_clk_hw_gate(const char *name, const char *paren
 				    shift, 0, &imx_ccm_lock);
 }
 
+static inline struct clk_hw *imx_dev_clk_hw_gate(struct device *dev, const char *name,
+						const char *parent, void __iomem *reg, u8 shift)
+{
+	return clk_hw_register_gate(dev, name, parent, CLK_SET_RATE_PARENT, reg,
+				    shift, 0, &imx_ccm_lock);
+}
+
 static inline struct clk_hw *imx_clk_hw_gate_dis(const char *name, const char *parent,
 		void __iomem *reg, u8 shift)
 {
@@ -422,6 +429,15 @@ static inline struct clk_hw *imx_clk_hw_mux(const char *name, void __iomem *reg,
 			width, 0, &imx_ccm_lock);
 }
 
+static inline struct clk_hw *imx_dev_clk_hw_mux(struct device *dev, const char *name,
+                        void __iomem *reg, u8 shift, u8 width,
+                        const char * const *parents, int num_parents)
+{
+        return clk_hw_register_mux(dev, name, parents, num_parents,
+                        CLK_SET_RATE_NO_REPARENT | CLK_SET_PARENT_GATE,
+                        reg, shift, width, 0, &imx_ccm_lock);
+}
+
 static inline struct clk *imx_clk_mux2(const char *name, void __iomem *reg,
 			u8 shift, u8 width, const char * const *parents,
 			int num_parents)
@@ -484,6 +500,19 @@ static inline struct clk_hw *imx_clk_hw_mux_flags(const char *name,
 				   reg, shift, width, 0, &imx_ccm_lock);
 }
 
+static inline struct clk_hw *imx_dev_clk_hw_mux_flags(struct device *dev,
+						  const char *name,
+						  void __iomem *reg, u8 shift,
+						  u8 width,
+						  const char * const *parents,
+						  int num_parents,
+						  unsigned long flags)
+{
+	return clk_hw_register_mux(dev, name, parents, num_parents,
+				   flags | CLK_SET_RATE_NO_REPARENT,
+				   reg, shift, width, 0, &imx_ccm_lock);
+}
+
 struct clk_hw *imx_clk_hw_cpu(const char *name, const char *parent_name,
 		struct clk *div, struct clk *mux, struct clk *pll,
 		struct clk *step);
-- 
2.7.4


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

* [RFC 07/11] dt-bindings: clocks: imx8mp: Add ids for audiomix clocks
  2020-03-03  9:03 [RFC 00/11] Add generic MFD i.MX mix and audiomix support Abel Vesa
                   ` (5 preceding siblings ...)
  2020-03-03  9:03 ` [RFC 06/11] clk: imx: Add helpers for passing the device as argument Abel Vesa
@ 2020-03-03  9:03 ` Abel Vesa
  2020-03-10 20:17   ` Rob Herring
  2020-03-21  0:51   ` Stephen Boyd
  2020-03-03  9:03 ` [RFC 08/11] clk: imx: Add audiomix clock controller support Abel Vesa
                   ` (4 subsequent siblings)
  11 siblings, 2 replies; 31+ messages in thread
From: Abel Vesa @ 2020-03-03  9:03 UTC (permalink / raw)
  To: Rob Herring, Shawn Guo, Sascha Hauer, Fabio Estevam,
	Mike Turquette, Stephen Boyd, Lee Jones, Anson Huang,
	Leonard Crestez, Peng Fan, Jacky Bai
  Cc: NXP Linux Team, devicetree, linux-arm-kernel,
	Linux Kernel Mailing List, linux-clk, Abel Vesa

Add all the clock ids for the audiomix clocks.

Signed-off-by: Abel Vesa <abel.vesa@nxp.com>
---
 include/dt-bindings/clock/imx8mp-clock.h | 62 ++++++++++++++++++++++++++++++++
 1 file changed, 62 insertions(+)

diff --git a/include/dt-bindings/clock/imx8mp-clock.h b/include/dt-bindings/clock/imx8mp-clock.h
index 47ab082..305433f 100644
--- a/include/dt-bindings/clock/imx8mp-clock.h
+++ b/include/dt-bindings/clock/imx8mp-clock.h
@@ -298,4 +298,66 @@
 
 #define IMX8MP_CLK_END				289
 
+#define IMX8MP_CLK_AUDIOMIX_SAI1_IPG		0
+#define IMX8MP_CLK_AUDIOMIX_SAI1_MCLK1		1
+#define IMX8MP_CLK_AUDIOMIX_SAI1_MCLK2		2
+#define IMX8MP_CLK_AUDIOMIX_SAI1_MCLK3		3
+#define IMX8MP_CLK_AUDIOMIX_SAI2_IPG		4
+#define IMX8MP_CLK_AUDIOMIX_SAI2_MCLK1		5
+#define IMX8MP_CLK_AUDIOMIX_SAI2_MCLK2		6
+#define IMX8MP_CLK_AUDIOMIX_SAI2_MCLK3		7
+#define IMX8MP_CLK_AUDIOMIX_SAI3_IPG		8
+#define IMX8MP_CLK_AUDIOMIX_SAI3_MCLK1		9
+#define IMX8MP_CLK_AUDIOMIX_SAI3_MCLK2		10
+#define IMX8MP_CLK_AUDIOMIX_SAI3_MCLK3		11
+#define IMX8MP_CLK_AUDIOMIX_SAI5_IPG		12
+#define IMX8MP_CLK_AUDIOMIX_SAI5_MCLK1		13
+#define IMX8MP_CLK_AUDIOMIX_SAI5_MCLK2		14
+#define IMX8MP_CLK_AUDIOMIX_SAI5_MCLK3		15
+#define IMX8MP_CLK_AUDIOMIX_SAI6_IPG		16
+#define IMX8MP_CLK_AUDIOMIX_SAI6_MCLK1		17
+#define IMX8MP_CLK_AUDIOMIX_SAI6_MCLK2		18
+#define IMX8MP_CLK_AUDIOMIX_SAI6_MCLK3		19
+#define IMX8MP_CLK_AUDIOMIX_SAI7_IPG		20
+#define IMX8MP_CLK_AUDIOMIX_SAI7_MCLK1		21
+#define IMX8MP_CLK_AUDIOMIX_SAI7_MCLK2		22
+#define IMX8MP_CLK_AUDIOMIX_SAI7_MCLK3		23
+#define IMX8MP_CLK_AUDIOMIX_ASRC_IPG		24
+#define IMX8MP_CLK_AUDIOMIX_PDM_IPG		25
+#define IMX8MP_CLK_AUDIOMIX_SDMA2_ROOT		26
+#define IMX8MP_CLK_AUDIOMIX_SDMA3_ROOT		27
+#define IMX8MP_CLK_AUDIOMIX_SPBA2_ROOT		28
+#define IMX8MP_CLK_AUDIOMIX_DSP_ROOT		29
+#define IMX8MP_CLK_AUDIOMIX_DSPDBG_ROOT		30
+#define IMX8MP_CLK_AUDIOMIX_EARC_IPG		31
+#define IMX8MP_CLK_AUDIOMIX_OCRAMA_IPG		32
+#define IMX8MP_CLK_AUDIOMIX_AUD2HTX_IPG		33
+#define IMX8MP_CLK_AUDIOMIX_EDMA_ROOT		34
+#define IMX8MP_CLK_AUDIOMIX_AUDPLL_ROOT		35
+#define IMX8MP_CLK_AUDIOMIX_MU2_ROOT		36
+#define IMX8MP_CLK_AUDIOMIX_MU3_ROOT		37
+#define IMX8MP_CLK_AUDIOMIX_EARC_PHY		38
+#define IMX8MP_CLK_AUDIOMIX_PDM_ROOT		39
+#define IMX8MP_CLK_AUDIOMIX_SAI1_MCLK1_SEL	40
+#define IMX8MP_CLK_AUDIOMIX_SAI1_MCLK2_SEL	41
+#define IMX8MP_CLK_AUDIOMIX_SAI2_MCLK1_SEL	42
+#define IMX8MP_CLK_AUDIOMIX_SAI2_MCLK2_SEL	43
+#define IMX8MP_CLK_AUDIOMIX_SAI3_MCLK1_SEL	44
+#define IMX8MP_CLK_AUDIOMIX_SAI3_MCLK2_SEL	45
+#define IMX8MP_CLK_AUDIOMIX_SAI4_MCLK1_SEL	46
+#define IMX8MP_CLK_AUDIOMIX_SAI4_MCLK2_SEL	47
+#define IMX8MP_CLK_AUDIOMIX_SAI5_MCLK1_SEL	48
+#define IMX8MP_CLK_AUDIOMIX_SAI5_MCLK2_SEL	49
+#define IMX8MP_CLK_AUDIOMIX_SAI6_MCLK1_SEL	50
+#define IMX8MP_CLK_AUDIOMIX_SAI6_MCLK2_SEL	51
+#define IMX8MP_CLK_AUDIOMIX_SAI7_MCLK1_SEL	52
+#define IMX8MP_CLK_AUDIOMIX_SAI7_MCLK2_SEL	53
+#define IMX8MP_CLK_AUDIOMIX_PDM_SEL		54
+#define IMX8MP_CLK_AUDIOMIX_SAI_PLL_REF_SEL	55
+#define IMX8MP_CLK_AUDIOMIX_SAI_PLL		56
+#define IMX8MP_CLK_AUDIOMIX_SAI_PLL_BYPASS	57
+#define IMX8MP_CLK_AUDIOMIX_SAI_PLL_OUT		58
+
+#define IMX8MP_CLK_AUDIOMIX_END			59
+
 #endif
-- 
2.7.4


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

* [RFC 08/11] clk: imx: Add audiomix clock controller support
  2020-03-03  9:03 [RFC 00/11] Add generic MFD i.MX mix and audiomix support Abel Vesa
                   ` (6 preceding siblings ...)
  2020-03-03  9:03 ` [RFC 07/11] dt-bindings: clocks: imx8mp: Add ids for audiomix clocks Abel Vesa
@ 2020-03-03  9:03 ` Abel Vesa
  2020-03-21  0:51   ` Stephen Boyd
  2020-03-03  9:03 ` [RFC 09/11] arm64: dts: imx8mp: Add audiomix clock controller node Abel Vesa
                   ` (3 subsequent siblings)
  11 siblings, 1 reply; 31+ messages in thread
From: Abel Vesa @ 2020-03-03  9:03 UTC (permalink / raw)
  To: Rob Herring, Shawn Guo, Sascha Hauer, Fabio Estevam,
	Mike Turquette, Stephen Boyd, Lee Jones, Anson Huang,
	Leonard Crestez, Peng Fan, Jacky Bai
  Cc: NXP Linux Team, devicetree, linux-arm-kernel,
	Linux Kernel Mailing List, linux-clk, Abel Vesa

The imx-mix MFD driver registers some devices, one of which, in case of
audiomix, maps correctly to a clock controller type. This driver registers
a clock controller for that.

Signed-off-by: Abel Vesa <abel.vesa@nxp.com>
---
 drivers/clk/imx/Makefile       |   2 +-
 drivers/clk/imx/clk-audiomix.c | 237 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 238 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/imx/clk-audiomix.c

diff --git a/drivers/clk/imx/Makefile b/drivers/clk/imx/Makefile
index 799a8ef..5a8d2cb 100644
--- a/drivers/clk/imx/Makefile
+++ b/drivers/clk/imx/Makefile
@@ -27,7 +27,7 @@ obj-$(CONFIG_MXC_CLK_SCU) += \
 
 obj-$(CONFIG_CLK_IMX8MM) += clk-imx8mm.o
 obj-$(CONFIG_CLK_IMX8MN) += clk-imx8mn.o
-obj-$(CONFIG_CLK_IMX8MP) += clk-imx8mp.o clk-gate-shared.o
+obj-$(CONFIG_CLK_IMX8MP) += clk-imx8mp.o clk-gate-shared.o clk-audiomix.o
 obj-$(CONFIG_CLK_IMX8MQ) += clk-imx8mq.o
 obj-$(CONFIG_CLK_IMX8QXP) += clk-imx8qxp.o clk-imx8qxp-lpcg.o
 
diff --git a/drivers/clk/imx/clk-audiomix.c b/drivers/clk/imx/clk-audiomix.c
new file mode 100644
index 00000000..8b84943
--- /dev/null
+++ b/drivers/clk/imx/clk-audiomix.c
@@ -0,0 +1,237 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2019 NXP.
+ */
+
+#include <dt-bindings/clock/imx8mp-clock.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+
+#include "clk.h"
+
+static int shared_count_pdm;
+static struct clk_hw **hws;
+static struct clk_hw_onecell_data *clk_hw_data;
+static uint32_t audiomix_clk_saved_regs[14];
+static struct clk *clk_audio_root;
+static struct clk *clk_audio_ahb;
+static struct clk *clk_audio_axi_div;
+
+static const struct imx_pll14xx_rate_table imx_audiomix_sai_pll_tbl[] = {
+	PLL_1443X_RATE(650000000U, 325, 3, 2, 0),
+};
+
+static const struct imx_pll14xx_clk imx_audiomix_sai_pll = {
+	.type = PLL_1443X,
+	.rate_table = imx_audiomix_sai_pll_tbl,
+};
+
+static const char *imx_sai_mclk2_sels[] = {"sai1", "sai2", "sai3", "dummy",
+					"sai5", "sai6", "sai7", "dummy",
+					"dummy", "dummy", "dummy",
+					"dummy", "dummy", "dummy", "dummy"};
+static const char *imx_sai1_mclk1_sels[] = {"sai1", "dummy", };
+static const char *imx_sai2_mclk1_sels[] = {"sai2", "dummy", };
+static const char *imx_sai3_mclk1_sels[] = {"sai3", "dummy", };
+static const char *imx_sai5_mclk1_sels[] = {"sai5", "dummy", };
+static const char *imx_sai6_mclk1_sels[] = {"sai6", "dummy", };
+static const char *imx_sai7_mclk1_sels[] = {"sai7", "dummy", };
+static const char *imx_pdm_sels[] = {"pdm", "sai_pll_div2", "dummy", "dummy" };
+static const char *imx_sai_pll_ref_sels[] = {"osc_24m", "dummy", "dummy", "dummy", };
+static const char *imx_sai_pll_bypass_sels[] = {"sai_pll", "sai_pll_ref_sel", };
+
+static int imx_audiomix_clk_suspend(struct device *dev)
+{
+	void __iomem *base;
+
+	base = dev_get_drvdata(dev->parent);
+
+	audiomix_clk_saved_regs[0] = readl(base);
+	audiomix_clk_saved_regs[1] = readl(base + 0x4);
+
+	audiomix_clk_saved_regs[2] = readl(base + 0x300);
+	audiomix_clk_saved_regs[3] = readl(base + 0x304);
+	audiomix_clk_saved_regs[4] = readl(base + 0x308);
+	audiomix_clk_saved_regs[5] = readl(base + 0x30C);
+	audiomix_clk_saved_regs[6] = readl(base + 0x310);
+	audiomix_clk_saved_regs[7] = readl(base + 0x314);
+	audiomix_clk_saved_regs[8] = readl(base + 0x318);
+
+	audiomix_clk_saved_regs[9] = readl(base + 0x400);
+	audiomix_clk_saved_regs[10] = readl(base + 0x404);
+	audiomix_clk_saved_regs[11] = readl(base + 0x408);
+	audiomix_clk_saved_regs[12] = readl(base + 0x40C);
+	audiomix_clk_saved_regs[13] = readl(base + 0x410);
+
+	clk_disable_unprepare(clk_audio_ahb);
+	clk_disable_unprepare(clk_audio_root);
+	clk_disable_unprepare(clk_audio_axi_div);
+	pm_runtime_put(dev);
+
+	return 0;
+}
+
+static int imx_audiomix_clk_resume(struct device *dev)
+{
+	void __iomem *base;
+
+	base = dev_get_drvdata(dev->parent);
+
+	pm_runtime_get(dev);
+	clk_prepare_enable(clk_audio_ahb);
+	clk_prepare_enable(clk_audio_root);
+	clk_prepare_enable(clk_audio_axi_div);
+
+	writel(audiomix_clk_saved_regs[0], base);
+	writel(audiomix_clk_saved_regs[1], base + 0x4);
+
+	writel(audiomix_clk_saved_regs[2], base + 0x300);
+	writel(audiomix_clk_saved_regs[3], base + 0x304);
+	writel(audiomix_clk_saved_regs[4], base + 0x308);
+	writel(audiomix_clk_saved_regs[5], base + 0x30C);
+	writel(audiomix_clk_saved_regs[6], base + 0x310);
+	writel(audiomix_clk_saved_regs[7], base + 0x314);
+	writel(audiomix_clk_saved_regs[8], base + 0x318);
+
+	writel(audiomix_clk_saved_regs[9], base + 0x400);
+	writel(audiomix_clk_saved_regs[10], base + 0x404);
+	writel(audiomix_clk_saved_regs[11], base + 0x408);
+	writel(audiomix_clk_saved_regs[12], base + 0x40C);
+	writel(audiomix_clk_saved_regs[13], base + 0x410);
+
+	return 0;
+}
+
+static int imx_audiomix_clk_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
+	void __iomem *base;
+
+	clk_audio_root = of_clk_get_by_name(np, "audio_root");
+	if (IS_ERR(clk_audio_root))
+		return PTR_ERR(clk_audio_root);
+
+	clk_audio_ahb = of_clk_get_by_name(np, "audio_ahb");
+	if (IS_ERR(clk_audio_ahb))
+		return PTR_ERR(clk_audio_ahb);
+
+	clk_audio_axi_div = of_clk_get_by_name(np, "audio_axi_div");
+	if (IS_ERR(clk_audio_axi_div))
+		return PTR_ERR(clk_audio_axi_div);
+
+	base = dev_get_drvdata(dev->parent);
+	if (IS_ERR(base))
+		return PTR_ERR(base);
+
+	clk_hw_data = kzalloc(struct_size(clk_hw_data, hws, IMX8MP_CLK_AUDIOMIX_END), GFP_KERNEL);
+	if (WARN_ON(!clk_hw_data))
+		return -ENOMEM;
+
+	clk_hw_data->num = IMX8MP_CLK_AUDIOMIX_END;
+	hws = clk_hw_data->hws;
+
+	pm_runtime_enable(dev);
+
+	hws[IMX8MP_CLK_AUDIOMIX_SAI_PLL_REF_SEL] = imx_dev_clk_hw_mux(dev, "sai_pll_ref_sel", base + 0x400, 0, 2, imx_sai_pll_ref_sels, ARRAY_SIZE(imx_sai_pll_ref_sels));
+	hws[IMX8MP_CLK_AUDIOMIX_SAI_PLL] = imx_dev_clk_hw_pll14xx(dev, "sai_pll", "sai_pll_ref_sel", base + 0x400, &imx_audiomix_sai_pll);
+
+	hws[IMX8MP_CLK_AUDIOMIX_SAI_PLL_BYPASS] = imx_dev_clk_hw_mux_flags(dev, "sai_pll_bypass", base + 0x400, 4, 1, imx_sai_pll_bypass_sels, ARRAY_SIZE(imx_sai_pll_bypass_sels), CLK_SET_RATE_PARENT);
+
+	hws[IMX8MP_CLK_AUDIOMIX_SAI_PLL_OUT] = imx_dev_clk_hw_gate(dev, "sai_pll_out", "sai_pll_bypass", base + 0x400, 13);
+
+	hws[IMX8MP_CLK_AUDIOMIX_SAI1_MCLK1_SEL] = imx_dev_clk_hw_mux_flags(dev, "sai1_mclk1_sel", base + 0x300, 0, 1, imx_sai1_mclk1_sels, ARRAY_SIZE(imx_sai1_mclk1_sels), CLK_SET_RATE_PARENT);
+	hws[IMX8MP_CLK_AUDIOMIX_SAI1_MCLK2_SEL] = imx_dev_clk_hw_mux(dev, "sai1_mclk2_sel", base + 0x300, 1, 4, imx_sai_mclk2_sels, ARRAY_SIZE(imx_sai_mclk2_sels));
+	hws[IMX8MP_CLK_AUDIOMIX_SAI2_MCLK1_SEL] = imx_dev_clk_hw_mux_flags(dev, "sai2_mclk1_sel", base + 0x304, 0, 1, imx_sai2_mclk1_sels, ARRAY_SIZE(imx_sai2_mclk1_sels), CLK_SET_RATE_PARENT);
+	hws[IMX8MP_CLK_AUDIOMIX_SAI2_MCLK2_SEL] = imx_dev_clk_hw_mux(dev, "sai2_mclk2_sel", base + 0x304, 1, 4, imx_sai_mclk2_sels, ARRAY_SIZE(imx_sai_mclk2_sels));
+	hws[IMX8MP_CLK_AUDIOMIX_SAI3_MCLK1_SEL] = imx_dev_clk_hw_mux_flags(dev, "sai3_mclk1_sel", base + 0x308, 0, 1, imx_sai3_mclk1_sels, ARRAY_SIZE(imx_sai3_mclk1_sels), CLK_SET_RATE_PARENT);
+	hws[IMX8MP_CLK_AUDIOMIX_SAI3_MCLK2_SEL] = imx_dev_clk_hw_mux(dev, "sai3_mclk2_sel", base + 0x308, 1, 4, imx_sai_mclk2_sels, ARRAY_SIZE(imx_sai_mclk2_sels));
+	hws[IMX8MP_CLK_AUDIOMIX_SAI5_MCLK1_SEL] = imx_dev_clk_hw_mux(dev, "sai5_mclk1_sel", base + 0x30C, 0, 1, imx_sai5_mclk1_sels, ARRAY_SIZE(imx_sai5_mclk1_sels));
+	hws[IMX8MP_CLK_AUDIOMIX_SAI5_MCLK2_SEL] = imx_dev_clk_hw_mux(dev, "sai5_mclk2_sel", base + 0x30C, 1, 4, imx_sai_mclk2_sels, ARRAY_SIZE(imx_sai_mclk2_sels));
+	hws[IMX8MP_CLK_AUDIOMIX_SAI6_MCLK1_SEL] = imx_dev_clk_hw_mux(dev, "sai6_mclk1_sel", base + 0x310, 0, 1, imx_sai6_mclk1_sels, ARRAY_SIZE(imx_sai6_mclk1_sels));
+	hws[IMX8MP_CLK_AUDIOMIX_SAI6_MCLK2_SEL] = imx_dev_clk_hw_mux(dev, "sai6_mclk2_sel", base + 0x310, 1, 4, imx_sai_mclk2_sels, ARRAY_SIZE(imx_sai_mclk2_sels));
+	hws[IMX8MP_CLK_AUDIOMIX_SAI7_MCLK1_SEL] = imx_dev_clk_hw_mux(dev, "sai7_mclk1_sel", base + 0x314, 0, 1, imx_sai7_mclk1_sels, ARRAY_SIZE(imx_sai7_mclk1_sels));
+	hws[IMX8MP_CLK_AUDIOMIX_SAI7_MCLK2_SEL] = imx_dev_clk_hw_mux(dev, "sai7_mclk2_sel", base + 0x314, 1, 4, imx_sai_mclk2_sels, ARRAY_SIZE(imx_sai_mclk2_sels));
+
+	hws[IMX8MP_CLK_AUDIOMIX_SAI1_IPG]    = imx_dev_clk_hw_gate(dev, "sai1_ipg_clk",   "ipg_audio_root", base, 0);
+	hws[IMX8MP_CLK_AUDIOMIX_SAI1_MCLK1]  = imx_dev_clk_hw_gate(dev, "sai1_mclk1_clk", "sai1_mclk1_sel", base, 1);
+	hws[IMX8MP_CLK_AUDIOMIX_SAI1_MCLK2]  = imx_dev_clk_hw_gate(dev, "sai1_mclk2_clk", "sai1_mclk2_sel", base, 2);
+	hws[IMX8MP_CLK_AUDIOMIX_SAI1_MCLK3]  = imx_dev_clk_hw_gate(dev, "sai1_mclk3_clk", "sai_pll_out", base, 3);
+	hws[IMX8MP_CLK_AUDIOMIX_SAI2_IPG]    = imx_dev_clk_hw_gate(dev, "sai2_ipg_clk",   "ipg_audio_root", base, 4);
+	hws[IMX8MP_CLK_AUDIOMIX_SAI2_MCLK1]  = imx_dev_clk_hw_gate(dev, "sai2_mclk1_clk", "sai2_mclk1_sel", base, 5);
+	hws[IMX8MP_CLK_AUDIOMIX_SAI2_MCLK2]  = imx_dev_clk_hw_gate(dev, "sai2_mclk2_clk", "sai2_mclk2_sel", base, 6);
+	hws[IMX8MP_CLK_AUDIOMIX_SAI2_MCLK3]  = imx_dev_clk_hw_gate(dev, "sai2_mclk3_clk", "sai_pll_out", base, 7);
+	hws[IMX8MP_CLK_AUDIOMIX_SAI3_IPG]    = imx_dev_clk_hw_gate(dev, "sai3_ipg_clk",   "ipg_audio_root", base, 8);
+	hws[IMX8MP_CLK_AUDIOMIX_SAI3_MCLK1]  = imx_dev_clk_hw_gate(dev, "sai3_mclk1_clk", "sai3_mclk1_sel", base, 9);
+	hws[IMX8MP_CLK_AUDIOMIX_SAI3_MCLK2]  = imx_dev_clk_hw_gate(dev, "sai3_mclk2_clk", "sai3_mclk2_sel", base, 10);
+	hws[IMX8MP_CLK_AUDIOMIX_SAI3_MCLK3]  = imx_dev_clk_hw_gate(dev, "sai3_mclk3_clk", "sai_pll_out", base, 11);
+	hws[IMX8MP_CLK_AUDIOMIX_SAI5_IPG]    = imx_dev_clk_hw_gate(dev, "sai5_ipg_clk",   "ipg_audio_root", base, 12);
+	hws[IMX8MP_CLK_AUDIOMIX_SAI5_MCLK1]  = imx_dev_clk_hw_gate(dev, "sai5_mclk1_clk", "sai5_mclk1_sel", base, 13);
+	hws[IMX8MP_CLK_AUDIOMIX_SAI5_MCLK2]  = imx_dev_clk_hw_gate(dev, "sai5_mclk2_clk", "sai5_mclk2_sel", base, 14);
+	hws[IMX8MP_CLK_AUDIOMIX_SAI5_MCLK3]  = imx_dev_clk_hw_gate(dev, "sai5_mclk3_clk", "sai_pll_out", base, 15);
+	hws[IMX8MP_CLK_AUDIOMIX_SAI6_IPG]    = imx_dev_clk_hw_gate(dev, "sai6_ipg_clk",   "ipg_audio_root", base, 16);
+	hws[IMX8MP_CLK_AUDIOMIX_SAI6_MCLK1]  = imx_dev_clk_hw_gate(dev, "sai6_mclk1_clk", "sai6_mclk1_sel", base, 17);
+	hws[IMX8MP_CLK_AUDIOMIX_SAI6_MCLK2]  = imx_dev_clk_hw_gate(dev, "sai6_mclk2_clk", "sai6_mclk2_sel", base, 18);
+	hws[IMX8MP_CLK_AUDIOMIX_SAI6_MCLK3]  = imx_dev_clk_hw_gate(dev, "sai6_mclk3_clk", "sai_pll_out", base, 19);
+	hws[IMX8MP_CLK_AUDIOMIX_SAI7_IPG]    = imx_dev_clk_hw_gate(dev, "sai7_ipg_clk",   "ipg_audio_root", base, 20);
+	hws[IMX8MP_CLK_AUDIOMIX_SAI7_MCLK1]  = imx_dev_clk_hw_gate(dev, "sai7_mclk1_clk", "sai7_mclk1_sel", base, 21);
+	hws[IMX8MP_CLK_AUDIOMIX_SAI7_MCLK2]  = imx_dev_clk_hw_gate(dev, "sai7_mclk2_clk", "sai7_mclk2_sel", base, 22);
+	hws[IMX8MP_CLK_AUDIOMIX_SAI7_MCLK3]  = imx_dev_clk_hw_gate(dev, "sai7_mclk3_clk", "sai_pll_out", base, 23);
+	hws[IMX8MP_CLK_AUDIOMIX_ASRC_IPG]    = imx_dev_clk_hw_gate(dev, "asrc_ipg_clk",   "ipg_audio_root", base, 24);
+	hws[IMX8MP_CLK_AUDIOMIX_PDM_IPG]     = imx_dev_clk_hw_gate_shared(dev, "pdm_ipg_clk", "ipg_audio_root", base, 25, &shared_count_pdm);
+	hws[IMX8MP_CLK_AUDIOMIX_PDM_ROOT]    = imx_dev_clk_hw_gate_shared(dev, "pdm_root_clk", "pdm", base, 25, &shared_count_pdm);
+
+	hws[IMX8MP_CLK_AUDIOMIX_SDMA2_ROOT]  = imx_dev_clk_hw_gate(dev, "sdma2_root_clk", "ipg_audio_root", base, 26);
+	hws[IMX8MP_CLK_AUDIOMIX_SDMA3_ROOT]  = imx_dev_clk_hw_gate(dev, "sdma3_root_clk", "ipg_audio_root", base, 27);
+	hws[IMX8MP_CLK_AUDIOMIX_SPBA2_ROOT]  = imx_dev_clk_hw_gate(dev, "spba2_root_clk", "ipg_audio_root", base, 28);
+	hws[IMX8MP_CLK_AUDIOMIX_DSP_ROOT]    = imx_dev_clk_hw_gate(dev, "dsp_root_clk",   "ipg_audio_root", base, 29);
+	hws[IMX8MP_CLK_AUDIOMIX_DSPDBG_ROOT] = imx_dev_clk_hw_gate(dev, "dsp_dbg_clk",    "ipg_audio_root", base, 30);
+	hws[IMX8MP_CLK_AUDIOMIX_EARC_IPG]    = imx_dev_clk_hw_gate(dev, "earc_ipg_clk",   "ipg_audio_root", base, 31);
+
+	hws[IMX8MP_CLK_AUDIOMIX_OCRAMA_IPG]  = imx_dev_clk_hw_gate(dev, "ocram_a_ipg_clk", "ipg_audio_root", base + 4, 0);
+	hws[IMX8MP_CLK_AUDIOMIX_AUD2HTX_IPG] = imx_dev_clk_hw_gate(dev, "aud2htx_ipg_clk", "ipg_audio_root", base + 4, 1);
+	hws[IMX8MP_CLK_AUDIOMIX_EDMA_ROOT]   = imx_dev_clk_hw_gate(dev, "edma_root_clk",   "ipg_audio_root", base + 4, 2);
+	hws[IMX8MP_CLK_AUDIOMIX_AUDPLL_ROOT] = imx_dev_clk_hw_gate(dev, "aud_pll_clk",  "ipg_audio_root", base + 4, 3);
+	hws[IMX8MP_CLK_AUDIOMIX_MU2_ROOT]    = imx_dev_clk_hw_gate(dev, "mu2_root_clk", "ipg_audio_root", base + 4, 4);
+	hws[IMX8MP_CLK_AUDIOMIX_MU3_ROOT]    = imx_dev_clk_hw_gate(dev, "mu3_root_clk", "ipg_audio_root", base + 4, 5);
+	hws[IMX8MP_CLK_AUDIOMIX_EARC_PHY]    = imx_dev_clk_hw_gate(dev, "earc_phy_clk", "ipg_audio_root", base + 4, 6);
+
+	hws[IMX8MP_CLK_AUDIOMIX_PDM_SEL] = imx_dev_clk_hw_mux(dev, "pdm_sel", base + 0x318, 1, 4, imx_pdm_sels, ARRAY_SIZE(imx_pdm_sels));
+
+	/* unbypass the pll */
+	clk_hw_set_parent(hws[IMX8MP_CLK_AUDIOMIX_SAI_PLL_BYPASS], hws[IMX8MP_CLK_AUDIOMIX_SAI_PLL]);
+
+	imx_check_clk_hws(hws, IMX8MP_CLK_AUDIOMIX_END);
+
+	of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_hw_data);
+
+	return 0;
+}
+
+UNIVERSAL_DEV_PM_OPS(imx_audiomix_clk_pm_ops, imx_audiomix_clk_suspend,
+			imx_audiomix_clk_resume, imx_audiomix_clk_resume);
+
+static const struct of_device_id imx_audiomix_clk_of_match[] = {
+	{ .compatible = "fsl,imx8mp-audiomix-clk" },
+	{ /* Sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, imx_audiomix_clk_of_match);
+
+
+static struct platform_driver imx_audiomix_clk_driver = {
+	.probe = imx_audiomix_clk_probe,
+	.driver = {
+		.name = "imx-audiomix-clk",
+		.of_match_table = of_match_ptr(imx_audiomix_clk_of_match),
+		.pm = &imx_audiomix_clk_pm_ops,
+	},
+};
+module_platform_driver(imx_audiomix_clk_driver);
-- 
2.7.4


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

* [RFC 09/11] arm64: dts: imx8mp: Add audiomix clock controller node
  2020-03-03  9:03 [RFC 00/11] Add generic MFD i.MX mix and audiomix support Abel Vesa
                   ` (7 preceding siblings ...)
  2020-03-03  9:03 ` [RFC 08/11] clk: imx: Add audiomix clock controller support Abel Vesa
@ 2020-03-03  9:03 ` Abel Vesa
  2020-03-03  9:03 ` [RFC 10/11] reset: imx: Add audiomix reset controller support Abel Vesa
                   ` (2 subsequent siblings)
  11 siblings, 0 replies; 31+ messages in thread
From: Abel Vesa @ 2020-03-03  9:03 UTC (permalink / raw)
  To: Rob Herring, Shawn Guo, Sascha Hauer, Fabio Estevam,
	Mike Turquette, Stephen Boyd, Lee Jones, Anson Huang,
	Leonard Crestez, Peng Fan, Jacky Bai
  Cc: NXP Linux Team, devicetree, linux-arm-kernel,
	Linux Kernel Mailing List, linux-clk, Abel Vesa

Add the audiomix clock controller as part of the audiomix MFD.

Signed-off-by: Abel Vesa <abel.vesa@nxp.com>
---
 arch/arm64/boot/dts/freescale/imx8mp.dtsi | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
index 77d2901e..f27acf9 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
@@ -621,6 +621,17 @@
 			audiomix: audiomix@30e20000 {
 				compatible = "fsl,imx8mp-audiomix";
 				reg = <0x30e20000 0x10000>;
+
+				audiomix_clk: clock-controller {
+					compatible = "fsl,imx8mp-audiomix-clk";
+					#clock-cells = <1>;
+					clocks = <&clk IMX8MP_CLK_AUDIO_ROOT>,
+						 <&clk IMX8MP_CLK_AUDIO_AHB>,
+						 <&clk IMX8MP_CLK_AUDIO_AXI_DIV>;
+					clock-names = "audio_root",
+						      "audio_ahb",
+						      "audio_axi_div";
+				};
 			};
 		};
 
-- 
2.7.4


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

* [RFC 10/11] reset: imx: Add audiomix reset controller support
  2020-03-03  9:03 [RFC 00/11] Add generic MFD i.MX mix and audiomix support Abel Vesa
                   ` (8 preceding siblings ...)
  2020-03-03  9:03 ` [RFC 09/11] arm64: dts: imx8mp: Add audiomix clock controller node Abel Vesa
@ 2020-03-03  9:03 ` Abel Vesa
  2020-03-04 11:41   ` Philipp Zabel
  2020-03-10 20:19   ` Rob Herring
  2020-03-03  9:03 ` [RFC 11/11] arm64: dts: imx8mp: Add audiomix reset controller node Abel Vesa
  2020-04-16 11:06 ` [RFC 00/11] Add generic MFD i.MX mix and audiomix support Arnd Bergmann
  11 siblings, 2 replies; 31+ messages in thread
From: Abel Vesa @ 2020-03-03  9:03 UTC (permalink / raw)
  To: Rob Herring, Shawn Guo, Sascha Hauer, Fabio Estevam,
	Mike Turquette, Stephen Boyd, Lee Jones, Anson Huang,
	Leonard Crestez, Peng Fan, Jacky Bai
  Cc: NXP Linux Team, devicetree, linux-arm-kernel,
	Linux Kernel Mailing List, linux-clk, Abel Vesa

The imx-mix MFD driver registers some devices, one of which, in case of
audiomix, maps correctly to a reset controller type. This driver registers
a reset controller for that. For now, only the EARC specific resets are added.

Signed-off-by: Abel Vesa <abel.vesa@nxp.com>
Reviewed-by: Leonard Crestez <leonard.crestez@nxp.com>
---
 drivers/reset/Kconfig                          |   7 ++
 drivers/reset/Makefile                         |   1 +
 drivers/reset/reset-imx-audiomix.c             | 122 +++++++++++++++++++++++++
 include/dt-bindings/reset/imx-audiomix-reset.h |  15 +++
 4 files changed, 145 insertions(+)
 create mode 100644 drivers/reset/reset-imx-audiomix.c
 create mode 100644 include/dt-bindings/reset/imx-audiomix-reset.h

diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
index d9efbfd..2f8d9b3 100644
--- a/drivers/reset/Kconfig
+++ b/drivers/reset/Kconfig
@@ -81,6 +81,13 @@ config RESET_INTEL_GW
 	  Say Y to control the reset signals provided by reset controller.
 	  Otherwise, say N.
 
+config RESET_IMX_AUDIOMIX
+	bool "i.MX Audiomix Reset Driver" if COMPILE_TEST
+	depends on HAS_IOMEM
+	default ARCH_MXC
+	help
+	  This enables the audiomix reset controller driver for i.MX SoCs.
+
 config RESET_LANTIQ
 	bool "Lantiq XWAY Reset Driver" if COMPILE_TEST
 	default SOC_TYPE_XWAY
diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
index 249ed35..cf23d38 100644
--- a/drivers/reset/Makefile
+++ b/drivers/reset/Makefile
@@ -12,6 +12,7 @@ obj-$(CONFIG_RESET_BRCMSTB_RESCAL) += reset-brcmstb-rescal.o
 obj-$(CONFIG_RESET_HSDK) += reset-hsdk.o
 obj-$(CONFIG_RESET_IMX7) += reset-imx7.o
 obj-$(CONFIG_RESET_INTEL_GW) += reset-intel-gw.o
+obj-$(CONFIG_RESET_IMX_AUDIOMIX) += reset-imx-audiomix.o
 obj-$(CONFIG_RESET_LANTIQ) += reset-lantiq.o
 obj-$(CONFIG_RESET_LPC18XX) += reset-lpc18xx.o
 obj-$(CONFIG_RESET_MESON) += reset-meson.o
diff --git a/drivers/reset/reset-imx-audiomix.c b/drivers/reset/reset-imx-audiomix.c
new file mode 100644
index 00000000..d1c62ef
--- /dev/null
+++ b/drivers/reset/reset-imx-audiomix.c
@@ -0,0 +1,122 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2019 NXP.
+ */
+
+#include <dt-bindings/reset/imx-audiomix-reset.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/reset-controller.h>
+
+#define IMX_AUDIOMIX_EARC_CTRL_REG	0x200
+
+#define IMX_AUDIOMIX_EARC_RESET_BIT	0x0
+#define IMX_AUDIOMIX_EARC_PHY_RESET_BIT	0x1
+
+struct imx_audiomix_reset_data {
+	void __iomem *base;
+	struct reset_controller_dev rcdev;
+	spinlock_t lock;
+};
+
+static int imx_audiomix_reset_set(struct reset_controller_dev *rcdev,
+			  unsigned long id, bool assert)
+{
+	struct imx_audiomix_reset_data *drvdata = container_of(rcdev,
+			struct imx_audiomix_reset_data, rcdev);
+	void __iomem *reg_addr = drvdata->base;
+	unsigned long flags;
+	unsigned int offset;
+	u32 reg;
+
+	switch (id) {
+	case IMX_AUDIOMIX_EARC_PHY_RESET:
+		reg_addr += IMX_AUDIOMIX_EARC_CTRL_REG;
+		offset = IMX_AUDIOMIX_EARC_PHY_RESET_BIT;
+		break;
+	case IMX_AUDIOMIX_EARC_RESET:
+		reg_addr += IMX_AUDIOMIX_EARC_CTRL_REG;
+		offset = IMX_AUDIOMIX_EARC_RESET_BIT;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	if (assert) {
+		pm_runtime_get_sync(rcdev->dev);
+		spin_lock_irqsave(&drvdata->lock, flags);
+		reg = readl(reg_addr);
+		writel(reg & ~BIT(offset), reg_addr);
+		spin_unlock_irqrestore(&drvdata->lock, flags);
+	} else {
+		spin_lock_irqsave(&drvdata->lock, flags);
+		reg = readl(reg_addr);
+		writel(reg | BIT(offset), reg_addr);
+		spin_unlock_irqrestore(&drvdata->lock, flags);
+		pm_runtime_put(rcdev->dev);
+	}
+
+	return 0;
+}
+
+static int imx_audiomix_reset_assert(struct reset_controller_dev *rcdev,
+			     unsigned long id)
+{
+	return imx_audiomix_reset_set(rcdev, id, true);
+}
+
+static int imx_audiomix_reset_deassert(struct reset_controller_dev *rcdev,
+			       unsigned long id)
+{
+	return imx_audiomix_reset_set(rcdev, id, false);
+}
+
+static const struct reset_control_ops imx_audiomix_reset_ops = {
+	.assert		= imx_audiomix_reset_assert,
+	.deassert	= imx_audiomix_reset_deassert,
+};
+
+static int imx_audiomix_reset_probe(struct platform_device *pdev)
+{
+	struct imx_audiomix_reset_data *drvdata;
+	struct device *dev = &pdev->dev;
+
+	drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL);
+	if (drvdata == NULL)
+		return -ENOMEM;
+
+	drvdata->base = dev_get_drvdata(dev->parent);
+
+	platform_set_drvdata(pdev, drvdata);
+
+	pm_runtime_enable(dev);
+
+	spin_lock_init(&drvdata->lock);
+
+	drvdata->rcdev.owner     = THIS_MODULE;
+	drvdata->rcdev.nr_resets = IMX_AUDIOMIX_RESET_NUM;
+	drvdata->rcdev.ops       = &imx_audiomix_reset_ops;
+	drvdata->rcdev.of_node   = dev->of_node;
+	drvdata->rcdev.dev	 = dev;
+
+	return devm_reset_controller_register(dev, &drvdata->rcdev);
+}
+
+static const struct of_device_id imx_audiomix_reset_dt_ids[] = {
+	{ .compatible = "fsl,imx8mp-audiomix-reset", },
+	{ /* sentinel */ },
+};
+
+static struct platform_driver imx_audiomix_reset_driver = {
+	.probe	= imx_audiomix_reset_probe,
+	.driver = {
+		.name		= KBUILD_MODNAME,
+		.of_match_table	= imx_audiomix_reset_dt_ids,
+	},
+};
+module_platform_driver(imx_audiomix_reset_driver);
diff --git a/include/dt-bindings/reset/imx-audiomix-reset.h b/include/dt-bindings/reset/imx-audiomix-reset.h
new file mode 100644
index 00000000..2e26878
--- /dev/null
+++ b/include/dt-bindings/reset/imx-audiomix-reset.h
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2019 NXP.
+ */
+
+#ifndef DT_BINDING_RESET_IMX_AUDIOMIX_H
+#define DT_BINDING_RESET_IMX_AUDIOMIX_H
+
+#define IMX_AUDIOMIX_EARC_RESET		0x0
+#define IMX_AUDIOMIX_EARC_PHY_RESET	0x1
+
+#define IMX_AUDIOMIX_RESET_NUM		2
+
+#endif
+
-- 
2.7.4


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

* [RFC 11/11] arm64: dts: imx8mp: Add audiomix reset controller node
  2020-03-03  9:03 [RFC 00/11] Add generic MFD i.MX mix and audiomix support Abel Vesa
                   ` (9 preceding siblings ...)
  2020-03-03  9:03 ` [RFC 10/11] reset: imx: Add audiomix reset controller support Abel Vesa
@ 2020-03-03  9:03 ` Abel Vesa
  2020-04-16 11:06 ` [RFC 00/11] Add generic MFD i.MX mix and audiomix support Arnd Bergmann
  11 siblings, 0 replies; 31+ messages in thread
From: Abel Vesa @ 2020-03-03  9:03 UTC (permalink / raw)
  To: Rob Herring, Shawn Guo, Sascha Hauer, Fabio Estevam,
	Mike Turquette, Stephen Boyd, Lee Jones, Anson Huang,
	Leonard Crestez, Peng Fan, Jacky Bai
  Cc: NXP Linux Team, devicetree, linux-arm-kernel,
	Linux Kernel Mailing List, linux-clk, Abel Vesa

Add the audiomix reset controller as part of the audiomix MFD.

Signed-off-by: Abel Vesa <abel.vesa@nxp.com>
---
 arch/arm64/boot/dts/freescale/imx8mp.dtsi | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
index f27acf9..ca7fc73 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
@@ -632,6 +632,11 @@
 						      "audio_ahb",
 						      "audio_axi_div";
 				};
+
+				audiomix_reset: reset-controller {
+					compatible = "fsl,imx8mp-audiomix-reset";
+					#reset-cells = <1>;
+				};
 			};
 		};
 
-- 
2.7.4


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

* Re: [RFC 10/11] reset: imx: Add audiomix reset controller support
  2020-03-03  9:03 ` [RFC 10/11] reset: imx: Add audiomix reset controller support Abel Vesa
@ 2020-03-04 11:41   ` Philipp Zabel
  2020-03-13 14:16     ` Abel Vesa
  2020-03-10 20:19   ` Rob Herring
  1 sibling, 1 reply; 31+ messages in thread
From: Philipp Zabel @ 2020-03-04 11:41 UTC (permalink / raw)
  To: Abel Vesa, Rob Herring, Shawn Guo, Sascha Hauer, Fabio Estevam,
	Mike Turquette, Stephen Boyd, Lee Jones, Anson Huang,
	Leonard Crestez, Peng Fan, Jacky Bai
  Cc: devicetree, Linux Kernel Mailing List, NXP Linux Team, linux-clk,
	linux-arm-kernel

Hi Abel,

On Tue, 2020-03-03 at 11:03 +0200, Abel Vesa wrote:
> The imx-mix MFD driver registers some devices, one of which, in case of
> audiomix, maps correctly to a reset controller type. This driver registers
> a reset controller for that. For now, only the EARC specific resets are added.
> 
> Signed-off-by: Abel Vesa <abel.vesa@nxp.com>
> Reviewed-by: Leonard Crestez <leonard.crestez@nxp.com>
> ---
>  drivers/reset/Kconfig                          |   7 ++
>  drivers/reset/Makefile                         |   1 +
>  drivers/reset/reset-imx-audiomix.c             | 122 +++++++++++++++++++++++++
>  include/dt-bindings/reset/imx-audiomix-reset.h |  15 +++
>  4 files changed, 145 insertions(+)
>  create mode 100644 drivers/reset/reset-imx-audiomix.c
>  create mode 100644 include/dt-bindings/reset/imx-audiomix-reset.h
> 
> diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
> index d9efbfd..2f8d9b3 100644
> --- a/drivers/reset/Kconfig
> +++ b/drivers/reset/Kconfig
> @@ -81,6 +81,13 @@ config RESET_INTEL_GW
>  	  Say Y to control the reset signals provided by reset controller.
>  	  Otherwise, say N.
>  
> +config RESET_IMX_AUDIOMIX
> +	bool "i.MX Audiomix Reset Driver" if COMPILE_TEST
> +	depends on HAS_IOMEM
> +	default ARCH_MXC
> +	help
> +	  This enables the audiomix reset controller driver for i.MX SoCs.
> +
>  config RESET_LANTIQ
>  	bool "Lantiq XWAY Reset Driver" if COMPILE_TEST
>  	default SOC_TYPE_XWAY
> diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
> index 249ed35..cf23d38 100644
> --- a/drivers/reset/Makefile
> +++ b/drivers/reset/Makefile
> @@ -12,6 +12,7 @@ obj-$(CONFIG_RESET_BRCMSTB_RESCAL) += reset-brcmstb-rescal.o
>  obj-$(CONFIG_RESET_HSDK) += reset-hsdk.o
>  obj-$(CONFIG_RESET_IMX7) += reset-imx7.o
>  obj-$(CONFIG_RESET_INTEL_GW) += reset-intel-gw.o
> +obj-$(CONFIG_RESET_IMX_AUDIOMIX) += reset-imx-audiomix.o
>  obj-$(CONFIG_RESET_LANTIQ) += reset-lantiq.o
>  obj-$(CONFIG_RESET_LPC18XX) += reset-lpc18xx.o
>  obj-$(CONFIG_RESET_MESON) += reset-meson.o
> diff --git a/drivers/reset/reset-imx-audiomix.c b/drivers/reset/reset-imx-audiomix.c
> new file mode 100644
> index 00000000..d1c62ef
> --- /dev/null
> +++ b/drivers/reset/reset-imx-audiomix.c
> @@ -0,0 +1,122 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright 2019 NXP.
> + */
> +
> +#include <dt-bindings/reset/imx-audiomix-reset.h>
> +#include <linux/err.h>
> +#include <linux/io.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +#include <linux/platform_device.h>
> +#include <linux/pm_runtime.h>
> +#include <linux/reset-controller.h>
> +
> +#define IMX_AUDIOMIX_EARC_CTRL_REG	0x200
> +
> +#define IMX_AUDIOMIX_EARC_RESET_BIT	0x0
> +#define IMX_AUDIOMIX_EARC_PHY_RESET_BIT	0x1
> +
> +struct imx_audiomix_reset_data {
> +	void __iomem *base;
> +	struct reset_controller_dev rcdev;
> +	spinlock_t lock;
> +};
> +
> +static int imx_audiomix_reset_set(struct reset_controller_dev *rcdev,
> +			  unsigned long id, bool assert)
> +{
> +	struct imx_audiomix_reset_data *drvdata = container_of(rcdev,
> +			struct imx_audiomix_reset_data, rcdev);
> +	void __iomem *reg_addr = drvdata->base;
> +	unsigned long flags;
> +	unsigned int offset;
> +	u32 reg;
> +
> +	switch (id) {
> +	case IMX_AUDIOMIX_EARC_PHY_RESET:
> +		reg_addr += IMX_AUDIOMIX_EARC_CTRL_REG;
> +		offset = IMX_AUDIOMIX_EARC_PHY_RESET_BIT;
> +		break;
> +	case IMX_AUDIOMIX_EARC_RESET:
> +		reg_addr += IMX_AUDIOMIX_EARC_CTRL_REG;
> +		offset = IMX_AUDIOMIX_EARC_RESET_BIT;
> +		break;
> +	default:
> +		return -EINVAL;
> +	}
> +
> +	if (assert) {
> +		pm_runtime_get_sync(rcdev->dev);

This seems wrong. Why is the runtime PM reference count incremented when
a reset is asserted ...

> +		spin_lock_irqsave(&drvdata->lock, flags);
> +		reg = readl(reg_addr);
> +		writel(reg & ~BIT(offset), reg_addr);
> +		spin_unlock_irqrestore(&drvdata->lock, flags);
> +	} else {
> +		spin_lock_irqsave(&drvdata->lock, flags);
> +		reg = readl(reg_addr);
> +		writel(reg | BIT(offset), reg_addr);
> +		spin_unlock_irqrestore(&drvdata->lock, flags);
> +		pm_runtime_put(rcdev->dev);

... and decremented when a reset is deasserted?

Apart from the runtime PM handling this looks like it could reuse reset-
simple.

> +	}
> +
> +	return 0;
> +}
> +
> +static int imx_audiomix_reset_assert(struct reset_controller_dev *rcdev,
> +			     unsigned long id)
> +{
> +	return imx_audiomix_reset_set(rcdev, id, true);
> +}
> +
> +static int imx_audiomix_reset_deassert(struct reset_controller_dev *rcdev,
> +			       unsigned long id)
> +{
> +	return imx_audiomix_reset_set(rcdev, id, false);
> +}
> +
> +static const struct reset_control_ops imx_audiomix_reset_ops = {
> +	.assert		= imx_audiomix_reset_assert,
> +	.deassert	= imx_audiomix_reset_deassert,
> +};
> +
> +static int imx_audiomix_reset_probe(struct platform_device *pdev)
> +{
> +	struct imx_audiomix_reset_data *drvdata;
> +	struct device *dev = &pdev->dev;
> +
> +	drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL);
> +	if (drvdata == NULL)
> +		return -ENOMEM;
> +
> +	drvdata->base = dev_get_drvdata(dev->parent);
> +
> +	platform_set_drvdata(pdev, drvdata);
> +
> +	pm_runtime_enable(dev);
> +
> +	spin_lock_init(&drvdata->lock);
> +
> +	drvdata->rcdev.owner     = THIS_MODULE;
> +	drvdata->rcdev.nr_resets = IMX_AUDIOMIX_RESET_NUM;
> +	drvdata->rcdev.ops       = &imx_audiomix_reset_ops;
> +	drvdata->rcdev.of_node   = dev->of_node;
> +	drvdata->rcdev.dev	 = dev;
> +
> +	return devm_reset_controller_register(dev, &drvdata->rcdev);
> +}
> +
> +static const struct of_device_id imx_audiomix_reset_dt_ids[] = {
> +	{ .compatible = "fsl,imx8mp-audiomix-reset", },
> +	{ /* sentinel */ },
> +};
> +
> +static struct platform_driver imx_audiomix_reset_driver = {
> +	.probe	= imx_audiomix_reset_probe,
> +	.driver = {
> +		.name		= KBUILD_MODNAME,
> +		.of_match_table	= imx_audiomix_reset_dt_ids,
> +	},
> +};
> +module_platform_driver(imx_audiomix_reset_driver);
> diff --git a/include/dt-bindings/reset/imx-audiomix-reset.h b/include/dt-bindings/reset/imx-audiomix-reset.h
> new file mode 100644
> index 00000000..2e26878
> --- /dev/null
> +++ b/include/dt-bindings/reset/imx-audiomix-reset.h
> @@ -0,0 +1,15 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright 2019 NXP.
> + */
> +
> +#ifndef DT_BINDING_RESET_IMX_AUDIOMIX_H
> +#define DT_BINDING_RESET_IMX_AUDIOMIX_H
> +
> +#define IMX_AUDIOMIX_EARC_RESET		0x0
> +#define IMX_AUDIOMIX_EARC_PHY_RESET	0x1
> +
> +#define IMX_AUDIOMIX_RESET_NUM		2
> +
> +#endif
> +

The imx-audiomix-reset.h change should go into a separate patch,
together with the binding docs for fsl,imx8mp-audiomix-reset.

regards
Philipp

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

* Re: [RFC 07/11] dt-bindings: clocks: imx8mp: Add ids for audiomix clocks
  2020-03-03  9:03 ` [RFC 07/11] dt-bindings: clocks: imx8mp: Add ids for audiomix clocks Abel Vesa
@ 2020-03-10 20:17   ` Rob Herring
  2020-03-21  0:51   ` Stephen Boyd
  1 sibling, 0 replies; 31+ messages in thread
From: Rob Herring @ 2020-03-10 20:17 UTC (permalink / raw)
  To: Abel Vesa
  Cc: Lee Jones, Anson Huang, Leonard Crestez, Peng Fan, Jacky Bai,
	NXP Linux Team, devicetree, linux-arm-kernel,
	Linux Kernel Mailing List, linux-clk, Abel Vesa

On Tue,  3 Mar 2020 11:03:22 +0200, Abel Vesa wrote:
> Add all the clock ids for the audiomix clocks.
> 
> Signed-off-by: Abel Vesa <abel.vesa@nxp.com>
> ---
>  include/dt-bindings/clock/imx8mp-clock.h | 62 ++++++++++++++++++++++++++++++++
>  1 file changed, 62 insertions(+)
> 

Acked-by: Rob Herring <robh@kernel.org>

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

* Re: [RFC 10/11] reset: imx: Add audiomix reset controller support
  2020-03-03  9:03 ` [RFC 10/11] reset: imx: Add audiomix reset controller support Abel Vesa
  2020-03-04 11:41   ` Philipp Zabel
@ 2020-03-10 20:19   ` Rob Herring
  1 sibling, 0 replies; 31+ messages in thread
From: Rob Herring @ 2020-03-10 20:19 UTC (permalink / raw)
  To: Abel Vesa
  Cc: Shawn Guo, Sascha Hauer, Fabio Estevam, Mike Turquette,
	Stephen Boyd, Lee Jones, Anson Huang, Leonard Crestez, Peng Fan,
	Jacky Bai, NXP Linux Team, devicetree, linux-arm-kernel,
	Linux Kernel Mailing List, linux-clk

On Tue, Mar 03, 2020 at 11:03:25AM +0200, Abel Vesa wrote:
> The imx-mix MFD driver registers some devices, one of which, in case of
> audiomix, maps correctly to a reset controller type. This driver registers
> a reset controller for that. For now, only the EARC specific resets are added.
> 
> Signed-off-by: Abel Vesa <abel.vesa@nxp.com>
> Reviewed-by: Leonard Crestez <leonard.crestez@nxp.com>
> ---
>  drivers/reset/Kconfig                          |   7 ++
>  drivers/reset/Makefile                         |   1 +
>  drivers/reset/reset-imx-audiomix.c             | 122 +++++++++++++++++++++++++
>  include/dt-bindings/reset/imx-audiomix-reset.h |  15 +++

This should be in a binding patch which makes me wonder where is the 
binding patch?

Rob

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

* RE: [RFC 02/11] arm64: dts: imx8mp: Add AIPS 4 and 5
  2020-03-03  9:03 ` [RFC 02/11] arm64: dts: imx8mp: Add AIPS 4 and 5 Abel Vesa
@ 2020-03-13  7:44   ` Peng Fan
  2020-03-23 10:48     ` Abel Vesa
  0 siblings, 1 reply; 31+ messages in thread
From: Peng Fan @ 2020-03-13  7:44 UTC (permalink / raw)
  To: Abel Vesa, Rob Herring, Shawn Guo, Sascha Hauer, Fabio Estevam,
	Mike Turquette, Stephen Boyd, Lee Jones, Anson Huang,
	Leonard Crestez, Jacky Bai
  Cc: dl-linux-imx, devicetree, linux-arm-kernel,
	Linux Kernel Mailing List, linux-clk, Abel Vesa

> Subject: [RFC 02/11] arm64: dts: imx8mp: Add AIPS 4 and 5
> 
> There are 5 AIPS maps in total, according to the RM. Add the missing ones
> here.
> 
> Signed-off-by: Abel Vesa <abel.vesa@nxp.com>
> ---
>  arch/arm64/boot/dts/freescale/imx8mp.dtsi | 16 ++++++++++++++++
>  1 file changed, 16 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi
> b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
> index 71b0c8f..a997ca7 100644
> --- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi
> +++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
> @@ -603,6 +603,22 @@
>  			};
>  		};
> 
> +		aips4: bus@32c00000 {
> +			compatible = "simple-bus";

"fsl,aips-bus", "simple-bus";

> +			reg = <0x32c00000 0x400000>;

Size is 64KB

> +			#address-cells = <1>;
> +			#size-cells = <1>;
> +			ranges;
> +		};
> +
> +		aips5: bus@30c00000 {
> +			compatible = "simple-bus";
> +			reg = <0x30c00000 0x400000>;

Ditto. Please correct compatible and reg.

Without this, I think there is no need to only
add bus here? It might be better to also include
subnodes under aips bus.

Regards,
Peng.

> +			#address-cells = <1>;
> +			#size-cells = <1>;
> +			ranges;
> +		};
> +
>  		gic: interrupt-controller@38800000 {
>  			compatible = "arm,gic-v3";
>  			reg = <0x38800000 0x10000>,
> --
> 2.7.4


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

* RE: [RFC 04/11] clk: imx: Add gate shared for i.MX8MP audiomix
  2020-03-03  9:03 ` [RFC 04/11] clk: imx: Add gate shared for i.MX8MP audiomix Abel Vesa
@ 2020-03-13  7:47   ` Peng Fan
  0 siblings, 0 replies; 31+ messages in thread
From: Peng Fan @ 2020-03-13  7:47 UTC (permalink / raw)
  To: Abel Vesa, Rob Herring, Shawn Guo, Sascha Hauer, Fabio Estevam,
	Mike Turquette, Stephen Boyd, Lee Jones, Anson Huang,
	Leonard Crestez, Jacky Bai
  Cc: dl-linux-imx, devicetree, linux-arm-kernel,
	Linux Kernel Mailing List, linux-clk, Abel Vesa

> Subject: [RFC 04/11] clk: imx: Add gate shared for i.MX8MP audiomix
> 
> The newer i.MX platform use some gates that have a shared control bit
> between them.

Could the existing clk_hw_register_gate2 handle your case?

Thanks,
Peng.
> 
> Signed-off-by: Abel Vesa <abel.vesa@nxp.com>
> ---
>  drivers/clk/imx/Makefile          |   2 +-
>  drivers/clk/imx/clk-gate-shared.c | 111
> ++++++++++++++++++++++++++++++++++++++
>  drivers/clk/imx/clk.h             |   4 ++
>  3 files changed, 116 insertions(+), 1 deletion(-)  create mode 100644
> drivers/clk/imx/clk-gate-shared.c
> 
> diff --git a/drivers/clk/imx/Makefile b/drivers/clk/imx/Makefile index
> 928f874c..799a8ef 100644
> --- a/drivers/clk/imx/Makefile
> +++ b/drivers/clk/imx/Makefile
> @@ -27,7 +27,7 @@ obj-$(CONFIG_MXC_CLK_SCU) += \
> 
>  obj-$(CONFIG_CLK_IMX8MM) += clk-imx8mm.o
>  obj-$(CONFIG_CLK_IMX8MN) += clk-imx8mn.o
> -obj-$(CONFIG_CLK_IMX8MP) += clk-imx8mp.o
> +obj-$(CONFIG_CLK_IMX8MP) += clk-imx8mp.o clk-gate-shared.o
>  obj-$(CONFIG_CLK_IMX8MQ) += clk-imx8mq.o
>  obj-$(CONFIG_CLK_IMX8QXP) += clk-imx8qxp.o clk-imx8qxp-lpcg.o
> 
> diff --git a/drivers/clk/imx/clk-gate-shared.c
> b/drivers/clk/imx/clk-gate-shared.c
> new file mode 100644
> index 00000000..961a0e3
> --- /dev/null
> +++ b/drivers/clk/imx/clk-gate-shared.c
> @@ -0,0 +1,111 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright 2019 NXP.
> + */
> +
> +#include <linux/clk-provider.h>
> +#include <linux/err.h>
> +#include <linux/io.h>
> +#include <linux/slab.h>
> +#include "clk.h"
> +
> +/**
> + * struct clk_gate_shared - i.MX specific gate clock having the gate
> +flag
> + * shared with other gate clocks
> + */
> +struct clk_gate_shared {
> +	struct clk_gate	gate;
> +	spinlock_t	*lock;
> +	unsigned int	*share_count;
> +};
> +
> +static int clk_gate_shared_enable(struct clk_hw *hw) {
> +	struct clk_gate *gate = to_clk_gate(hw);
> +	struct clk_gate_shared *shgate = container_of(gate,
> +					struct clk_gate_shared, gate);
> +	unsigned long flags = 0;
> +	int ret = 0;
> +
> +	spin_lock_irqsave(shgate->lock, flags);
> +
> +	if (shgate->share_count && (*shgate->share_count)++ > 0)
> +		goto out;
> +
> +	ret = clk_gate_ops.enable(hw);
> +out:
> +	spin_unlock_irqrestore(shgate->lock, flags);
> +
> +	return ret;
> +}
> +
> +static void clk_gate_shared_disable(struct clk_hw *hw) {
> +	struct clk_gate *gate = to_clk_gate(hw);
> +	struct clk_gate_shared *shgate = container_of(gate,
> +					struct clk_gate_shared, gate);
> +	unsigned long flags = 0;
> +
> +	spin_lock_irqsave(shgate->lock, flags);
> +
> +	if (shgate->share_count) {
> +		if (WARN_ON(*shgate->share_count == 0))
> +			goto out;
> +		else if (--(*shgate->share_count) > 0)
> +			goto out;
> +	}
> +
> +	clk_gate_ops.disable(hw);
> +out:
> +	spin_unlock_irqrestore(shgate->lock, flags); }
> +
> +static int clk_gate_shared_is_enabled(struct clk_hw *hw) {
> +	return clk_gate_ops.is_enabled(hw);
> +}
> +
> +static const struct clk_ops clk_gate_shared_ops = {
> +	.enable = clk_gate_shared_enable,
> +	.disable = clk_gate_shared_disable,
> +	.is_enabled = clk_gate_shared_is_enabled, };
> +
> +struct clk_hw *imx_dev_clk_hw_gate_shared(struct device *dev, const char
> *name,
> +				const char *parent, void __iomem *reg,
> +				u8 shift, unsigned int *share_count) {
> +	struct clk_gate_shared *shgate;
> +	struct clk_gate *gate;
> +	struct clk_hw *hw;
> +	struct clk_init_data init;
> +	int ret;
> +
> +	shgate = kzalloc(sizeof(*shgate), GFP_KERNEL);
> +	if (!shgate)
> +		return ERR_PTR(-ENOMEM);
> +	gate = &shgate->gate;
> +
> +	init.name = name;
> +	init.ops = &clk_gate_shared_ops;
> +	init.flags = CLK_OPS_PARENT_ENABLE;
> +	init.parent_names = parent ? &parent : NULL;
> +	init.num_parents = parent ? 1 : 0;
> +
> +	gate->reg = reg;
> +	gate->bit_idx = shift;
> +	gate->lock = NULL;
> +	gate->hw.init = &init;
> +	shgate->lock = &imx_ccm_lock;
> +	shgate->share_count = share_count;
> +
> +	hw = &gate->hw;
> +
> +	ret = clk_hw_register(NULL, hw);
> +	if (ret) {
> +		kfree(shgate);
> +		return ERR_PTR(ret);
> +	}
> +
> +	return hw;
> +}
> diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h index
> f074dd8..51d6c26 100644
> --- a/drivers/clk/imx/clk.h
> +++ b/drivers/clk/imx/clk.h
> @@ -151,6 +151,10 @@ struct clk_hw *imx_clk_hw_sscg_pll(const char
> *name,
>  				void __iomem *base,
>  				unsigned long flags);
> 
> +struct clk_hw *imx_dev_clk_hw_gate_shared(struct device *dev, const char
> *name,
> +				const char *parent, void __iomem *reg,
> +				u8 shift, unsigned int *share_count);
> +
>  enum imx_pllv3_type {
>  	IMX_PLLV3_GENERIC,
>  	IMX_PLLV3_SYS,
> --
> 2.7.4


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

* RE: [RFC 05/11] clk: imx: pll14xx: Add the device as argument when registering
  2020-03-03  9:03 ` [RFC 05/11] clk: imx: pll14xx: Add the device as argument when registering Abel Vesa
@ 2020-03-13  7:50   ` Peng Fan
  2020-03-21  0:46   ` Stephen Boyd
  1 sibling, 0 replies; 31+ messages in thread
From: Peng Fan @ 2020-03-13  7:50 UTC (permalink / raw)
  To: Abel Vesa, Rob Herring, Shawn Guo, Sascha Hauer, Fabio Estevam,
	Mike Turquette, Stephen Boyd, Lee Jones, Anson Huang,
	Leonard Crestez, Jacky Bai
  Cc: dl-linux-imx, devicetree, linux-arm-kernel,
	Linux Kernel Mailing List, linux-clk, Abel Vesa

> Subject: [RFC 05/11] clk: imx: pll14xx: Add the device as argument when
> registering
> 
> In order to allow runtime PM, the device needs to be passed on to the register
> function. Audiomix clock controller, used on i.MX8MP and future platforms,
> registers a pll14xx and has runtime PM support.
> 
> Signed-off-by: Abel Vesa <abel.vesa@nxp.com>
> ---
>  drivers/clk/imx/clk-pll14xx.c |  6 +++---
>  drivers/clk/imx/clk.h         | 13 ++++++++++---
>  2 files changed, 13 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/clk/imx/clk-pll14xx.c b/drivers/clk/imx/clk-pll14xx.c index
> a83bbbe..2fbc28c 100644
> --- a/drivers/clk/imx/clk-pll14xx.c
> +++ b/drivers/clk/imx/clk-pll14xx.c
> @@ -378,9 +378,9 @@ static const struct clk_ops clk_pll1443x_ops = {
>  	.set_rate	= clk_pll1443x_set_rate,
>  };
> 
> -struct clk_hw *imx_clk_hw_pll14xx(const char *name, const char
> *parent_name,
> -				  void __iomem *base,
> -				  const struct imx_pll14xx_clk *pll_clk)
> +struct clk_hw *imx_dev_clk_hw_pll14xx(struct device *dev, const char
> *name,
> +                            const char *parent_name, void __iomem
> *base,
> +                            const struct imx_pll14xx_clk *pll_clk)
>  {

Should the pointer dev be passed to clk_hw_register?

Thanks,
Peng.

>  	struct clk_pll14xx *pll;
>  	struct clk_hw *hw;
> diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h index
> 51d6c26..cb28f06 100644
> --- a/drivers/clk/imx/clk.h
> +++ b/drivers/clk/imx/clk.h
> @@ -131,9 +131,9 @@ struct clk *imx_clk_pll14xx(const char *name, const
> char *parent_name,  #define imx_clk_pll14xx(name, parent_name, base,
> pll_clk) \
>  	to_clk(imx_clk_hw_pll14xx(name, parent_name, base, pll_clk))
> 
> -struct clk_hw *imx_clk_hw_pll14xx(const char *name, const char
> *parent_name,
> -				  void __iomem *base,
> -				  const struct imx_pll14xx_clk *pll_clk);
> +struct clk_hw *imx_dev_clk_hw_pll14xx(struct device *dev, const char
> *name,
> +                            const char *parent_name, void __iomem
> *base,
> +                            const struct imx_pll14xx_clk *pll_clk);
> 
>  struct clk_hw *imx_clk_hw_pllv1(enum imx_pllv1_type type, const char
> *name,
>  		const char *parent, void __iomem *base); @@ -244,6 +244,13 @@
> static inline struct clk *to_clk(struct clk_hw *hw)
>  	return hw->clk;
>  }
> 
> +static inline struct clk_hw *imx_clk_hw_pll14xx(const char *name, const
> char *parent_name,
> +				  void __iomem *base,
> +				  const struct imx_pll14xx_clk *pll_clk) {
> +	return imx_dev_clk_hw_pll14xx(NULL, name, parent_name, base,
> pll_clk);
> +}
> +
>  static inline struct clk_hw *imx_clk_hw_fixed(const char *name, int rate)  {
>  	return clk_hw_register_fixed_rate(NULL, name, NULL, 0, rate);
> --
> 2.7.4


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

* RE: [RFC 06/11] clk: imx: Add helpers for passing the device as argument
  2020-03-03  9:03 ` [RFC 06/11] clk: imx: Add helpers for passing the device as argument Abel Vesa
@ 2020-03-13  7:58   ` Peng Fan
  2020-03-21  0:46   ` Stephen Boyd
  1 sibling, 0 replies; 31+ messages in thread
From: Peng Fan @ 2020-03-13  7:58 UTC (permalink / raw)
  To: Abel Vesa, Rob Herring, Shawn Guo, Sascha Hauer, Fabio Estevam,
	Mike Turquette, Stephen Boyd, Lee Jones, Anson Huang,
	Leonard Crestez, Jacky Bai
  Cc: dl-linux-imx, devicetree, linux-arm-kernel,
	Linux Kernel Mailing List, linux-clk, Abel Vesa

> Subject: [RFC 06/11] clk: imx: Add helpers for passing the device as argument
> 
> All the imx clocks that need to be registered by the audiomix need to pass on
> the device so that the runtime PM support could work properly.
> 
> Signed-off-by: Abel Vesa <abel.vesa@nxp.com>

Reviewed-by: Peng Fan <peng.fan@nxp.com>

> ---
>  drivers/clk/imx/clk.h | 29 +++++++++++++++++++++++++++++
>  1 file changed, 29 insertions(+)
> 
> diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h index
> cb28f06..42960a9 100644
> --- a/drivers/clk/imx/clk.h
> +++ b/drivers/clk/imx/clk.h
> @@ -321,6 +321,13 @@ static inline struct clk_hw *imx_clk_hw_gate(const
> char *name, const char *paren
>  				    shift, 0, &imx_ccm_lock);
>  }
> 
> +static inline struct clk_hw *imx_dev_clk_hw_gate(struct device *dev, const
> char *name,
> +						const char *parent, void __iomem *reg, u8 shift)
> {
> +	return clk_hw_register_gate(dev, name, parent, CLK_SET_RATE_PARENT,
> reg,
> +				    shift, 0, &imx_ccm_lock);
> +}
> +
>  static inline struct clk_hw *imx_clk_hw_gate_dis(const char *name, const
> char *parent,
>  		void __iomem *reg, u8 shift)
>  {
> @@ -422,6 +429,15 @@ static inline struct clk_hw *imx_clk_hw_mux(const
> char *name, void __iomem *reg,
>  			width, 0, &imx_ccm_lock);
>  }
> 
> +static inline struct clk_hw *imx_dev_clk_hw_mux(struct device *dev, const
> char *name,
> +                        void __iomem *reg, u8 shift, u8 width,
> +                        const char * const *parents, int num_parents)
> {
> +        return clk_hw_register_mux(dev, name, parents, num_parents,
> +                        CLK_SET_RATE_NO_REPARENT |
> CLK_SET_PARENT_GATE,
> +                        reg, shift, width, 0, &imx_ccm_lock); }
> +
>  static inline struct clk *imx_clk_mux2(const char *name, void __iomem
> *reg,
>  			u8 shift, u8 width, const char * const *parents,
>  			int num_parents)
> @@ -484,6 +500,19 @@ static inline struct clk_hw
> *imx_clk_hw_mux_flags(const char *name,
>  				   reg, shift, width, 0, &imx_ccm_lock);  }
> 
> +static inline struct clk_hw *imx_dev_clk_hw_mux_flags(struct device *dev,
> +						  const char *name,
> +						  void __iomem *reg, u8 shift,
> +						  u8 width,
> +						  const char * const *parents,
> +						  int num_parents,
> +						  unsigned long flags)
> +{
> +	return clk_hw_register_mux(dev, name, parents, num_parents,
> +				   flags | CLK_SET_RATE_NO_REPARENT,
> +				   reg, shift, width, 0, &imx_ccm_lock); }
> +
>  struct clk_hw *imx_clk_hw_cpu(const char *name, const char
> *parent_name,
>  		struct clk *div, struct clk *mux, struct clk *pll,
>  		struct clk *step);
> --
> 2.7.4


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

* Re: [RFC 10/11] reset: imx: Add audiomix reset controller support
  2020-03-04 11:41   ` Philipp Zabel
@ 2020-03-13 14:16     ` Abel Vesa
  2020-03-13 15:55       ` Philipp Zabel
  0 siblings, 1 reply; 31+ messages in thread
From: Abel Vesa @ 2020-03-13 14:16 UTC (permalink / raw)
  To: Philipp Zabel
  Cc: Rob Herring, Shawn Guo, Sascha Hauer, Fabio Estevam,
	Mike Turquette, Stephen Boyd, Lee Jones, Anson Huang,
	Leonard Crestez, Peng Fan, Jacky Bai, devicetree,
	Linux Kernel Mailing List, NXP Linux Team, linux-clk,
	linux-arm-kernel

On 20-03-04 12:41:33, Philipp Zabel wrote:
> Hi Abel,
> 
> On Tue, 2020-03-03 at 11:03 +0200, Abel Vesa wrote:
> > The imx-mix MFD driver registers some devices, one of which, in case of
> > audiomix, maps correctly to a reset controller type. This driver registers
> > a reset controller for that. For now, only the EARC specific resets are added.
> > 
> > Signed-off-by: Abel Vesa <abel.vesa@nxp.com>
> > Reviewed-by: Leonard Crestez <leonard.crestez@nxp.com>
> > ---
> >  drivers/reset/Kconfig                          |   7 ++
> >  drivers/reset/Makefile                         |   1 +
> >  drivers/reset/reset-imx-audiomix.c             | 122 +++++++++++++++++++++++++
> >  include/dt-bindings/reset/imx-audiomix-reset.h |  15 +++
> >  4 files changed, 145 insertions(+)
> >  create mode 100644 drivers/reset/reset-imx-audiomix.c
> >  create mode 100644 include/dt-bindings/reset/imx-audiomix-reset.h
> > 
> > diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
> > index d9efbfd..2f8d9b3 100644
> > --- a/drivers/reset/Kconfig
> > +++ b/drivers/reset/Kconfig
> > @@ -81,6 +81,13 @@ config RESET_INTEL_GW
> >  	  Say Y to control the reset signals provided by reset controller.
> >  	  Otherwise, say N.
> >  
> > +config RESET_IMX_AUDIOMIX
> > +	bool "i.MX Audiomix Reset Driver" if COMPILE_TEST
> > +	depends on HAS_IOMEM
> > +	default ARCH_MXC
> > +	help
> > +	  This enables the audiomix reset controller driver for i.MX SoCs.
> > +
> >  config RESET_LANTIQ
> >  	bool "Lantiq XWAY Reset Driver" if COMPILE_TEST
> >  	default SOC_TYPE_XWAY
> > diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
> > index 249ed35..cf23d38 100644
> > --- a/drivers/reset/Makefile
> > +++ b/drivers/reset/Makefile
> > @@ -12,6 +12,7 @@ obj-$(CONFIG_RESET_BRCMSTB_RESCAL) += reset-brcmstb-rescal.o
> >  obj-$(CONFIG_RESET_HSDK) += reset-hsdk.o
> >  obj-$(CONFIG_RESET_IMX7) += reset-imx7.o
> >  obj-$(CONFIG_RESET_INTEL_GW) += reset-intel-gw.o
> > +obj-$(CONFIG_RESET_IMX_AUDIOMIX) += reset-imx-audiomix.o
> >  obj-$(CONFIG_RESET_LANTIQ) += reset-lantiq.o
> >  obj-$(CONFIG_RESET_LPC18XX) += reset-lpc18xx.o
> >  obj-$(CONFIG_RESET_MESON) += reset-meson.o
> > diff --git a/drivers/reset/reset-imx-audiomix.c b/drivers/reset/reset-imx-audiomix.c
> > new file mode 100644
> > index 00000000..d1c62ef
> > --- /dev/null
> > +++ b/drivers/reset/reset-imx-audiomix.c
> > @@ -0,0 +1,122 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright 2019 NXP.
> > + */
> > +
> > +#include <dt-bindings/reset/imx-audiomix-reset.h>
> > +#include <linux/err.h>
> > +#include <linux/io.h>
> > +#include <linux/module.h>
> > +#include <linux/of.h>
> > +#include <linux/of_address.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/pm_runtime.h>
> > +#include <linux/reset-controller.h>
> > +
> > +#define IMX_AUDIOMIX_EARC_CTRL_REG	0x200
> > +
> > +#define IMX_AUDIOMIX_EARC_RESET_BIT	0x0
> > +#define IMX_AUDIOMIX_EARC_PHY_RESET_BIT	0x1
> > +
> > +struct imx_audiomix_reset_data {
> > +	void __iomem *base;
> > +	struct reset_controller_dev rcdev;
> > +	spinlock_t lock;
> > +};
> > +
> > +static int imx_audiomix_reset_set(struct reset_controller_dev *rcdev,
> > +			  unsigned long id, bool assert)
> > +{
> > +	struct imx_audiomix_reset_data *drvdata = container_of(rcdev,
> > +			struct imx_audiomix_reset_data, rcdev);
> > +	void __iomem *reg_addr = drvdata->base;
> > +	unsigned long flags;
> > +	unsigned int offset;
> > +	u32 reg;
> > +
> > +	switch (id) {
> > +	case IMX_AUDIOMIX_EARC_PHY_RESET:
> > +		reg_addr += IMX_AUDIOMIX_EARC_CTRL_REG;
> > +		offset = IMX_AUDIOMIX_EARC_PHY_RESET_BIT;
> > +		break;
> > +	case IMX_AUDIOMIX_EARC_RESET:
> > +		reg_addr += IMX_AUDIOMIX_EARC_CTRL_REG;
> > +		offset = IMX_AUDIOMIX_EARC_RESET_BIT;
> > +		break;
> > +	default:
> > +		return -EINVAL;
> > +	}
> > +
> > +	if (assert) {
> > +		pm_runtime_get_sync(rcdev->dev);
> 
> This seems wrong. Why is the runtime PM reference count incremented when
> a reset is asserted ...

The audiomix IP has its own power domain. 

The way I see it, when the last deassert is done, there is no point
in keeping the audiomix on. So, unless the clock controller part of it does it,
the audiomix will be powered down.

> 
> > +		spin_lock_irqsave(&drvdata->lock, flags);
> > +		reg = readl(reg_addr);
> > +		writel(reg & ~BIT(offset), reg_addr);
> > +		spin_unlock_irqrestore(&drvdata->lock, flags);
> > +	} else {
> > +		spin_lock_irqsave(&drvdata->lock, flags);
> > +		reg = readl(reg_addr);
> > +		writel(reg | BIT(offset), reg_addr);
> > +		spin_unlock_irqrestore(&drvdata->lock, flags);
> > +		pm_runtime_put(rcdev->dev);
> 
> ... and decremented when a reset is deasserted?
> 
> Apart from the runtime PM handling this looks like it could reuse reset-
> simple.
> 
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +static int imx_audiomix_reset_assert(struct reset_controller_dev *rcdev,
> > +			     unsigned long id)
> > +{
> > +	return imx_audiomix_reset_set(rcdev, id, true);
> > +}
> > +
> > +static int imx_audiomix_reset_deassert(struct reset_controller_dev *rcdev,
> > +			       unsigned long id)
> > +{
> > +	return imx_audiomix_reset_set(rcdev, id, false);
> > +}
> > +
> > +static const struct reset_control_ops imx_audiomix_reset_ops = {
> > +	.assert		= imx_audiomix_reset_assert,
> > +	.deassert	= imx_audiomix_reset_deassert,
> > +};
> > +
> > +static int imx_audiomix_reset_probe(struct platform_device *pdev)
> > +{
> > +	struct imx_audiomix_reset_data *drvdata;
> > +	struct device *dev = &pdev->dev;
> > +
> > +	drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL);
> > +	if (drvdata == NULL)
> > +		return -ENOMEM;
> > +
> > +	drvdata->base = dev_get_drvdata(dev->parent);
> > +
> > +	platform_set_drvdata(pdev, drvdata);
> > +
> > +	pm_runtime_enable(dev);
> > +
> > +	spin_lock_init(&drvdata->lock);
> > +
> > +	drvdata->rcdev.owner     = THIS_MODULE;
> > +	drvdata->rcdev.nr_resets = IMX_AUDIOMIX_RESET_NUM;
> > +	drvdata->rcdev.ops       = &imx_audiomix_reset_ops;
> > +	drvdata->rcdev.of_node   = dev->of_node;
> > +	drvdata->rcdev.dev	 = dev;
> > +
> > +	return devm_reset_controller_register(dev, &drvdata->rcdev);
> > +}
> > +
> > +static const struct of_device_id imx_audiomix_reset_dt_ids[] = {
> > +	{ .compatible = "fsl,imx8mp-audiomix-reset", },
> > +	{ /* sentinel */ },
> > +};
> > +
> > +static struct platform_driver imx_audiomix_reset_driver = {
> > +	.probe	= imx_audiomix_reset_probe,
> > +	.driver = {
> > +		.name		= KBUILD_MODNAME,
> > +		.of_match_table	= imx_audiomix_reset_dt_ids,
> > +	},
> > +};
> > +module_platform_driver(imx_audiomix_reset_driver);
> > diff --git a/include/dt-bindings/reset/imx-audiomix-reset.h b/include/dt-bindings/reset/imx-audiomix-reset.h
> > new file mode 100644
> > index 00000000..2e26878
> > --- /dev/null
> > +++ b/include/dt-bindings/reset/imx-audiomix-reset.h
> > @@ -0,0 +1,15 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright 2019 NXP.
> > + */
> > +
> > +#ifndef DT_BINDING_RESET_IMX_AUDIOMIX_H
> > +#define DT_BINDING_RESET_IMX_AUDIOMIX_H
> > +
> > +#define IMX_AUDIOMIX_EARC_RESET		0x0
> > +#define IMX_AUDIOMIX_EARC_PHY_RESET	0x1
> > +
> > +#define IMX_AUDIOMIX_RESET_NUM		2
> > +
> > +#endif
> > +
> 
> The imx-audiomix-reset.h change should go into a separate patch,
> together with the binding docs for fsl,imx8mp-audiomix-reset.
> 
> regards
> Philipp

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

* Re: [RFC 10/11] reset: imx: Add audiomix reset controller support
  2020-03-13 14:16     ` Abel Vesa
@ 2020-03-13 15:55       ` Philipp Zabel
  2020-03-18 11:08         ` Abel Vesa
  0 siblings, 1 reply; 31+ messages in thread
From: Philipp Zabel @ 2020-03-13 15:55 UTC (permalink / raw)
  To: Abel Vesa
  Cc: Rob Herring, Shawn Guo, Sascha Hauer, Fabio Estevam,
	Mike Turquette, Stephen Boyd, Lee Jones, Anson Huang,
	Leonard Crestez, Peng Fan, Jacky Bai, devicetree,
	Linux Kernel Mailing List, NXP Linux Team, linux-clk,
	linux-arm-kernel

On Fri, 2020-03-13 at 16:16 +0200, Abel Vesa wrote:
[...]
> > > +	if (assert) {
> > > +		pm_runtime_get_sync(rcdev->dev);
> > 
> > This seems wrong. Why is the runtime PM reference count incremented when
> > a reset is asserted ...
> 
> The audiomix IP has its own power domain. 

The reset controller does not control the power domain for its
consumers. The consumer of this reset should implement runtime PM.

> The way I see it, when the last deassert is done, there is no point
> in keeping the audiomix on. So, unless the clock controller part of it does it,
> the audiomix will be powered down.

You mean when the last assert is done? Presumably the driver wants to
use the hardware after deasserting the reset and asserts the reset when
it is done.

regards
Philipp

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

* Re: [RFC 10/11] reset: imx: Add audiomix reset controller support
  2020-03-13 15:55       ` Philipp Zabel
@ 2020-03-18 11:08         ` Abel Vesa
  0 siblings, 0 replies; 31+ messages in thread
From: Abel Vesa @ 2020-03-18 11:08 UTC (permalink / raw)
  To: Philipp Zabel
  Cc: Rob Herring, Shawn Guo, Sascha Hauer, Fabio Estevam,
	Mike Turquette, Stephen Boyd, Lee Jones, Anson Huang,
	Leonard Crestez, Peng Fan, Jacky Bai, devicetree,
	Linux Kernel Mailing List, NXP Linux Team, linux-clk,
	linux-arm-kernel

On 20-03-13 16:55:47, Philipp Zabel wrote:
> On Fri, 2020-03-13 at 16:16 +0200, Abel Vesa wrote:
> [...]
> > > > +	if (assert) {
> > > > +		pm_runtime_get_sync(rcdev->dev);
> > > 
> > > This seems wrong. Why is the runtime PM reference count incremented when
> > > a reset is asserted ...
> > 
> > The audiomix IP has its own power domain. 
> 
> The reset controller does not control the power domain for its
> consumers. The consumer of this reset should implement runtime PM.
> 

No, the reset controller itself is part of a more complex IP called audiomix
that has its own power domain.

> > The way I see it, when the last deassert is done, there is no point
> > in keeping the audiomix on. So, unless the clock controller part of it does it,
> > the audiomix will be powered down.
> 
> You mean when the last assert is done? Presumably the driver wants to
> use the hardware after deasserting the reset and asserts the reset when
> it is done.

No, I mean deassert. If there is no reset asserted anymore, then the audiomix
can power down, if nothing else (I'm talking about the other stuff that's
in the audiomix, like clock controller) keeping it on.

The reset controller needs to be on only when there is an assertion of at least
one reset bit going on.

> 
> regards
> Philipp

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

* Re: [RFC 05/11] clk: imx: pll14xx: Add the device as argument when registering
  2020-03-03  9:03 ` [RFC 05/11] clk: imx: pll14xx: Add the device as argument when registering Abel Vesa
  2020-03-13  7:50   ` Peng Fan
@ 2020-03-21  0:46   ` Stephen Boyd
  1 sibling, 0 replies; 31+ messages in thread
From: Stephen Boyd @ 2020-03-21  0:46 UTC (permalink / raw)
  To: Abel Vesa, Anson Huang, Fabio Estevam, Jacky Bai, Lee Jones,
	Leonard Crestez, Mike Turquette, Peng Fan, Rob Herring,
	Sascha Hauer, Shawn Guo
  Cc: NXP Linux Team, devicetree, linux-arm-kernel,
	Linux Kernel Mailing List, linux-clk, Abel Vesa

Quoting Abel Vesa (2020-03-03 01:03:20)
> In order to allow runtime PM, the device needs to be passed on
> to the register function. Audiomix clock controller, used on
> i.MX8MP and future platforms, registers a pll14xx and has runtime
> PM support.
> 
> Signed-off-by: Abel Vesa <abel.vesa@nxp.com>
> ---

Reviewed-by: Stephen Boyd <sboyd@kernel.org>

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

* Re: [RFC 06/11] clk: imx: Add helpers for passing the device as argument
  2020-03-03  9:03 ` [RFC 06/11] clk: imx: Add helpers for passing the device as argument Abel Vesa
  2020-03-13  7:58   ` Peng Fan
@ 2020-03-21  0:46   ` Stephen Boyd
  1 sibling, 0 replies; 31+ messages in thread
From: Stephen Boyd @ 2020-03-21  0:46 UTC (permalink / raw)
  To: Abel Vesa, Anson Huang, Fabio Estevam, Jacky Bai, Lee Jones,
	Leonard Crestez, Mike Turquette, Peng Fan, Rob Herring,
	Sascha Hauer, Shawn Guo
  Cc: NXP Linux Team, devicetree, linux-arm-kernel,
	Linux Kernel Mailing List, linux-clk, Abel Vesa

Quoting Abel Vesa (2020-03-03 01:03:21)
> All the imx clocks that need to be registered by the audiomix need to pass
> on the device so that the runtime PM support could work properly.
> 
> Signed-off-by: Abel Vesa <abel.vesa@nxp.com>
> ---

Reviewed-by: Stephen Boyd <sboyd@kernel.org>

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

* Re: [RFC 08/11] clk: imx: Add audiomix clock controller support
  2020-03-03  9:03 ` [RFC 08/11] clk: imx: Add audiomix clock controller support Abel Vesa
@ 2020-03-21  0:51   ` Stephen Boyd
  0 siblings, 0 replies; 31+ messages in thread
From: Stephen Boyd @ 2020-03-21  0:51 UTC (permalink / raw)
  To: Abel Vesa, Anson Huang, Fabio Estevam, Jacky Bai, Lee Jones,
	Leonard Crestez, Mike Turquette, Peng Fan, Rob Herring,
	Sascha Hauer, Shawn Guo
  Cc: NXP Linux Team, devicetree, linux-arm-kernel,
	Linux Kernel Mailing List, linux-clk, Abel Vesa

Quoting Abel Vesa (2020-03-03 01:03:23)
> diff --git a/drivers/clk/imx/clk-audiomix.c b/drivers/clk/imx/clk-audiomix.c
> new file mode 100644
> index 00000000..8b84943
> --- /dev/null
> +++ b/drivers/clk/imx/clk-audiomix.c
> @@ -0,0 +1,237 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright 2019 NXP.
> + */
> +
> +#include <dt-bindings/clock/imx8mp-clock.h>
> +#include <linux/clk.h>
> +#include <linux/err.h>
> +#include <linux/io.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +#include <linux/platform_device.h>
> +#include <linux/pm_runtime.h>
> +#include <linux/slab.h>
> +#include <linux/types.h>
> +
> +#include "clk.h"
> +
> +static int shared_count_pdm;
> +static struct clk_hw **hws;
> +static struct clk_hw_onecell_data *clk_hw_data;
> +static uint32_t audiomix_clk_saved_regs[14];
> +static struct clk *clk_audio_root;
> +static struct clk *clk_audio_ahb;
> +static struct clk *clk_audio_axi_div;
> +
> +static const struct imx_pll14xx_rate_table imx_audiomix_sai_pll_tbl[] = {
> +       PLL_1443X_RATE(650000000U, 325, 3, 2, 0),
> +};
> +
> +static const struct imx_pll14xx_clk imx_audiomix_sai_pll = {
> +       .type = PLL_1443X,
> +       .rate_table = imx_audiomix_sai_pll_tbl,
> +};
> +
> +static const char *imx_sai_mclk2_sels[] = {"sai1", "sai2", "sai3", "dummy",
> +                                       "sai5", "sai6", "sai7", "dummy",
> +                                       "dummy", "dummy", "dummy",
> +                                       "dummy", "dummy", "dummy", "dummy"};
> +static const char *imx_sai1_mclk1_sels[] = {"sai1", "dummy", };
> +static const char *imx_sai2_mclk1_sels[] = {"sai2", "dummy", };
> +static const char *imx_sai3_mclk1_sels[] = {"sai3", "dummy", };
> +static const char *imx_sai5_mclk1_sels[] = {"sai5", "dummy", };
> +static const char *imx_sai6_mclk1_sels[] = {"sai6", "dummy", };
> +static const char *imx_sai7_mclk1_sels[] = {"sai7", "dummy", };
> +static const char *imx_pdm_sels[] = {"pdm", "sai_pll_div2", "dummy", "dummy" };
> +static const char *imx_sai_pll_ref_sels[] = {"osc_24m", "dummy", "dummy", "dummy", };
> +static const char *imx_sai_pll_bypass_sels[] = {"sai_pll", "sai_pll_ref_sel", };
> +
> +static int imx_audiomix_clk_suspend(struct device *dev)
> +{
> +       void __iomem *base;
> +
> +       base = dev_get_drvdata(dev->parent);
> +
> +       audiomix_clk_saved_regs[0] = readl(base);
> +       audiomix_clk_saved_regs[1] = readl(base + 0x4);
> +
> +       audiomix_clk_saved_regs[2] = readl(base + 0x300);
> +       audiomix_clk_saved_regs[3] = readl(base + 0x304);
> +       audiomix_clk_saved_regs[4] = readl(base + 0x308);
> +       audiomix_clk_saved_regs[5] = readl(base + 0x30C);
> +       audiomix_clk_saved_regs[6] = readl(base + 0x310);
> +       audiomix_clk_saved_regs[7] = readl(base + 0x314);
> +       audiomix_clk_saved_regs[8] = readl(base + 0x318);
> +
> +       audiomix_clk_saved_regs[9] = readl(base + 0x400);
> +       audiomix_clk_saved_regs[10] = readl(base + 0x404);
> +       audiomix_clk_saved_regs[11] = readl(base + 0x408);
> +       audiomix_clk_saved_regs[12] = readl(base + 0x40C);
> +       audiomix_clk_saved_regs[13] = readl(base + 0x410);

Maybe use three loops that have an 'i' and an offset and then += 4 all
the time? Would be a little more compact.

> +
> +       clk_disable_unprepare(clk_audio_ahb);
> +       clk_disable_unprepare(clk_audio_root);
> +       clk_disable_unprepare(clk_audio_axi_div);
> +       pm_runtime_put(dev);
> +
> +       return 0;
> +}
> +
> +static int imx_audiomix_clk_resume(struct device *dev)
> +{
> +       void __iomem *base;
> +
> +       base = dev_get_drvdata(dev->parent);
> +
> +       pm_runtime_get(dev);
> +       clk_prepare_enable(clk_audio_ahb);
> +       clk_prepare_enable(clk_audio_root);
> +       clk_prepare_enable(clk_audio_axi_div);
> +
> +       writel(audiomix_clk_saved_regs[0], base);
> +       writel(audiomix_clk_saved_regs[1], base + 0x4);
> +
> +       writel(audiomix_clk_saved_regs[2], base + 0x300);
> +       writel(audiomix_clk_saved_regs[3], base + 0x304);
> +       writel(audiomix_clk_saved_regs[4], base + 0x308);
> +       writel(audiomix_clk_saved_regs[5], base + 0x30C);
> +       writel(audiomix_clk_saved_regs[6], base + 0x310);
> +       writel(audiomix_clk_saved_regs[7], base + 0x314);
> +       writel(audiomix_clk_saved_regs[8], base + 0x318);
> +
> +       writel(audiomix_clk_saved_regs[9], base + 0x400);
> +       writel(audiomix_clk_saved_regs[10], base + 0x404);
> +       writel(audiomix_clk_saved_regs[11], base + 0x408);
> +       writel(audiomix_clk_saved_regs[12], base + 0x40C);
> +       writel(audiomix_clk_saved_regs[13], base + 0x410);
> +
> +       return 0;
> +}
> +
> +static int imx_audiomix_clk_probe(struct platform_device *pdev)
> +{
> +       struct device *dev = &pdev->dev;
> +       struct device_node *np = dev->of_node;
> +       void __iomem *base;
> +
> +       clk_audio_root = of_clk_get_by_name(np, "audio_root");

Any reason devm_clk_get() can't be used?

> +       if (IS_ERR(clk_audio_root))
> +               return PTR_ERR(clk_audio_root);
> +
> +       clk_audio_ahb = of_clk_get_by_name(np, "audio_ahb");
> +       if (IS_ERR(clk_audio_ahb))
> +               return PTR_ERR(clk_audio_ahb);
> +
> +       clk_audio_axi_div = of_clk_get_by_name(np, "audio_axi_div");
> +       if (IS_ERR(clk_audio_axi_div))
> +               return PTR_ERR(clk_audio_axi_div);
> +
> +       base = dev_get_drvdata(dev->parent);
> +       if (IS_ERR(base))
> +               return PTR_ERR(base);
> +
> +       clk_hw_data = kzalloc(struct_size(clk_hw_data, hws, IMX8MP_CLK_AUDIOMIX_END), GFP_KERNEL);

This line is long. Please limit length.

> +       if (WARN_ON(!clk_hw_data))
> +               return -ENOMEM;
> +
> +       clk_hw_data->num = IMX8MP_CLK_AUDIOMIX_END;
> +       hws = clk_hw_data->hws;
> +
> +       pm_runtime_enable(dev);
> +
> +       hws[IMX8MP_CLK_AUDIOMIX_SAI_PLL_REF_SEL] = imx_dev_clk_hw_mux(dev, "sai_pll_ref_sel", base + 0x400, 0, 2, imx_sai_pll_ref_sels, ARRAY_SIZE(imx_sai_pll_ref_sels));
> +       hws[IMX8MP_CLK_AUDIOMIX_SAI_PLL] = imx_dev_clk_hw_pll14xx(dev, "sai_pll", "sai_pll_ref_sel", base + 0x400, &imx_audiomix_sai_pll);
> +
> +       hws[IMX8MP_CLK_AUDIOMIX_SAI_PLL_BYPASS] = imx_dev_clk_hw_mux_flags(dev, "sai_pll_bypass", base + 0x400, 4, 1, imx_sai_pll_bypass_sels, ARRAY_SIZE(imx_sai_pll_bypass_sels), CLK_SET_RATE_PARENT);
> +
> +       hws[IMX8MP_CLK_AUDIOMIX_SAI_PLL_OUT] = imx_dev_clk_hw_gate(dev, "sai_pll_out", "sai_pll_bypass", base + 0x400, 13);
> +
> +       hws[IMX8MP_CLK_AUDIOMIX_SAI1_MCLK1_SEL] = imx_dev_clk_hw_mux_flags(dev, "sai1_mclk1_sel", base + 0x300, 0, 1, imx_sai1_mclk1_sels, ARRAY_SIZE(imx_sai1_mclk1_sels), CLK_SET_RATE_PARENT);
> +       hws[IMX8MP_CLK_AUDIOMIX_SAI1_MCLK2_SEL] = imx_dev_clk_hw_mux(dev, "sai1_mclk2_sel", base + 0x300, 1, 4, imx_sai_mclk2_sels, ARRAY_SIZE(imx_sai_mclk2_sels));
> +       hws[IMX8MP_CLK_AUDIOMIX_SAI2_MCLK1_SEL] = imx_dev_clk_hw_mux_flags(dev, "sai2_mclk1_sel", base + 0x304, 0, 1, imx_sai2_mclk1_sels, ARRAY_SIZE(imx_sai2_mclk1_sels), CLK_SET_RATE_PARENT);
> +       hws[IMX8MP_CLK_AUDIOMIX_SAI2_MCLK2_SEL] = imx_dev_clk_hw_mux(dev, "sai2_mclk2_sel", base + 0x304, 1, 4, imx_sai_mclk2_sels, ARRAY_SIZE(imx_sai_mclk2_sels));
> +       hws[IMX8MP_CLK_AUDIOMIX_SAI3_MCLK1_SEL] = imx_dev_clk_hw_mux_flags(dev, "sai3_mclk1_sel", base + 0x308, 0, 1, imx_sai3_mclk1_sels, ARRAY_SIZE(imx_sai3_mclk1_sels), CLK_SET_RATE_PARENT);
> +       hws[IMX8MP_CLK_AUDIOMIX_SAI3_MCLK2_SEL] = imx_dev_clk_hw_mux(dev, "sai3_mclk2_sel", base + 0x308, 1, 4, imx_sai_mclk2_sels, ARRAY_SIZE(imx_sai_mclk2_sels));
> +       hws[IMX8MP_CLK_AUDIOMIX_SAI5_MCLK1_SEL] = imx_dev_clk_hw_mux(dev, "sai5_mclk1_sel", base + 0x30C, 0, 1, imx_sai5_mclk1_sels, ARRAY_SIZE(imx_sai5_mclk1_sels));
> +       hws[IMX8MP_CLK_AUDIOMIX_SAI5_MCLK2_SEL] = imx_dev_clk_hw_mux(dev, "sai5_mclk2_sel", base + 0x30C, 1, 4, imx_sai_mclk2_sels, ARRAY_SIZE(imx_sai_mclk2_sels));
> +       hws[IMX8MP_CLK_AUDIOMIX_SAI6_MCLK1_SEL] = imx_dev_clk_hw_mux(dev, "sai6_mclk1_sel", base + 0x310, 0, 1, imx_sai6_mclk1_sels, ARRAY_SIZE(imx_sai6_mclk1_sels));
> +       hws[IMX8MP_CLK_AUDIOMIX_SAI6_MCLK2_SEL] = imx_dev_clk_hw_mux(dev, "sai6_mclk2_sel", base + 0x310, 1, 4, imx_sai_mclk2_sels, ARRAY_SIZE(imx_sai_mclk2_sels));
> +       hws[IMX8MP_CLK_AUDIOMIX_SAI7_MCLK1_SEL] = imx_dev_clk_hw_mux(dev, "sai7_mclk1_sel", base + 0x314, 0, 1, imx_sai7_mclk1_sels, ARRAY_SIZE(imx_sai7_mclk1_sels));
> +       hws[IMX8MP_CLK_AUDIOMIX_SAI7_MCLK2_SEL] = imx_dev_clk_hw_mux(dev, "sai7_mclk2_sel", base + 0x314, 1, 4, imx_sai_mclk2_sels, ARRAY_SIZE(imx_sai_mclk2_sels));
> +
> +       hws[IMX8MP_CLK_AUDIOMIX_SAI1_IPG]    = imx_dev_clk_hw_gate(dev, "sai1_ipg_clk",   "ipg_audio_root", base, 0);
> +       hws[IMX8MP_CLK_AUDIOMIX_SAI1_MCLK1]  = imx_dev_clk_hw_gate(dev, "sai1_mclk1_clk", "sai1_mclk1_sel", base, 1);
> +       hws[IMX8MP_CLK_AUDIOMIX_SAI1_MCLK2]  = imx_dev_clk_hw_gate(dev, "sai1_mclk2_clk", "sai1_mclk2_sel", base, 2);
> +       hws[IMX8MP_CLK_AUDIOMIX_SAI1_MCLK3]  = imx_dev_clk_hw_gate(dev, "sai1_mclk3_clk", "sai_pll_out", base, 3);
> +       hws[IMX8MP_CLK_AUDIOMIX_SAI2_IPG]    = imx_dev_clk_hw_gate(dev, "sai2_ipg_clk",   "ipg_audio_root", base, 4);
> +       hws[IMX8MP_CLK_AUDIOMIX_SAI2_MCLK1]  = imx_dev_clk_hw_gate(dev, "sai2_mclk1_clk", "sai2_mclk1_sel", base, 5);
> +       hws[IMX8MP_CLK_AUDIOMIX_SAI2_MCLK2]  = imx_dev_clk_hw_gate(dev, "sai2_mclk2_clk", "sai2_mclk2_sel", base, 6);
> +       hws[IMX8MP_CLK_AUDIOMIX_SAI2_MCLK3]  = imx_dev_clk_hw_gate(dev, "sai2_mclk3_clk", "sai_pll_out", base, 7);
> +       hws[IMX8MP_CLK_AUDIOMIX_SAI3_IPG]    = imx_dev_clk_hw_gate(dev, "sai3_ipg_clk",   "ipg_audio_root", base, 8);
> +       hws[IMX8MP_CLK_AUDIOMIX_SAI3_MCLK1]  = imx_dev_clk_hw_gate(dev, "sai3_mclk1_clk", "sai3_mclk1_sel", base, 9);
> +       hws[IMX8MP_CLK_AUDIOMIX_SAI3_MCLK2]  = imx_dev_clk_hw_gate(dev, "sai3_mclk2_clk", "sai3_mclk2_sel", base, 10);
> +       hws[IMX8MP_CLK_AUDIOMIX_SAI3_MCLK3]  = imx_dev_clk_hw_gate(dev, "sai3_mclk3_clk", "sai_pll_out", base, 11);
> +       hws[IMX8MP_CLK_AUDIOMIX_SAI5_IPG]    = imx_dev_clk_hw_gate(dev, "sai5_ipg_clk",   "ipg_audio_root", base, 12);
> +       hws[IMX8MP_CLK_AUDIOMIX_SAI5_MCLK1]  = imx_dev_clk_hw_gate(dev, "sai5_mclk1_clk", "sai5_mclk1_sel", base, 13);
> +       hws[IMX8MP_CLK_AUDIOMIX_SAI5_MCLK2]  = imx_dev_clk_hw_gate(dev, "sai5_mclk2_clk", "sai5_mclk2_sel", base, 14);
> +       hws[IMX8MP_CLK_AUDIOMIX_SAI5_MCLK3]  = imx_dev_clk_hw_gate(dev, "sai5_mclk3_clk", "sai_pll_out", base, 15);
> +       hws[IMX8MP_CLK_AUDIOMIX_SAI6_IPG]    = imx_dev_clk_hw_gate(dev, "sai6_ipg_clk",   "ipg_audio_root", base, 16);
> +       hws[IMX8MP_CLK_AUDIOMIX_SAI6_MCLK1]  = imx_dev_clk_hw_gate(dev, "sai6_mclk1_clk", "sai6_mclk1_sel", base, 17);
> +       hws[IMX8MP_CLK_AUDIOMIX_SAI6_MCLK2]  = imx_dev_clk_hw_gate(dev, "sai6_mclk2_clk", "sai6_mclk2_sel", base, 18);
> +       hws[IMX8MP_CLK_AUDIOMIX_SAI6_MCLK3]  = imx_dev_clk_hw_gate(dev, "sai6_mclk3_clk", "sai_pll_out", base, 19);
> +       hws[IMX8MP_CLK_AUDIOMIX_SAI7_IPG]    = imx_dev_clk_hw_gate(dev, "sai7_ipg_clk",   "ipg_audio_root", base, 20);
> +       hws[IMX8MP_CLK_AUDIOMIX_SAI7_MCLK1]  = imx_dev_clk_hw_gate(dev, "sai7_mclk1_clk", "sai7_mclk1_sel", base, 21);
> +       hws[IMX8MP_CLK_AUDIOMIX_SAI7_MCLK2]  = imx_dev_clk_hw_gate(dev, "sai7_mclk2_clk", "sai7_mclk2_sel", base, 22);
> +       hws[IMX8MP_CLK_AUDIOMIX_SAI7_MCLK3]  = imx_dev_clk_hw_gate(dev, "sai7_mclk3_clk", "sai_pll_out", base, 23);
> +       hws[IMX8MP_CLK_AUDIOMIX_ASRC_IPG]    = imx_dev_clk_hw_gate(dev, "asrc_ipg_clk",   "ipg_audio_root", base, 24);
> +       hws[IMX8MP_CLK_AUDIOMIX_PDM_IPG]     = imx_dev_clk_hw_gate_shared(dev, "pdm_ipg_clk", "ipg_audio_root", base, 25, &shared_count_pdm);
> +       hws[IMX8MP_CLK_AUDIOMIX_PDM_ROOT]    = imx_dev_clk_hw_gate_shared(dev, "pdm_root_clk", "pdm", base, 25, &shared_count_pdm);
> +
> +       hws[IMX8MP_CLK_AUDIOMIX_SDMA2_ROOT]  = imx_dev_clk_hw_gate(dev, "sdma2_root_clk", "ipg_audio_root", base, 26);
> +       hws[IMX8MP_CLK_AUDIOMIX_SDMA3_ROOT]  = imx_dev_clk_hw_gate(dev, "sdma3_root_clk", "ipg_audio_root", base, 27);
> +       hws[IMX8MP_CLK_AUDIOMIX_SPBA2_ROOT]  = imx_dev_clk_hw_gate(dev, "spba2_root_clk", "ipg_audio_root", base, 28);
> +       hws[IMX8MP_CLK_AUDIOMIX_DSP_ROOT]    = imx_dev_clk_hw_gate(dev, "dsp_root_clk",   "ipg_audio_root", base, 29);
> +       hws[IMX8MP_CLK_AUDIOMIX_DSPDBG_ROOT] = imx_dev_clk_hw_gate(dev, "dsp_dbg_clk",    "ipg_audio_root", base, 30);
> +       hws[IMX8MP_CLK_AUDIOMIX_EARC_IPG]    = imx_dev_clk_hw_gate(dev, "earc_ipg_clk",   "ipg_audio_root", base, 31);
> +
> +       hws[IMX8MP_CLK_AUDIOMIX_OCRAMA_IPG]  = imx_dev_clk_hw_gate(dev, "ocram_a_ipg_clk", "ipg_audio_root", base + 4, 0);
> +       hws[IMX8MP_CLK_AUDIOMIX_AUD2HTX_IPG] = imx_dev_clk_hw_gate(dev, "aud2htx_ipg_clk", "ipg_audio_root", base + 4, 1);
> +       hws[IMX8MP_CLK_AUDIOMIX_EDMA_ROOT]   = imx_dev_clk_hw_gate(dev, "edma_root_clk",   "ipg_audio_root", base + 4, 2);
> +       hws[IMX8MP_CLK_AUDIOMIX_AUDPLL_ROOT] = imx_dev_clk_hw_gate(dev, "aud_pll_clk",  "ipg_audio_root", base + 4, 3);
> +       hws[IMX8MP_CLK_AUDIOMIX_MU2_ROOT]    = imx_dev_clk_hw_gate(dev, "mu2_root_clk", "ipg_audio_root", base + 4, 4);
> +       hws[IMX8MP_CLK_AUDIOMIX_MU3_ROOT]    = imx_dev_clk_hw_gate(dev, "mu3_root_clk", "ipg_audio_root", base + 4, 5);
> +       hws[IMX8MP_CLK_AUDIOMIX_EARC_PHY]    = imx_dev_clk_hw_gate(dev, "earc_phy_clk", "ipg_audio_root", base + 4, 6);

These ones are OK because they're basically setting up an array and we
can't help it.

> +
> +       hws[IMX8MP_CLK_AUDIOMIX_PDM_SEL] = imx_dev_clk_hw_mux(dev, "pdm_sel", base + 0x318, 1, 4, imx_pdm_sels, ARRAY_SIZE(imx_pdm_sels));
> +
> +       /* unbypass the pll */
> +       clk_hw_set_parent(hws[IMX8MP_CLK_AUDIOMIX_SAI_PLL_BYPASS], hws[IMX8MP_CLK_AUDIOMIX_SAI_PLL]);

But this is long again so please don't.

> +
> +       imx_check_clk_hws(hws, IMX8MP_CLK_AUDIOMIX_END);
> +
> +       of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_hw_data);
> +
> +       return 0;
> +}
> +
> +UNIVERSAL_DEV_PM_OPS(imx_audiomix_clk_pm_ops, imx_audiomix_clk_suspend,
> +                       imx_audiomix_clk_resume, imx_audiomix_clk_resume);
> +
> +static const struct of_device_id imx_audiomix_clk_of_match[] = {
> +       { .compatible = "fsl,imx8mp-audiomix-clk" },
> +       { /* Sentinel */ },

Nitpick: Drop comma after sentinel so that nothing can come after
without causing compile error.

> +};

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

* Re: [RFC 07/11] dt-bindings: clocks: imx8mp: Add ids for audiomix clocks
  2020-03-03  9:03 ` [RFC 07/11] dt-bindings: clocks: imx8mp: Add ids for audiomix clocks Abel Vesa
  2020-03-10 20:17   ` Rob Herring
@ 2020-03-21  0:51   ` Stephen Boyd
  1 sibling, 0 replies; 31+ messages in thread
From: Stephen Boyd @ 2020-03-21  0:51 UTC (permalink / raw)
  To: Abel Vesa, Anson Huang, Fabio Estevam, Jacky Bai, Lee Jones,
	Leonard Crestez, Mike Turquette, Peng Fan, Rob Herring,
	Sascha Hauer, Shawn Guo
  Cc: NXP Linux Team, devicetree, linux-arm-kernel,
	Linux Kernel Mailing List, linux-clk, Abel Vesa

Quoting Abel Vesa (2020-03-03 01:03:22)
> Add all the clock ids for the audiomix clocks.
> 
> Signed-off-by: Abel Vesa <abel.vesa@nxp.com>
> ---

Reviewed-by: Stephen Boyd <sboyd@kernel.org>

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

* Re: [RFC 02/11] arm64: dts: imx8mp: Add AIPS 4 and 5
  2020-03-13  7:44   ` Peng Fan
@ 2020-03-23 10:48     ` Abel Vesa
  0 siblings, 0 replies; 31+ messages in thread
From: Abel Vesa @ 2020-03-23 10:48 UTC (permalink / raw)
  To: Peng Fan
  Cc: Rob Herring, Shawn Guo, Sascha Hauer, Fabio Estevam,
	Mike Turquette, Stephen Boyd, Lee Jones, Anson Huang,
	Leonard Crestez, Jacky Bai, dl-linux-imx, devicetree,
	linux-arm-kernel, Linux Kernel Mailing List, linux-clk

On 20-03-13 07:44:43, Peng Fan wrote:
> > Subject: [RFC 02/11] arm64: dts: imx8mp: Add AIPS 4 and 5
> > 
> > There are 5 AIPS maps in total, according to the RM. Add the missing ones
> > here.
> > 
> > Signed-off-by: Abel Vesa <abel.vesa@nxp.com>
> > ---
> >  arch/arm64/boot/dts/freescale/imx8mp.dtsi | 16 ++++++++++++++++
> >  1 file changed, 16 insertions(+)
> > 
> > diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi
> > b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
> > index 71b0c8f..a997ca7 100644
> > --- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi
> > +++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
> > @@ -603,6 +603,22 @@
> >  			};
> >  		};
> > 
> > +		aips4: bus@32c00000 {
> > +			compatible = "simple-bus";
> 
> "fsl,aips-bus", "simple-bus";
> 
> > +			reg = <0x32c00000 0x400000>;
> 
> Size is 64KB
> 
> > +			#address-cells = <1>;
> > +			#size-cells = <1>;
> > +			ranges;
> > +		};
> > +
> > +		aips5: bus@30c00000 {
> > +			compatible = "simple-bus";
> > +			reg = <0x30c00000 0x400000>;
> 
> Ditto. Please correct compatible and reg.
> 

Will do in the next version.

> Without this, I think there is no need to only
> add bus here? It might be better to also include
> subnodes under aips bus.

AIPS 5 is needed by the next patch in this series.
So it wouldn't make sense to have a patch that adds
only the fifth one, skipping the fourth one.

> 
> Regards,
> Peng.
> 
> > +			#address-cells = <1>;
> > +			#size-cells = <1>;
> > +			ranges;
> > +		};
> > +
> >  		gic: interrupt-controller@38800000 {
> >  			compatible = "arm,gic-v3";
> >  			reg = <0x38800000 0x10000>,
> > --
> > 2.7.4
> 

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

* Re: [RFC 01/11] mfd: Add i.MX generic mix support
  2020-03-03  9:03 ` [RFC 01/11] mfd: Add i.MX generic mix support Abel Vesa
@ 2020-03-26 11:03   ` Lee Jones
  2020-03-26 12:30     ` Abel Vesa
  0 siblings, 1 reply; 31+ messages in thread
From: Lee Jones @ 2020-03-26 11:03 UTC (permalink / raw)
  To: Abel Vesa
  Cc: Rob Herring, Shawn Guo, Sascha Hauer, Fabio Estevam,
	Mike Turquette, Stephen Boyd, Anson Huang, Leonard Crestez,
	Peng Fan, Jacky Bai, NXP Linux Team, devicetree,
	linux-arm-kernel, Linux Kernel Mailing List, linux-clk

On Tue, 03 Mar 2020, Abel Vesa wrote:

> Some of the i.MX SoCs have a IP for interfacing the dedicated IPs with
> clocks, resets and interrupts, plus some other specific control registers.
> To allow the functionality to be split between drivers, this MFD driver is
> added that has only two purposes: register the devices and map the entire
> register addresses. Everything else is left to the dedicated drivers that will
> bind to the registered devices.
> 
> Signed-off-by: Abel Vesa <abel.vesa@nxp.com>
> ---
>  drivers/mfd/Kconfig   | 11 +++++++++++
>  drivers/mfd/Makefile  |  1 +
>  drivers/mfd/imx-mix.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 60 insertions(+)
>  create mode 100644 drivers/mfd/imx-mix.c
> 
> diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
> index 3c547ed..3c89288 100644
> --- a/drivers/mfd/Kconfig
> +++ b/drivers/mfd/Kconfig
> @@ -460,6 +460,17 @@ config MFD_MX25_TSADC
>  	  i.MX25 processors. They consist of a conversion queue for general
>  	  purpose ADC and a queue for Touchscreens.
>  
> +config MFD_IMX_MIX
> +	tristate "NXP i.MX Generic Mix Control Driver"
> +	depends on OF || COMPILE_TEST
> +	help
> +	  Enable generic mixes support. On some i.MX platforms, there are
> +	  devices that are a mix of multiple functionalities like reset
> +	  controllers, clock controllers and some others. In order to split
> +	  those functionalities between the right drivers, this MFD populates
> +	  with virtual devices based on what's found in the devicetree node,
> +	  leaving the rest of the behavior control to the dedicated driver.
> +
>  config MFD_HI6421_PMIC
>  	tristate "HiSilicon Hi6421 PMU/Codec IC"
>  	depends on OF
> diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
> index f935d10..5b2ae5d 100644
> --- a/drivers/mfd/Makefile
> +++ b/drivers/mfd/Makefile
> @@ -113,6 +113,7 @@ obj-$(CONFIG_MFD_TWL4030_AUDIO)	+= twl4030-audio.o
>  obj-$(CONFIG_TWL6040_CORE)	+= twl6040.o
>  
>  obj-$(CONFIG_MFD_MX25_TSADC)	+= fsl-imx25-tsadc.o
> +obj-$(CONFIG_MFD_IMX_MIX)	+= imx-mix.o
>  
>  obj-$(CONFIG_MFD_MC13XXX)	+= mc13xxx-core.o
>  obj-$(CONFIG_MFD_MC13XXX_SPI)	+= mc13xxx-spi.o
> diff --git a/drivers/mfd/imx-mix.c b/drivers/mfd/imx-mix.c
> new file mode 100644
> index 00000000..d3f8c71
> --- /dev/null
> +++ b/drivers/mfd/imx-mix.c
> @@ -0,0 +1,48 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright 2019 NXP.
> + */
> +
> +#include <linux/clk.h>
> +#include <linux/clk-provider.h>
> +#include <linux/err.h>
> +#include <linux/io.h>
> +#include <linux/module.h>
> +#include <linux/of_address.h>
> +#include <linux/spinlock.h>
> +#include <linux/types.h>
> +#include <linux/platform_device.h>
> +#include <linux/of_platform.h>
> +
> +#include <linux/mfd/core.h>
> +
> +static int imx_audiomix_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct resource *res;
> +	void __iomem *base;
> +
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	base = devm_ioremap_resource(dev, res);
> +	if (IS_ERR(base))
> +		return PTR_ERR(base);
> +
> +	dev_set_drvdata(dev, base);
> +
> +	return devm_of_platform_populate(dev);
> +}
> +
> +static const struct of_device_id imx_audiomix_of_match[] = {
> +	{ .compatible = "fsl,imx8mp-audiomix" },
> +	{ /* Sentinel */ },
> +};
> +MODULE_DEVICE_TABLE(of, imx_audiomix_of_match);

This needs DT binding documentation.

Do the sub-device memory ranges overlap?

> +static struct platform_driver imx_audiomix_driver = {
> +	.probe = imx_audiomix_probe,
> +	.driver = {
> +		.name = "imx-audiomix",
> +		.of_match_table = of_match_ptr(imx_audiomix_of_match),
> +	},
> +};
> +module_platform_driver(imx_audiomix_driver);

-- 
Lee Jones [李琼斯]
Linaro Services Technical Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

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

* Re: [RFC 01/11] mfd: Add i.MX generic mix support
  2020-03-26 11:03   ` Lee Jones
@ 2020-03-26 12:30     ` Abel Vesa
  0 siblings, 0 replies; 31+ messages in thread
From: Abel Vesa @ 2020-03-26 12:30 UTC (permalink / raw)
  To: Lee Jones
  Cc: Rob Herring, Shawn Guo, Sascha Hauer, Fabio Estevam,
	Mike Turquette, Stephen Boyd, Anson Huang, Leonard Crestez,
	Peng Fan, Jacky Bai, NXP Linux Team, devicetree,
	linux-arm-kernel, Linux Kernel Mailing List, linux-clk

On 20-03-26 11:03:06, Lee Jones wrote:
> On Tue, 03 Mar 2020, Abel Vesa wrote:
> 
> > Some of the i.MX SoCs have a IP for interfacing the dedicated IPs with
> > clocks, resets and interrupts, plus some other specific control registers.
> > To allow the functionality to be split between drivers, this MFD driver is
> > added that has only two purposes: register the devices and map the entire
> > register addresses. Everything else is left to the dedicated drivers that will
> > bind to the registered devices.
> > 
> > Signed-off-by: Abel Vesa <abel.vesa@nxp.com>
> > ---
> >  drivers/mfd/Kconfig   | 11 +++++++++++
> >  drivers/mfd/Makefile  |  1 +
> >  drivers/mfd/imx-mix.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
> >  3 files changed, 60 insertions(+)
> >  create mode 100644 drivers/mfd/imx-mix.c
> > 
> > diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
> > index 3c547ed..3c89288 100644
> > --- a/drivers/mfd/Kconfig
> > +++ b/drivers/mfd/Kconfig
> > @@ -460,6 +460,17 @@ config MFD_MX25_TSADC
> >  	  i.MX25 processors. They consist of a conversion queue for general
> >  	  purpose ADC and a queue for Touchscreens.
> >  
> > +config MFD_IMX_MIX
> > +	tristate "NXP i.MX Generic Mix Control Driver"
> > +	depends on OF || COMPILE_TEST
> > +	help
> > +	  Enable generic mixes support. On some i.MX platforms, there are
> > +	  devices that are a mix of multiple functionalities like reset
> > +	  controllers, clock controllers and some others. In order to split
> > +	  those functionalities between the right drivers, this MFD populates
> > +	  with virtual devices based on what's found in the devicetree node,
> > +	  leaving the rest of the behavior control to the dedicated driver.
> > +
> >  config MFD_HI6421_PMIC
> >  	tristate "HiSilicon Hi6421 PMU/Codec IC"
> >  	depends on OF
> > diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
> > index f935d10..5b2ae5d 100644
> > --- a/drivers/mfd/Makefile
> > +++ b/drivers/mfd/Makefile
> > @@ -113,6 +113,7 @@ obj-$(CONFIG_MFD_TWL4030_AUDIO)	+= twl4030-audio.o
> >  obj-$(CONFIG_TWL6040_CORE)	+= twl6040.o
> >  
> >  obj-$(CONFIG_MFD_MX25_TSADC)	+= fsl-imx25-tsadc.o
> > +obj-$(CONFIG_MFD_IMX_MIX)	+= imx-mix.o
> >  
> >  obj-$(CONFIG_MFD_MC13XXX)	+= mc13xxx-core.o
> >  obj-$(CONFIG_MFD_MC13XXX_SPI)	+= mc13xxx-spi.o
> > diff --git a/drivers/mfd/imx-mix.c b/drivers/mfd/imx-mix.c
> > new file mode 100644
> > index 00000000..d3f8c71
> > --- /dev/null
> > +++ b/drivers/mfd/imx-mix.c
> > @@ -0,0 +1,48 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright 2019 NXP.
> > + */
> > +
> > +#include <linux/clk.h>
> > +#include <linux/clk-provider.h>
> > +#include <linux/err.h>
> > +#include <linux/io.h>
> > +#include <linux/module.h>
> > +#include <linux/of_address.h>
> > +#include <linux/spinlock.h>
> > +#include <linux/types.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/of_platform.h>
> > +
> > +#include <linux/mfd/core.h>
> > +
> > +static int imx_audiomix_probe(struct platform_device *pdev)
> > +{
> > +	struct device *dev = &pdev->dev;
> > +	struct resource *res;
> > +	void __iomem *base;
> > +
> > +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> > +	base = devm_ioremap_resource(dev, res);
> > +	if (IS_ERR(base))
> > +		return PTR_ERR(base);
> > +
> > +	dev_set_drvdata(dev, base);
> > +
> > +	return devm_of_platform_populate(dev);
> > +}
> > +
> > +static const struct of_device_id imx_audiomix_of_match[] = {
> > +	{ .compatible = "fsl,imx8mp-audiomix" },
> > +	{ /* Sentinel */ },
> > +};
> > +MODULE_DEVICE_TABLE(of, imx_audiomix_of_match);
> 
> This needs DT binding documentation.
> 
> Do the sub-device memory ranges overlap?
> 

Yes, they do.

Resent another version of this series yesterday.

> > +static struct platform_driver imx_audiomix_driver = {
> > +	.probe = imx_audiomix_probe,
> > +	.driver = {
> > +		.name = "imx-audiomix",
> > +		.of_match_table = of_match_ptr(imx_audiomix_of_match),
> > +	},
> > +};
> > +module_platform_driver(imx_audiomix_driver);
> 
> -- 
> Lee Jones [李琼斯]
> Linaro Services Technical Lead
> Linaro.org │ Open source software for ARM SoCs
> Follow Linaro: Facebook | Twitter | Blog

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

* Re: [RFC 00/11] Add generic MFD i.MX mix and audiomix support
  2020-03-03  9:03 [RFC 00/11] Add generic MFD i.MX mix and audiomix support Abel Vesa
                   ` (10 preceding siblings ...)
  2020-03-03  9:03 ` [RFC 11/11] arm64: dts: imx8mp: Add audiomix reset controller node Abel Vesa
@ 2020-04-16 11:06 ` Arnd Bergmann
  2020-04-16 11:06   ` Arnd Bergmann
  11 siblings, 1 reply; 31+ messages in thread
From: Arnd Bergmann @ 2020-04-16 11:06 UTC (permalink / raw)
  To: Abel Vesa
  Cc: Rob Herring, Shawn Guo, Sascha Hauer, Fabio Estevam,
	Mike Turquette, Stephen Boyd, Lee Jones, Anson Huang,
	Leonard Crestez, Peng Fan, Jacky Bai, NXP Linux Team, DTML,
	Linux ARM, Linux Kernel Mailing List, linux-clk

On Tue, Mar 3, 2020 at 10:04 AM Abel Vesa <abel.vesa@nxp.com> wrote:
>
> The i.MX8MP has some new IPs called mixes. They are formed usually by some
> GPRs that can be split into different functionalities. The first example
> here is the audiomix which has dedicated registers that can be registered
> as a clock controller and some other registers that can be registered as
> a reset controller, plus some dedicated ones that will be registered as
> syscon and used by each dedicated audio IP.
>
> More mixes to be following the same structure are to come, like hdmimix,
> dispmix and mediamix. They will all be populated and registered by the MFD
> imx-mix generic driver.

Can you enumerate what functionality is in each one?

I'm not convinced that using an MFD driver is the best solution here,
compared to e.g. a clk driver with a few extra bits in it, if most of the
code for the child drivers ends up being for the clk subsystem.

Lee suggested maybe having a generic (platform independent) driver
for it, which may help here, as it would let others share the trivial
mfd portion.

Another option that we are using on several platforms today is to
have a single syscon node and have other drivers that reference
that one using a phandle to get at the regmap.

      Arnd

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

* Re: [RFC 00/11] Add generic MFD i.MX mix and audiomix support
  2020-04-16 11:06 ` [RFC 00/11] Add generic MFD i.MX mix and audiomix support Arnd Bergmann
@ 2020-04-16 11:06   ` Arnd Bergmann
  0 siblings, 0 replies; 31+ messages in thread
From: Arnd Bergmann @ 2020-04-16 11:06 UTC (permalink / raw)
  To: Abel Vesa
  Cc: Rob Herring, Shawn Guo, Sascha Hauer, Fabio Estevam,
	Mike Turquette, Stephen Boyd, Lee Jones, Anson Huang,
	Leonard Crestez, Peng Fan, Jacky Bai, NXP Linux Team, DTML,
	Linux ARM, Linux Kernel Mailing List, linux-clk

On Thu, Apr 16, 2020 at 1:06 PM Arnd Bergmann <arnd@arndb.de> wrote:
>
> On Tue, Mar 3, 2020 at 10:04 AM Abel Vesa <abel.vesa@nxp.com> wrote:
> >
> > The i.MX8MP has some new IPs called mixes. They are formed usually by some
> > GPRs that can be split into different functionalities. The first example
> > here is the audiomix which has dedicated registers that can be registered
> > as a clock controller and some other registers that can be registered as
> > a reset controller, plus some dedicated ones that will be registered as
> > syscon and used by each dedicated audio IP.
> >
> > More mixes to be following the same structure are to come, like hdmimix,
> > dispmix and mediamix. They will all be populated and registered by the MFD
> > imx-mix generic driver.
>
> Can you enumerate what functionality is in each one?
>
> I'm not convinced that using an MFD driver is the best solution here,
> compared to e.g. a clk driver with a few extra bits in it, if most of the
> code for the child drivers ends up being for the clk subsystem.
>
> Lee suggested maybe having a generic (platform independent) driver
> for it, which may help here, as it would let others share the trivial
> mfd portion.
>
> Another option that we are using on several platforms today is to
> have a single syscon node and have other drivers that reference
> that one using a phandle to get at the regmap.

Sorry I replied to the wrong thread, I meant to reply to the v3 version.

       Arnd

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

end of thread, other threads:[~2020-04-16 11:34 UTC | newest]

Thread overview: 31+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-03-03  9:03 [RFC 00/11] Add generic MFD i.MX mix and audiomix support Abel Vesa
2020-03-03  9:03 ` [RFC 01/11] mfd: Add i.MX generic mix support Abel Vesa
2020-03-26 11:03   ` Lee Jones
2020-03-26 12:30     ` Abel Vesa
2020-03-03  9:03 ` [RFC 02/11] arm64: dts: imx8mp: Add AIPS 4 and 5 Abel Vesa
2020-03-13  7:44   ` Peng Fan
2020-03-23 10:48     ` Abel Vesa
2020-03-03  9:03 ` [RFC 03/11] arm64: dts: imx8mp: Add audiomix node Abel Vesa
2020-03-03  9:03 ` [RFC 04/11] clk: imx: Add gate shared for i.MX8MP audiomix Abel Vesa
2020-03-13  7:47   ` Peng Fan
2020-03-03  9:03 ` [RFC 05/11] clk: imx: pll14xx: Add the device as argument when registering Abel Vesa
2020-03-13  7:50   ` Peng Fan
2020-03-21  0:46   ` Stephen Boyd
2020-03-03  9:03 ` [RFC 06/11] clk: imx: Add helpers for passing the device as argument Abel Vesa
2020-03-13  7:58   ` Peng Fan
2020-03-21  0:46   ` Stephen Boyd
2020-03-03  9:03 ` [RFC 07/11] dt-bindings: clocks: imx8mp: Add ids for audiomix clocks Abel Vesa
2020-03-10 20:17   ` Rob Herring
2020-03-21  0:51   ` Stephen Boyd
2020-03-03  9:03 ` [RFC 08/11] clk: imx: Add audiomix clock controller support Abel Vesa
2020-03-21  0:51   ` Stephen Boyd
2020-03-03  9:03 ` [RFC 09/11] arm64: dts: imx8mp: Add audiomix clock controller node Abel Vesa
2020-03-03  9:03 ` [RFC 10/11] reset: imx: Add audiomix reset controller support Abel Vesa
2020-03-04 11:41   ` Philipp Zabel
2020-03-13 14:16     ` Abel Vesa
2020-03-13 15:55       ` Philipp Zabel
2020-03-18 11:08         ` Abel Vesa
2020-03-10 20:19   ` Rob Herring
2020-03-03  9:03 ` [RFC 11/11] arm64: dts: imx8mp: Add audiomix reset controller node Abel Vesa
2020-04-16 11:06 ` [RFC 00/11] Add generic MFD i.MX mix and audiomix support Arnd Bergmann
2020-04-16 11:06   ` Arnd Bergmann

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).