Devicetree
 help / color / mirror / Atom feed
* Re: [PATCH v2 4/4] ARM: PWM: add allwinner sun8i pwm support.
From: Maxime Ripard @ 2018-05-18  8:15 UTC (permalink / raw)
  To: Hao Zhang
  Cc: Thierry Reding, robh+dt-DgEjT+Ai2ygdnm+yROfE0A, Mark Rutland,
	linux-I+IVW8TIWO2tmTQ+vhA3Yw, Chen-Yu Tsai, Claudiu Beznea,
	linux-gpio-u79uwXL29TY76Z2rM5mHXA, open list,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	moderated list:ARM/Allwinner sunXi SoC support,
	linux-pwm-u79uwXL29TY76Z2rM5mHXA,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw
In-Reply-To: <CAJeuY79ObkssY_=SLG==7xZri10P3yWFhXC3=CUVrdQ+7cBoHA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>

[-- Attachment #1: Type: text/plain, Size: 2431 bytes --]

On Thu, May 17, 2018 at 10:48:58PM +0800, Hao Zhang wrote:
> 2018-05-15 19:17 GMT+08:00 Maxime Ripard <maxime.ripard-LDxbnhwyfcJBDgjK7y7TUQ@public.gmane.org>:
> > Hi,
> >
> > On Mon, May 14, 2018 at 10:45:44PM +0800, Hao Zhang wrote:
> >> 2018-02-26 17:00 GMT+08:00 Maxime Ripard <maxime.ripard-LDxbnhwyfcJBDgjK7y7TUQ@public.gmane.org>:
> >> > Thanks for respinning this serie. It looks mostly good, but you still
> >> > have a quite significant number of checkpatch (--strict) warnings that
> >> > you should address.
> >>
> >> Thanks for reviews :) ,i'm sorry for that, it will be fixed next
> >> time.  and, besides, in what situation were the checkpatch warning
> >> can be ignore?
> >
> > The only one that can be reasonably be ignored is the long line
> > warning, and only if complying to the limit would make it less easy to
> > understand.
> >
> >> >
> >> > On Sun, Feb 25, 2018 at 09:53:08PM +0800, hao_zhang wrote:
> >> >> +#define CAPTURE_IRQ_ENABLE_REG       0x0010
> >> >> +#define CFIE(ch)     BIT(ch << 1 + 1)
> >> >> +#define CRIE(ch)     BIT(ch << 1)
> >> >
> >> > You should also put your argument between parentheses here (and in all
> >> > your other macros).
> >>
> >> Do you mean like this ?
> >> #define CFIE(ch)     BIT((ch) << 1 + 1)
> >> #define CRIE(ch)     BIT((ch) << 1)
> >
> > Yep, exactly. Otherwise, if you do something like CRIE(1 + 1), the
> > result will be BIT(1 + 1 << 1), which will expand to 3, instead of 4.
> >
> > Also, CFIE looks a bit weird here, is it the offset that is
> > incremented, or the value? You should probably have parentheses to
> > make it explicit.
> 
> The vallue,
> BIT(((ch) << 1) + 1) It seem not very nice...
> 
> uhmm...
> In CAPTURE_IRQ_ENABLE_REG odd number is CFIE, even number is CRIE
> each channel has one CFIE and CRIE.
> 
> we can also describe like this:
> #define CFIE(ch)     BIT((ch) * 2 + 1)
> #define CRIE(ch)     BIT((ch) * 2)

That works for me.

Maxime

-- 
Maxime Ripard, Bootlin (formerly Free Electrons)
Embedded Linux and Kernel engineering
https://bootlin.com

-- 
You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit https://groups.google.com/d/optout.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply

* Re: [PATCH] ARM64: dts: sun50i: a64: Add spi flash node for sopine
From: Maxime Ripard @ 2018-05-18  8:11 UTC (permalink / raw)
  To: Emmanuel Vadot
  Cc: wens, robh+dt, mark.rutland, catalin.marinas, will.deacon,
	linux-arm-kernel, devicetree, linux-kernel
In-Reply-To: <20180517150613.11916-1-manu@freebsd.org>

[-- Attachment #1: Type: text/plain, Size: 1145 bytes --]

Hi,

On Thu, May 17, 2018 at 05:06:13PM +0200, Emmanuel Vadot wrote:
> The Sopine and Pine64-LTS have a winbond w25q128 spi flash on spi0.
> Add a node for it.
> 
> Signed-off-by: Emmanuel Vadot <manu@freebsd.org>
> ---
>  arch/arm64/boot/dts/allwinner/sun50i-a64-sopine.dtsi | 12 ++++++++++++
>  1 file changed, 12 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine.dtsi
> index 43418bd881d8..3285aebc06d9 100644
> --- a/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine.dtsi
> +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine.dtsi
> @@ -66,6 +66,18 @@
>  	};
>  };
>  
> +&spi0  {
> +	status = "okay";
> +
> +	flash@0 {
> +		#address-cells = <1>;
> +		#size-cells = <1>;
> +		compatible = "w25q128", "jedec,spi-nor";

This applies to this patch and your previous Orange Pi PC2 one, but
the part name must have a vendor. Or you can drop it entirely if the
SPI-NOR driver can auto-detect it properly.

Maxime

-- 
Maxime Ripard, Bootlin (formerly Free Electrons)
Embedded Linux and Kernel engineering
https://bootlin.com

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply

* Re: [PATCH v3] ASoC: ssm2305: Add amplifier driver
From: Marco Felsch @ 2018-05-18  8:07 UTC (permalink / raw)
  To: Mark Brown
  Cc: mark.rutland, devicetree, alsa-devel, lars, lgirdwood, robh+dt,
	kernel
In-Reply-To: <20180517170826.GV20254@sirena.org.uk>

Dear Mark,

On 18-05-17 18:08, Mark Brown wrote:
> On Thu, May 17, 2018 at 03:55:18PM +0200, Marco Felsch wrote:
> 
> > +++ b/sound/soc/codecs/ssm2305.c
> > @@ -0,0 +1,104 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Analog Devices SSM2305 Amplifier Driver
> 
> Please submit a followup patch which makes the entire comment a C++ one
> rather than mixing them in the same comment block, it makes things look
> more intentional.

I'm a bit confused. As documented by the 
Documentation/process/license-rules.rst the license header should be a C++
comment but for all block comments the 'normal' coding style should be
applied. I can seperate the license header and the comment to make it
more intentional.

// SPDX-License-Identifier: GPL-2.0

/*
 * Analog Devices SSM2305 Amplifier Driver
 *
 * Copyright (C) 2018 Pengutronix, Marco Felsch <kernel@pengutronix.de>
 */

Is that better?

Marco

^ permalink raw reply

* Re: [PATCH 1/1] ARM:dts:sunxi: Add Olimex A20-SOM-EVB-eMMC board
From: Maxime Ripard @ 2018-05-18  8:03 UTC (permalink / raw)
  To: Stefan Mavrodiev
  Cc: Rob Herring, Mark Rutland, Chen-Yu Tsai,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	open list, moderated list:ARM/Allwinner sunXi SoC support,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw
In-Reply-To: <1526470689-6275-1-git-send-email-stefan-kyXcfZUBQGPQT0dZR+AlfA@public.gmane.org>

[-- Attachment #1: Type: text/plain, Size: 414 bytes --]

On Wed, May 16, 2018 at 02:38:08PM +0300, Stefan Mavrodiev wrote:
> With the new rev.E of A20-SOM-EVB, there is option for 16GB eMMC.
> Currently used card is KLMAG2GEND, wired to MMC2 slot.
> 
> Signed-off-by: Stefan Mavrodiev <stefan-kyXcfZUBQGPQT0dZR+AlfA@public.gmane.org>

Applied, thanks!

Maxime

-- 
Maxime Ripard, Bootlin (formerly Free Electrons)
Embedded Linux and Kernel engineering
https://bootlin.com

^ permalink raw reply

* Re: [PATCH 1/1] ARM:dts:sunxi: Add Olimex A20-SOM-EVB-eMMC board
From: Maxime Ripard @ 2018-05-18  8:02 UTC (permalink / raw)
  To: Stefan Mavrodiev
  Cc: Stefan Wahren, Rob Herring, Mark Rutland,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Chen-Yu Tsai,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw
In-Reply-To: <7ad11904-be61-a459-f2be-ff37fcd02402-kyXcfZUBQGPQT0dZR+AlfA@public.gmane.org>

[-- Attachment #1: Type: text/plain, Size: 2574 bytes --]

On Thu, May 17, 2018 at 10:34:06AM +0300, Stefan Mavrodiev wrote:
> On 05/17/2018 10:25 AM, Stefan Wahren wrote:
> > Hi Stefan,
> > 
> > > Stefan Mavrodiev <stefan-kyXcfZUBQGPQT0dZR+AlfA@public.gmane.org> hat am 16. Mai 2018 um 13:38 geschrieben:
> > > 
> > > 
> > > With the new rev.E of A20-SOM-EVB, there is option for 16GB eMMC.
> > > Currently used card is KLMAG2GEND, wired to MMC2 slot.
> > > 
> > > Signed-off-by: Stefan Mavrodiev <stefan-kyXcfZUBQGPQT0dZR+AlfA@public.gmane.org>
> > > ---
> > >   arch/arm/boot/dts/Makefile                         |  1 +
> > >   .../arm/boot/dts/sun7i-a20-olimex-som-evb-emmc.dts | 37 ++++++++++++++++++++++
> > >   2 files changed, 38 insertions(+)
> > >   create mode 100644 arch/arm/boot/dts/sun7i-a20-olimex-som-evb-emmc.dts
> > > 
> > > diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
> > > index 1db91ec..7f1ee65 100644
> > > --- a/arch/arm/boot/dts/Makefile
> > > +++ b/arch/arm/boot/dts/Makefile
> > > @@ -959,6 +959,7 @@ dtb-$(CONFIG_MACH_SUN7I) += \
> > >   	sun7i-a20-m3.dtb \
> > >   	sun7i-a20-mk808c.dtb \
> > >   	sun7i-a20-olimex-som-evb.dtb \
> > > +	sun7i-a20-olimex-som-evb-emmc.dtb \
> > >   	sun7i-a20-olimex-som204-evb.dtb \
> > >   	sun7i-a20-olimex-som204-evb-emmc.dtb \
> > >   	sun7i-a20-olinuxino-lime.dtb \
> > > diff --git a/arch/arm/boot/dts/sun7i-a20-olimex-som-evb-emmc.dts b/arch/arm/boot/dts/sun7i-a20-olimex-som-evb-emmc.dts
> > > new file mode 100644
> > > index 0000000..81ebc97
> > > --- /dev/null
> > > +++ b/arch/arm/boot/dts/sun7i-a20-olimex-som-evb-emmc.dts
> > > @@ -0,0 +1,37 @@
> > > +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> > > +/*
> > > + * Device Tree Source for A20-Olimex-SOM-EVB-eMMC Board
> > > + *
> > > + * Copyright (C) 2018 Olimex Ltd.
> > > + *   Author: Stefan Mavrodiev <stefan-kyXcfZUBQGPQT0dZR+AlfA@public.gmane.org>
> > > + */
> > > +
> > > +/dts-v1/;
> > > +#include "sun7i-a20-olimex-som-evb.dts"
> > > +
> > > +/ {
> > > +
> > > +	model = "Olimex A20-Olimex-SOM-EVB-eMMC";
> > > +	compatible = "olimex,a20-olimex-som-evb-emmc", "allwinner,sun7i-a20";
> > the file Documentation/devicetree/bindings/arm/olimex.txt seems to be out of date. I cannot find any recent board compatible.
> > 
> > Didn't checkpatch complain about it?
>
> Yes it did. I didn't get is seriously because neither Olimex A20 based board
> is documented in the binding.

I guess we should fix that as well, but that can come in a subsequent
patch.

Maxime

-- 
Maxime Ripard, Bootlin (formerly Free Electrons)
Embedded Linux and Kernel engineering
https://bootlin.com

^ permalink raw reply

* [PATCH v2] PM / devfreq: Add support for QCOM devfreq firmware
From: Saravana Kannan @ 2018-05-18  7:52 UTC (permalink / raw)
  To: MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Rob Herring,
	Mark Rutland
  Cc: Saravana Kannan, Rajendra Nayak, Amit Kucheria, linux-pm,
	devicetree, linux-kernel

The firmware present in some QCOM chipsets offloads the steps necessary for
changing the frequency of some devices (Eg: L3). This driver implements the
devfreq interface for this firmware so that various governors could be used
to scale the frequency of these devices.

Each client (say cluster 0 and cluster 1) that wants to vote for a
particular device's frequency (say, L3 frequency) is represented as a
separate voter device (qcom,devfreq-fw-voter) that's a child of the
firmware device (qcom,devfreq-fw).

Signed-off-by: Saravana Kannan <skannan@codeaurora.org>
---
 .../bindings/devfreq/devfreq-qcom-fw.txt           |  41 +++
 drivers/devfreq/Kconfig                            |  14 +
 drivers/devfreq/Makefile                           |   1 +
 drivers/devfreq/devfreq_qcom_fw.c                  | 330 +++++++++++++++++++++
 4 files changed, 386 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/devfreq/devfreq-qcom-fw.txt
 create mode 100644 drivers/devfreq/devfreq_qcom_fw.c

diff --git a/Documentation/devicetree/bindings/devfreq/devfreq-qcom-fw.txt b/Documentation/devicetree/bindings/devfreq/devfreq-qcom-fw.txt
new file mode 100644
index 0000000..f882a0b
--- /dev/null
+++ b/Documentation/devicetree/bindings/devfreq/devfreq-qcom-fw.txt
@@ -0,0 +1,41 @@
+QCOM Devfreq firmware device
+
+Some Qualcomm Technologies, Inc. (QTI) chipsets have a firmware that
+offloads the steps for frequency switching. It provides a table of
+supported frequencies and a register to request one of the supported
+freqencies.
+
+The qcom,devfreq-fw represents this firmware as a device. Sometimes,
+multiple entities want to vote on the frequency request that is sent to the
+firmware. The qcom,devfreq-fw-voter represents these voters as child
+devices of the corresponding qcom,devfreq-fw device.
+
+Required properties:
+- compatible:		Must be "qcom,devfreq-fw" or "qcom,devfreq-fw-voter"
+Only for qcom,devfreq-fw:
+- reg:			Pairs of physical base addresses and region sizes of
+			memory mapped registers.
+- reg-names:		Names of the bases for the above registers.
+			Required register regions are:
+			- "en-base": address of register to check if the
+			  firmware is enabled.
+			- "ftbl-base": address region for the frequency
+			  table.
+			- "perf-base": address of register to request a
+			  frequency.
+
+Example:
+
+	qcom,devfreq-l3 {
+		compatible = "qcom,devfreq-fw";
+		reg-names = "en-base", "ftbl-base", "perf-base";
+		reg = <0x18321000 0x4>, <0x18321110 0x600>, <0x18321920 0x4>;
+
+		qcom,cpu0-l3 {
+			compatible = "qcom,devfreq-fw-voter";
+		};
+
+		qcom,cpu4-l3 {
+			compatible = "qcom,devfreq-fw-voter";
+		};
+	};
diff --git a/drivers/devfreq/Kconfig b/drivers/devfreq/Kconfig
index 49fd170..5eeb33f 100644
--- a/drivers/devfreq/Kconfig
+++ b/drivers/devfreq/Kconfig
@@ -121,6 +121,20 @@ config ARM_RK3399_DMC_DEVFREQ
           It sets the frequency for the memory controller and reads the usage counts
           from hardware.
 
+config ARM_QCOM_DEVFREQ_FW
+	bool "Qualcomm Technologies Inc. DEVFREQ FW driver"
+	depends on ARCH_QCOM
+	select DEVFREQ_GOV_PERFORMANCE
+	select DEVFREQ_GOV_POWERSAVE
+	select DEVFREQ_GOV_USERSPACE
+	default n
+	help
+	  The firmware present in some QCOM chipsets offloads the steps
+	  necessary for changing the frequency of some devices (Eg: L3). This
+	  driver implements the devfreq interface for this firmware so that
+	  various governors could be used to scale the frequency of these
+	  devices.
+
 source "drivers/devfreq/event/Kconfig"
 
 endif # PM_DEVFREQ
diff --git a/drivers/devfreq/Makefile b/drivers/devfreq/Makefile
index 905f341..cafe7c2 100644
--- a/drivers/devfreq/Makefile
+++ b/drivers/devfreq/Makefile
@@ -12,6 +12,7 @@ obj-$(CONFIG_DEVFREQ_GOV_CPUFREQ)	+= governor_cpufreq.o
 obj-$(CONFIG_ARM_EXYNOS_BUS_DEVFREQ)	+= exynos-bus.o
 obj-$(CONFIG_ARM_RK3399_DMC_DEVFREQ)	+= rk3399_dmc.o
 obj-$(CONFIG_ARM_TEGRA_DEVFREQ)		+= tegra-devfreq.o
+obj-$(CONFIG_ARM_QCOM_DEVFREQ_FW)	+= devfreq_qcom_fw.o
 
 # DEVFREQ Event Drivers
 obj-$(CONFIG_PM_DEVFREQ_EVENT)		+= event/
diff --git a/drivers/devfreq/devfreq_qcom_fw.c b/drivers/devfreq/devfreq_qcom_fw.c
new file mode 100644
index 0000000..511758a
--- /dev/null
+++ b/drivers/devfreq/devfreq_qcom_fw.c
@@ -0,0 +1,330 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ */
+
+#include <linux/err.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/list.h>
+#include <linux/devfreq.h>
+#include <linux/pm_opp.h>
+
+#define INIT_HZ				300000000UL
+#define XO_HZ				19200000UL
+#define FTBL_MAX_ENTRIES		40U
+#define FTBL_ROW_SIZE			32
+
+#define SRC_MASK	GENMASK(31, 30)
+#define SRC_SHIFT	30
+#define MULT_MASK	GENMASK(7, 0)
+
+struct devfreq_qcom_fw {
+	void __iomem *perf_base;
+	struct devfreq_dev_profile dp;
+	struct list_head voters;
+	struct list_head voter;
+	unsigned int index;
+};
+
+static DEFINE_SPINLOCK(voter_lock);
+
+static int devfreq_qcom_fw_target(struct device *dev, unsigned long *freq,
+				  u32 flags)
+{
+	struct devfreq_qcom_fw *d = dev_get_drvdata(dev), *pd, *v;
+	struct devfreq_dev_profile *p = &d->dp;
+	unsigned int index;
+	unsigned long lflags;
+	struct dev_pm_opp *opp;
+	void __iomem *perf_base = d->perf_base;
+
+	opp = devfreq_recommended_opp(dev, freq, flags);
+	if (!IS_ERR(opp))
+		dev_pm_opp_put(opp);
+	else
+		return PTR_ERR(opp);
+
+	for (index = 0; index < p->max_state; index++)
+		if (p->freq_table[index] == *freq)
+			break;
+
+	if (index >= p->max_state) {
+		dev_err(dev, "Unable to find index for freq (%lu)!\n", *freq);
+		return -EINVAL;
+	}
+
+	d->index = index;
+
+	spin_lock_irqsave(&voter_lock, lflags);
+	/* Voter */
+	if (!perf_base) {
+		pd = dev_get_drvdata(dev->parent);
+		list_for_each_entry(v, &pd->voters, voter)
+			index = max(index, v->index);
+		perf_base = pd->perf_base;
+	}
+
+	writel_relaxed(index, perf_base);
+	spin_unlock_irqrestore(&voter_lock, lflags);
+
+	return 0;
+}
+
+static int devfreq_qcom_fw_get_cur_freq(struct device *dev,
+						 unsigned long *freq)
+{
+	struct devfreq_qcom_fw *d = dev_get_drvdata(dev);
+	struct devfreq_dev_profile *p = &d->dp;
+	unsigned int index;
+
+	/* Voter */
+	if (!d->perf_base) {
+		index = d->index;
+	} else {
+		index = readl_relaxed(d->perf_base);
+		index = min(index, p->max_state - 1);
+	}
+	*freq = p->freq_table[index];
+
+	return 0;
+}
+
+static int devfreq_qcom_populate_opp(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	u32 data, src, mult, i;
+	unsigned long freq, prev_freq;
+	struct resource *res;
+	void __iomem *lut_base;
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "lut-base");
+	if (!res) {
+		dev_err(dev, "Unable to find lut-base!\n");
+		return -EINVAL;
+	}
+
+	lut_base = devm_ioremap(dev, res->start, resource_size(res));
+	if (!lut_base) {
+		dev_err(dev, "Unable to map lut-base\n");
+		return -ENOMEM;
+	}
+
+	for (i = 0; i < FTBL_MAX_ENTRIES; i++) {
+		data = readl_relaxed(lut_base + i * FTBL_ROW_SIZE);
+		src = ((data & SRC_MASK) >> SRC_SHIFT);
+		mult = (data & MULT_MASK);
+		freq = src ? XO_HZ * mult : INIT_HZ;
+
+		/*
+		 * Two of the same frequencies with the same core counts means
+		 * end of table.
+		 */
+		if (i > 0 && prev_freq == freq)
+			break;
+
+		dev_pm_opp_add(&pdev->dev, freq, 0);
+
+		prev_freq = freq;
+	}
+
+	devm_iounmap(dev, lut_base);
+
+	return 0;
+}
+
+static int devfreq_qcom_init_hw(struct platform_device *pdev)
+{
+	struct devfreq_qcom_fw *d;
+	struct resource *res;
+	struct device *dev = &pdev->dev;
+	int ret = 0;
+	void __iomem *en_base;
+
+	d = devm_kzalloc(dev, sizeof(*d), GFP_KERNEL);
+	if (!d)
+		return -ENOMEM;
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "en-base");
+	if (!res) {
+		dev_err(dev, "Unable to find en-base!\n");
+		return -EINVAL;
+	}
+
+	en_base = devm_ioremap(dev, res->start, resource_size(res));
+	if (!en_base) {
+		dev_err(dev, "Unable to map en-base\n");
+		return -ENOMEM;
+	}
+
+	/* Firmware should be enabled state to proceed */
+	if (!(readl_relaxed(en_base) & 1)) {
+		dev_err(dev, "Firmware not enabled\n");
+		return -ENODEV;
+	}
+
+	devm_iounmap(dev, en_base);
+
+	ret = devfreq_qcom_populate_opp(pdev);
+	if (ret) {
+		dev_err(dev, "Failed to read FTBL\n");
+		return ret;
+	}
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "perf-base");
+	if (!res) {
+		dev_err(dev, "Unable to find perf-base!\n");
+		ret = -EINVAL;
+		goto out;
+	}
+
+	d->perf_base = devm_ioremap(dev, res->start, resource_size(res));
+	if (!d->perf_base) {
+		dev_err(dev, "Unable to map perf-base\n");
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	INIT_LIST_HEAD(&d->voters);
+	dev_set_drvdata(dev, d);
+
+out:
+	if (ret)
+		dev_pm_opp_remove_table(dev);
+	return ret;
+}
+
+static int devfreq_qcom_copy_opp(struct device *src_dev, struct device *dst_dev)
+{
+	unsigned long freq;
+	int i, cnt, ret = 0;
+	struct dev_pm_opp *opp;
+
+	if (!src_dev)
+		return -ENODEV;
+
+	cnt = dev_pm_opp_get_opp_count(src_dev);
+	if (!cnt)
+		return -EINVAL;
+
+	for (i = 0, freq = 0; i < cnt; i++, freq++) {
+		opp = dev_pm_opp_find_freq_ceil(src_dev, &freq);
+		if (IS_ERR(opp)) {
+			ret = -EINVAL;
+			break;
+		}
+		dev_pm_opp_put(opp);
+
+		ret = dev_pm_opp_add(dst_dev, freq, 0);
+		if (ret)
+			break;
+	}
+
+	if (ret)
+		dev_pm_opp_remove_table(dst_dev);
+	return ret;
+}
+
+static int devfreq_qcom_init_voter(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device *par_dev = dev->parent;
+	struct devfreq_qcom_fw *d, *pd = dev_get_drvdata(par_dev);
+	int ret = 0;
+
+	d = devm_kzalloc(dev, sizeof(*d), GFP_KERNEL);
+	if (!d)
+		return -ENOMEM;
+
+	ret = devfreq_qcom_copy_opp(dev->parent, dev);
+	if (ret) {
+		dev_err(dev, "Failed to copy parent OPPs\n");
+		return ret;
+	}
+
+	list_add(&d->voter, &pd->voters);
+	dev_set_drvdata(dev, d);
+
+	return 0;
+}
+
+static int devfreq_qcom_fw_driver_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	int ret = 0;
+	struct devfreq_qcom_fw *d;
+	struct devfreq_dev_profile *p;
+	struct devfreq *df;
+
+	if (!of_device_get_match_data(dev))
+		ret = devfreq_qcom_init_voter(pdev);
+	else
+		ret = devfreq_qcom_init_hw(pdev);
+	if (ret) {
+		dev_err(dev, "Unable to probe device!\n");
+		return ret;
+	}
+
+	/*
+	 * If device has voter children, do no register directly with devfreq
+	 */
+	if (of_get_available_child_count(dev->of_node)) {
+		of_platform_populate(dev->of_node, NULL, NULL, dev);
+		dev_info(dev, "Devfreq QCOM Firmware parent dev inited.\n");
+		return 0;
+	}
+
+	d = dev_get_drvdata(dev);
+	p = &d->dp;
+	p->polling_ms = 50;
+	p->target = devfreq_qcom_fw_target;
+	p->get_cur_freq = devfreq_qcom_fw_get_cur_freq;
+
+	df = devm_devfreq_add_device(dev, p, "performance", NULL);
+	if (IS_ERR(df)) {
+		dev_err(dev, "Unable to register Devfreq QCOM Firmware dev!\n");
+		return PTR_ERR(df);
+	}
+
+	dev_info(dev, "Devfreq QCOM Firmware dev registered.\n");
+
+	return 0;
+}
+
+static const struct of_device_id match_table[] = {
+	{ .compatible = "qcom,devfreq-fw", .data = (void *) 1 },
+	{ .compatible = "qcom,devfreq-fw-voter", .data = (void *) 0 },
+	{}
+};
+
+static struct platform_driver devfreq_qcom_fw_driver = {
+	.probe = devfreq_qcom_fw_driver_probe,
+	.driver = {
+		.name = "devfreq-qcom-fw",
+		.of_match_table = match_table,
+		.owner = THIS_MODULE,
+	},
+};
+
+static int __init devfreq_qcom_fw_init(void)
+{
+	return platform_driver_register(&devfreq_qcom_fw_driver);
+}
+subsys_initcall(devfreq_qcom_fw_init);
+
+static void __exit devfreq_qcom_fw_exit(void)
+{
+	platform_driver_unregister(&devfreq_qcom_fw_driver);
+}
+module_exit(devfreq_qcom_fw_exit);
+
+MODULE_DESCRIPTION("Devfreq QCOM Firmware");
+MODULE_LICENSE("GPL v2");
-- 
Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

^ permalink raw reply related

* Re: [PATCH 1/5] dt-bindings: pinctrl: document the STMFX pinctrl bindings
From: Amelie DELAUNAY @ 2018-05-18  7:29 UTC (permalink / raw)
  To: Lee Jones
  Cc: Mark Rutland, Rob Herring, Alexandre TORGUE,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Linus Walleij, Russell King, linux-kernel@vger.kernel.org,
	open list:GPIO SUBSYSTEM, Maxime Coquelin, Linux ARM
In-Reply-To: <20180517063640.GK5130@dell>

On 05/17/2018 08:36 AM, Lee Jones wrote:
> On Wed, 16 May 2018, Amelie DELAUNAY wrote:
> 
>>
>>
>> On 05/16/2018 04:20 PM, Linus Walleij wrote:
>>> On Wed, May 9, 2018 at 9:56 AM, Amelie DELAUNAY <amelie.delaunay@st.com> wrote:
>>>
>>>> Indeed, stmfx has other functions than GPIO. But, after comments done
>>>> here: [1] and there: [2], it has been decided to move MFD parent/GPIO
>>>> child drivers into a single PINCTRL/GPIO driver because of the following
>>>> reasons:
>>>> - Other stmfx functions (IDD measurement and TouchScreen controller) are
>>>> not used on any of the boards using an stmfx and supported by Linux, so
>>>> no way to test these functions, and no need to maintain them while they
>>>> are not being used.
>>>> - But, in the case a new board will use more than GPIO function on
>>>> stmfx, the actual implementation allow to easily extract common init
>>>> part of stmfx and put it in an MFD driver.
>>>>
>>>> So I could remove gpio sub-node and put its contents in stmfx node and
>>>> keep single PINCTRL/GPIO driver for the time being.
>>>> Please advise,
>>>
>>> I would normally advice to use the right modeling from the start, create
>>> the MFD driver and spawn the devices from there. It is confusing
>>> if the layout of the driver(s) doesn't really match the layout of the
>>> hardware.
>>>
>>> I understand that it is a pain to write new MFD drivers to get your
>>> things going and it would be "nice to get this working really quick
>>> now" but in my experience it is better to do it right from the start.
>>>
>>
>> Hi Linus,
>>
>> Thanks for your advice. I understand the point.
>> So, the right modeling would be to:
>> - create an MFD driver with the common init part of stmfx
>> - remove all common init part of stmfx-pinctrl driver and keep only all
>> gpio/pinctrl functions.
>>
>> I will not develop the other stmfx functions (IDD measurement driver and
>> TouchScreen controller driver) because, as explained ealier, they are
>> not used on any of the boards using an stmfx and supported by Linux, so
>> no way to test these functions, and no need to maintain them while they
>> are not being used.
>>
>> Lee, are you OK with that ?
> 
> I missed a lot of this conversation I think, but from what I've read,
> it sounds fine.
> 

I summarize the situation:
- I still don't have an official datasheet for STMFX device which could 
justify the use of an MFD driver;
- the MFD driver will contain the STMFX chip initialization stuff such 
as regmap initialization (regmap structure will be shared with the 
child), chip initialization, global interrupt management;
- there will be only one child (GPIO/PINCTRL node) for the time being.

So, is "MFD driver + GPIO/PINCTRL driver" the right modeling, and does 
it still sound fine after this summary ? :)

Thanks,
Amelie

^ permalink raw reply

* Re: [PATCH] PM / devfreq: Add support for QCOM devfreq FW
From: skannan @ 2018-05-18  7:16 UTC (permalink / raw)
  To: Chanwoo Choi
  Cc: MyungJoo Ham, Kyungmin Park, Rob Herring, Mark Rutland, linux-pm,
	devicetree, linux-kernel
In-Reply-To: <5AFE3A30.4040505@samsung.com>

On 2018-05-17 19:28, Chanwoo Choi wrote:
> Hi,
> 
> On 2018년 05월 17일 15:02, Saravana Kannan wrote:
>> The firmware present in some QCOM chipsets offloads the steps 
>> necessary for
>> changing the frequency of some devices (Eg: L3). This driver 
>> implements the
>> devfreq interface for this firmware so that various governors could be 
>> used
>> to scale the frequency of these devices.
> 
> The description doesn't include what kind of firmware. You have to 
> explain
> the type and role of firmware.

Not exactly sure what you mean. I described exactly what the firmware 
does. Not sure what you mean by what kind of firmware. I just understand 
the interface with it -- not the implementation of the firmware or 
hardware.

> And it doesn't contain the description
> of correlation
> between 'qcom,devfreq-fw' and 'qcom,devfreq-fw-voter'.
> 

Will do.

>> 
>> Signed-off-by: Saravana Kannan <skannan@codeaurora.org>
>> ---
>>  .../bindings/devfreq/devfreq-qcom-fw.txt           |  31 ++
>>  drivers/devfreq/Kconfig                            |  14 +
>>  drivers/devfreq/Makefile                           |   1 +
>>  drivers/devfreq/devfreq_qcom_fw.c                  | 326 
>> +++++++++++++++++++++
>>  4 files changed, 372 insertions(+)
>>  create mode 100644 
>> Documentation/devicetree/bindings/devfreq/devfreq-qcom-fw.txt
>>  create mode 100644 drivers/devfreq/devfreq_qcom_fw.c
>> 
>> diff --git 
>> a/Documentation/devicetree/bindings/devfreq/devfreq-qcom-fw.txt 
>> b/Documentation/devicetree/bindings/devfreq/devfreq-qcom-fw.txt
>> new file mode 100644
>> index 0000000..5e1aecf
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/devfreq/devfreq-qcom-fw.txt
>> @@ -0,0 +1,31 @@
>> +QCOM Devfreq FW device
>> +
>> +Some Qualcomm Technologies, Inc. (QTI) chipsets have a FW that 
>> offloads the
>> +child devices of the corresponding qcom,devfreq-fw device.
>> +
>> +Required properties:
>> +- compatible:		Must be "qcom,devfreq-fw" or "qcom,devfreq-fw-voter"
> 
> The use of 'devfreq' word is not proper because 'devfreq' is framework 
> name.
> I think you have to use the specific SoC name for the compatible.

I don't think it's mandatory to use chip name. Typically you pick the IP 
name. This IP is a firmware just for scaling device frequency - so 
called it qcom,devfreq-fw. I'll see what the DT maintainers say about 
this.

> In the future,
> if you need to support the new SoC with this driver, just you can add
> the new compatible.
> 
>> +Only for qcom,devfreq-fw:
>> +- reg:			Pairs of physical base addresses and region sizes of
>> +			memory mapped registers.
>> +- reg-names:		Names of the bases for the above registers. Expected
>> +			bases are: "en-base", "lut-base" and "perf-base".
> 
> It is not possible to understand what are meaning of "en-base",
> "lut-base" and "perf-base".
> because they depend on specific H/W specification. You have to add the
> detailed description
> why they are necessary. Also, you should explain whether thery are
> mandatory or optional.

The are all mandatory, that's why I didn't have the "Optional" heading. 
I can add descriptions.

> 
>> +
>> +Example:
>> +
>> +	qcom,devfreq-l3 {
>> +		compatible = "qcom,devfreq-fw";
>> +		reg-names = "en-base", "lut-base", "perf-base";
>> +		reg = <0x18321000 0x4>, <0x18321110 0x600>, <0x18321920 0x4>;
>> +
>> +		qcom,cpu0-l3 {
>> +			compatible = "qcom,devfreq-fw-voter";
>> +		};
>> +
>> +		qcom,cpu4-l3 {
>> +			compatible = "qcom,devfreq-fw-voter";
>> +		};
>> +	};
>> diff --git a/drivers/devfreq/Kconfig b/drivers/devfreq/Kconfig
>> index 6a172d3..8503018 100644
>> --- a/drivers/devfreq/Kconfig
>> +++ b/drivers/devfreq/Kconfig
>> @@ -113,6 +113,20 @@ config ARM_RK3399_DMC_DEVFREQ
>>            It sets the frequency for the memory controller and reads 
>> the usage counts
>>            from hardware.
>> 
>> +config ARM_QCOM_DEVFREQ_FW
>> +	bool "Qualcomm Technologies Inc. DEVFREQ FW driver"
>> +	depends on ARCH_QCOM
>> +	select DEVFREQ_GOV_PERFORMANCE
>> +	select DEVFREQ_GOV_POWERSAVE
>> +	select DEVFREQ_GOV_USERSPACE
>> +	default n
>> +	help
>> +	  The firmware present in some QCOM chipsets offloads the steps
>> +	  necessary for changing the frequency of some devices (Eg: L3). 
>> This
>> +	  driver implements the devfreq interface for this firmware so that
>> +	  various governors could be used to scale the frequency of these
>> +	  devices.
> 
> As I commented, you need to add a description of what kind of firmwar.

Again, not sure what you mean by "what kind of firmware". It's exactly 
what I've described here. Can you please elaborate?

>> +
>>  source "drivers/devfreq/event/Kconfig"
>> 
>>  endif # PM_DEVFREQ
>> diff --git a/drivers/devfreq/Makefile b/drivers/devfreq/Makefile
>> index 32b8d4d..f1cc8990 100644
>> --- a/drivers/devfreq/Makefile
>> +++ b/drivers/devfreq/Makefile
>> @@ -11,6 +11,7 @@ obj-$(CONFIG_DEVFREQ_GOV_PASSIVE)	+= 
>> governor_passive.o
>>  obj-$(CONFIG_ARM_EXYNOS_BUS_DEVFREQ)	+= exynos-bus.o
>>  obj-$(CONFIG_ARM_RK3399_DMC_DEVFREQ)	+= rk3399_dmc.o
>>  obj-$(CONFIG_ARM_TEGRA_DEVFREQ)		+= tegra-devfreq.o
>> +obj-$(CONFIG_ARM_QCOM_DEVFREQ_FW)	+= devfreq_qcom_fw.o
>> 
>>  # DEVFREQ Event Drivers
>>  obj-$(CONFIG_PM_DEVFREQ_EVENT)		+= event/
>> diff --git a/drivers/devfreq/devfreq_qcom_fw.c 
>> b/drivers/devfreq/devfreq_qcom_fw.c
>> new file mode 100644
>> index 0000000..3e85f76
>> --- /dev/null
>> +++ b/drivers/devfreq/devfreq_qcom_fw.c
>> @@ -0,0 +1,326 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +/*
>> + * Copyright (c) 2018, The Linux Foundation. All rights reserved.
> 
> Is it right? or Qualcomm?

Yup, it's right.

> 
>> + */
>> +
>> +#include <linux/err.h>
>> +#include <linux/errno.h>
>> +#include <linux/init.h>
>> +#include <linux/io.h>
>> +#include <linux/kernel.h>
>> +#include <linux/module.h>
>> +#include <linux/of.h>
>> +#include <linux/of_address.h>
>> +#include <linux/of_platform.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/slab.h>
>> +#include <linux/list.h>
>> +#include <linux/devfreq.h>
>> +#include <linux/pm_opp.h>
>> +
>> +#define INIT_RATE			300000000UL
>> +#define XO_RATE				19200000UL
>> +#define LUT_MAX_ENTRIES			40U
>> +#define LUT_ROW_SIZE			32
> 
> I don't know what are the meaning of 'XO', 'LUT'.

XO is a very common term for crystal oscillator. I don't want to change 
these symbols.
LUT stands for Look up table. But I can rename it to FREQ_TBL_.

Thanks,
Saravana

^ permalink raw reply

* Re: [PATCH v4 3/3] ARM: dts: sun7i: Add support for the Ainol AW1 tablet
From: Maxime Ripard @ 2018-05-18  7:14 UTC (permalink / raw)
  To: Paul Kocialkowski
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Rob Herring, Mark Rutland,
	Chen-Yu Tsai, Thierry Reding, David Airlie
In-Reply-To: <0da5787f0ce2309a74db88820bc58b3b3501c451.camel-W9ppeneeCTY@public.gmane.org>

[-- Attachment #1: Type: text/plain, Size: 2936 bytes --]

On Mon, May 14, 2018 at 10:36:08PM +0200, Paul Kocialkowski wrote:
> > > +	backlight: backlight {
> > > +		compatible = "pwm-backlight";
> > > +		pwms = <&pwm 0 50000 PWM_POLARITY_INVERTED>;
> > > +		brightness-levels = <  0   1   1   1   1   2   2   2
> > > +				       2   3   3   3   3   4   4   4
> > > +				       5   5   5   6   6   6   7   7
> > > +				       8   8   8   9   9   9  10  10
> > > +				      10  11  11  12  12  12  13  13
> > > +				      14  14  14  15  15  16  16  17
> > > +				      17  17  18  18  19  19  20  20
> > > +				      21  21  21  22  22  23  23  24
> > > +				      24  25  25  26  26  27  27  28
> > > +				      28  29  30  30  31  31  32  32
> > > +				      33  33  34  35  35  36  36  37
> > > +				      38  38  39  39  40  41  41  42
> > > +				      43  43  44  44  45  46  47  47
> > > +				      48  49  49  50  51  51  52  53
> > > +				      54  54  55  56  57  57  58  59
> > > +				      60  61  61  62  63  64  65  65
> > > +				      66  67  68  69  70  71  71  72
> > > +				      73  74  75  76  77  78  79  80
> > > +				      81  82  83  84  85  86  87  88
> > > +				      89  90  91  92  93  94  95  96
> > > +				      97  98  99 101 102 103 104 105
> > > +				     106 108 109 110 111 112 114 115
> > > +				     116 117 119 120 121 123 124 125
> > > +				     127 128 129 131 132 133 135 136
> > > +				     138 139 141 142 144 145 147 148
> > > +				     150 151 153 154 156 157 159 161
> > > +				     162 164 166 167 169 171 173 174
> > > +				     176 178 180 181 183 185 187 189
> > > +				     191 192 194 196 198 200 202 204
> > > +				     206 208 210 212 214 216 219 221
> > > +				     223 225 227 229 232 234 236 238
> > > +				     241 242 244 246 248 250 253 255>;
> > 
> > You kind of overdid it here :)
> > 
> > What I meant to say before was that if you have 10 elements (and you
> > really should have something in that magnitude) each step should
> > increase the perceived brightness by 10%.
> 
> Mhh I think 10 elements would fall too short to really depict the curve
> with appropriate precision. Given the usual size for brightness cursors
> in e.g. gnome-shell, it feels like a bigger number would be more
> appropriate. Let's make it to 100 with values from 0 to 255!
> 
> > In this particular case, I really think having something close to <0 4
> > 8 16 32 64 128 255> would be enough.
> > 
> > And in general, that kind of odd looking table without any more
> > context is just screaming for a comment :)
> 
> Noted, I will explain the idea, but probably without the exact formula
> that's really a nasty hack written down on a piece of paper sitting in
> my garbage at this point.

So no one will ever be able to understand where this sequence comes
from (yourself-in-two-years included). That sounds like a pretty bad
idea.

Maxime

-- 
Maxime Ripard, Bootlin (formerly Free Electrons)
Embedded Linux and Kernel engineering
https://bootlin.com

^ permalink raw reply

* Re: [PATCH v4 06/12] media: dt-bindings: add bindings for i.MX7 media driver
From: Sakari Ailus @ 2018-05-18  6:58 UTC (permalink / raw)
  To: Rui Miguel Silva
  Cc: devel, devicetree, sakari.ailus, Greg Kroah-Hartman, Ryan Harkin,
	Rob Herring, Philipp Zabel, Steve Longerbeam, Fabio Estevam,
	mchehab, Shawn Guo, linux-media
In-Reply-To: <20180517125033.18050-7-rui.silva@linaro.org>

Hi Rui,

On Thu, May 17, 2018 at 01:50:27PM +0100, Rui Miguel Silva wrote:
> Add bindings documentation for i.MX7 media drivers.
> 
> Signed-off-by: Rui Miguel Silva <rui.silva@linaro.org>
> ---
>  .../devicetree/bindings/media/imx7.txt        | 145 ++++++++++++++++++
>  1 file changed, 145 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/media/imx7.txt
> 
> diff --git a/Documentation/devicetree/bindings/media/imx7.txt b/Documentation/devicetree/bindings/media/imx7.txt
> new file mode 100644
> index 000000000000..161cff8e6442
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/media/imx7.txt
> @@ -0,0 +1,145 @@
> +Freescale i.MX7 Media Video Device
> +==================================
> +
> +Video Media Controller node
> +---------------------------

Note that DT bindings document the hardware, they are as such not Linux
dependent.

> +
> +This is the media controller node for video capture support. It is a
> +virtual device that lists the camera serial interface nodes that the
> +media device will control.

Ditto.

> +
> +Required properties:
> +- compatible : "fsl,imx7-capture-subsystem";
> +- ports      : Should contain a list of phandles pointing to camera
> +		sensor interface port of CSI
> +
> +example:
> +
> +capture-subsystem {

What's the purpose of this node, if you only refer to another device? This
one rather does not look like a real device at all.

> +	compatible = "fsl,imx7-capture-subsystem";
> +	ports = <&csi>;
> +};
> +
> +
> +mipi_csi2 node
> +--------------
> +
> +This is the device node for the MIPI CSI-2 receiver core in i.MX7 SoC. It is
> +compatible with previous version of Samsung D-phy.
> +
> +Required properties:
> +
> +- compatible    : "fsl,imx7-mipi-csi2";
> +- reg           : base address and length of the register set for the device;
> +- interrupts    : should contain MIPI CSIS interrupt;
> +- clocks        : list of clock specifiers, see
> +        Documentation/devicetree/bindings/clock/clock-bindings.txt for details;
> +- clock-names   : must contain "pclk", "wrap" and "phy" entries, matching
> +                  entries in the clock property;
> +- power-domains : a phandle to the power domain, see
> +          Documentation/devicetree/bindings/power/power_domain.txt for details.
> +- reset-names   : should include following entry "mrst";
> +- resets        : a list of phandle, should contain reset entry of
> +                  reset-names;
> +- phy-supply    : from the generic phy bindings, a phandle to a regulator that
> +	          provides power to MIPI CSIS core;
> +- bus-width     : maximum number of data lanes supported (SoC specific);
> +
> +Optional properties:
> +
> +- clock-frequency : The IP's main (system bus) clock frequency in Hz, default
> +		    value when this property is not specified is 166 MHz;
> +
> +port node
> +---------
> +
> +- reg		  : (required) can take the values 0 or 1, where 0 is the
> +                     related sink port and port 1 should be the source one;
> +
> +endpoint node
> +-------------
> +
> +- data-lanes    : (required) an array specifying active physical MIPI-CSI2
> +		    data input lanes and their mapping to logical lanes; the
> +		    array's content is unused, only its length is meaningful;
> +
> +- fsl,csis-hs-settle : (optional) differential receiver (HS-RX) settle time;

Could you calculate this, as other drivers do? It probably changes
depending on the device runtime configuration.

> +
> +example:
> +
> +        mipi_csi: mipi-csi@30750000 {
> +                #address-cells = <1>;
> +                #size-cells = <0>;
> +
> +                compatible = "fsl,imx7-mipi-csi2";
> +                reg = <0x30750000 0x10000>;
> +                interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
> +                clocks = <&clks IMX7D_IPG_ROOT_CLK>,
> +                                <&clks IMX7D_MIPI_CSI_ROOT_CLK>,
> +                                <&clks IMX7D_MIPI_DPHY_ROOT_CLK>;
> +                clock-names = "pclk", "wrap", "phy";
> +                clock-names = "mipi", "phy";
> +                clock-frequency = <166000000>;
> +                power-domains = <&pgc_mipi_phy>;
> +                phy-supply = <&reg_1p0d>;
> +                resets = <&src IMX7_RESET_MIPI_PHY_MRST>;
> +                reset-names = "mrst";
> +                bus-width = <4>;
> +                fsl,csis-hs-settle = <3>;
> +                fsl,csis-clk-settle = <0>;
> +
> +                port@0 {
> +                        reg = <0>;
> +
> +                        mipi_from_sensor: endpoint {
> +                                remote-endpoint = <&ov2680_to_mipi>;
> +                                data-lanes = <1>;
> +                        };
> +                };
> +
> +                port@1 {
> +                        reg = <1>;
> +
> +                        mipi_vc0_to_csi_mux: endpoint {
> +                                remote-endpoint = <&csi_mux_from_mipi_vc0>;
> +                        };
> +                };
> +        };
> +
> +
> +csi node
> +--------
> +
> +This is device node for the CMOS Sensor Interface (CSI) which enables the chip
> +to connect directly to external CMOS image sensors.
> +
> +Required properties:
> +
> +- compatible    : "fsl,imx7-csi";
> +- reg           : base address and length of the register set for the device;
> +- interrupts    : should contain CSI interrupt;
> +- clocks        : list of clock specifiers, see
> +        Documentation/devicetree/bindings/clock/clock-bindings.txt for details;
> +- clock-names   : must contain "axi", "mclk" and "dcic" entries, matching
> +                 entries in the clock property;
> +
> +example:
> +
> +                csi: csi@30710000 {
> +                        #address-cells = <1>;
> +                        #size-cells = <0>;
> +
> +                        compatible = "fsl,imx7-csi";
> +                        reg = <0x30710000 0x10000>;
> +                        interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
> +                        clocks = <&clks IMX7D_CLK_DUMMY>,
> +                                        <&clks IMX7D_CSI_MCLK_ROOT_CLK>,
> +                                        <&clks IMX7D_CLK_DUMMY>;
> +                        clock-names = "axi", "mclk", "dcic";
> +
> +                        port {
> +                                csi_from_csi_mux: endpoint {
> +                                        remote-endpoint = <&csi_mux_to_csi>;
> +                                };
> +                        };
> +                };

-- 
Regards,

Sakari Ailus
e-mail: sakari.ailus@iki.fi

^ permalink raw reply

* Re: [PATCH 1/2] dt-bindings: power: Add ZynqMP power domain bindings
From: Marek Szyprowski @ 2018-05-18  6:30 UTC (permalink / raw)
  To: Jolly Shah, Geert Uytterhoeven, Rob Herring
  Cc: Matthias Brugger, Andy Gross, Shawn Guo, Geert Uytterhoeven,
	Björn Andersson, sean.wang@mediatek.com, Michal Simek,
	Mark Rutland, Rajan Vaja,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Linux ARM, Linux Kernel Mailing List
In-Reply-To: <SN1PR02MB37588BFF357865F4C9628D99B8910@SN1PR02MB3758.namprd02.prod.outlook.com>

Hi Jolly,

On 2018-05-17 23:10, Jolly Shah wrote:

>>>>>> +Example:
>>>>>> +     zynqmp-genpd {
>>>>>> +             compatible = "xlnx,zynqmp-genpd";
>>>>> What's the control interface for controlling the domains?
>>>>>> +
>>>>>> +             pd_usb0: pd-usb0 {
>>>>>> +                     pd-id = <22>;
>>>>>> +                     #power-domain-cells = <0>;
>>>>> There's no need for all these sub nodes. Make #power-domain-cells 1
>>>>> and put the id in the cell value.
>>>> That was my first reaction, too...
>>>>>> +             };
>>>>>> +
>>>>>> +             pd_sata: pd-sata {
>>>>>> +                     pd-id = <28>;
>>>>>> +                     #power-domain-cells = <0>;
>>>>>> +             };
>>>>>> +
>>>>>> +             pd_gpu: pd-gpu {
>>>>>> +                     pd-id = <58 20 21>;
>>>> ... until I saw the above.
>>>> Controlling the GPU power area requires controlling 3 physical areas?
>>>>
>>>> However, doing it this way may bite you in the future, if a need
>>>> arises to control a subset. And what about power up/down order?
>>> What about defining 3 separate domains and arranging them in
>>> parent-child relationship? generic power domains already supports that
>>> and this allows to nicely define the power on/off order.
>>>
>>>>>> +                     #power-domain-cells = <0x0>;
>>>>>> +             };
>>>>>> +     };
>> I agree it should be arranged in as parent child order to control subset or control
>> order. Will incorporate those changes in next version.
>
> As suggested, I tried out parent, child approach. However what I found is Genpd core takes care of parent child dependencies for power on off routines only. In our case, We need them in attach-detach routines too. In that case, we need to handle dependencies manually for those routines. Please suggest better approach, if any.

What do you mean to handle attach-detach?

Best regards
-- 
Marek Szyprowski, PhD
Samsung R&D Institute Poland

^ permalink raw reply

* [PATCH v3 3/3] arm64: dts: qcom: msm8996: Add ufs related nodes
From: Bjorn Andersson @ 2018-05-18  6:26 UTC (permalink / raw)
  To: Andy Gross, David Brown
  Cc: Mark Rutland, devicetree, Catalin Marinas, Will Deacon,
	linux-kernel, Rob Herring, linux-arm-msm, linux-soc,
	linux-arm-kernel
In-Reply-To: <20180518062638.31777-1-bjorn.andersson@linaro.org>

Add the UFS QMP phy node and the UFS host controller node, now that we
have working UFS and the necessary clocks in place.

Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
---
 arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi |  8 ++
 arch/arm64/boot/dts/qcom/msm8996.dtsi        | 85 ++++++++++++++++++++
 2 files changed, 93 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi b/arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi
index 8be666ea92bd..00e3ecd1180a 100644
--- a/arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi
+++ b/arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi
@@ -122,6 +122,14 @@
 			status = "okay";
 		};
 
+		phy@627000 {
+			status = "okay";
+		};
+
+		ufshc@624000 {
+			status = "okay";
+		};
+
 		phy@34000 {
 			status = "okay";
 		};
diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi b/arch/arm64/boot/dts/qcom/msm8996.dtsi
index 37b7152cb064..221bb3d383c5 100644
--- a/arch/arm64/boot/dts/qcom/msm8996.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi
@@ -633,6 +633,91 @@
 			#interrupt-cells = <4>;
 		};
 
+		ufsphy: phy@627000 {
+			compatible = "qcom,msm8996-ufs-phy-qmp-14nm";
+			reg = <0x627000 0xda8>;
+			reg-names = "phy_mem";
+			#phy-cells = <0>;
+
+			vdda-phy-supply = <&pm8994_l28>;
+			vdda-pll-supply = <&pm8994_l12>;
+
+			vdda-phy-max-microamp = <18380>;
+			vdda-pll-max-microamp = <9440>;
+
+			vddp-ref-clk-supply = <&pm8994_l25>;
+			vddp-ref-clk-max-microamp = <100>;
+			vddp-ref-clk-always-on;
+
+			clock-names = "ref_clk_src", "ref_clk";
+			clocks = <&rpmcc RPM_SMD_LN_BB_CLK>,
+				 <&gcc GCC_UFS_CLKREF_CLK>;
+			status = "disabled";
+
+			power-domains = <&gcc UFS_GDSC>;
+		};
+
+		ufshc@624000 {
+			compatible = "qcom,ufshc";
+			reg = <0x624000 0x2500>;
+			interrupts = <GIC_SPI 265 IRQ_TYPE_LEVEL_HIGH>;
+
+			phys = <&ufsphy>;
+			phy-names = "ufsphy";
+
+			vcc-supply = <&pm8994_l20>;
+			vccq-supply = <&pm8994_l25>;
+			vccq2-supply = <&pm8994_s4>;
+
+			vcc-max-microamp = <600000>;
+			vccq-max-microamp = <450000>;
+			vccq2-max-microamp = <450000>;
+
+			clock-names =
+				"core_clk_src",
+				"core_clk",
+				"bus_clk",
+				"bus_aggr_clk",
+				"iface_clk",
+				"core_clk_unipro_src",
+				"core_clk_unipro",
+				"core_clk_ice",
+				"ref_clk",
+				"tx_lane0_sync_clk",
+				"rx_lane0_sync_clk";
+			clocks =
+				<&gcc UFS_AXI_CLK_SRC>,
+				<&gcc GCC_UFS_AXI_CLK>,
+				<&gcc GCC_SYS_NOC_UFS_AXI_CLK>,
+				<&gcc GCC_AGGRE2_UFS_AXI_CLK>,
+				<&gcc GCC_UFS_AHB_CLK>,
+				<&gcc UFS_ICE_CORE_CLK_SRC>,
+				<&gcc GCC_UFS_UNIPRO_CORE_CLK>,
+				<&gcc GCC_UFS_ICE_CORE_CLK>,
+				<&rpmcc RPM_SMD_LN_BB_CLK>,
+				<&gcc GCC_UFS_TX_SYMBOL_0_CLK>,
+				<&gcc GCC_UFS_RX_SYMBOL_0_CLK>;
+			freq-table-hz =
+				<100000000 200000000>,
+				<0 0>,
+				<0 0>,
+				<0 0>,
+				<0 0>,
+				<150000000 300000000>,
+				<0 0>,
+				<0 0>,
+				<0 0>,
+				<0 0>,
+				<0 0>;
+
+			lanes-per-direction = <1>;
+			status = "disabled";
+
+			ufs_variant {
+				compatible = "qcom,ufs_variant";
+			};
+		};
+
 		mmcc: clock-controller@8c0000 {
 			compatible = "qcom,mmcc-msm8996";
 			#clock-cells = <1>;
-- 
2.17.0

^ permalink raw reply related

* Re: [PATCH v10 25/27] ARM: davinci: add device tree support to timer
From: Sekhar Nori @ 2018-05-18  6:05 UTC (permalink / raw)
  To: David Lechner, linux-clk, devicetree, linux-arm-kernel
  Cc: Michael Turquette, Stephen Boyd, Rob Herring, Mark Rutland,
	Kevin Hilman, Bartosz Golaszewski, Adam Ford, linux-kernel
In-Reply-To: <1162de58-00bc-fdfa-eef1-48a094834ac3@lechnology.com>

On Thursday 17 May 2018 08:39 PM, David Lechner wrote:
> On 05/17/2018 09:35 AM, Sekhar Nori wrote:
>> Hi David,
>>
>> On Wednesday 09 May 2018 10:56 PM, David Lechner wrote:
>>> This adds device tree support to the davinci timer so that when clocks
>>> are moved to device tree, the timer will still work.
>>>
>>> Signed-off-by: David Lechner <david@lechnology.com>
>>> ---
>>
>>> +static int __init of_davinci_timer_init(struct device_node *np)
>>> +{
>>> +    struct clk *clk;
>>> +
>>> +    clk = of_clk_get(np, 0);
>>> +    if (IS_ERR(clk)) {
>>> +        struct of_phandle_args clkspec;
>>> +
>>> +        /*
>>> +         * Fall back to using ref_clk if the actual clock is not
>>> +         * available. There will be problems later if the real clock
>>> +         * source is disabled.
>>> +         */
>>> +
>>> +        pr_warn("%s: falling back to ref_clk\n", __func__);
>>> +
>>> +        clkspec.np = of_find_node_by_name(NULL, "ref_clk");
>>> +        if (IS_ERR(clkspec.np)) {
>>> +            pr_err("%s: No clock available for timer!\n", __func__);
>>> +            return PTR_ERR(clkspec.np);
>>> +        }
>>> +        clk = of_clk_get_from_provider(&clkspec);
>>> +        of_node_put(clkspec.np);
>>> +    }
>>
>> Do we need this error path now?
>>
>> Thanks,
>> Sekhar
>>
> 
> No, not really.

Then lets just print an error and return the error number.

Thanks,
Sekhar

^ permalink raw reply

* Re: [v4 2/6] dmaengine: fsl-qdma: Add qDMA controller driver for Layerscape SoCs
From: Vinod @ 2018-05-18  4:21 UTC (permalink / raw)
  To: Wen He
  Cc: dmaengine@vger.kernel.org, robh+dt@kernel.org,
	devicetree@vger.kernel.org, Leo Li, Jiafei Pan, Jiaheng Fan
In-Reply-To: <DB6PR0401MB2503E7EEB3C97028AD131C7CE2910@DB6PR0401MB2503.eurprd04.prod.outlook.com>

On 17-05-18, 11:27, Wen He wrote:
> > > +
> > > +/* Registers for bit and genmask */
> > > +#define FSL_QDMA_CQIDR_SQT		0x8000
> > 
> > BIT() ?
> 
> Sorry, Maybe I should replace 0x8000 to BIT(15).

yes please

> > > +u64 pre_addr, pre_queue;
> > 
> > why do we have a global?
> 
> Let's us see qDMA that how is works?
> 
> First, the status notification for DMA jobs are reported back to the status queue.
> Status information is carried within the command descriptor status/command field,
> bits 120-127. The command descriptor dequeue pointer advances only after the
> transaction has completed and the status information field has been updated.
> 
> Then, the command descriptor address field wiil pointer to the command descriptor in
> its original format. It is the responsibity of the address of the status queue consumer
> to deallocate buffers as needed when the command descriptor address pointer is non-zero.
> 
> More details of the Status Queue can be found in QorIQ Layerscape Soc datasheet.
> 
> So, these variable is used to record latest value that command descriptor queue
> and status field.
> 
> Every time variables value is zero when set these variable to local, that's not what I want.

Why not store them in driver context?

> > > +static void fsl_qdma_comp_fill_memcpy(struct fsl_qdma_comp *fsl_comp,
> > > +					dma_addr_t dst, dma_addr_t src, u32 len) {
> > > +	struct fsl_qdma_format *ccdf, *csgf_desc, *csgf_src, *csgf_dest;
> > > +	struct fsl_qdma_sdf *sdf;
> > > +	struct fsl_qdma_ddf *ddf;
> > > +
> > > +	ccdf = (struct fsl_qdma_format *)fsl_comp->virt_addr;
> > 
> > Cast are not required to/away from void
> > 
> 
> Does means: remove force conver?

yes and it would work

> > > +static struct fsl_qdma_comp *fsl_qdma_request_enqueue_desc(
> > > +					struct fsl_qdma_chan *fsl_chan,
> > > +					unsigned int dst_nents,
> > > +					unsigned int src_nents)
> > > +{
> > > +	struct fsl_qdma_comp *comp_temp;
> > > +	struct fsl_qdma_sg *sg_block;
> > > +	struct fsl_qdma_queue *queue = fsl_chan->queue;
> > > +	unsigned long flags;
> > > +	unsigned int dst_sg_entry_block, src_sg_entry_block, sg_entry_total,
> > > +i;
> > > +
> > > +	spin_lock_irqsave(&queue->queue_lock, flags);
> > > +	if (list_empty(&queue->comp_free)) {
> > > +		spin_unlock_irqrestore(&queue->queue_lock, flags);
> > > +		comp_temp = kzalloc(sizeof(*comp_temp), GFP_KERNEL);
> > > +		if (!comp_temp)
> > > +			return NULL;
> > > +		comp_temp->virt_addr = dma_pool_alloc(queue->comp_pool,
> > > +						      GFP_KERNEL,
> > > +						      &comp_temp->bus_addr);
> > > +		if (!comp_temp->virt_addr) {
> > > +			kfree(comp_temp);
> > > +			return NULL;
> > > +		}
> > > +
> > > +	} else {
> > > +		comp_temp = list_first_entry(&queue->comp_free,
> > > +					     struct fsl_qdma_comp,
> > > +					     list);
> > > +		list_del(&comp_temp->list);
> > > +		spin_unlock_irqrestore(&queue->queue_lock, flags);
> > > +	}
> > > +
> > > +	if (dst_nents != 0)
> > > +		dst_sg_entry_block = dst_nents /
> > > +					(FSL_QDMA_EXPECT_SG_ENTRY_NUM - 1) + 1;
> > 
> > DIV_ROUND_UP()?
> > 
> 
> The DIV_ROUND_UP() definition see below:
> 
> #define DIV_ROUND_UP __KERNEL_DIV_ROUND_UP
> #define __KERNEL_DIV_ROUND_UP(n ,d) (((n) + (d) - 1) / (d))
> 
> But here is 'd / (n - 1) + 1' ?

Yeah this doesn't look apt here, check if any other macros suits...

> > > +			memset(sg_block->virt_addr, 0,
> > > +					FSL_QDMA_EXPECT_SG_ENTRY_NUM * 16);
> > 
> > why FSL_QDMA_EXPECT_SG_ENTRY_NUM * 16? and not what you
> > allocated?
> > 
> 
> see line 497.
> The sg_pool buffer size created is FSL_QDMA_EXPECT_SG_ENTRY_NUM * 16.

Please document this

> > > +static int fsl_qdma_queue_transfer_complete(struct fsl_qdma_engine
> > > +*fsl_qdma) {
> > > +	struct fsl_qdma_queue *fsl_queue = fsl_qdma->queue;
> > > +	struct fsl_qdma_queue *fsl_status = fsl_qdma->status;
> > > +	struct fsl_qdma_queue *temp_queue;
> > > +	struct fsl_qdma_comp *fsl_comp;
> > > +	struct fsl_qdma_format *status_addr;
> > > +	struct fsl_qdma_format *csgf_src;
> > > +	void __iomem *block = fsl_qdma->block_base;
> > > +	u32 reg, i;
> > > +	bool duplicate, duplicate_handle;
> > > +
> > > +	while (1) {
> > > +		duplicate = 0;
> > > +		duplicate_handle = 0;
> > > +		reg = qdma_readl(fsl_qdma, block + FSL_QDMA_BSQSR);
> > > +		if (reg & FSL_QDMA_BSQSR_QE)
> > > +			return 0;
> > > +		status_addr = fsl_status->virt_head;
> > > +		if (qdma_ccdf_get_queue(status_addr) == pre_queue &&
> > > +			qdma_ccdf_addr_get64(status_addr) == pre_addr)
> > > +			duplicate = 1;
> > > +		i = qdma_ccdf_get_queue(status_addr);
> > > +		pre_queue = qdma_ccdf_get_queue(status_addr);
> > > +		pre_addr = qdma_ccdf_addr_get64(status_addr);
> > > +		temp_queue = fsl_queue + i;
> > > +		spin_lock(&temp_queue->queue_lock);
> > > +		if (list_empty(&temp_queue->comp_used)) {
> > > +			if (duplicate)
> > > +				duplicate_handle = 1;
> > > +			else {
> > > +				spin_unlock(&temp_queue->queue_lock);
> > > +				return -1;
> > 
> > -1? really. You are in while(1) wouldn't break make sense here?
> > 
> 
> Does means: using break?

it means two things, we don't use return -1, if it is valid error then return
a proper kernel error code
second, since it is a while loop, do you want to use a break?
 
-- 
~Vinod

^ permalink raw reply

* Re: [PATCH 2/2] dmaengine: rcar-dmac: Document R8A77990 bindings
From: Vinod Koul @ 2018-05-18  4:08 UTC (permalink / raw)
  To: Ulrich Hecht
  Cc: linux-renesas-soc, horms, dmaengine, devicetree,
	Hiroyuki Yokoyama
In-Reply-To: <1526475979-13891-2-git-send-email-ulrich.hecht+renesas@gmail.com>

On 16-05-18, 15:06, Ulrich Hecht wrote:
> From: Hiroyuki Yokoyama <hiroyuki.yokoyama.vx@renesas.com>
> 
> Renesas R-Car E3 (R8A77990) SoC also has the R-Car gen2/3 compatible DMA
> controllers, so document the SoC specific binding.

This fails to apply for me, please rebase and send

-- 
~Vinod

^ permalink raw reply

* Re: [PATCH 1/2] dmaengine: usb-dmac: Document R8A7799{0,5} bindings
From: Vinod Koul @ 2018-05-18  4:06 UTC (permalink / raw)
  To: Ulrich Hecht
  Cc: linux-renesas-soc, horms, dmaengine, devicetree,
	Hiroyuki Yokoyama
In-Reply-To: <1526475979-13891-1-git-send-email-ulrich.hecht+renesas@gmail.com>

On 16-05-18, 15:06, Ulrich Hecht wrote:
> From: Hiroyuki Yokoyama <hiroyuki.yokoyama.vx@renesas.com>
> 
> Renesas R-Car D3 (R8A77995) and E3 (R8A77990) SoCs also have the R-Car
> gen2/3 compatible DMA controllers, so document the SoC specific binding.

Applied, thanks

-- 
~Vinod

^ permalink raw reply

* Re: Revisiting Devicetree Overlay Manager
From: Frank Rowand @ 2018-05-18  3:53 UTC (permalink / raw)
  To: Manivannan Sadhasivam
  Cc: robh, grant.likely, pantelis.antoniou, dimitrysh, john.stultz,
	nicolas.dechesne, devicetree, daniel.thompson, loic.poulain
In-Reply-To: <8715b1f9-5e30-a14e-a029-fcc129a09c22@gmail.com>

Hi Manivannan,

On 04/25/18 10:26, Frank Rowand wrote:
> Hi Manivannan,
> 
> Sorry for the delay.  I'll try to get to this today or tommorrow.
> 
> -Frank

Sorry for the even longer than expected delay.  As I mentioned to you
off-list (bad Frank!), I wanted to pull together a lot of my disparate
thoughts on overlays before responding to your specific proposal and
questions.  The first (of probably many versions) of that write up
is at:

  https://elinux.org/Frank%27s_Evolving_Overlay_Thoughts

My thoughts on some of your questions are addressed on that page.
I still need to read through your questions because there are
probably several that I did not address on that page.

-Frank

> 
> 
> On 04/25/18 00:34, Manivannan Sadhasivam wrote:
>> Hi Frank,
>>
>> Did you had time to look into this? Especially I'd like to hear your
>> opinion on the first pain point I have mentioned. I can understand
>> that the whole point on introducing the of_overlay_fdt_apply() API
>> is to remove the duplication of overlay FDT unflattening, but do you have
>> any idea of how we can make this API work with overlay nodes appended
>> to the base DTB?
>>
>> Thanks,
>> Mani
>>
>> On Thu, Apr 19, 2018 at 08:08:04PM +0530, Manivannan Sadhasivam wrote:
>>> Hello Everyone,
>>>
>>> I have just started working on the Devicetree Overlay Manager support in
>>> kernel. The idea is to merge overlays at boot time specified via some
>>> interface like kernel command line. The motivation for this work comes from
>>> Overlay Manager [1] submitted by John last year. The mechanism which I have
>>> been working on is an extension to John's work. It focusses on addressing
>>> Rob's comments on the Overlay Manager which involves having multiple ways
>>> to load overlays.
>>>
>>> Proposal:
>>> =========
>>>
>>> 1. Pass all devicetree overlays via following methods:
>>>    - Overlays appended to base DTB
>>>    - Individual overlays built into kernel as firmware blobs
>>>    - Any other ways?
>>>
>>> 2. Specify overlays to load via kernel command line as below:
>>>    - overlay_mgr.overlays=<overlay1,overlay2,...>
>>>
>>> 3. Merge only the specified overlays during boot time. First look for the
>>> overlay in the base DTB. If it is found, just apply it, else defer to firmware
>>> load approach.
>>>
>>> The Overlay Manager code is expected to be very simple and will just do the
>>> above mentioned work. Later on, it will be extended to support dynamic
>>> modification of overlays from userspace with some additional security
>>> features like having a property listed in the base devicetree for only
>>> allowing changes to the current node and its child nodes, etc...
>>>
>>> Pain Points:
>>> ============
>>>
>>> 1. Starting from 4.17 we don't have any API exposed from DT core to merge
>>> individual devicetree nodes. We only have of_overlay_fdt_apply() function
>>> which takes the whole FDT. This will work very well for the firmware approach
>>> since we will pass the overlays blobs but not for overlays appended to base DTB,
>>> where we will pass individual overlay nodes.
>>>
>>> 2. Using firmware load method will force us to have this Overlay Manager code
>>> at late_initcall level since firmware class exists only in fs_inticall level,
>>> which might be too late for some devices.
>>>
>>> 3. This whole approach is not expected to work very well (still not yet tested)
>>> on DSI based devices since it needs to be present at very early during boot
>>> process.
>>>
>>> The Overlay Manager propsed here will be board agnostic and it should work on
>>> all platforms supporting DT. This will be a _very_ useful feature for the
>>> development boards such as 96Boards, Raspberry Pi, BBB etc... and also for
>>> production ready devices.
>>>
>>> So, I'd like to hear suggestions/feedbacks for the above mentioned proposal &
>>> pain points and hope to land the most awaited feature in kernel.
>>>
>>> Regards,
>>> Mani
>>>
>>> [1] https://lkml.org/lkml/2017/10/10/20
>>
> 
> .
> 

^ permalink raw reply

* [PATCH v2 5/5] arm64: dts: rockchip: Add sdmmc UHS support for roc-rk3328-cc
From: djw @ 2018-05-18  3:52 UTC (permalink / raw)
  To: linux-rockchip
  Cc: Wayne Chou, Levin Du, Heiko Stuebner, devicetree, David Wu,
	Liang Chen, William Wu, linux-kernel, Rob Herring, Joseph Chen,
	Will Deacon, Rocky Hao, Mark Rutland, Catalin Marinas,
	linux-arm-kernel
In-Reply-To: <1526615528-9707-1-git-send-email-djw@t-chip.com.cn>

From: Levin Du <djw@t-chip.com.cn>

In roc-rk3328-cc board, the signal voltage of sdmmc is supplied by
the vcc_sdio regulator, which is a mux between 1.8V and 3.3V,
controlled by a special output only gpio pin labeled
"gpiomut_pmuio_iout", corresponding bit 1 of the syscon GRF_SOC_CON10.

This special pin can now be reference as <&gpio_mute 1>, thanks
to the gpio-syscon driver, which makes writing regulator-gpio possible.

If the signal voltage changes, the io domain needs to change
correspondingly.

To use this feature, the following options are required in kernel config:
 - CONFIG_GPIO_SYSCON=y
 - CONFIG_POWER_AVS=y
 - CONFIG_ROCKCHIP_IODOMAIN=y

Signed-off-by: Levin Du <djw@t-chip.com.cn>

---

Changes in v2:
- Rename gpio_syscon10 to gpio_mute in rk3328-roc-cc.dts

Changes in v1:
- Split into small patches
- Sort dts properties in sdmmc node

 arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts | 20 +++++++++++++++++++-
 1 file changed, 19 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts b/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts
index b983abd..e3162bb 100644
--- a/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts
@@ -41,6 +41,19 @@
 		vin-supply = <&vcc_io>;
 	};
 
+	vcc_sdio: sdmmcio-regulator {
+		compatible = "regulator-gpio";
+		gpios = <&gpio_mute 1 GPIO_ACTIVE_HIGH>;
+		states = <1800000 0x1
+			  3300000 0x0>;
+		regulator-name = "vcc_sdio";
+		regulator-type = "voltage";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-always-on;
+		vin-supply = <&vcc_sys>;
+	};
+
 	vcc_host1_5v: vcc_otg_5v: vcc-host1-5v-regulator {
 		compatible = "regulator-fixed";
 		enable-active-high;
@@ -213,7 +226,7 @@
 
 	vccio1-supply = <&vcc_io>;
 	vccio2-supply = <&vcc18_emmc>;
-	vccio3-supply = <&vcc_io>;
+	vccio3-supply = <&vcc_sdio>;
 	vccio4-supply = <&vcc_18>;
 	vccio5-supply = <&vcc_io>;
 	vccio6-supply = <&vcc_io>;
@@ -242,7 +255,12 @@
 	max-frequency = <150000000>;
 	pinctrl-names = "default";
 	pinctrl-0 = <&sdmmc0_clk &sdmmc0_cmd &sdmmc0_dectn &sdmmc0_bus4>;
+	sd-uhs-sdr12;
+	sd-uhs-sdr25;
+	sd-uhs-sdr50;
+	sd-uhs-sdr104;
 	vmmc-supply = <&vcc_sd>;
+	vqmmc-supply = <&vcc_sdio>;
 	status = "okay";
 };
 
-- 
2.7.4

^ permalink raw reply related

* [PATCH v2 4/5] arm64: dts: rockchip: Add io-domain to roc-rk3328-cc
From: djw @ 2018-05-18  3:52 UTC (permalink / raw)
  To: linux-rockchip
  Cc: Wayne Chou, Levin Du, Heiko Stuebner, devicetree, David Wu,
	Liang Chen, William Wu, linux-kernel, Rob Herring, Rocky Hao,
	Will Deacon, Mark Rutland, Catalin Marinas, linux-arm-kernel,
	David S. Miller
In-Reply-To: <1526615528-9707-1-git-send-email-djw@t-chip.com.cn>

From: Levin Du <djw@t-chip.com.cn>

It is necessary for the io domain setting of the SoC to match
the voltage supplied by the regulators.

Signed-off-by: Levin Du <djw@t-chip.com.cn>

---

Changes in v2: None
Changes in v1:
- Split from V0.

 arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts b/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts
index 246c317..b983abd 100644
--- a/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts
@@ -208,6 +208,18 @@
 	};
 };
 
+&io_domains {
+	status = "okay";
+
+	vccio1-supply = <&vcc_io>;
+	vccio2-supply = <&vcc18_emmc>;
+	vccio3-supply = <&vcc_io>;
+	vccio4-supply = <&vcc_18>;
+	vccio5-supply = <&vcc_io>;
+	vccio6-supply = <&vcc_io>;
+	pmuio-supply = <&vcc_io>;
+};
+
 &pinctrl {
 	pmic {
 		pmic_int_l: pmic-int-l {
-- 
2.7.4

^ permalink raw reply related

* [PATCH v2 3/5] arm64: dts: rockchip: Add gpio-mute to rk3328
From: djw @ 2018-05-18  3:52 UTC (permalink / raw)
  To: linux-rockchip
  Cc: Wayne Chou, Levin Du, Heiko Stuebner, devicetree, David Wu,
	Arnd Bergmann, Finley Xiao, William Wu, Sugar Zhang, linux-kernel,
	Robin Murphy, Rob Herring, Rocky Hao, Will Deacon, Mark Rutland,
	Catalin Marinas, linux-arm-kernel
In-Reply-To: <1526615528-9707-1-git-send-email-djw@t-chip.com.cn>

From: Levin Du <djw@t-chip.com.cn>

Adding a new gpio controller named "gpio-mute" to rk3328, providing
access to the GPIO_MUTE pin defined in the syscon GRF_SOC_CON10.

The GPIO_MUTE pin is referred to as <&gpio-mute 1>.

Signed-off-by: Levin Du <djw@t-chip.com.cn>

---

Changes in v2:
- Rename gpio_syscon10 to gpio_mute in rk3328.dtsi

Changes in v1:
- Split from V0 and add to rk3328.dtsi for general use.

 arch/arm64/boot/dts/rockchip/rk3328.dtsi | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
index b8e9da1..5ba29d3 100644
--- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
@@ -309,6 +309,13 @@
 			mode-loader = <BOOT_BL_DOWNLOAD>;
 		};
 
+		/* The GPIO_MUTE pin is referred to as <&gpio-mute 1>.*/
+		gpio_mute: gpio-mute {
+			compatible = "rockchip,gpio-syscon";
+			gpio-controller;
+			#gpio-cells = <2>;
+			gpio,syscon-dev = <0 0x0428 0>;
+		};
 	};
 
 	uart0: serial@ff110000 {
-- 
2.7.4

^ permalink raw reply related

* [PATCH v2 2/5] gpio: syscon: Add gpio-syscon for rockchip
From: djw @ 2018-05-18  3:52 UTC (permalink / raw)
  To: linux-rockchip
  Cc: Wayne Chou, Levin Du, Heiko Stuebner, devicetree, Linus Walleij,
	linux-kernel, linux-gpio, Rob Herring, Mark Rutland,
	linux-arm-kernel
In-Reply-To: <1526615528-9707-1-git-send-email-djw@t-chip.com.cn>

From: Levin Du <djw@t-chip.com.cn>

Some GPIOs sit in the GRF_SOC_CON registers of Rockchip SoCs,
which do not belong to the general pinctrl.

Adding gpio-syscon support makes controlling regulator or
LED using these special pins very easy by reusing existing
drivers, such as gpio-regulator and led-gpio.

Signed-off-by: Levin Du <djw@t-chip.com.cn>

---

Changes in v2:
- Rename gpio_syscon10 to gpio_mute in doc

Changes in v1:
- Refactured for general gpio-syscon usage for Rockchip SoCs.
- Add doc rockchip,gpio-syscon.txt

 .../bindings/gpio/rockchip,gpio-syscon.txt         | 41 ++++++++++++++++++++++
 drivers/gpio/gpio-syscon.c                         | 30 ++++++++++++++++
 2 files changed, 71 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/gpio/rockchip,gpio-syscon.txt

diff --git a/Documentation/devicetree/bindings/gpio/rockchip,gpio-syscon.txt b/Documentation/devicetree/bindings/gpio/rockchip,gpio-syscon.txt
new file mode 100644
index 0000000..b1b2a67
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/rockchip,gpio-syscon.txt
@@ -0,0 +1,41 @@
+* Rockchip GPIO support for GRF_SOC_CON registers
+
+Required properties:
+- compatible: Should contain "rockchip,gpio-syscon".
+- gpio-controller: Marks the device node as a gpio controller.
+- #gpio-cells: Should be two. The first cell is the pin number and
+  the second cell is used to specify the gpio polarity:
+    0 = Active high,
+    1 = Active low.
+- gpio,syscon-dev: Should contain <grf_phandle syscon_offset 0>.
+  If declared as child of the grf node, the grf_phandle can be 0.
+
+Example:
+
+1. As child of grf node:
+
+	grf: syscon@ff100000 {
+		compatible = "rockchip,rk3328-grf", "syscon", "simple-mfd";
+
+		gpio_mute: gpio-mute {
+			compatible = "rockchip,gpio-syscon";
+			gpio-controller;
+			#gpio-cells = <2>;
+			gpio,syscon-dev = <0 0x0428 0>;
+		};
+	};
+
+
+2. Not child of grf node:
+
+	grf: syscon@ff100000 {
+		compatible = "rockchip,rk3328-grf", "syscon", "simple-mfd";
+		//...
+	};
+
+	gpio_mute: gpio-mute {
+		compatible = "rockchip,gpio-syscon";
+		gpio-controller;
+		#gpio-cells = <2>;
+		gpio,syscon-dev = <&grf 0x0428 0>;
+	};
diff --git a/drivers/gpio/gpio-syscon.c b/drivers/gpio/gpio-syscon.c
index 7325b86..e24b408 100644
--- a/drivers/gpio/gpio-syscon.c
+++ b/drivers/gpio/gpio-syscon.c
@@ -135,6 +135,32 @@ static const struct syscon_gpio_data clps711x_mctrl_gpio = {
 	.dat_bit_offset	= 0x40 * 8 + 8,
 };
 
+static void rockchip_gpio_set(struct gpio_chip *chip, unsigned int offset,
+			      int val)
+{
+	struct syscon_gpio_priv *priv = gpiochip_get_data(chip);
+	unsigned int offs;
+	u8 bit;
+	u32 data;
+	int ret;
+
+	offs = priv->dreg_offset + priv->data->dat_bit_offset + offset;
+	bit = offs % SYSCON_REG_BITS;
+	data = (val ? BIT(bit) : 0) | BIT(bit + 16);
+	ret = regmap_write(priv->syscon,
+			   (offs / SYSCON_REG_BITS) * SYSCON_REG_SIZE,
+			   data);
+	if (ret < 0)
+		dev_err(chip->parent, "gpio write failed ret(%d)\n", ret);
+}
+
+static const struct syscon_gpio_data rockchip_gpio_syscon = {
+	/* Rockchip GRF_SOC_CON Bits 0-15 */
+	.flags		= GPIO_SYSCON_FEAT_OUT,
+	.bit_count	= 16,
+	.set		= rockchip_gpio_set,
+};
+
 #define KEYSTONE_LOCK_BIT BIT(0)
 
 static void keystone_gpio_set(struct gpio_chip *chip, unsigned offset, int val)
@@ -175,6 +201,10 @@ static const struct of_device_id syscon_gpio_ids[] = {
 		.compatible	= "ti,keystone-dsp-gpio",
 		.data		= &keystone_dsp_gpio,
 	},
+	{
+		.compatible	= "rockchip,gpio-syscon",
+		.data		= &rockchip_gpio_syscon,
+	},
 	{ }
 };
 MODULE_DEVICE_TABLE(of, syscon_gpio_ids);
-- 
2.7.4

^ permalink raw reply related

* [PATCH v2 0/5] Add sdmmc UHS support to ROC-RK3328-CC board.
From: djw @ 2018-05-18  3:32 UTC (permalink / raw)
  To: linux-rockchip
  Cc: Wayne Chou, Levin Du, Heiko Stuebner, Arnd Bergmann, Liang Chen,
	Linus Walleij, Robin Murphy, Rob Herring, Catalin Marinas,
	David Wu, Finley Xiao, William Wu, Rocky Hao, Will Deacon,
	devicetree, linux-gpio, linux-arm-kernel, David S. Miller,
	Sugar Zhang, linux-kernel, Joseph Chen, Mark Rutland <mark>

From: Levin Du <djw@t-chip.com.cn>


Hi all, this is an attemp to add sdmmc UHS support to the
ROC-RK3328-CC board.

This patch series adds a new compatible `rockchip,gpio-syscon` to
the gpio-syscon driver for general Rockchip SoC usage.

A new gpio controller named `gpio_mute` is defined in
rk3328.dtsi so that all rk3328 boards has access to it.

The ROC-RK3328-CC board use the new gpio <&gpio_mute 1> in
gpio-regulator to control the signal voltage of the sdmmc.
It is essential for UHS support which requires 1.8V signal voltage.

Many thanks to Heiko's great advice!

Changes in v2:
- Rename gpio_syscon10 to gpio_mute in doc
- Rename gpio_syscon10 to gpio_mute in rk3328.dtsi
- Rename gpio_syscon10 to gpio_mute in rk3328-roc-cc.dts

Changes in v1:
- New: allow fetching syscon from parent node in gpio-syscon driver
- Refactured for general gpio-syscon usage for Rockchip SoCs.
- Add doc rockchip,gpio-syscon.txt
- Split from V0 into small patches
- Sort dts properties in sdmmc node

Heiko Stuebner (1):
  gpio: syscon: allow fetching syscon from parent node

Levin Du (4):
  gpio: syscon: Add gpio-syscon for rockchip
  arm64: dts: rockchip: Add gpio-mute to rk3328
  arm64: dts: rockchip: Add io-domain to roc-rk3328-cc
  arm64: dts: rockchip: Add sdmmc UHS support for roc-rk3328-cc

 .../bindings/gpio/rockchip,gpio-syscon.txt         | 41 ++++++++++++++++++++++
 arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts     | 30 ++++++++++++++++
 arch/arm64/boot/dts/rockchip/rk3328.dtsi           |  7 ++++
 drivers/gpio/gpio-syscon.c                         | 32 +++++++++++++++++
 4 files changed, 110 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/gpio/rockchip,gpio-syscon.txt

-- 
2.7.4

^ permalink raw reply

* [PATCH 5/5] MAINTAINERS: Add Actions Semi S900 pinctrl entries
From: Manivannan Sadhasivam @ 2018-05-18  2:30 UTC (permalink / raw)
  To: linus.walleij, robh+dt, afaerber
  Cc: liuwei, mp-cs, 96boards, devicetree, andy.shevchenko,
	daniel.thompson, amit.kucheria, linux-arm-kernel, linux-gpio,
	linux-kernel, hzhang, bdong, manivannanece23,
	Manivannan Sadhasivam
In-Reply-To: <20180518023056.7869-1-manivannan.sadhasivam@linaro.org>

Add S900 pinctrl entries under ARCH_ACTIONS

Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
---
 MAINTAINERS | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 640dabc4c311..9e1a17c9b4a7 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1125,10 +1125,12 @@ F:	arch/arm/mach-actions/
 F:	arch/arm/boot/dts/owl-*
 F:	arch/arm64/boot/dts/actions/
 F:	drivers/clocksource/owl-*
+F:	drivers/pinctrl/actions/*
 F:	drivers/soc/actions/
 F:	include/dt-bindings/power/owl-*
 F:	include/linux/soc/actions/
 F:	Documentation/devicetree/bindings/arm/actions.txt
+F:	Documentation/devicetree/bindings/pinctrl/actions,s900-pinctrl.txt
 F:	Documentation/devicetree/bindings/power/actions,owl-sps.txt
 F:	Documentation/devicetree/bindings/timer/actions,owl-timer.txt
 
-- 
2.14.1

^ permalink raw reply related

* [PATCH 4/5] pinctrl: actions: Add gpio support for Actions S900 SoC
From: Manivannan Sadhasivam @ 2018-05-18  2:30 UTC (permalink / raw)
  To: linus.walleij, robh+dt, afaerber
  Cc: liuwei, mp-cs, 96boards, devicetree, andy.shevchenko,
	daniel.thompson, amit.kucheria, linux-arm-kernel, linux-gpio,
	linux-kernel, hzhang, bdong, manivannanece23,
	Manivannan Sadhasivam
In-Reply-To: <20180518023056.7869-1-manivannan.sadhasivam@linaro.org>

Add gpio support to pinctrl driver for Actions Semi S900 SoC.

Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
---
 drivers/pinctrl/actions/Kconfig        |   1 +
 drivers/pinctrl/actions/pinctrl-owl.c  | 206 +++++++++++++++++++++++++++++++++
 drivers/pinctrl/actions/pinctrl-owl.h  |  20 ++++
 drivers/pinctrl/actions/pinctrl-s900.c |  29 ++++-
 4 files changed, 255 insertions(+), 1 deletion(-)

diff --git a/drivers/pinctrl/actions/Kconfig b/drivers/pinctrl/actions/Kconfig
index ede97cdbbc12..490927b4ea76 100644
--- a/drivers/pinctrl/actions/Kconfig
+++ b/drivers/pinctrl/actions/Kconfig
@@ -4,6 +4,7 @@ config PINCTRL_OWL
 	select PINMUX
 	select PINCONF
 	select GENERIC_PINCONF
+	select GPIOLIB
 	help
 	  Say Y here to enable Actions Semi OWL pinctrl driver
 
diff --git a/drivers/pinctrl/actions/pinctrl-owl.c b/drivers/pinctrl/actions/pinctrl-owl.c
index ee090697b1e9..4942e34c8b76 100644
--- a/drivers/pinctrl/actions/pinctrl-owl.c
+++ b/drivers/pinctrl/actions/pinctrl-owl.c
@@ -11,6 +11,7 @@
 
 #include <linux/clk.h>
 #include <linux/err.h>
+#include <linux/gpio/driver.h>
 #include <linux/io.h>
 #include <linux/module.h>
 #include <linux/of.h>
@@ -31,6 +32,7 @@
  * struct owl_pinctrl - pinctrl state of the device
  * @dev: device handle
  * @pctrldev: pinctrl handle
+ * @chip: gpio chip
  * @lock: spinlock to protect registers
  * @soc: reference to soc_data
  * @base: pinctrl register base address
@@ -38,6 +40,7 @@
 struct owl_pinctrl {
 	struct device *dev;
 	struct pinctrl_dev *pctrldev;
+	struct gpio_chip chip;
 	raw_spinlock_t lock;
 	struct clk *clk;
 	const struct owl_pinctrl_soc_data *soc;
@@ -536,6 +539,198 @@ static struct pinctrl_desc owl_pinctrl_desc = {
 	.owner = THIS_MODULE,
 };
 
+static const struct owl_gpio_port *
+owl_gpio_get_port(struct owl_pinctrl *pctrl, unsigned int *pin)
+{
+	unsigned int start = 0, i;
+
+	for (i = 0; i < pctrl->soc->nports; i++) {
+		const struct owl_gpio_port *port = &pctrl->soc->ports[i];
+
+		if (*pin >= start && *pin < start + port->pins) {
+			*pin -= start;
+			return port;
+		}
+
+		start += port->pins;
+	}
+
+	return NULL;
+}
+
+static void owl_gpio_update_reg(void __iomem *base, unsigned int pin, int flag)
+{
+	u32 val;
+
+	val = readl_relaxed(base);
+
+	if (flag)
+		val |= BIT(pin);
+	else
+		val &= ~BIT(pin);
+
+	writel_relaxed(val, base);
+}
+
+static int owl_gpio_request(struct gpio_chip *chip, unsigned int offset)
+{
+	struct owl_pinctrl *pctrl = gpiochip_get_data(chip);
+	const struct owl_gpio_port *port;
+	void __iomem *gpio_base;
+	unsigned long flags;
+
+	port = owl_gpio_get_port(pctrl, &offset);
+	if (WARN_ON(port == NULL))
+		return -ENODEV;
+
+	gpio_base = pctrl->base + port->offset;
+
+	/*
+	 * GPIOs have higher priority over other modules, so either setting
+	 * them as OUT or IN is sufficient
+	 */
+	raw_spin_lock_irqsave(&pctrl->lock, flags);
+	owl_gpio_update_reg(gpio_base + port->outen, offset, true);
+	raw_spin_unlock_irqrestore(&pctrl->lock, flags);
+
+	return 0;
+}
+
+static void owl_gpio_free(struct gpio_chip *chip, unsigned int offset)
+{
+	struct owl_pinctrl *pctrl = gpiochip_get_data(chip);
+	const struct owl_gpio_port *port;
+	void __iomem *gpio_base;
+	unsigned long flags;
+
+	port = owl_gpio_get_port(pctrl, &offset);
+	if (WARN_ON(port == NULL))
+		return;
+
+	gpio_base = pctrl->base + port->offset;
+
+	raw_spin_lock_irqsave(&pctrl->lock, flags);
+	/* disable gpio output */
+	owl_gpio_update_reg(gpio_base + port->outen, offset, false);
+
+	/* disable gpio input */
+	owl_gpio_update_reg(gpio_base + port->inen, offset, false);
+	raw_spin_unlock_irqrestore(&pctrl->lock, flags);
+}
+
+static int owl_gpio_get(struct gpio_chip *chip, unsigned int offset)
+{
+	struct owl_pinctrl *pctrl = gpiochip_get_data(chip);
+	const struct owl_gpio_port *port;
+	void __iomem *gpio_base;
+	unsigned long flags;
+	u32 val;
+
+	port = owl_gpio_get_port(pctrl, &offset);
+	if (WARN_ON(port == NULL))
+		return -ENODEV;
+
+	gpio_base = pctrl->base + port->offset;
+
+	raw_spin_lock_irqsave(&pctrl->lock, flags);
+	val = readl_relaxed(gpio_base + port->dat);
+	raw_spin_unlock_irqrestore(&pctrl->lock, flags);
+
+	return !!(val & BIT(offset));
+}
+
+static void owl_gpio_set(struct gpio_chip *chip, unsigned int offset, int value)
+{
+	struct owl_pinctrl *pctrl = gpiochip_get_data(chip);
+	const struct owl_gpio_port *port;
+	void __iomem *gpio_base;
+	unsigned long flags;
+
+	port = owl_gpio_get_port(pctrl, &offset);
+	if (WARN_ON(port == NULL))
+		return;
+
+	gpio_base = pctrl->base + port->offset;
+
+	raw_spin_lock_irqsave(&pctrl->lock, flags);
+	owl_gpio_update_reg(gpio_base + port->dat, offset, value);
+	raw_spin_unlock_irqrestore(&pctrl->lock, flags);
+}
+
+static int owl_gpio_direction_input(struct gpio_chip *chip, unsigned int offset)
+{
+	struct owl_pinctrl *pctrl = gpiochip_get_data(chip);
+	const struct owl_gpio_port *port;
+	void __iomem *gpio_base;
+	unsigned long flags;
+
+	port = owl_gpio_get_port(pctrl, &offset);
+	if (WARN_ON(port == NULL))
+		return -ENODEV;
+
+	gpio_base = pctrl->base + port->offset;
+
+	raw_spin_lock_irqsave(&pctrl->lock, flags);
+	owl_gpio_update_reg(gpio_base + port->outen, offset, false);
+	owl_gpio_update_reg(gpio_base + port->inen, offset, true);
+	raw_spin_unlock_irqrestore(&pctrl->lock, flags);
+
+	return 0;
+}
+
+static int owl_gpio_direction_output(struct gpio_chip *chip,
+				unsigned int offset, int value)
+{
+	struct owl_pinctrl *pctrl = gpiochip_get_data(chip);
+	const struct owl_gpio_port *port;
+	void __iomem *gpio_base;
+	unsigned long flags;
+
+	port = owl_gpio_get_port(pctrl, &offset);
+	if (WARN_ON(port == NULL))
+		return -ENODEV;
+
+	gpio_base = pctrl->base + port->offset;
+
+	raw_spin_lock_irqsave(&pctrl->lock, flags);
+	owl_gpio_update_reg(gpio_base + port->inen, offset, false);
+	owl_gpio_update_reg(gpio_base + port->outen, offset, true);
+	owl_gpio_update_reg(gpio_base + port->dat, offset, value);
+	raw_spin_unlock_irqrestore(&pctrl->lock, flags);
+
+	return 0;
+}
+
+static int owl_gpio_init(struct owl_pinctrl *pctrl)
+{
+	struct gpio_chip *chip;
+	int ret;
+
+	chip = &pctrl->chip;
+	chip->base = -1;
+	chip->ngpio = pctrl->soc->ngpios;
+	chip->label = dev_name(pctrl->dev);
+	chip->parent = pctrl->dev;
+	chip->owner = THIS_MODULE;
+	chip->of_node = pctrl->dev->of_node;
+
+	ret = gpiochip_add_data(&pctrl->chip, pctrl);
+	if (ret) {
+		dev_err(pctrl->dev, "failed to register gpiochip\n");
+		return ret;
+	}
+
+	ret = gpiochip_add_pin_range(&pctrl->chip, dev_name(pctrl->dev),
+							0, 0, chip->ngpio);
+	if (ret) {
+		dev_err(pctrl->dev, "failed to add pin range\n");
+		gpiochip_remove(&pctrl->chip);
+		return ret;
+	}
+
+	return 0;
+}
+
 int owl_pinctrl_probe(struct platform_device *pdev,
 				struct owl_pinctrl_soc_data *soc_data)
 {
@@ -571,6 +766,13 @@ int owl_pinctrl_probe(struct platform_device *pdev,
 	owl_pinctrl_desc.pins = soc_data->pins;
 	owl_pinctrl_desc.npins = soc_data->npins;
 
+	pctrl->chip.direction_input  = owl_gpio_direction_input;
+	pctrl->chip.direction_output = owl_gpio_direction_output;
+	pctrl->chip.get = owl_gpio_get;
+	pctrl->chip.set = owl_gpio_set;
+	pctrl->chip.request = owl_gpio_request;
+	pctrl->chip.free = owl_gpio_free;
+
 	pctrl->soc = soc_data;
 	pctrl->dev = &pdev->dev;
 
@@ -581,6 +783,10 @@ int owl_pinctrl_probe(struct platform_device *pdev,
 		return PTR_ERR(pctrl->pctrldev);
 	}
 
+	ret = owl_gpio_init(pctrl);
+	if (ret)
+		return ret;
+
 	platform_set_drvdata(pdev, pctrl);
 
 	return 0;
diff --git a/drivers/pinctrl/actions/pinctrl-owl.h b/drivers/pinctrl/actions/pinctrl-owl.h
index 448f81a6db3b..74342378937c 100644
--- a/drivers/pinctrl/actions/pinctrl-owl.h
+++ b/drivers/pinctrl/actions/pinctrl-owl.h
@@ -114,6 +114,22 @@ struct owl_pinmux_func {
 	unsigned int ngroups;
 };
 
+/**
+ * struct owl_gpio_port - Actions GPIO port info
+ * @offset: offset of the GPIO port.
+ * @pins: number of pins belongs to the GPIO port.
+ * @outen: offset of the output enable register.
+ * @inen: offset of the input enable register.
+ * @dat: offset of the data register.
+ */
+struct owl_gpio_port {
+	unsigned int offset;
+	unsigned int pins;
+	unsigned int outen;
+	unsigned int inen;
+	unsigned int dat;
+};
+
 /**
  * struct owl_pinctrl_soc_data - Actions pin controller driver configuration
  * @pins: array describing all pins of the pin controller.
@@ -124,6 +140,8 @@ struct owl_pinmux_func {
  * @ngroups: number of entries in @groups.
  * @padinfo: array describing the pad info of this SoC.
  * @ngpios: number of pingroups the driver should expose as GPIOs.
+ * @port: array describing all GPIO ports of this SoC.
+ * @nports: number of GPIO ports in this SoC.
  */
 struct owl_pinctrl_soc_data {
 	const struct pinctrl_pin_desc *pins;
@@ -134,6 +152,8 @@ struct owl_pinctrl_soc_data {
 	unsigned int ngroups;
 	const struct owl_padinfo *padinfo;
 	unsigned int ngpios;
+	const struct owl_gpio_port *ports;
+	unsigned int nports;
 };
 
 int owl_pinctrl_probe(struct platform_device *pdev,
diff --git a/drivers/pinctrl/actions/pinctrl-s900.c b/drivers/pinctrl/actions/pinctrl-s900.c
index 08d93f8fc086..5503c7945764 100644
--- a/drivers/pinctrl/actions/pinctrl-s900.c
+++ b/drivers/pinctrl/actions/pinctrl-s900.c
@@ -33,6 +33,13 @@
 #define PAD_SR1			(0x0274)
 #define PAD_SR2			(0x0278)
 
+#define OWL_GPIO_PORT_A		0
+#define OWL_GPIO_PORT_B		1
+#define OWL_GPIO_PORT_C		2
+#define OWL_GPIO_PORT_D		3
+#define OWL_GPIO_PORT_E		4
+#define OWL_GPIO_PORT_F		5
+
 #define _GPIOA(offset)		(offset)
 #define _GPIOB(offset)		(32 + (offset))
 #define _GPIOC(offset)		(64 + (offset))
@@ -1814,6 +1821,24 @@ static struct owl_padinfo s900_padinfo[NUM_PADS] = {
 	[SGPIO3] = PAD_INFO_PULLCTL_ST(SGPIO3)
 };
 
+#define OWL_GPIO_PORT(port, base, count, _outen, _inen, _dat)	\
+	[OWL_GPIO_PORT_##port] = {				\
+		.offset = base,					\
+		.pins = count,					\
+		.outen = _outen,				\
+		.inen = _inen,					\
+		.dat = _dat,					\
+	}
+
+static const struct owl_gpio_port s900_gpio_ports[] = {
+	OWL_GPIO_PORT(A, 0x0000, 32, 0x0, 0x4, 0x8),
+	OWL_GPIO_PORT(B, 0x000C, 32, 0x0, 0x4, 0x8),
+	OWL_GPIO_PORT(C, 0x0018, 12, 0x0, 0x4, 0x8),
+	OWL_GPIO_PORT(D, 0x0024, 30, 0x0, 0x4, 0x8),
+	OWL_GPIO_PORT(E, 0x0030, 32, 0x0, 0x4, 0x8),
+	OWL_GPIO_PORT(F, 0x00F0, 8, 0x0, 0x4, 0x8)
+};
+
 static struct owl_pinctrl_soc_data s900_pinctrl_data = {
 	.padinfo = s900_padinfo,
 	.pins = (const struct pinctrl_pin_desc *)s900_pads,
@@ -1822,7 +1847,9 @@ static struct owl_pinctrl_soc_data s900_pinctrl_data = {
 	.nfunctions = ARRAY_SIZE(s900_functions),
 	.groups = s900_groups,
 	.ngroups = ARRAY_SIZE(s900_groups),
-	.ngpios = NUM_GPIOS
+	.ngpios = NUM_GPIOS,
+	.ports = s900_gpio_ports,
+	.nports = ARRAY_SIZE(s900_gpio_ports)
 };
 
 static int s900_pinctrl_probe(struct platform_device *pdev)
-- 
2.14.1

^ permalink raw reply related

* [PATCH 3/5] arm64: dts: actions: Add gpio line names to Bubblegum-96 board
From: Manivannan Sadhasivam @ 2018-05-18  2:30 UTC (permalink / raw)
  To: linus.walleij, robh+dt, afaerber
  Cc: liuwei, mp-cs, 96boards, devicetree, andy.shevchenko,
	daniel.thompson, amit.kucheria, linux-arm-kernel, linux-gpio,
	linux-kernel, hzhang, bdong, manivannanece23,
	Manivannan Sadhasivam
In-Reply-To: <20180518023056.7869-1-manivannan.sadhasivam@linaro.org>

Add gpio line names to Actions Semi S900 based Bubblegum-96 board.

Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
---
 arch/arm64/boot/dts/actions/s900-bubblegum-96.dts | 175 ++++++++++++++++++++++
 1 file changed, 175 insertions(+)

diff --git a/arch/arm64/boot/dts/actions/s900-bubblegum-96.dts b/arch/arm64/boot/dts/actions/s900-bubblegum-96.dts
index ff043c961d75..d0ba35df9015 100644
--- a/arch/arm64/boot/dts/actions/s900-bubblegum-96.dts
+++ b/arch/arm64/boot/dts/actions/s900-bubblegum-96.dts
@@ -34,3 +34,178 @@
 	status = "okay";
 	clocks = <&cmu CLK_UART5>;
 };
+
+/*
+ * GPIO name legend: proper name = the GPIO line is used as GPIO
+ *         NC = not connected (pin out but not routed from the chip to
+ *              anything the board)
+ *         "[PER]" = pin is muxed for [peripheral] (not GPIO)
+ *         LSEC = Low Speed External Connector
+ *         HSEC = High Speed External Connector
+ *
+ * Line names are taken from the schematic "Schematics Bubblegum96"
+ * version v1.0
+ *
+ * For the lines routed to the external connectors the
+ * lines are named after the 96Boards CE Specification 1.0,
+ * Appendix "Expansion Connector Signal Description".
+ *
+ * When the 96Boards naming of a line and the schematic name of
+ * the same line are in conflict, the 96Boards specification
+ * takes precedence, which means that the external UART on the
+ * LSEC is named UART0 while the schematic and SoC names this
+ * UART2. Only exception is the I2C lines for which the schematic
+ * naming has been preferred. This is only for the informational
+ * lines i.e. "[FOO]", the GPIO named lines "GPIO-A" thru "GPIO-L"
+ * are the only ones actually used for GPIO.
+ */
+
+&pinctrl {
+	gpio-line-names =
+		"GPIO-A", /* GPIO_0, LSEC pin 23 */
+		"GPIO-B", /* GPIO_1, LSEC pin 24 */
+		"GPIO-C", /* GPIO_2, LSEC pin 25 */
+		"GPIO-D", /* GPIO_3, LSEC pin 26 */
+		"GPIO-E", /* GPIO_4, LSEC pin 27 */
+		"GPIO-F", /* GPIO_5, LSEC pin 28 */
+		"GPIO-G", /* GPIO_6, LSEC pin 29 */
+		"GPIO-H", /* GPIO_7, LSEC pin 30 */
+		"GPIO-I", /* GPIO_8, LSEC pin 31 */
+		"GPIO-J", /* GPIO_9, LSEC pin 32 */
+		"NC", /* GPIO_10 */
+		"NC", /* GPIO_11 */
+		"SIRQ2_1V8", /* GPIO_12 */
+		"PCM0_OUT", /* GPIO_13 */
+		"WIFI_LED", /* GPIO_14 */
+		"PCM0_SYNC", /* GPIO_15 */
+		"PCM0_CLK", /* GPIO_16 */
+		"PCM0_IN", /* GPIO_17 */
+		"BT_LED", /* GPIO_18 */
+		"LED0", /* GPIO_19 */
+		"LED1", /* GPIO_20 */
+		"JTAG_TCK", /* GPIO_21 */
+		"JTAG_TMS", /* GPIO_22 */
+		"JTAG_TDI", /* GPIO_23 */
+		"JTAG_TDO", /* GPIO_24 */
+		"[UART1_RxD]", /* GPIO_25, LSEC pin 13 */
+		"NC", /* GPIO_26 */
+		"[UART1_TxD]", /* GPIO_27, LSEC pin 11 */
+		"SD0_D0", /* GPIO_28 */
+		"SD0_D1", /* GPIO_29 */
+		"SD0_D2", /* GPIO_30 */
+		"SD0_D3", /* GPIO_31 */
+		"SD1_D0", /* GPIO_32 */
+		"SD1_D1", /* GPIO_33 */
+		"SD1_D2", /* GPIO_34 */
+		"SD1_D3", /* GPIO_35 */
+		"SD0_CMD", /* GPIO_36 */
+		"SD0_CLK", /* GPIO_37 */
+		"SD1_CMD", /* GPIO_38 */
+		"SD1_CLK", /* GPIO_39 */
+		"SPI0_SCLK", /* GPIO_40, LSEC pin 8 */
+		"SPI0_CS", /* GPIO_41, LSEC pin 12 */
+		"SPI0_DIN", /* GPIO_42, LSEC pin 10 */
+		"SPI0_DOUT", /* GPIO_43, LSEC pin 14 */
+		"I2C5_SDATA", /* GPIO_44, HSEC pin 36 */
+		"I2C5_SCLK", /* GPIO_45, HSEC pin 38 */
+		"UART0_RX", /* GPIO_46, LSEC pin 7 */
+		"UART0_TX", /* GPIO_47, LSEC pin 5 */
+		"UART0_RTSB", /* GPIO_48, LSEC pin 9 */
+		"UART0_CTSB", /* GPIO_49, LSEC pin 3 */
+		"I2C4_SCLK", /* GPIO_50, HSEC pin 32 */
+		"I2C4_SDATA", /* GPIO_51, HSEC pin 34 */
+		"I2C0_SCLK", /* GPIO_52 */
+		"I2C0_SDATA", /* GPIO_53 */
+		"I2C1_SCLK", /* GPIO_54, LSEC pin 15 */
+		"I2C1_SDATA", /* GPIO_55, LSEC pin 17 */
+		"I2C2_SCLK", /* GPIO_56, LSEC pin 19 */
+		"I2C2_SDATA", /* GPIO_57, LSEC pin 21 */
+		"CSI0_DN0", /* GPIO_58, HSEC pin 10 */
+		"CSI0_DP0", /* GPIO_59, HSEC pin 8 */
+		"CSI0_DN1", /* GPIO_60, HSEC pin 16 */
+		"CSI0_DP1", /* GPIO_61, HSEC pin 14 */
+		"CSI0_CN", /* GPIO_62, HSEC pin 4 */
+		"CSI0_CP", /* GPIO_63, HSEC pin 2 */
+		"CSI0_DN2", /* GPIO_64, HSEC pin 22 */
+		"CSI0_DP2", /* GPIO_65, HSEC pin 20 */
+		"CSI0_DN3", /* GPIO_66, HSEC pin 28 */
+		"CSI0_DP3", /* GPIO_67, HSEC pin 26 */
+		"[CLK0]", /* GPIO_68, HSEC pin 15 */
+		"CSI1_DN0", /* GPIO_69, HSEC pin 44 */
+		"CSI1_DP0", /* GPIO_70, HSEC pin 42 */
+		"CSI1_DN1", /* GPIO_71, HSEC pin 50 */
+		"CSI1_DP1", /* GPIO_72, HSEC pin 48 */
+		"CSI1_CN", /* GPIO_73, HSEC pin 56 */
+		"CSI1_CP", /* GPIO_74, HSEC pin 54 */
+		"[CLK1]", /* GPIO_75, HSEC pin 17 */
+		"[GPIOD0]", /* GPIO_76 */
+		"[GPIOD1]", /* GPIO_77 */
+		"BT_RST_N", /* GPIO_78 */
+		"EXT_DC_EN", /* GPIO_79 */
+		"[PCM_DI]", /* GPIO_80, LSEC pin 22 */
+		"[PCM_DO]", /* GPIO_81, LSEC pin 20 */
+		"[PCM_CLK]", /* GPIO_82, LSEC pin 18 */
+		"[PCM_FS]", /* GPIO_83, LSEC pin 16 */
+		"WAKE_BT", /* GPIO_84 */
+		"WL_REG_ON", /* GPIO_85 */
+		"NC", /* GPIO_86 */
+		"NC", /* GPIO_87 */
+		"NC", /* GPIO_88 */
+		"NC", /* GPIO_89 */
+		"NC", /* GPIO_90 */
+		"WIFI_WAKE", /* GPIO_91 */
+		"BT_WAKE", /* GPIO_92 */
+		"NC", /* GPIO_93 */
+		"OTG_EN2", /* GPIO_94 */
+		"OTG_EN", /* GPIO_95 */
+		"DSI_DP3", /* GPIO_96, HSEC pin 45 */
+		"DSI_DN3", /* GPIO_97, HSEC pin 47 */
+		"DSI_DP1", /* GPIO_98, HSEC pin 33 */
+		"DSI_DN1", /* GPIO_99, HSEC pin 35 */
+		"DSI_CP", /* GPIO_100, HSEC pin 21 */
+		"DSI_CN", /* GPIO_101, HSEC pin 23 */
+		"DSI_DP0", /* GPIO_102, HSEC pin 27 */
+		"DSI_DN0", /* GPIO_103, HSEC pin 29 */
+		"DSI_DP2", /* GPIO_104, HSEC pin 39 */
+		"DSI_DN2", /* GPIO_105, HSEC pin 41 */
+		"N0_D0", /* GPIO_106 */
+		"N0_D1", /* GPIO_107 */
+		"N0_D2", /* GPIO_108 */
+		"N0_D3", /* GPIO_109 */
+		"N0_D4", /* GPIO_110 */
+		"N0_D5", /* GPIO_111 */
+		"N0_D6", /* GPIO_112 */
+		"N0_D7", /* GPIO_113 */
+		"N0_DQS", /* GPIO_114 */
+		"N0_DQSN", /* GPIO_115 */
+		"NC", /* GPIO_116 */
+		"NC", /* GPIO_117 */
+		"NC", /* GPIO_118 */
+		"N0_CEB1", /* GPIO_119 */
+		"CARD_DT", /* GPIO_120 */
+		"N0_CEB3", /* GPIO_121 */
+		"SD_DAT0", /* GPIO_122, HSEC pin 1 */
+		"SD_DAT1", /* GPIO_123, HSEC pin 3 */
+		"SD_DAT2", /* GPIO_124, HSEC pin 5 */
+		"SD_DAT3", /* GPIO_125, HSEC pin 7 */
+		"NC", /* GPIO_126 */
+		"NC", /* GPIO_127 */
+		"[PWR_BTN_N]", /* GPIO_128, LSEC pin 4 */
+		"[RST_BTN_N]", /* GPIO_129, LSEC pin 6 */
+		"NC", /* GPIO_130 */
+		"SD_CMD", /* GPIO_131 */
+		"GPIO-L", /* GPIO_132, LSEC pin 34 */
+		"GPIO-K", /* GPIO_133, LSEC pin 33 */
+		"NC", /* GPIO_134 */
+		"SD_SCLK", /* GPIO_135 */
+		"NC", /* GPIO_136 */
+		"JTAG_TRST", /* GPIO_137 */
+		"I2C3_SCLK", /* GPIO_138 */
+		"LED2", /* GPIO_139 */
+		"LED3", /* GPIO_140 */
+		"I2C3_SDATA", /* GPIO_141 */
+		"UART3_RX", /* GPIO_142 */
+		"UART3_TX", /* GPIO_143 */
+		"UART3_RTSB", /* GPIO_144 */
+		"UART3_CTSB"; /* GPIO_145 */
+};
-- 
2.14.1

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox