* 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 = <®_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
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox