* Re: [PATCH v6 4/9] counter: 104-quad-8: Add Generic Counter interface support
From: Jonathan Cameron @ 2018-05-20 15:42 UTC (permalink / raw)
To: William Breathitt Gray
Cc: benjamin.gaignard, fabrice.gasnier, linux-iio, linux-kernel,
devicetree, linux-arm-kernel
In-Reply-To: <881ede525a87ef68fad76cc757ce0ba72df03e5a.1526487615.git.vilhelm.gray@gmail.com>
On Wed, 16 May 2018 13:51:25 -0400
William Breathitt Gray <vilhelm.gray@gmail.com> wrote:
> This patch adds support for the Generic Counter interface to the
> 104-QUAD-8 driver. The existing 104-QUAD-8 device interface should not
> be affected by this patch; all changes are intended as supplemental
> additions as perceived by the user.
>
> Generic Counter Counts are created for the eight quadrature channel
> counts, as well as their respective quadrature A and B Signals (which
> are associated via respective Synapse structures) and respective index
> Signals.
>
> The new Generic Counter interface sysfs attributes are intended to
> expose the same functionality and data available via the existing
> 104-QUAD-8 IIO device interface; the Generic Counter interface serves
> to provide the respective functionality and data in a standard way
> expected of counter devices.
>
> Signed-off-by: William Breathitt Gray <vilhelm.gray@gmail.com>
A few general comments that applied just as well to the original driver
as they do to the modified version.
I wonder if this would be easier to review as two patches.
Move the driver then add the counter interfaces?
Right now people kind of have to review the old IIO driver and
all the new stuff which is a big job..
Jonathan
> ---
> MAINTAINERS | 4 +-
> drivers/counter/104-quad-8.c | 1335 ++++++++++++++++++++++++++++++
> drivers/counter/Kconfig | 21 +
> drivers/counter/Makefile | 2 +
> drivers/iio/counter/104-quad-8.c | 596 -------------
> drivers/iio/counter/Kconfig | 17 -
> drivers/iio/counter/Makefile | 1 -
> 7 files changed, 1360 insertions(+), 616 deletions(-)
> create mode 100644 drivers/counter/104-quad-8.c
> delete mode 100644 drivers/iio/counter/104-quad-8.c
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 7a01aa63fb33..f11bf7885aeb 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -266,12 +266,12 @@ L: linux-gpio@vger.kernel.org
> S: Maintained
> F: drivers/gpio/gpio-104-idio-16.c
>
> -ACCES 104-QUAD-8 IIO DRIVER
> +ACCES 104-QUAD-8 DRIVER
> M: William Breathitt Gray <vilhelm.gray@gmail.com>
> L: linux-iio@vger.kernel.org
> S: Maintained
> F: Documentation/ABI/testing/sysfs-bus-iio-counter-104-quad-8
> -F: drivers/iio/counter/104-quad-8.c
> +F: drivers/counter/104-quad-8.c
>
> ACCES PCI-IDIO-16 GPIO DRIVER
> M: William Breathitt Gray <vilhelm.gray@gmail.com>
> diff --git a/drivers/counter/104-quad-8.c b/drivers/counter/104-quad-8.c
> new file mode 100644
> index 000000000000..7c72fb72d660
> --- /dev/null
> +++ b/drivers/counter/104-quad-8.c
> @@ -0,0 +1,1335 @@
> +// SPDX-License-Identifier: GPL-2.0-only
If you are happy with SPDX drop the GPL text below to keep things
short.
> +/*
> + * IIO driver for the ACCES 104-QUAD-8
> + * Copyright (C) 2016 William Breathitt Gray
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License, version 2, as
> + * published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful, but
> + * WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + * General Public License for more details.
> + *
> + * This driver supports the ACCES 104-QUAD-8 and ACCES 104-QUAD-4.
> + */
> +#include <linux/bitops.h>
...
> +static int quad8_probe(struct device *dev, unsigned int id)
> +{
> + struct iio_dev *indio_dev;
> + struct quad8_iio *quad8iio;
> + int i, j;
> + unsigned int base_offset;
> + int err;
> +
> + if (!devm_request_region(dev, base[id], QUAD8_EXTENT, dev_name(dev))) {
> + dev_err(dev, "Unable to lock port addresses (0x%X-0x%X)\n",
> + base[id], base[id] + QUAD8_EXTENT);
> + return -EBUSY;
> + }
> +
> + /* Allocate IIO device; this also allocates driver data structure */
> + indio_dev = devm_iio_device_alloc(dev, sizeof(*quad8iio));
> + if (!indio_dev)
> + return -ENOMEM;
> +
> + /* Initialize IIO device */
> + indio_dev->info = &quad8_info;
> + indio_dev->modes = INDIO_DIRECT_MODE;
> + indio_dev->num_channels = ARRAY_SIZE(quad8_channels);
> + indio_dev->channels = quad8_channels;
> + indio_dev->name = dev_name(dev);
> + indio_dev->dev.parent = dev;
> +
> + /* Initialize Counter device and driver data */
> + quad8iio = iio_priv(indio_dev);
> + quad8iio->counter.name = dev_name(dev);
> + quad8iio->counter.parent = dev;
> + quad8iio->counter.ops = &quad8_ops;
> + quad8iio->counter.counts = quad8_counts;
> + quad8iio->counter.num_counts = ARRAY_SIZE(quad8_counts);
> + quad8iio->counter.signals = quad8_signals;
> + quad8iio->counter.num_signals = ARRAY_SIZE(quad8_signals);
> + quad8iio->counter.priv = quad8iio;
> + quad8iio->base = base[id];
> +
> + /* Reset all counters and disable interrupt function */
> + outb(0x01, base[id] + 0x11);
> + /* Set initial configuration for all counters */
> + for (i = 0; i < QUAD8_NUM_COUNTERS; i++) {
> + base_offset = base[id] + 2 * i;
> + /* Reset Byte Pointer */
> + outb(0x01, base_offset + 1);
I'm going to be fussy. There are lots of values
in here that look like register bits and you could exchange much of
this documentation for a some good defines...
Taking base_offset + 1 bits 5 and 6 look to select the actual register
and the rest of them do the control.
Anyhow, not critical but the readability of this code could be improved
somewhat.
> + /* Reset Preset Register */
> + for (j = 0; j < 3; j++)
> + outb(0x00, base_offset);
> + /* Reset Borrow, Carry, Compare, and Sign flags */
> + outb(0x04, base_offset + 1);
> + /* Reset Error flag */
> + outb(0x06, base_offset + 1);
> + /* Binary encoding; Normal count; non-quadrature mode */
> + outb(0x20, base_offset + 1);
> + /* Disable A and B inputs; preset on index; FLG1 as Carry */
> + outb(0x40, base_offset + 1);
> + /* Disable index function; negative index polarity */
> + outb(0x60, base_offset + 1);
> + }
> + /* Enable all counters */
> + outb(0x00, base[id] + 0x11);
> +
> + /* Register IIO device */
> + err = devm_iio_device_register(dev, indio_dev);
> + if (err)
> + return err;
> +
> + /* Register Counter device */
> + return devm_counter_register(dev, &quad8iio->counter);
> +}
> +
> +static struct isa_driver quad8_driver = {
> + .probe = quad8_probe,
> + .driver = {
> + .name = "104-quad-8"
> + }
> +};
> +
> +module_isa_driver(quad8_driver, num_quad8);
> +
> +MODULE_AUTHOR("William Breathitt Gray <vilhelm.gray@gmail.com>");
> +MODULE_DESCRIPTION("ACCES 104-QUAD-8 IIO driver");
> +MODULE_LICENSE("GPL v2");
> diff --git a/drivers/counter/Kconfig b/drivers/counter/Kconfig
> index 65fa92abd5a4..73f03372484f 100644
> --- a/drivers/counter/Kconfig
> +++ b/drivers/counter/Kconfig
> @@ -16,3 +16,24 @@ menuconfig COUNTER
> consumption. The Generic Counter interface enables drivers to support
> and expose a common set of components and functionality present in
> counter devices.
> +
> +if COUNTER
> +
> +config 104_QUAD_8
> + tristate "ACCES 104-QUAD-8 driver"
> + depends on PC104 && X86 && IIO
> + select ISA_BUS_API
> + help
> + Say yes here to build support for the ACCES 104-QUAD-8 quadrature
> + encoder counter/interface device family (104-QUAD-8, 104-QUAD-4).
> +
> + Performing a write to a counter's IIO_CHAN_INFO_RAW sets the counter and
> + also clears the counter's respective error flag. Although the counters
> + have a 25-bit range, only the lower 24 bits may be set, either directly
> + or via a counter's preset attribute. Interrupts are not supported by
> + this driver.
This text probably wants to be updated to reflect the new counter subsystem support..
> +
> + The base port addresses for the devices may be configured via the base
> + array module parameter.
> +
> +endif # COUNTER
> diff --git a/drivers/counter/Makefile b/drivers/counter/Makefile
> index ad1ba7109cdc..23a4f6263e45 100644
> --- a/drivers/counter/Makefile
> +++ b/drivers/counter/Makefile
> @@ -6,3 +6,5 @@
>
> obj-$(CONFIG_COUNTER) += counter.o
> counter-y := generic-counter.o
> +
> +obj-$(CONFIG_104_QUAD_8) += 104-quad-8.o
> diff --git a/drivers/iio/counter/104-quad-8.c b/drivers/iio/counter/104-quad-8.c
...
^ permalink raw reply
* Re: [PATCH v6 6/9] dt-bindings: counter: Document stm32 quadrature encoder
From: Jonathan Cameron @ 2018-05-20 15:47 UTC (permalink / raw)
To: Rob Herring
Cc: Benjamin Gaignard, William Breathitt Gray, Mark Rutland,
devicetree, Benjamin Gaignard, linux-iio,
linux-kernel@vger.kernel.org,
moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE,
Fabrice Gasnier
In-Reply-To: <20180518162815.GA24966@rob-hp-laptop>
On Fri, 18 May 2018 11:28:15 -0500
Rob Herring <robh@kernel.org> wrote:
> On Thu, May 17, 2018 at 08:59:40PM +0200, Benjamin Gaignard wrote:
> > 2018-05-17 18:23 GMT+02:00 Rob Herring <robh+dt@kernel.org>:
> > > On Wed, May 16, 2018 at 12:51 PM, William Breathitt Gray
> > > <vilhelm.gray@gmail.com> wrote:
> > >> From: Benjamin Gaignard <benjamin.gaignard@st.com>
> > >
> > > v6? Where's v1-v5?
> > >
> > >> Add bindings for STM32 Timer quadrature encoder.
> > >> It is a sub-node of STM32 Timer which implement the
> > >> counter part of the hardware.
> > >>
> > >> Cc: Rob Herring <robh+dt@kernel.org>
> > >> Cc: Mark Rutland <mark.rutland@arm.com>
> > >> Signed-off-by: Benjamin Gaignard <benjamin.gaignard@st.com>
> > >> Signed-off-by: William Breathitt Gray <vilhelm.gray@gmail.com>
> > >> ---
> > >> .../bindings/counter/stm32-timer-cnt.txt | 26 +++++++++++++++++++
> > >> .../devicetree/bindings/mfd/stm32-timers.txt | 7 +++++
> > >> 2 files changed, 33 insertions(+)
> > >> create mode 100644 Documentation/devicetree/bindings/counter/stm32-timer-cnt.txt
> > >>
> > >> diff --git a/Documentation/devicetree/bindings/counter/stm32-timer-cnt.txt b/Documentation/devicetree/bindings/counter/stm32-timer-cnt.txt
> > >> new file mode 100644
> > >> index 000000000000..377728128bef
> > >> --- /dev/null
> > >> +++ b/Documentation/devicetree/bindings/counter/stm32-timer-cnt.txt
> > >> @@ -0,0 +1,26 @@
> > >> +STMicroelectronics STM32 Timer quadrature encoder
> > >> +
> > >> +STM32 Timer provides quadrature encoder counter mode to detect
> > >
> > > 'mode' does not sound like a sub-block of the timers block.
> >
> > quadrature encoding is one of the counting modes of this hardware
> > block which is enable to count on other signals/triggers
>
> You don't need a child node and compatible to set a mode.
A pile of extra hardware becomes relevant and you only want
to be in this state if you have appropriate external device
wired up. In this case there is admittedly not a lot here
but some devices will look a bit more like a touchscreen controller.
They are often build on top of an ADC module, but have a load
of touch screen only signals and electrical elements that
warrant being represented as a separate node in the DT.
>
> > >> +angular position and direction of rotary elements,
> > >> +from IN1 and IN2 input signals.
> > >> +
> > >> +Must be a sub-node of an STM32 Timer device tree node.
> > >> +See ../mfd/stm32-timers.txt for details about the parent node.
> > >> +
> > >> +Required properties:
> > >> +- compatible: Must be "st,stm32-timer-counter".
> > >> +- pinctrl-names: Set to "default".
> > >> +- pinctrl-0: List of phandles pointing to pin configuration nodes,
> > >> + to set IN1/IN2 pins in mode of operation for Low-Power
> > >> + Timer input on external pin.
> > >> +
> > >> +Example:
> > >> + timers@40010000 {
> > >> + compatible = "st,stm32-timers";
> > >> + ...
> > >> + counter {
> > >> + compatible = "st,stm32-timer-counter";
> > >
> > > Is there only 1? How is the counter addressed?
> >
> > Yes there is only one counter per hardware block.
> > Counter is addressed like the two others sub-nodes and the details
> > about parent mode are describe in stm32-timers.txt
> > Should I add them here too ? so example will be like that:
>
> No, you should drop the child node and add pinctrl to the parent.
>
> Any other functions this block has that you plan on adding? Please make
> bindings as complete as possible, not what you currently have drivers
> for.
>
> > timers@40010000 {
> > #address-cells = <1>;
> > #size-cells = <0>;
> > compatible = "st,stm32-timers";
> > reg = <0x40010000 0x400>;
> > clocks = <&rcc 0 160>;
> > clock-names = "int";
> > counter {
> > compatible = "st,stm32-timer-counter";
> > pinctrl-names = "default";
> > pinctrl-0 = <&tim1_in_pins>;
> > };
> > };
> >
> > Benjamin
> > >
> > > _______________________________________________
> > > linux-arm-kernel mailing list
> > > linux-arm-kernel@lists.infradead.org
> > > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v6 9/9] iio: counter: Remove IIO counter subdirectory
From: Jonathan Cameron @ 2018-05-20 15:53 UTC (permalink / raw)
To: William Breathitt Gray
Cc: benjamin.gaignard, fabrice.gasnier, linux-iio, linux-kernel,
devicetree, linux-arm-kernel
In-Reply-To: <4c335e0eebfbaf6e86f41e0f2864d76993d90b13.1526487615.git.vilhelm.gray@gmail.com>
On Wed, 16 May 2018 13:52:39 -0400
William Breathitt Gray <vilhelm.gray@gmail.com> wrote:
> This patch removes the IIO counter subdirectory which is now superceded
> by the Counter subsystem. Deprecation warnings are added to the
> documentation of the relevant IIO counter sysfs attributes.
>
> Signed-off-by: William Breathitt Gray <vilhelm.gray@gmail.com>
Please drop the directory when it becomes empty rather than in a later
patch. IIRC there are some issues with empty Makefiles that will
make building inbetween tricky.
For the deprecated markings.
Acked-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
> ---
> Documentation/ABI/testing/sysfs-bus-iio | 8 ++++++++
> .../ABI/testing/sysfs-bus-iio-counter-104-quad-8 | 16 ++++++++++++++++
> drivers/iio/Kconfig | 1 -
> drivers/iio/Makefile | 1 -
> drivers/iio/counter/Kconfig | 8 --------
> drivers/iio/counter/Makefile | 5 -----
> 6 files changed, 24 insertions(+), 15 deletions(-)
> delete mode 100644 drivers/iio/counter/Kconfig
> delete mode 100644 drivers/iio/counter/Makefile
>
> diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio
> index 731146c3b138..6115d97b075e 100644
> --- a/Documentation/ABI/testing/sysfs-bus-iio
> +++ b/Documentation/ABI/testing/sysfs-bus-iio
> @@ -1637,6 +1637,8 @@ What: /sys/bus/iio/devices/iio:deviceX/in_countY_raw
> KernelVersion: 4.10
> Contact: linux-iio@vger.kernel.org
> Description:
> + This interface is deprecated; please use the Counter subsystem.
> +
> Raw counter device counts from channel Y. For quadrature
> counters, multiplication by an available [Y]_scale results in
> the counts of a single quadrature signal phase from channel Y.
> @@ -1645,6 +1647,8 @@ What: /sys/bus/iio/devices/iio:deviceX/in_indexY_raw
> KernelVersion: 4.10
> Contact: linux-iio@vger.kernel.org
> Description:
> + This interface is deprecated; please use the Counter subsystem.
> +
> Raw counter device index value from channel Y. This attribute
> provides an absolute positional reference (e.g. a pulse once per
> revolution) which may be used to home positional systems as
> @@ -1654,6 +1658,8 @@ What: /sys/bus/iio/devices/iio:deviceX/in_count_count_direction_available
> KernelVersion: 4.12
> Contact: linux-iio@vger.kernel.org
> Description:
> + This interface is deprecated; please use the Counter subsystem.
> +
> A list of possible counting directions which are:
> - "up" : counter device is increasing.
> - "down": counter device is decreasing.
> @@ -1662,4 +1668,6 @@ What: /sys/bus/iio/devices/iio:deviceX/in_countY_count_direction
> KernelVersion: 4.12
> Contact: linux-iio@vger.kernel.org
> Description:
> + This interface is deprecated; please use the Counter subsystem.
> +
> Raw counter device counters direction for channel Y.
> diff --git a/Documentation/ABI/testing/sysfs-bus-iio-counter-104-quad-8 b/Documentation/ABI/testing/sysfs-bus-iio-counter-104-quad-8
> index 7fac2c268d9a..bac3d0d48b7b 100644
> --- a/Documentation/ABI/testing/sysfs-bus-iio-counter-104-quad-8
> +++ b/Documentation/ABI/testing/sysfs-bus-iio-counter-104-quad-8
> @@ -6,6 +6,8 @@ What: /sys/bus/iio/devices/iio:deviceX/in_index_synchronous_mode_available
> KernelVersion: 4.10
> Contact: linux-iio@vger.kernel.org
> Description:
> + This interface is deprecated; please use the Counter subsystem.
> +
> Discrete set of available values for the respective counter
> configuration are listed in this file.
>
> @@ -13,6 +15,8 @@ What: /sys/bus/iio/devices/iio:deviceX/in_countY_count_mode
> KernelVersion: 4.10
> Contact: linux-iio@vger.kernel.org
> Description:
> + This interface is deprecated; please use the Counter subsystem.
> +
> Count mode for channel Y. Four count modes are available:
> normal, range limit, non-recycle, and modulo-n. The preset value
> for channel Y is used by the count mode where required.
> @@ -47,6 +51,8 @@ What: /sys/bus/iio/devices/iio:deviceX/in_countY_noise_error
> KernelVersion: 4.10
> Contact: linux-iio@vger.kernel.org
> Description:
> + This interface is deprecated; please use the Counter subsystem.
> +
> Read-only attribute that indicates whether excessive noise is
> present at the channel Y count inputs in quadrature clock mode;
> irrelevant in non-quadrature clock mode.
> @@ -55,6 +61,8 @@ What: /sys/bus/iio/devices/iio:deviceX/in_countY_preset
> KernelVersion: 4.10
> Contact: linux-iio@vger.kernel.org
> Description:
> + This interface is deprecated; please use the Counter subsystem.
> +
> If the counter device supports preset registers, the preset
> count for channel Y is provided by this attribute.
>
> @@ -62,6 +70,8 @@ What: /sys/bus/iio/devices/iio:deviceX/in_countY_quadrature_mode
> KernelVersion: 4.10
> Contact: linux-iio@vger.kernel.org
> Description:
> + This interface is deprecated; please use the Counter subsystem.
> +
> Configure channel Y counter for non-quadrature or quadrature
> clock mode. Selecting non-quadrature clock mode will disable
> synchronous load mode. In quadrature clock mode, the channel Y
> @@ -83,6 +93,8 @@ What: /sys/bus/iio/devices/iio:deviceX/in_countY_set_to_preset_on_index
> KernelVersion: 4.10
> Contact: linux-iio@vger.kernel.org
> Description:
> + This interface is deprecated; please use the Counter subsystem.
> +
> Whether to set channel Y counter with channel Y preset value
> when channel Y index input is active, or continuously count.
> Valid attribute values are boolean.
> @@ -91,6 +103,8 @@ What: /sys/bus/iio/devices/iio:deviceX/in_indexY_index_polarity
> KernelVersion: 4.10
> Contact: linux-iio@vger.kernel.org
> Description:
> + This interface is deprecated; please use the Counter subsystem.
> +
> Active level of channel Y index input; irrelevant in
> non-synchronous load mode.
>
> @@ -98,6 +112,8 @@ What: /sys/bus/iio/devices/iio:deviceX/in_indexY_synchronous_mode
> KernelVersion: 4.10
> Contact: linux-iio@vger.kernel.org
> Description:
> + This interface is deprecated; please use the Counter subsystem.
> +
> Configure channel Y counter for non-synchronous or synchronous
> load mode. Synchronous load mode cannot be selected in
> non-quadrature clock mode.
> diff --git a/drivers/iio/Kconfig b/drivers/iio/Kconfig
> index d69e85a8bdc3..1152efad91a1 100644
> --- a/drivers/iio/Kconfig
> +++ b/drivers/iio/Kconfig
> @@ -74,7 +74,6 @@ source "drivers/iio/afe/Kconfig"
> source "drivers/iio/amplifiers/Kconfig"
> source "drivers/iio/chemical/Kconfig"
> source "drivers/iio/common/Kconfig"
> -source "drivers/iio/counter/Kconfig"
> source "drivers/iio/dac/Kconfig"
> source "drivers/iio/dummy/Kconfig"
> source "drivers/iio/frequency/Kconfig"
> diff --git a/drivers/iio/Makefile b/drivers/iio/Makefile
> index d8cba9c229c0..7bdd31f1b88f 100644
> --- a/drivers/iio/Makefile
> +++ b/drivers/iio/Makefile
> @@ -20,7 +20,6 @@ obj-y += amplifiers/
> obj-y += buffer/
> obj-y += chemical/
> obj-y += common/
> -obj-y += counter/
> obj-y += dac/
> obj-y += dummy/
> obj-y += gyro/
> diff --git a/drivers/iio/counter/Kconfig b/drivers/iio/counter/Kconfig
> deleted file mode 100644
> index 95a7a0df6cac..000000000000
> --- a/drivers/iio/counter/Kconfig
> +++ /dev/null
> @@ -1,8 +0,0 @@
> -#
> -# Counter devices
> -#
> -# When adding new entries keep the list in alphabetical order
> -
> -menu "Counters"
> -
> -endmenu
> diff --git a/drivers/iio/counter/Makefile b/drivers/iio/counter/Makefile
> deleted file mode 100644
> index 8fd3d954775a..000000000000
> --- a/drivers/iio/counter/Makefile
> +++ /dev/null
> @@ -1,5 +0,0 @@
> -#
> -# Makefile for IIO counter devices
> -#
> -
> -# When adding new entries keep the list in alphabetical order
^ permalink raw reply
* [PATCH v1 0/7] add external interrupt support to MT7622 pinctrl
From: sean.wang @ 2018-05-20 17:01 UTC (permalink / raw)
To: robh+dt, mark.rutland, linus.walleij, matthias.bgg, devicetree,
linux-mediatek
Cc: linux-gpio, Sean Wang, linux-kernel, linux-arm-kernel
From: Sean Wang <sean.wang@mediatek.com>
The series is to add external interrupt support to MT7622 pinctrl.
Before we can freely do that in pinctrl-mt7622.c with patch 3, a refactor
work has to be done with patch 2 to split EINT-related code from a
specific driver and then allows pintrl-mt7622.c to reuse it.
patch 1, 3, 7: add EINT support to MT7622 pinctrl.
patch 2, 6: make EINT-related become a generic way for all MediaTek
pinctrl.
patch 4, 5: eliminate unnecessary code in existent EINT-related ones after
refactor work was done.
Sean Wang (7):
dt-bindings: pinctrl: add external interrupt support to MT7622 pinctrl
pinctrl: mediatek: refactor EINT related code for all MediaTek pinctrl
can fit
pinctrl: mediatek: add EINT support to MT7622 SoC
pinctrl: mediatek: use generic EINT register maps for each SoC
pinctrl: mediatek: remove unused fields in struct mtk_eint_hw
MAINTAINERS: update entry for PIN CONTROLLER - MEDIATEK
arm64: dts: mt7622: add EINT support to pinctrl
.../devicetree/bindings/pinctrl/pinctrl-mt7622.txt | 10 +
MAINTAINERS | 1 +
arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts | 2 +-
arch/arm64/boot/dts/mediatek/mt7622.dtsi | 8 +-
drivers/pinctrl/mediatek/Kconfig | 6 +
drivers/pinctrl/mediatek/Makefile | 1 +
drivers/pinctrl/mediatek/mtk-eint.c | 492 +++++++++++++++++
drivers/pinctrl/mediatek/mtk-eint.h | 106 ++++
drivers/pinctrl/mediatek/pinctrl-mt2701.c | 25 +-
drivers/pinctrl/mediatek/pinctrl-mt2712.c | 25 +-
drivers/pinctrl/mediatek/pinctrl-mt7622.c | 143 +++++
drivers/pinctrl/mediatek/pinctrl-mt8127.c | 25 +-
drivers/pinctrl/mediatek/pinctrl-mt8135.c | 25 +-
drivers/pinctrl/mediatek/pinctrl-mt8173.c | 25 +-
drivers/pinctrl/mediatek/pinctrl-mtk-common.c | 608 ++++-----------------
drivers/pinctrl/mediatek/pinctrl-mtk-common.h | 13 +-
16 files changed, 901 insertions(+), 614 deletions(-)
create mode 100644 drivers/pinctrl/mediatek/mtk-eint.c
create mode 100644 drivers/pinctrl/mediatek/mtk-eint.h
--
2.7.4
^ permalink raw reply
* [PATCH v1 1/7] dt-bindings: pinctrl: add external interrupt support to MT7622 pinctrl
From: sean.wang @ 2018-05-20 17:01 UTC (permalink / raw)
To: robh+dt, mark.rutland, linus.walleij, matthias.bgg, devicetree,
linux-mediatek
Cc: linux-arm-kernel, linux-gpio, linux-kernel, Sean Wang
In-Reply-To: <cover.1526835466.git.sean.wang@mediatek.com>
From: Sean Wang <sean.wang@mediatek.com>
Extend the capability of MT7622 pinctrl with adding EINT so that each
GPIO can be used to notify CPU when a signal state is changing on the
line as an external interrupt.
Signed-off-by: Sean Wang <sean.wang@mediatek.com>
---
Documentation/devicetree/bindings/pinctrl/pinctrl-mt7622.txt | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-mt7622.txt b/Documentation/devicetree/bindings/pinctrl/pinctrl-mt7622.txt
index f18ed99..743b32d 100644
--- a/Documentation/devicetree/bindings/pinctrl/pinctrl-mt7622.txt
+++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-mt7622.txt
@@ -9,6 +9,16 @@ Required properties for the root node:
- #gpio-cells: Should be two. The first cell is the pin number and the
second is the GPIO flags.
+Optional properties:
+- interrupt-controller : Marks the device node as an interrupt controller
+
+If the property interrupt-controller is defined, following property is required
+- reg-names: A string describing the "reg" entries. Must contain "eint".
+- interrupts : The interrupt output from the controller.
+- #interrupt-cells: Should be two.
+- interrupt-parent: Phandle of the interrupt parent to which the external
+ GPIO interrupts are forwarded to.
+
Please refer to pinctrl-bindings.txt in this directory for details of the
common pinctrl bindings used by client devices, including the meaning of the
phrase "pin configuration node".
--
2.7.4
^ permalink raw reply related
* [PATCH v1 2/7] pinctrl: mediatek: refactor EINT related code for all MediaTek pinctrl can fit
From: sean.wang @ 2018-05-20 17:01 UTC (permalink / raw)
To: robh+dt, mark.rutland, linus.walleij, matthias.bgg, devicetree,
linux-mediatek
Cc: linux-arm-kernel, linux-gpio, linux-kernel, Sean Wang
In-Reply-To: <cover.1526835466.git.sean.wang@mediatek.com>
From: Sean Wang <sean.wang@mediatek.com>
This patch is in preparation for adding EINT support to MT7622 pinctrl,
and the refactoring doesn't alter any existent logic.
A reason we have to refactor EINT code pieces into a generic way is that
currently, they're tightly coupled with a certain type of MediaTek pinctrl
would cause a grown in a very bad way as there is different types of
pinctrl devices getting to join.
Therefore, it is an essential or urgent thing that EINT code pieces are
refactored to eliminate any dependencies across GPIO and EINT as possible.
Additional structure mtk_eint_[xt, hw, regs] are being introduced for
indicating how maps being designed between GPIO and EINT hw number, how to
set and get GPIO state for a certain EINT pin, what characteristic on a
EINT device is present on various SoCs.
Signed-off-by: Sean Wang <sean.wang@mediatek.com>
---
drivers/pinctrl/mediatek/Kconfig | 6 +
drivers/pinctrl/mediatek/Makefile | 1 +
drivers/pinctrl/mediatek/mtk-eint.c | 492 +++++++++++++++++++++
drivers/pinctrl/mediatek/mtk-eint.h | 107 +++++
drivers/pinctrl/mediatek/pinctrl-mt2701.c | 12 +-
drivers/pinctrl/mediatek/pinctrl-mt2712.c | 12 +-
drivers/pinctrl/mediatek/pinctrl-mt8127.c | 12 +-
drivers/pinctrl/mediatek/pinctrl-mt8135.c | 12 +-
drivers/pinctrl/mediatek/pinctrl-mt8173.c | 12 +-
drivers/pinctrl/mediatek/pinctrl-mtk-common.c | 604 +++++---------------------
drivers/pinctrl/mediatek/pinctrl-mtk-common.h | 13 +-
11 files changed, 756 insertions(+), 527 deletions(-)
create mode 100644 drivers/pinctrl/mediatek/mtk-eint.c
create mode 100644 drivers/pinctrl/mediatek/mtk-eint.h
diff --git a/drivers/pinctrl/mediatek/Kconfig b/drivers/pinctrl/mediatek/Kconfig
index 862c5db..310db42 100644
--- a/drivers/pinctrl/mediatek/Kconfig
+++ b/drivers/pinctrl/mediatek/Kconfig
@@ -1,12 +1,18 @@
menu "MediaTek pinctrl drivers"
depends on ARCH_MEDIATEK || COMPILE_TEST
+config EINT_MTK
+ bool "MediaTek External Interrupt Support"
+ depends on PINCTRL_MTK || COMPILE_TEST
+ select IRQ_DOMAIN
+
config PINCTRL_MTK
bool
depends on OF
select PINMUX
select GENERIC_PINCONF
select GPIOLIB
+ select EINT_MTK
select OF_GPIO
# For ARMv7 SoCs
diff --git a/drivers/pinctrl/mediatek/Makefile b/drivers/pinctrl/mediatek/Makefile
index 7959e77..3de7156 100644
--- a/drivers/pinctrl/mediatek/Makefile
+++ b/drivers/pinctrl/mediatek/Makefile
@@ -1,5 +1,6 @@
# SPDX-License-Identifier: GPL-2.0
# Core
+obj-$(CONFIG_EINT_MTK) += mtk-eint.o
obj-$(CONFIG_PINCTRL_MTK) += pinctrl-mtk-common.o
# SoC Drivers
diff --git a/drivers/pinctrl/mediatek/mtk-eint.c b/drivers/pinctrl/mediatek/mtk-eint.c
new file mode 100644
index 0000000..30f3316
--- /dev/null
+++ b/drivers/pinctrl/mediatek/mtk-eint.c
@@ -0,0 +1,492 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2014-2018 MediaTek Inc.
+
+/*
+ * Library for MediaTek External Interrupt Support
+ *
+ * Author: Maoguang Meng <maoguang.meng@mediatek.com>
+ * Sean Wang <sean.wang@mediatek.com>
+ *
+ */
+
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/gpio.h>
+#include <linux/io.h>
+#include <linux/irqdomain.h>
+#include <linux/of_irq.h>
+#include <linux/platform_device.h>
+
+#include "mtk-eint.h"
+
+#define MTK_EINT_EDGE_SENSITIVE 0
+#define MTK_EINT_LEVEL_SENSITIVE 1
+#define MTK_EINT_DBNC_SET_DBNC_BITS 4
+#define MTK_EINT_DBNC_RST_BIT (0x1 << 1)
+#define MTK_EINT_DBNC_SET_EN (0x1 << 0)
+
+static const struct mtk_eint_regs mtk_generic_eint_regs = {
+ .stat = 0x000,
+ .ack = 0x040,
+ .mask = 0x080,
+ .mask_set = 0x0c0,
+ .mask_clr = 0x100,
+ .sens = 0x140,
+ .sens_set = 0x180,
+ .sens_clr = 0x1c0,
+ .soft = 0x200,
+ .soft_set = 0x240,
+ .soft_clr = 0x280,
+ .pol = 0x300,
+ .pol_set = 0x340,
+ .pol_clr = 0x380,
+ .dom_en = 0x400,
+ .dbnc_ctrl = 0x500,
+ .dbnc_set = 0x600,
+ .dbnc_clr = 0x700,
+};
+
+static void __iomem *mtk_eint_get_offset(struct mtk_eint *eint,
+ unsigned int eint_num,
+ unsigned int offset)
+{
+ unsigned int eint_base = 0;
+ void __iomem *reg;
+
+ if (eint_num >= eint->hw->ap_num)
+ eint_base = eint->hw->ap_num;
+
+ reg = eint->base + offset + ((eint_num - eint_base) / 32) * 4;
+
+ return reg;
+}
+
+static unsigned int mtk_eint_can_en_debounce(struct mtk_eint *eint,
+ unsigned int eint_num)
+{
+ unsigned int sens;
+ unsigned int bit = BIT(eint_num % 32);
+ void __iomem *reg = mtk_eint_get_offset(eint, eint_num,
+ eint->regs->sens);
+
+ if (readl(reg) & bit)
+ sens = MTK_EINT_LEVEL_SENSITIVE;
+ else
+ sens = MTK_EINT_EDGE_SENSITIVE;
+
+ if (eint_num < eint->hw->db_cnt && sens != MTK_EINT_EDGE_SENSITIVE)
+ return 1;
+ else
+ return 0;
+}
+
+static int mtk_eint_flip_edge(struct mtk_eint *eint, int hwirq)
+{
+ int start_level, curr_level;
+ unsigned int reg_offset;
+ u32 mask = BIT(hwirq & 0x1f);
+ u32 port = (hwirq >> 5) & eint->hw->port_mask;
+ void __iomem *reg = eint->base + (port << 2);
+
+ curr_level = eint->gpio_xlate->get_gpio_state(eint->pctl, hwirq);
+
+ do {
+ start_level = curr_level;
+ if (start_level)
+ reg_offset = eint->regs->pol_clr;
+ else
+ reg_offset = eint->regs->pol_set;
+ writel(mask, reg + reg_offset);
+
+ curr_level = eint->gpio_xlate->get_gpio_state(eint->pctl,
+ hwirq);
+ } while (start_level != curr_level);
+
+ return start_level;
+}
+
+static void mtk_eint_mask(struct irq_data *d)
+{
+ struct mtk_eint *eint = irq_data_get_irq_chip_data(d);
+ u32 mask = BIT(d->hwirq & 0x1f);
+ void __iomem *reg = mtk_eint_get_offset(eint, d->hwirq,
+ eint->regs->mask_set);
+
+ writel(mask, reg);
+}
+
+static void mtk_eint_unmask(struct irq_data *d)
+{
+ struct mtk_eint *eint = irq_data_get_irq_chip_data(d);
+ u32 mask = BIT(d->hwirq & 0x1f);
+ void __iomem *reg = mtk_eint_get_offset(eint, d->hwirq,
+ eint->regs->mask_clr);
+
+ writel(mask, reg);
+
+ if (eint->dual_edge[d->hwirq])
+ mtk_eint_flip_edge(eint, d->hwirq);
+}
+
+static unsigned int mtk_eint_get_mask(struct mtk_eint *eint,
+ unsigned int eint_num)
+{
+ unsigned int bit = BIT(eint_num % 32);
+ void __iomem *reg = mtk_eint_get_offset(eint, eint_num,
+ eint->regs->mask);
+
+ return !!(readl(reg) & bit);
+}
+
+static void mtk_eint_ack(struct irq_data *d)
+{
+ struct mtk_eint *eint = irq_data_get_irq_chip_data(d);
+ u32 mask = BIT(d->hwirq & 0x1f);
+ void __iomem *reg = mtk_eint_get_offset(eint, d->hwirq,
+ eint->regs->ack);
+
+ writel(mask, reg);
+}
+
+static int mtk_eint_set_type(struct irq_data *d, unsigned int type)
+{
+ struct mtk_eint *eint = irq_data_get_irq_chip_data(d);
+ u32 mask = BIT(d->hwirq & 0x1f);
+ void __iomem *reg;
+
+ if (((type & IRQ_TYPE_EDGE_BOTH) && (type & IRQ_TYPE_LEVEL_MASK)) ||
+ ((type & IRQ_TYPE_LEVEL_MASK) == IRQ_TYPE_LEVEL_MASK)) {
+ dev_err(eint->dev,
+ "Can't configure IRQ%d (EINT%lu) for type 0x%X\n",
+ d->irq, d->hwirq, type);
+ return -EINVAL;
+ }
+
+ if ((type & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH)
+ eint->dual_edge[d->hwirq] = 1;
+ else
+ eint->dual_edge[d->hwirq] = 0;
+
+ if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_EDGE_FALLING)) {
+ reg = mtk_eint_get_offset(eint, d->hwirq, eint->regs->pol_clr);
+ writel(mask, reg);
+ } else {
+ reg = mtk_eint_get_offset(eint, d->hwirq, eint->regs->pol_set);
+ writel(mask, reg);
+ }
+
+ if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) {
+ reg = mtk_eint_get_offset(eint, d->hwirq, eint->regs->sens_clr);
+ writel(mask, reg);
+ } else {
+ reg = mtk_eint_get_offset(eint, d->hwirq, eint->regs->sens_set);
+ writel(mask, reg);
+ }
+
+ if (eint->dual_edge[d->hwirq])
+ mtk_eint_flip_edge(eint, d->hwirq);
+
+ return 0;
+}
+
+static int mtk_eint_irq_set_wake(struct irq_data *d, unsigned int on)
+{
+ struct mtk_eint *eint = irq_data_get_irq_chip_data(d);
+ int shift = d->hwirq & 0x1f;
+ int reg = d->hwirq >> 5;
+
+ if (on)
+ eint->wake_mask[reg] |= BIT(shift);
+ else
+ eint->wake_mask[reg] &= ~BIT(shift);
+
+ return 0;
+}
+
+static void mtk_eint_chip_write_mask(const struct mtk_eint *eint,
+ void __iomem *base, u32 *buf)
+{
+ int port;
+ void __iomem *reg;
+
+ for (port = 0; port < eint->hw->ports; port++) {
+ reg = base + (port << 2);
+ writel_relaxed(~buf[port], reg + eint->regs->mask_set);
+ writel_relaxed(buf[port], reg + eint->regs->mask_clr);
+ }
+}
+
+static void mtk_eint_chip_read_mask(const struct mtk_eint *eint,
+ void __iomem *base, u32 *buf)
+{
+ int port;
+ void __iomem *reg;
+
+ for (port = 0; port < eint->hw->ports; port++) {
+ reg = base + eint->regs->mask + (port << 2);
+ buf[port] = ~readl_relaxed(reg);
+ /* Mask is 0 when irq is enabled, and 1 when disabled. */
+ }
+}
+
+static int mtk_eint_irq_request_resources(struct irq_data *d)
+{
+ struct mtk_eint *eint = irq_data_get_irq_chip_data(d);
+ struct gpio_chip *gpio_c;
+ unsigned int gpio_n;
+ int err;
+
+ err = eint->gpio_xlate->get_gpio_n(eint->pctl, d->hwirq,
+ &gpio_n, &gpio_c);
+ if (err < 0) {
+ dev_err(eint->dev, "Can not find pin\n");
+ return err;
+ }
+
+ err = gpiochip_lock_as_irq(gpio_c, gpio_n);
+ if (err < 0) {
+ dev_err(eint->dev, "unable to lock HW IRQ %lu for IRQ\n",
+ irqd_to_hwirq(d));
+ return err;
+ }
+
+ err = eint->gpio_xlate->set_gpio_as_eint(eint->pctl, d->hwirq);
+ if (err < 0) {
+ dev_err(eint->dev, "Can not eint mode\n");
+ return err;
+ }
+
+ return 0;
+}
+
+static void mtk_eint_irq_release_resources(struct irq_data *d)
+{
+ struct mtk_eint *eint = irq_data_get_irq_chip_data(d);
+ struct gpio_chip *gpio_c;
+ unsigned int gpio_n;
+
+ eint->gpio_xlate->get_gpio_n(eint->pctl, d->hwirq, &gpio_n,
+ &gpio_c);
+
+ gpiochip_unlock_as_irq(gpio_c, gpio_n);
+}
+
+static struct irq_chip mtk_eint_irq_chip = {
+ .name = "mt-eint",
+ .irq_disable = mtk_eint_mask,
+ .irq_mask = mtk_eint_mask,
+ .irq_unmask = mtk_eint_unmask,
+ .irq_ack = mtk_eint_ack,
+ .irq_set_type = mtk_eint_set_type,
+ .irq_set_wake = mtk_eint_irq_set_wake,
+ .irq_request_resources = mtk_eint_irq_request_resources,
+ .irq_release_resources = mtk_eint_irq_release_resources,
+};
+
+static unsigned int mtk_eint_hw_init(struct mtk_eint *eint)
+{
+ void __iomem *reg = eint->base + eint->regs->dom_en;
+ unsigned int i;
+
+ for (i = 0; i < eint->hw->ap_num; i += 32) {
+ writel(0xffffffff, reg);
+ reg += 4;
+ }
+
+ return 0;
+}
+
+static inline void
+mtk_eint_debounce_process(struct mtk_eint *eint, int index)
+{
+ unsigned int rst, ctrl_offset;
+ unsigned int bit, dbnc;
+
+ ctrl_offset = (index / 4) * 4 + eint->regs->dbnc_ctrl;
+ dbnc = readl(eint->base + ctrl_offset);
+ bit = MTK_EINT_DBNC_SET_EN << ((index % 4) * 8);
+ if ((bit & dbnc) > 0) {
+ ctrl_offset = (index / 4) * 4 + eint->regs->dbnc_set;
+ rst = MTK_EINT_DBNC_RST_BIT << ((index % 4) * 8);
+ writel(rst, eint->base + ctrl_offset);
+ }
+}
+
+static void mtk_eint_irq_handler(struct irq_desc *desc)
+{
+ struct irq_chip *chip = irq_desc_get_chip(desc);
+ struct mtk_eint *eint = irq_desc_get_handler_data(desc);
+ unsigned int status, eint_num;
+ int offset, index, virq;
+ void __iomem *reg = mtk_eint_get_offset(eint, 0, eint->regs->stat);
+ int dual_edge, start_level, curr_level;
+
+ chained_irq_enter(chip, desc);
+ for (eint_num = 0; eint_num < eint->hw->ap_num; eint_num += 32,
+ reg += 4) {
+ status = readl(reg);
+ while (status) {
+ offset = __ffs(status);
+ index = eint_num + offset;
+ virq = irq_find_mapping(eint->domain, index);
+ status &= ~BIT(offset);
+
+ dual_edge = eint->dual_edge[index];
+ if (dual_edge) {
+ /*
+ * Clear soft-irq in case we raised it last
+ * time.
+ */
+ writel(BIT(offset), reg - eint->regs->stat +
+ eint->regs->soft_clr);
+
+ start_level =
+ eint->gpio_xlate->get_gpio_state(eint->pctl,
+ index);
+ }
+
+ generic_handle_irq(virq);
+
+ if (dual_edge) {
+ curr_level = mtk_eint_flip_edge(eint, index);
+
+ /*
+ * If level changed, we might lost one edge
+ * interrupt, raised it through soft-irq.
+ */
+ if (start_level != curr_level)
+ writel(BIT(offset), reg -
+ eint->regs->stat +
+ eint->regs->soft_set);
+ }
+
+ if (index < eint->hw->db_cnt)
+ mtk_eint_debounce_process(eint, index);
+ }
+ }
+ chained_irq_exit(chip, desc);
+}
+
+int mtk_eint_do_suspend(struct mtk_eint *eint)
+{
+ mtk_eint_chip_read_mask(eint, eint->base, eint->cur_mask);
+ mtk_eint_chip_write_mask(eint, eint->base, eint->wake_mask);
+
+ return 0;
+}
+
+int mtk_eint_do_resume(struct mtk_eint *eint)
+{
+ mtk_eint_chip_write_mask(eint, eint->base, eint->cur_mask);
+
+ return 0;
+}
+
+int mtk_eint_set_debounce(struct mtk_eint *eint, unsigned long eint_num,
+ unsigned int debounce)
+{
+ int virq, eint_offset;
+ unsigned int set_offset, bit, clr_bit, clr_offset, rst, i, unmask,
+ dbnc;
+ static const unsigned int debounce_time[] = {500, 1000, 16000, 32000,
+ 64000, 128000, 256000};
+ struct irq_data *d;
+
+ virq = irq_find_mapping(eint->domain, eint_num);
+ eint_offset = (eint_num % 4) * 8;
+ d = irq_get_irq_data(virq);
+
+ set_offset = (eint_num / 4) * 4 + eint->regs->dbnc_set;
+ clr_offset = (eint_num / 4) * 4 + eint->regs->dbnc_clr;
+
+ if (!mtk_eint_can_en_debounce(eint, eint_num))
+ return -EINVAL;
+
+ dbnc = ARRAY_SIZE(debounce_time);
+ for (i = 0; i < ARRAY_SIZE(debounce_time); i++) {
+ if (debounce <= debounce_time[i]) {
+ dbnc = i;
+ break;
+ }
+ }
+
+ if (!mtk_eint_get_mask(eint, eint_num)) {
+ mtk_eint_mask(d);
+ unmask = 1;
+ } else {
+ unmask = 0;
+ }
+
+ clr_bit = 0xff << eint_offset;
+ writel(clr_bit, eint->base + clr_offset);
+
+ bit = ((dbnc << MTK_EINT_DBNC_SET_DBNC_BITS) | MTK_EINT_DBNC_SET_EN) <<
+ eint_offset;
+ rst = MTK_EINT_DBNC_RST_BIT << eint_offset;
+ writel(rst | bit, eint->base + set_offset);
+
+ /*
+ * Delay a while (more than 2T) to wait for hw debounce counter reset
+ * work correctly.
+ */
+ udelay(1);
+ if (unmask == 1)
+ mtk_eint_unmask(d);
+
+ return 0;
+}
+
+int mtk_eint_find_irq(struct mtk_eint *eint, unsigned long eint_n)
+{
+ int irq;
+
+ irq = irq_find_mapping(eint->domain, eint_n);
+ if (!irq)
+ return -EINVAL;
+
+ return irq;
+}
+
+int mtk_eint_do_init(struct mtk_eint *eint)
+{
+ int i;
+
+ /* If clients don't assign a specific regs, let's use generic one */
+ if (!eint->regs)
+ eint->regs = &mtk_generic_eint_regs;
+
+ eint->wake_mask = devm_kcalloc(eint->dev, eint->hw->ports,
+ sizeof(*eint->wake_mask), GFP_KERNEL);
+ if (!eint->wake_mask)
+ return -ENOMEM;
+
+ eint->cur_mask = devm_kcalloc(eint->dev, eint->hw->ports,
+ sizeof(*eint->cur_mask), GFP_KERNEL);
+ if (!eint->cur_mask)
+ return -ENOMEM;
+
+ eint->dual_edge = devm_kcalloc(eint->dev, eint->hw->ap_num,
+ sizeof(int), GFP_KERNEL);
+ if (!eint->dual_edge)
+ return -ENOMEM;
+
+ eint->domain = irq_domain_add_linear(eint->dev->of_node,
+ eint->hw->ap_num,
+ &irq_domain_simple_ops, NULL);
+ if (!eint->domain)
+ return -ENOMEM;
+
+ mtk_eint_hw_init(eint);
+ for (i = 0; i < eint->hw->ap_num; i++) {
+ int virq = irq_create_mapping(eint->domain, i);
+
+ irq_set_chip_and_handler(virq, &mtk_eint_irq_chip,
+ handle_level_irq);
+ irq_set_chip_data(virq, eint);
+ }
+
+ irq_set_chained_handler_and_data(eint->irq, mtk_eint_irq_handler,
+ eint);
+
+ return 0;
+}
diff --git a/drivers/pinctrl/mediatek/mtk-eint.h b/drivers/pinctrl/mediatek/mtk-eint.h
new file mode 100644
index 0000000..55b4d5f
--- /dev/null
+++ b/drivers/pinctrl/mediatek/mtk-eint.h
@@ -0,0 +1,107 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2014-2018 MediaTek Inc.
+ *
+ * Author: Maoguang Meng <maoguang.meng@mediatek.com>
+ * Sean Wang <sean.wang@mediatek.com>
+ *
+ */
+#ifndef __MTK_EINT_H
+#define __MTK_EINT_H
+
+#include <linux/irqdomain.h>
+
+struct mtk_eint_regs {
+ unsigned int stat;
+ unsigned int ack;
+ unsigned int mask;
+ unsigned int mask_set;
+ unsigned int mask_clr;
+ unsigned int sens;
+ unsigned int sens_set;
+ unsigned int sens_clr;
+ unsigned int soft;
+ unsigned int soft_set;
+ unsigned int soft_clr;
+ unsigned int pol;
+ unsigned int pol_set;
+ unsigned int pol_clr;
+ unsigned int dom_en;
+ unsigned int dbnc_ctrl;
+ unsigned int dbnc_set;
+ unsigned int dbnc_clr;
+};
+
+struct mtk_eint_hw {
+ const char *name;
+ u8 port_mask;
+ u8 ports;
+ unsigned int ap_num;
+ unsigned int db_cnt;
+};
+
+struct mtk_eint;
+
+struct mtk_eint_xt {
+ int (*get_gpio_n)(void *data, unsigned long eint_n,
+ unsigned int *gpio_n,
+ struct gpio_chip **gpio_chip);
+ int (*get_gpio_state)(void *data, unsigned long eint_n);
+ int (*set_gpio_as_eint)(void *data, unsigned long eint_n);
+};
+
+struct mtk_eint {
+ struct device *dev;
+ void __iomem *base;
+ struct irq_domain *domain;
+ int irq;
+
+ int *dual_edge;
+ u32 *wake_mask;
+ u32 *cur_mask;
+
+ /* Used to fit into various EINT device */
+ const struct mtk_eint_hw *hw;
+ const struct mtk_eint_regs *regs;
+
+ /* Used to fit into various pinctrl device */
+ void *pctl;
+ const struct mtk_eint_xt *gpio_xlate;
+};
+
+#if IS_ENABLED(CONFIG_EINT_MTK)
+int mtk_eint_do_init(struct mtk_eint *eint);
+int mtk_eint_do_suspend(struct mtk_eint *eint);
+int mtk_eint_do_resume(struct mtk_eint *eint);
+int mtk_eint_set_debounce(struct mtk_eint *eint, unsigned long eint_n,
+ unsigned int debounce);
+int mtk_eint_find_irq(struct mtk_eint *eint, unsigned long eint_n);
+
+#else
+static inline int mtk_eint_do_init(struct mtk_eint *eint)
+{
+ return -EOPNOTSUPP;
+}
+
+static inline int mtk_eint_do_suspend(struct mtk_eint *eint)
+{
+ return -EOPNOTSUPP;
+}
+
+static inline int mtk_eint_do_resume(struct mtk_eint *eint)
+{
+ return -EOPNOTSUPP;
+}
+
+int mtk_eint_set_debounce(struct mtk_eint *eint, unsigned long eint_n,
+ unsigned int debounce)
+{
+ return -EOPNOTSUPP;
+}
+
+int mtk_eint_find_irq(struct mtk_eint *eint, unsigned long eint_n)
+{
+ return -EOPNOTSUPP;
+}
+#endif
+#endif /* __MTK_EINT_H */
diff --git a/drivers/pinctrl/mediatek/pinctrl-mt2701.c b/drivers/pinctrl/mediatek/pinctrl-mt2701.c
index f86f3b3..e0963c6 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mt2701.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mt2701.c
@@ -531,8 +531,14 @@ static const struct mtk_pinctrl_devdata mt2701_pinctrl_data = {
.port_shf = 4,
.port_mask = 0x1f,
.port_align = 4,
- .eint_offsets = {
+ .eint_hw = {
.name = "mt2701_eint",
+ .port_mask = 6,
+ .ports = 6,
+ .ap_num = 169,
+ .db_cnt = 16,
+ },
+ .eint_regs = {
.stat = 0x000,
.ack = 0x040,
.mask = 0x080,
@@ -551,11 +557,7 @@ static const struct mtk_pinctrl_devdata mt2701_pinctrl_data = {
.dbnc_ctrl = 0x500,
.dbnc_set = 0x600,
.dbnc_clr = 0x700,
- .port_mask = 6,
- .ports = 6,
},
- .ap_num = 169,
- .db_cnt = 16,
};
static int mt2701_pinctrl_probe(struct platform_device *pdev)
diff --git a/drivers/pinctrl/mediatek/pinctrl-mt2712.c b/drivers/pinctrl/mediatek/pinctrl-mt2712.c
index 81e11f9..02aff28 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mt2712.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mt2712.c
@@ -576,8 +576,14 @@ static const struct mtk_pinctrl_devdata mt2712_pinctrl_data = {
.port_shf = 4,
.port_mask = 0xf,
.port_align = 4,
- .eint_offsets = {
+ .eint_hw = {
.name = "mt2712_eint",
+ .port_mask = 0xf,
+ .ports = 8,
+ .ap_num = 229,
+ .db_cnt = 40,
+ },
+ .eint_regs = {
.stat = 0x000,
.ack = 0x040,
.mask = 0x080,
@@ -596,11 +602,7 @@ static const struct mtk_pinctrl_devdata mt2712_pinctrl_data = {
.dbnc_ctrl = 0x500,
.dbnc_set = 0x600,
.dbnc_clr = 0x700,
- .port_mask = 0xf,
- .ports = 8,
},
- .ap_num = 229,
- .db_cnt = 40,
};
static int mt2712_pinctrl_probe(struct platform_device *pdev)
diff --git a/drivers/pinctrl/mediatek/pinctrl-mt8127.c b/drivers/pinctrl/mediatek/pinctrl-mt8127.c
index d764915..71f6258 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mt8127.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mt8127.c
@@ -300,8 +300,14 @@ static const struct mtk_pinctrl_devdata mt8127_pinctrl_data = {
.port_shf = 4,
.port_mask = 0xf,
.port_align = 4,
- .eint_offsets = {
+ .eint_hw = {
.name = "mt8127_eint",
+ .port_mask = 7,
+ .ports = 6,
+ .ap_num = 143,
+ .db_cnt = 16,
+ },
+ .eint_regs = {
.stat = 0x000,
.ack = 0x040,
.mask = 0x080,
@@ -320,11 +326,7 @@ static const struct mtk_pinctrl_devdata mt8127_pinctrl_data = {
.dbnc_ctrl = 0x500,
.dbnc_set = 0x600,
.dbnc_clr = 0x700,
- .port_mask = 7,
- .ports = 6,
},
- .ap_num = 143,
- .db_cnt = 16,
};
static int mt8127_pinctrl_probe(struct platform_device *pdev)
diff --git a/drivers/pinctrl/mediatek/pinctrl-mt8135.c b/drivers/pinctrl/mediatek/pinctrl-mt8135.c
index d8c645f..fdfa357 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mt8135.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mt8135.c
@@ -313,8 +313,14 @@ static const struct mtk_pinctrl_devdata mt8135_pinctrl_data = {
.port_shf = 4,
.port_mask = 0xf,
.port_align = 4,
- .eint_offsets = {
+ .eint_hw = {
.name = "mt8135_eint",
+ .port_mask = 7,
+ .ports = 6,
+ .ap_num = 192,
+ .db_cnt = 16,
+ },
+ .eint_regs = {
.stat = 0x000,
.ack = 0x040,
.mask = 0x080,
@@ -333,11 +339,7 @@ static const struct mtk_pinctrl_devdata mt8135_pinctrl_data = {
.dbnc_ctrl = 0x500,
.dbnc_set = 0x600,
.dbnc_clr = 0x700,
- .port_mask = 7,
- .ports = 6,
},
- .ap_num = 192,
- .db_cnt = 16,
};
static int mt8135_pinctrl_probe(struct platform_device *pdev)
diff --git a/drivers/pinctrl/mediatek/pinctrl-mt8173.c b/drivers/pinctrl/mediatek/pinctrl-mt8173.c
index 8bfd427..1466c95 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mt8173.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mt8173.c
@@ -340,8 +340,14 @@ static const struct mtk_pinctrl_devdata mt8173_pinctrl_data = {
.port_shf = 4,
.port_mask = 0xf,
.port_align = 4,
- .eint_offsets = {
+ .eint_hw = {
.name = "mt8173_eint",
+ .port_mask = 7,
+ .ports = 6,
+ .ap_num = 224,
+ .db_cnt = 16,
+ },
+ .eint_regs = {
.stat = 0x000,
.ack = 0x040,
.mask = 0x080,
@@ -360,11 +366,7 @@ static const struct mtk_pinctrl_devdata mt8173_pinctrl_data = {
.dbnc_ctrl = 0x500,
.dbnc_set = 0x600,
.dbnc_clr = 0x700,
- .port_mask = 7,
- .ports = 6,
},
- .ap_num = 224,
- .db_cnt = 16,
};
static int mt8173_pinctrl_probe(struct platform_device *pdev)
diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
index c3975a0..11e0d0f 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
@@ -38,6 +38,7 @@
#include "../core.h"
#include "../pinconf.h"
#include "../pinctrl-utils.h"
+#include "mtk-eint.h"
#include "pinctrl-mtk-common.h"
#define MAX_GPIO_MODE_PER_REG 5
@@ -831,243 +832,38 @@ static int mtk_gpio_get(struct gpio_chip *chip, unsigned offset)
static int mtk_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
{
- const struct mtk_desc_pin *pin;
struct mtk_pinctrl *pctl = gpiochip_get_data(chip);
- int irq;
-
- pin = pctl->devdata->pins + offset;
- if (pin->eint.eintnum == NO_EINT_SUPPORT)
- return -EINVAL;
-
- irq = irq_find_mapping(pctl->domain, pin->eint.eintnum);
- if (!irq)
- return -EINVAL;
-
- return irq;
-}
-
-static int mtk_pinctrl_irq_request_resources(struct irq_data *d)
-{
- struct mtk_pinctrl *pctl = irq_data_get_irq_chip_data(d);
- const struct mtk_desc_pin *pin;
- int ret;
-
- pin = mtk_find_pin_by_eint_num(pctl, d->hwirq);
-
- if (!pin) {
- dev_err(pctl->dev, "Can not find pin\n");
- return -EINVAL;
- }
-
- ret = gpiochip_lock_as_irq(pctl->chip, pin->pin.number);
- if (ret) {
- dev_err(pctl->dev, "unable to lock HW IRQ %lu for IRQ\n",
- irqd_to_hwirq(d));
- return ret;
- }
-
- /* set mux to INT mode */
- mtk_pmx_set_mode(pctl->pctl_dev, pin->pin.number, pin->eint.eintmux);
- /* set gpio direction to input */
- mtk_pmx_gpio_set_direction(pctl->pctl_dev, NULL, pin->pin.number, true);
- /* set input-enable */
- mtk_pconf_set_ies_smt(pctl, pin->pin.number, 1, PIN_CONFIG_INPUT_ENABLE);
-
- return 0;
-}
-
-static void mtk_pinctrl_irq_release_resources(struct irq_data *d)
-{
- struct mtk_pinctrl *pctl = irq_data_get_irq_chip_data(d);
- const struct mtk_desc_pin *pin;
-
- pin = mtk_find_pin_by_eint_num(pctl, d->hwirq);
-
- if (!pin) {
- dev_err(pctl->dev, "Can not find pin\n");
- return;
- }
-
- gpiochip_unlock_as_irq(pctl->chip, pin->pin.number);
-}
-
-static void __iomem *mtk_eint_get_offset(struct mtk_pinctrl *pctl,
- unsigned int eint_num, unsigned int offset)
-{
- unsigned int eint_base = 0;
- void __iomem *reg;
-
- if (eint_num >= pctl->devdata->ap_num)
- eint_base = pctl->devdata->ap_num;
-
- reg = pctl->eint_reg_base + offset + ((eint_num - eint_base) / 32) * 4;
-
- return reg;
-}
-
-/*
- * mtk_can_en_debounce: Check the EINT number is able to enable debounce or not
- * @eint_num: the EINT number to setmtk_pinctrl
- */
-static unsigned int mtk_eint_can_en_debounce(struct mtk_pinctrl *pctl,
- unsigned int eint_num)
-{
- unsigned int sens;
- unsigned int bit = BIT(eint_num % 32);
- const struct mtk_eint_offsets *eint_offsets =
- &pctl->devdata->eint_offsets;
-
- void __iomem *reg = mtk_eint_get_offset(pctl, eint_num,
- eint_offsets->sens);
-
- if (readl(reg) & bit)
- sens = MT_LEVEL_SENSITIVE;
- else
- sens = MT_EDGE_SENSITIVE;
-
- if ((eint_num < pctl->devdata->db_cnt) && (sens != MT_EDGE_SENSITIVE))
- return 1;
- else
- return 0;
-}
-
-/*
- * mtk_eint_get_mask: To get the eint mask
- * @eint_num: the EINT number to get
- */
-static unsigned int mtk_eint_get_mask(struct mtk_pinctrl *pctl,
- unsigned int eint_num)
-{
- unsigned int bit = BIT(eint_num % 32);
- const struct mtk_eint_offsets *eint_offsets =
- &pctl->devdata->eint_offsets;
-
- void __iomem *reg = mtk_eint_get_offset(pctl, eint_num,
- eint_offsets->mask);
-
- return !!(readl(reg) & bit);
-}
-
-static int mtk_eint_flip_edge(struct mtk_pinctrl *pctl, int hwirq)
-{
- int start_level, curr_level;
- unsigned int reg_offset;
- const struct mtk_eint_offsets *eint_offsets = &(pctl->devdata->eint_offsets);
- u32 mask = BIT(hwirq & 0x1f);
- u32 port = (hwirq >> 5) & eint_offsets->port_mask;
- void __iomem *reg = pctl->eint_reg_base + (port << 2);
- const struct mtk_desc_pin *pin;
-
- pin = mtk_find_pin_by_eint_num(pctl, hwirq);
- curr_level = mtk_gpio_get(pctl->chip, pin->pin.number);
- do {
- start_level = curr_level;
- if (start_level)
- reg_offset = eint_offsets->pol_clr;
- else
- reg_offset = eint_offsets->pol_set;
- writel(mask, reg + reg_offset);
-
- curr_level = mtk_gpio_get(pctl->chip, pin->pin.number);
- } while (start_level != curr_level);
-
- return start_level;
-}
-
-static void mtk_eint_mask(struct irq_data *d)
-{
- struct mtk_pinctrl *pctl = irq_data_get_irq_chip_data(d);
- const struct mtk_eint_offsets *eint_offsets =
- &pctl->devdata->eint_offsets;
- u32 mask = BIT(d->hwirq & 0x1f);
- void __iomem *reg = mtk_eint_get_offset(pctl, d->hwirq,
- eint_offsets->mask_set);
-
- writel(mask, reg);
-}
-
-static void mtk_eint_unmask(struct irq_data *d)
-{
- struct mtk_pinctrl *pctl = irq_data_get_irq_chip_data(d);
- const struct mtk_eint_offsets *eint_offsets =
- &pctl->devdata->eint_offsets;
- u32 mask = BIT(d->hwirq & 0x1f);
- void __iomem *reg = mtk_eint_get_offset(pctl, d->hwirq,
- eint_offsets->mask_clr);
-
- writel(mask, reg);
-
- if (pctl->eint_dual_edges[d->hwirq])
- mtk_eint_flip_edge(pctl, d->hwirq);
-}
-
-static int mtk_gpio_set_debounce(struct gpio_chip *chip, unsigned offset,
- unsigned debounce)
-{
- struct mtk_pinctrl *pctl = dev_get_drvdata(chip->parent);
- int eint_num, virq, eint_offset;
- unsigned int set_offset, bit, clr_bit, clr_offset, rst, i, unmask, dbnc;
- static const unsigned int debounce_time[] = {500, 1000, 16000, 32000, 64000,
- 128000, 256000};
const struct mtk_desc_pin *pin;
- struct irq_data *d;
+ unsigned long eint_n;
pin = pctl->devdata->pins + offset;
if (pin->eint.eintnum == NO_EINT_SUPPORT)
return -EINVAL;
- eint_num = pin->eint.eintnum;
- virq = irq_find_mapping(pctl->domain, eint_num);
- eint_offset = (eint_num % 4) * 8;
- d = irq_get_irq_data(virq);
-
- set_offset = (eint_num / 4) * 4 + pctl->devdata->eint_offsets.dbnc_set;
- clr_offset = (eint_num / 4) * 4 + pctl->devdata->eint_offsets.dbnc_clr;
- if (!mtk_eint_can_en_debounce(pctl, eint_num))
- return -ENOSYS;
-
- dbnc = ARRAY_SIZE(debounce_time);
- for (i = 0; i < ARRAY_SIZE(debounce_time); i++) {
- if (debounce <= debounce_time[i]) {
- dbnc = i;
- break;
- }
- }
+ eint_n = pin->eint.eintnum;
- if (!mtk_eint_get_mask(pctl, eint_num)) {
- mtk_eint_mask(d);
- unmask = 1;
- } else {
- unmask = 0;
- }
-
- clr_bit = 0xff << eint_offset;
- writel(clr_bit, pctl->eint_reg_base + clr_offset);
-
- bit = ((dbnc << EINT_DBNC_SET_DBNC_BITS) | EINT_DBNC_SET_EN) <<
- eint_offset;
- rst = EINT_DBNC_RST_BIT << eint_offset;
- writel(rst | bit, pctl->eint_reg_base + set_offset);
-
- /* Delay a while (more than 2T) to wait for hw debounce counter reset
- work correctly */
- udelay(1);
- if (unmask == 1)
- mtk_eint_unmask(d);
-
- return 0;
+ return mtk_eint_find_irq(pctl->eint, eint_n);
}
static int mtk_gpio_set_config(struct gpio_chip *chip, unsigned offset,
unsigned long config)
{
+ struct mtk_pinctrl *pctl = gpiochip_get_data(chip);
+ const struct mtk_desc_pin *pin;
+ unsigned long eint_n;
u32 debounce;
if (pinconf_to_config_param(config) != PIN_CONFIG_INPUT_DEBOUNCE)
return -ENOTSUPP;
+ pin = pctl->devdata->pins + offset;
+ if (pin->eint.eintnum == NO_EINT_SUPPORT)
+ return -EINVAL;
+
debounce = pinconf_to_config_argument(config);
- return mtk_gpio_set_debounce(chip, offset, debounce);
+ eint_n = pin->eint.eintnum;
+
+ return mtk_eint_set_debounce(pctl->eint, eint_n, debounce);
}
static const struct gpio_chip mtk_gpio_chip = {
@@ -1084,117 +880,18 @@ static const struct gpio_chip mtk_gpio_chip = {
.of_gpio_n_cells = 2,
};
-static int mtk_eint_set_type(struct irq_data *d,
- unsigned int type)
-{
- struct mtk_pinctrl *pctl = irq_data_get_irq_chip_data(d);
- const struct mtk_eint_offsets *eint_offsets =
- &pctl->devdata->eint_offsets;
- u32 mask = BIT(d->hwirq & 0x1f);
- void __iomem *reg;
-
- if (((type & IRQ_TYPE_EDGE_BOTH) && (type & IRQ_TYPE_LEVEL_MASK)) ||
- ((type & IRQ_TYPE_LEVEL_MASK) == IRQ_TYPE_LEVEL_MASK)) {
- dev_err(pctl->dev, "Can't configure IRQ%d (EINT%lu) for type 0x%X\n",
- d->irq, d->hwirq, type);
- return -EINVAL;
- }
-
- if ((type & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH)
- pctl->eint_dual_edges[d->hwirq] = 1;
- else
- pctl->eint_dual_edges[d->hwirq] = 0;
-
- if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_EDGE_FALLING)) {
- reg = mtk_eint_get_offset(pctl, d->hwirq,
- eint_offsets->pol_clr);
- writel(mask, reg);
- } else {
- reg = mtk_eint_get_offset(pctl, d->hwirq,
- eint_offsets->pol_set);
- writel(mask, reg);
- }
-
- if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) {
- reg = mtk_eint_get_offset(pctl, d->hwirq,
- eint_offsets->sens_clr);
- writel(mask, reg);
- } else {
- reg = mtk_eint_get_offset(pctl, d->hwirq,
- eint_offsets->sens_set);
- writel(mask, reg);
- }
-
- if (pctl->eint_dual_edges[d->hwirq])
- mtk_eint_flip_edge(pctl, d->hwirq);
-
- return 0;
-}
-
-static int mtk_eint_irq_set_wake(struct irq_data *d, unsigned int on)
-{
- struct mtk_pinctrl *pctl = irq_data_get_irq_chip_data(d);
- int shift = d->hwirq & 0x1f;
- int reg = d->hwirq >> 5;
-
- if (on)
- pctl->wake_mask[reg] |= BIT(shift);
- else
- pctl->wake_mask[reg] &= ~BIT(shift);
-
- return 0;
-}
-
-static void mtk_eint_chip_write_mask(const struct mtk_eint_offsets *chip,
- void __iomem *eint_reg_base, u32 *buf)
-{
- int port;
- void __iomem *reg;
-
- for (port = 0; port < chip->ports; port++) {
- reg = eint_reg_base + (port << 2);
- writel_relaxed(~buf[port], reg + chip->mask_set);
- writel_relaxed(buf[port], reg + chip->mask_clr);
- }
-}
-
-static void mtk_eint_chip_read_mask(const struct mtk_eint_offsets *chip,
- void __iomem *eint_reg_base, u32 *buf)
-{
- int port;
- void __iomem *reg;
-
- for (port = 0; port < chip->ports; port++) {
- reg = eint_reg_base + chip->mask + (port << 2);
- buf[port] = ~readl_relaxed(reg);
- /* Mask is 0 when irq is enabled, and 1 when disabled. */
- }
-}
-
static int mtk_eint_suspend(struct device *device)
{
- void __iomem *reg;
struct mtk_pinctrl *pctl = dev_get_drvdata(device);
- const struct mtk_eint_offsets *eint_offsets =
- &pctl->devdata->eint_offsets;
- reg = pctl->eint_reg_base;
- mtk_eint_chip_read_mask(eint_offsets, reg, pctl->cur_mask);
- mtk_eint_chip_write_mask(eint_offsets, reg, pctl->wake_mask);
-
- return 0;
+ return mtk_eint_do_suspend(pctl->eint);
}
static int mtk_eint_resume(struct device *device)
{
struct mtk_pinctrl *pctl = dev_get_drvdata(device);
- const struct mtk_eint_offsets *eint_offsets =
- &pctl->devdata->eint_offsets;
- mtk_eint_chip_write_mask(eint_offsets,
- pctl->eint_reg_base, pctl->cur_mask);
-
- return 0;
+ return mtk_eint_do_resume(pctl->eint);
}
const struct dev_pm_ops mtk_eint_pm_ops = {
@@ -1202,117 +899,6 @@ const struct dev_pm_ops mtk_eint_pm_ops = {
.resume_noirq = mtk_eint_resume,
};
-static void mtk_eint_ack(struct irq_data *d)
-{
- struct mtk_pinctrl *pctl = irq_data_get_irq_chip_data(d);
- const struct mtk_eint_offsets *eint_offsets =
- &pctl->devdata->eint_offsets;
- u32 mask = BIT(d->hwirq & 0x1f);
- void __iomem *reg = mtk_eint_get_offset(pctl, d->hwirq,
- eint_offsets->ack);
-
- writel(mask, reg);
-}
-
-static struct irq_chip mtk_pinctrl_irq_chip = {
- .name = "mt-eint",
- .irq_disable = mtk_eint_mask,
- .irq_mask = mtk_eint_mask,
- .irq_unmask = mtk_eint_unmask,
- .irq_ack = mtk_eint_ack,
- .irq_set_type = mtk_eint_set_type,
- .irq_set_wake = mtk_eint_irq_set_wake,
- .irq_request_resources = mtk_pinctrl_irq_request_resources,
- .irq_release_resources = mtk_pinctrl_irq_release_resources,
-};
-
-static unsigned int mtk_eint_init(struct mtk_pinctrl *pctl)
-{
- const struct mtk_eint_offsets *eint_offsets =
- &pctl->devdata->eint_offsets;
- void __iomem *reg = pctl->eint_reg_base + eint_offsets->dom_en;
- unsigned int i;
-
- for (i = 0; i < pctl->devdata->ap_num; i += 32) {
- writel(0xffffffff, reg);
- reg += 4;
- }
- return 0;
-}
-
-static inline void
-mtk_eint_debounce_process(struct mtk_pinctrl *pctl, int index)
-{
- unsigned int rst, ctrl_offset;
- unsigned int bit, dbnc;
- const struct mtk_eint_offsets *eint_offsets =
- &pctl->devdata->eint_offsets;
-
- ctrl_offset = (index / 4) * 4 + eint_offsets->dbnc_ctrl;
- dbnc = readl(pctl->eint_reg_base + ctrl_offset);
- bit = EINT_DBNC_SET_EN << ((index % 4) * 8);
- if ((bit & dbnc) > 0) {
- ctrl_offset = (index / 4) * 4 + eint_offsets->dbnc_set;
- rst = EINT_DBNC_RST_BIT << ((index % 4) * 8);
- writel(rst, pctl->eint_reg_base + ctrl_offset);
- }
-}
-
-static void mtk_eint_irq_handler(struct irq_desc *desc)
-{
- struct irq_chip *chip = irq_desc_get_chip(desc);
- struct mtk_pinctrl *pctl = irq_desc_get_handler_data(desc);
- unsigned int status, eint_num;
- int offset, index, virq;
- const struct mtk_eint_offsets *eint_offsets =
- &pctl->devdata->eint_offsets;
- void __iomem *reg = mtk_eint_get_offset(pctl, 0, eint_offsets->stat);
- int dual_edges, start_level, curr_level;
- const struct mtk_desc_pin *pin;
-
- chained_irq_enter(chip, desc);
- for (eint_num = 0;
- eint_num < pctl->devdata->ap_num;
- eint_num += 32, reg += 4) {
- status = readl(reg);
- while (status) {
- offset = __ffs(status);
- index = eint_num + offset;
- virq = irq_find_mapping(pctl->domain, index);
- status &= ~BIT(offset);
-
- dual_edges = pctl->eint_dual_edges[index];
- if (dual_edges) {
- /* Clear soft-irq in case we raised it
- last time */
- writel(BIT(offset), reg - eint_offsets->stat +
- eint_offsets->soft_clr);
-
- pin = mtk_find_pin_by_eint_num(pctl, index);
- start_level = mtk_gpio_get(pctl->chip,
- pin->pin.number);
- }
-
- generic_handle_irq(virq);
-
- if (dual_edges) {
- curr_level = mtk_eint_flip_edge(pctl, index);
-
- /* If level changed, we might lost one edge
- interrupt, raised it through soft-irq */
- if (start_level != curr_level)
- writel(BIT(offset), reg -
- eint_offsets->stat +
- eint_offsets->soft_set);
- }
-
- if (index < pctl->devdata->db_cnt)
- mtk_eint_debounce_process(pctl , index);
- }
- }
- chained_irq_exit(chip, desc);
-}
-
static int mtk_pctrl_build_state(struct platform_device *pdev)
{
struct mtk_pinctrl *pctl = platform_get_drvdata(pdev);
@@ -1345,6 +931,97 @@ static int mtk_pctrl_build_state(struct platform_device *pdev)
return 0;
}
+static int
+mtk_xt_get_gpio_n(void *data, unsigned long eint_n, unsigned int *gpio_n,
+ struct gpio_chip **gpio_chip)
+{
+ struct mtk_pinctrl *pctl = (struct mtk_pinctrl *)data;
+ const struct mtk_desc_pin *pin;
+
+ pin = mtk_find_pin_by_eint_num(pctl, eint_n);
+ if (!pin)
+ return -EINVAL;
+
+ *gpio_chip = pctl->chip;
+ *gpio_n = pin->pin.number;
+
+ return 0;
+}
+
+static int mtk_xt_get_gpio_state(void *data, unsigned long eint_n)
+{
+ struct mtk_pinctrl *pctl = (struct mtk_pinctrl *)data;
+ const struct mtk_desc_pin *pin;
+
+ pin = mtk_find_pin_by_eint_num(pctl, eint_n);
+ if (!pin)
+ return -EINVAL;
+
+ return mtk_gpio_get(pctl->chip, pin->pin.number);
+}
+
+static int mtk_xt_set_gpio_as_eint(void *data, unsigned long eint_n)
+{
+ struct mtk_pinctrl *pctl = (struct mtk_pinctrl *)data;
+ const struct mtk_desc_pin *pin;
+
+ pin = mtk_find_pin_by_eint_num(pctl, eint_n);
+ if (!pin)
+ return -EINVAL;
+
+ /* set mux to INT mode */
+ mtk_pmx_set_mode(pctl->pctl_dev, pin->pin.number, pin->eint.eintmux);
+ /* set gpio direction to input */
+ mtk_pmx_gpio_set_direction(pctl->pctl_dev, NULL, pin->pin.number,
+ true);
+ /* set input-enable */
+ mtk_pconf_set_ies_smt(pctl, pin->pin.number, 1,
+ PIN_CONFIG_INPUT_ENABLE);
+
+ return 0;
+}
+
+static const struct mtk_eint_xt mtk_eint_xt = {
+ .get_gpio_n = mtk_xt_get_gpio_n,
+ .get_gpio_state = mtk_xt_get_gpio_state,
+ .set_gpio_as_eint = mtk_xt_set_gpio_as_eint,
+};
+
+static int mtk_eint_init(struct mtk_pinctrl *pctl, struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+ struct resource *res;
+
+ if (!of_property_read_bool(np, "interrupt-controller"))
+ return -ENODEV;
+
+ pctl->eint = devm_kzalloc(pctl->dev, sizeof(*pctl->eint), GFP_KERNEL);
+ if (!pctl->eint)
+ return -ENOMEM;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "Unable to get eint resource\n");
+ return -ENODEV;
+ }
+
+ pctl->eint->base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(pctl->eint->base))
+ return PTR_ERR(pctl->eint->base);
+
+ pctl->eint->irq = irq_of_parse_and_map(np, 0);
+ if (!pctl->eint->irq)
+ return -EINVAL;
+
+ pctl->eint->dev = &pdev->dev;
+ pctl->eint->regs = &pctl->devdata->eint_regs;
+ pctl->eint->hw = &pctl->devdata->eint_hw;
+ pctl->eint->pctl = pctl;
+ pctl->eint->gpio_xlate = &mtk_eint_xt;
+
+ return mtk_eint_do_init(pctl->eint);
+}
+
int mtk_pctrl_init(struct platform_device *pdev,
const struct mtk_pinctrl_devdata *data,
struct regmap *regmap)
@@ -1353,8 +1030,7 @@ int mtk_pctrl_init(struct platform_device *pdev,
struct mtk_pinctrl *pctl;
struct device_node *np = pdev->dev.of_node, *node;
struct property *prop;
- struct resource *res;
- int i, ret, irq, ports_buf;
+ int ret, i;
pctl = devm_kzalloc(&pdev->dev, sizeof(*pctl), GFP_KERNEL);
if (!pctl)
@@ -1441,70 +1117,10 @@ int mtk_pctrl_init(struct platform_device *pdev,
goto chip_error;
}
- if (!of_property_read_bool(np, "interrupt-controller"))
- return 0;
-
- /* Get EINT register base from dts. */
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res) {
- dev_err(&pdev->dev, "Unable to get Pinctrl resource\n");
- ret = -EINVAL;
- goto chip_error;
- }
-
- pctl->eint_reg_base = devm_ioremap_resource(&pdev->dev, res);
- if (IS_ERR(pctl->eint_reg_base)) {
- ret = -EINVAL;
- goto chip_error;
- }
-
- ports_buf = pctl->devdata->eint_offsets.ports;
- pctl->wake_mask = devm_kcalloc(&pdev->dev, ports_buf,
- sizeof(*pctl->wake_mask), GFP_KERNEL);
- if (!pctl->wake_mask) {
- ret = -ENOMEM;
- goto chip_error;
- }
-
- pctl->cur_mask = devm_kcalloc(&pdev->dev, ports_buf,
- sizeof(*pctl->cur_mask), GFP_KERNEL);
- if (!pctl->cur_mask) {
- ret = -ENOMEM;
- goto chip_error;
- }
-
- pctl->eint_dual_edges = devm_kcalloc(&pdev->dev, pctl->devdata->ap_num,
- sizeof(int), GFP_KERNEL);
- if (!pctl->eint_dual_edges) {
- ret = -ENOMEM;
- goto chip_error;
- }
-
- irq = irq_of_parse_and_map(np, 0);
- if (!irq) {
- dev_err(&pdev->dev, "couldn't parse and map irq\n");
- ret = -EINVAL;
- goto chip_error;
- }
-
- pctl->domain = irq_domain_add_linear(np,
- pctl->devdata->ap_num, &irq_domain_simple_ops, NULL);
- if (!pctl->domain) {
- dev_err(&pdev->dev, "Couldn't register IRQ domain\n");
- ret = -ENOMEM;
+ ret = mtk_eint_init(pctl, pdev);
+ if (ret)
goto chip_error;
- }
-
- mtk_eint_init(pctl);
- for (i = 0; i < pctl->devdata->ap_num; i++) {
- int virq = irq_create_mapping(pctl->domain, i);
-
- irq_set_chip_and_handler(virq, &mtk_pinctrl_irq_chip,
- handle_level_irq);
- irq_set_chip_data(virq, pctl);
- }
- irq_set_chained_handler_and_data(irq, mtk_eint_irq_handler, pctl);
return 0;
chip_error:
diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common.h b/drivers/pinctrl/mediatek/pinctrl-mtk-common.h
index 8543bc4..346e3db 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common.h
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.h
@@ -19,6 +19,8 @@
#include <linux/regmap.h>
#include <linux/pinctrl/pinconf-generic.h>
+#include "mtk-eint.h"
+
#define NO_EINT_SUPPORT 255
#define MT_EDGE_SENSITIVE 0
#define MT_LEVEL_SENSITIVE 1
@@ -258,9 +260,8 @@ struct mtk_pinctrl_devdata {
unsigned char port_shf;
unsigned char port_mask;
unsigned char port_align;
- struct mtk_eint_offsets eint_offsets;
- unsigned int ap_num;
- unsigned int db_cnt;
+ struct mtk_eint_hw eint_hw;
+ struct mtk_eint_regs eint_regs;
};
struct mtk_pinctrl {
@@ -274,11 +275,7 @@ struct mtk_pinctrl {
const char **grp_names;
struct pinctrl_dev *pctl_dev;
const struct mtk_pinctrl_devdata *devdata;
- void __iomem *eint_reg_base;
- struct irq_domain *domain;
- int *eint_dual_edges;
- u32 *wake_mask;
- u32 *cur_mask;
+ struct mtk_eint *eint;
};
int mtk_pctrl_init(struct platform_device *pdev,
--
2.7.4
^ permalink raw reply related
* [PATCH v1 3/7] pinctrl: mediatek: add EINT support to MT7622 SoC
From: sean.wang @ 2018-05-20 17:01 UTC (permalink / raw)
To: robh+dt, mark.rutland, linus.walleij, matthias.bgg, devicetree,
linux-mediatek
Cc: linux-arm-kernel, linux-gpio, linux-kernel, Sean Wang
In-Reply-To: <cover.1526835466.git.sean.wang@mediatek.com>
From: Sean Wang <sean.wang@mediatek.com>
Add EINT support to MT7622 SoC and the support is made as just an option
to MT7622 pinctrl.
Signed-off-by: Sean Wang <sean.wang@mediatek.com>
---
drivers/pinctrl/mediatek/Kconfig | 2 +-
drivers/pinctrl/mediatek/pinctrl-mt7622.c | 143 ++++++++++++++++++++++++++++++
2 files changed, 144 insertions(+), 1 deletion(-)
diff --git a/drivers/pinctrl/mediatek/Kconfig b/drivers/pinctrl/mediatek/Kconfig
index 310db42..9905dc6 100644
--- a/drivers/pinctrl/mediatek/Kconfig
+++ b/drivers/pinctrl/mediatek/Kconfig
@@ -3,7 +3,7 @@ menu "MediaTek pinctrl drivers"
config EINT_MTK
bool "MediaTek External Interrupt Support"
- depends on PINCTRL_MTK || COMPILE_TEST
+ depends on PINCTRL_MTK || PINCTRL_MT7622 || COMPILE_TEST
select IRQ_DOMAIN
config PINCTRL_MTK
diff --git a/drivers/pinctrl/mediatek/pinctrl-mt7622.c b/drivers/pinctrl/mediatek/pinctrl-mt7622.c
index 06e8406..ad6da11 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mt7622.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mt7622.c
@@ -19,6 +19,7 @@
#include <linux/init.h>
#include <linux/mfd/syscon.h>
#include <linux/of.h>
+#include <linux/of_irq.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/pinctrl/pinctrl.h>
@@ -30,6 +31,7 @@
#include "../core.h"
#include "../pinconf.h"
#include "../pinmux.h"
+#include "mtk-eint.h"
#define PINCTRL_PINCTRL_DEV KBUILD_MODNAME
#define MTK_RANGE(_a) { .range = (_a), .nranges = ARRAY_SIZE(_a), }
@@ -123,6 +125,8 @@ struct mtk_pin_soc {
unsigned int ngrps;
const struct function_desc *funcs;
unsigned int nfuncs;
+ const struct mtk_eint_regs *eint_regs;
+ const struct mtk_eint_hw *eint_hw;
};
struct mtk_pinctrl {
@@ -131,6 +135,7 @@ struct mtk_pinctrl {
struct device *dev;
struct gpio_chip chip;
const struct mtk_pin_soc *soc;
+ struct mtk_eint *eint;
};
static const struct mtk_pin_field_calc mt7622_pin_mode_range[] = {
@@ -913,6 +918,13 @@ static const struct pin_config_item mtk_conf_items[] = {
};
#endif
+static const struct mtk_eint_hw mt7622_eint_hw = {
+ .port_mask = 7,
+ .ports = 7,
+ .ap_num = ARRAY_SIZE(mt7622_pins),
+ .db_cnt = 20,
+};
+
static const struct mtk_pin_soc mt7622_data = {
.reg_cal = mt7622_reg_cals,
.pins = mt7622_pins,
@@ -921,6 +933,7 @@ static const struct mtk_pin_soc mt7622_data = {
.ngrps = ARRAY_SIZE(mt7622_groups),
.funcs = mt7622_functions,
.nfuncs = ARRAY_SIZE(mt7622_functions),
+ .eint_hw = &mt7622_eint_hw,
};
static void mtk_w32(struct mtk_pinctrl *pctl, u32 reg, u32 val)
@@ -1441,6 +1454,32 @@ static int mtk_gpio_direction_output(struct gpio_chip *chip, unsigned int gpio,
return pinctrl_gpio_direction_output(chip->base + gpio);
}
+static int mtk_gpio_to_irq(struct gpio_chip *chip, unsigned int offset)
+{
+ struct mtk_pinctrl *hw = gpiochip_get_data(chip);
+ unsigned long eint_n;
+
+ eint_n = offset;
+
+ return mtk_eint_find_irq(hw->eint, eint_n);
+}
+
+static int mtk_gpio_set_config(struct gpio_chip *chip, unsigned int offset,
+ unsigned long config)
+{
+ struct mtk_pinctrl *hw = gpiochip_get_data(chip);
+ unsigned long eint_n;
+ u32 debounce;
+
+ if (pinconf_to_config_param(config) != PIN_CONFIG_INPUT_DEBOUNCE)
+ return -ENOTSUPP;
+
+ debounce = pinconf_to_config_argument(config);
+ eint_n = offset;
+
+ return mtk_eint_set_debounce(hw->eint, eint_n, debounce);
+}
+
static int mtk_build_gpiochip(struct mtk_pinctrl *hw, struct device_node *np)
{
struct gpio_chip *chip = &hw->chip;
@@ -1454,6 +1493,8 @@ static int mtk_build_gpiochip(struct mtk_pinctrl *hw, struct device_node *np)
chip->direction_output = mtk_gpio_direction_output;
chip->get = mtk_gpio_get;
chip->set = mtk_gpio_set;
+ chip->to_irq = mtk_gpio_to_irq,
+ chip->set_config = mtk_gpio_set_config,
chip->base = -1;
chip->ngpio = hw->soc->npins;
chip->of_node = np;
@@ -1514,6 +1555,103 @@ static int mtk_build_functions(struct mtk_pinctrl *hw)
return 0;
}
+static int mtk_xt_get_gpio_n(void *data, unsigned long eint_n,
+ unsigned int *gpio_n,
+ struct gpio_chip **gpio_chip)
+{
+ struct mtk_pinctrl *hw = (struct mtk_pinctrl *)data;
+
+ *gpio_chip = &hw->chip;
+ *gpio_n = eint_n;
+
+ return 0;
+}
+
+static int mtk_xt_get_gpio_state(void *data, unsigned long eint_n)
+{
+ struct mtk_pinctrl *hw = (struct mtk_pinctrl *)data;
+ struct gpio_chip *gpio_chip;
+ unsigned int gpio_n;
+ int err;
+
+ err = mtk_xt_get_gpio_n(hw, eint_n, &gpio_n, &gpio_chip);
+ if (err)
+ return err;
+
+ return mtk_gpio_get(gpio_chip, gpio_n);
+}
+
+static int mtk_xt_set_gpio_as_eint(void *data, unsigned long eint_n)
+{
+ struct mtk_pinctrl *hw = (struct mtk_pinctrl *)data;
+ struct gpio_chip *gpio_chip;
+ unsigned int gpio_n;
+ int err;
+
+ err = mtk_xt_get_gpio_n(hw, eint_n, &gpio_n, &gpio_chip);
+ if (err)
+ return err;
+
+ err = mtk_hw_set_value(hw, gpio_n, PINCTRL_PIN_REG_MODE,
+ MTK_GPIO_MODE);
+ if (err)
+ return err;
+
+ err = mtk_hw_set_value(hw, gpio_n, PINCTRL_PIN_REG_DIR, MTK_INPUT);
+ if (err)
+ return err;
+
+ err = mtk_hw_set_value(hw, gpio_n, PINCTRL_PIN_REG_SMT, MTK_ENABLE);
+ if (err)
+ return err;
+
+ return 0;
+}
+
+static const struct mtk_eint_xt mtk_eint_xt = {
+ .get_gpio_n = mtk_xt_get_gpio_n,
+ .get_gpio_state = mtk_xt_get_gpio_state,
+ .set_gpio_as_eint = mtk_xt_set_gpio_as_eint,
+};
+
+static int
+mtk_build_eint(struct mtk_pinctrl *hw, struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+ struct resource *res;
+
+ if (!IS_ENABLED(CONFIG_EINT_MTK))
+ return 0;
+
+ if (!of_property_read_bool(np, "interrupt-controller"))
+ return -ENODEV;
+
+ hw->eint = devm_kzalloc(hw->dev, sizeof(*hw->eint), GFP_KERNEL);
+ if (!hw->eint)
+ return -ENOMEM;
+
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "eint");
+ if (!res) {
+ dev_err(&pdev->dev, "Unable to get eint resource\n");
+ return -ENODEV;
+ }
+
+ hw->eint->base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(hw->eint->base))
+ return PTR_ERR(hw->eint->base);
+
+ hw->eint->irq = irq_of_parse_and_map(np, 0);
+ if (!hw->eint->irq)
+ return -EINVAL;
+
+ hw->eint->dev = &pdev->dev;
+ hw->eint->hw = hw->soc->eint_hw;
+ hw->eint->pctl = hw;
+ hw->eint->gpio_xlate = &mtk_eint_xt;
+
+ return mtk_eint_do_init(hw->eint);
+}
+
static const struct of_device_id mtk_pinctrl_of_match[] = {
{ .compatible = "mediatek,mt7622-pinctrl", .data = &mt7622_data},
{ }
@@ -1577,6 +1715,11 @@ static int mtk_pinctrl_probe(struct platform_device *pdev)
return err;
}
+ err = mtk_build_eint(hw, pdev);
+ if (err)
+ dev_warn(&pdev->dev,
+ "Failed to add EINT, but pinctrl still can work\n");
+
platform_set_drvdata(pdev, hw);
return 0;
--
2.7.4
^ permalink raw reply related
* [PATCH v1 4/7] pinctrl: mediatek: use generic EINT register maps for each SoC
From: sean.wang @ 2018-05-20 17:01 UTC (permalink / raw)
To: robh+dt, mark.rutland, linus.walleij, matthias.bgg, devicetree,
linux-mediatek
Cc: linux-arm-kernel, linux-gpio, linux-kernel, Sean Wang
In-Reply-To: <cover.1526835466.git.sean.wang@mediatek.com>
From: Sean Wang <sean.wang@mediatek.com>
So far, EINT on each SoC all used exactly identical register map and thus
it's better that we apply generic register map already supported in EINT
library and stop copy-n-pasting the same data block and filling into its
platform data.
Signed-off-by: Sean Wang <sean.wang@mediatek.com>
---
drivers/pinctrl/mediatek/pinctrl-mt2701.c | 20 --------------------
drivers/pinctrl/mediatek/pinctrl-mt2712.c | 20 --------------------
drivers/pinctrl/mediatek/pinctrl-mt8127.c | 20 --------------------
drivers/pinctrl/mediatek/pinctrl-mt8135.c | 20 --------------------
drivers/pinctrl/mediatek/pinctrl-mt8173.c | 20 --------------------
drivers/pinctrl/mediatek/pinctrl-mtk-common.c | 6 +++++-
drivers/pinctrl/mediatek/pinctrl-mtk-common.h | 2 +-
7 files changed, 6 insertions(+), 102 deletions(-)
diff --git a/drivers/pinctrl/mediatek/pinctrl-mt2701.c b/drivers/pinctrl/mediatek/pinctrl-mt2701.c
index e0963c6..db22250 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mt2701.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mt2701.c
@@ -538,26 +538,6 @@ static const struct mtk_pinctrl_devdata mt2701_pinctrl_data = {
.ap_num = 169,
.db_cnt = 16,
},
- .eint_regs = {
- .stat = 0x000,
- .ack = 0x040,
- .mask = 0x080,
- .mask_set = 0x0c0,
- .mask_clr = 0x100,
- .sens = 0x140,
- .sens_set = 0x180,
- .sens_clr = 0x1c0,
- .soft = 0x200,
- .soft_set = 0x240,
- .soft_clr = 0x280,
- .pol = 0x300,
- .pol_set = 0x340,
- .pol_clr = 0x380,
- .dom_en = 0x400,
- .dbnc_ctrl = 0x500,
- .dbnc_set = 0x600,
- .dbnc_clr = 0x700,
- },
};
static int mt2701_pinctrl_probe(struct platform_device *pdev)
diff --git a/drivers/pinctrl/mediatek/pinctrl-mt2712.c b/drivers/pinctrl/mediatek/pinctrl-mt2712.c
index 02aff28..6e2acef 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mt2712.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mt2712.c
@@ -583,26 +583,6 @@ static const struct mtk_pinctrl_devdata mt2712_pinctrl_data = {
.ap_num = 229,
.db_cnt = 40,
},
- .eint_regs = {
- .stat = 0x000,
- .ack = 0x040,
- .mask = 0x080,
- .mask_set = 0x0c0,
- .mask_clr = 0x100,
- .sens = 0x140,
- .sens_set = 0x180,
- .sens_clr = 0x1c0,
- .soft = 0x200,
- .soft_set = 0x240,
- .soft_clr = 0x280,
- .pol = 0x300,
- .pol_set = 0x340,
- .pol_clr = 0x380,
- .dom_en = 0x400,
- .dbnc_ctrl = 0x500,
- .dbnc_set = 0x600,
- .dbnc_clr = 0x700,
- },
};
static int mt2712_pinctrl_probe(struct platform_device *pdev)
diff --git a/drivers/pinctrl/mediatek/pinctrl-mt8127.c b/drivers/pinctrl/mediatek/pinctrl-mt8127.c
index 71f6258..949a235 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mt8127.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mt8127.c
@@ -307,26 +307,6 @@ static const struct mtk_pinctrl_devdata mt8127_pinctrl_data = {
.ap_num = 143,
.db_cnt = 16,
},
- .eint_regs = {
- .stat = 0x000,
- .ack = 0x040,
- .mask = 0x080,
- .mask_set = 0x0c0,
- .mask_clr = 0x100,
- .sens = 0x140,
- .sens_set = 0x180,
- .sens_clr = 0x1c0,
- .soft = 0x200,
- .soft_set = 0x240,
- .soft_clr = 0x280,
- .pol = 0x300,
- .pol_set = 0x340,
- .pol_clr = 0x380,
- .dom_en = 0x400,
- .dbnc_ctrl = 0x500,
- .dbnc_set = 0x600,
- .dbnc_clr = 0x700,
- },
};
static int mt8127_pinctrl_probe(struct platform_device *pdev)
diff --git a/drivers/pinctrl/mediatek/pinctrl-mt8135.c b/drivers/pinctrl/mediatek/pinctrl-mt8135.c
index fdfa357..974a1f43 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mt8135.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mt8135.c
@@ -320,26 +320,6 @@ static const struct mtk_pinctrl_devdata mt8135_pinctrl_data = {
.ap_num = 192,
.db_cnt = 16,
},
- .eint_regs = {
- .stat = 0x000,
- .ack = 0x040,
- .mask = 0x080,
- .mask_set = 0x0c0,
- .mask_clr = 0x100,
- .sens = 0x140,
- .sens_set = 0x180,
- .sens_clr = 0x1c0,
- .soft = 0x200,
- .soft_set = 0x240,
- .soft_clr = 0x280,
- .pol = 0x300,
- .pol_set = 0x340,
- .pol_clr = 0x380,
- .dom_en = 0x400,
- .dbnc_ctrl = 0x500,
- .dbnc_set = 0x600,
- .dbnc_clr = 0x700,
- },
};
static int mt8135_pinctrl_probe(struct platform_device *pdev)
diff --git a/drivers/pinctrl/mediatek/pinctrl-mt8173.c b/drivers/pinctrl/mediatek/pinctrl-mt8173.c
index 1466c95..a836cee3 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mt8173.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mt8173.c
@@ -347,26 +347,6 @@ static const struct mtk_pinctrl_devdata mt8173_pinctrl_data = {
.ap_num = 224,
.db_cnt = 16,
},
- .eint_regs = {
- .stat = 0x000,
- .ack = 0x040,
- .mask = 0x080,
- .mask_set = 0x0c0,
- .mask_clr = 0x100,
- .sens = 0x140,
- .sens_set = 0x180,
- .sens_clr = 0x1c0,
- .soft = 0x200,
- .soft_set = 0x240,
- .soft_clr = 0x280,
- .pol = 0x300,
- .pol_set = 0x340,
- .pol_clr = 0x380,
- .dom_en = 0x400,
- .dbnc_ctrl = 0x500,
- .dbnc_set = 0x600,
- .dbnc_clr = 0x700,
- },
};
static int mt8173_pinctrl_probe(struct platform_device *pdev)
diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
index 11e0d0f..b379969 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
@@ -1014,7 +1014,11 @@ static int mtk_eint_init(struct mtk_pinctrl *pctl, struct platform_device *pdev)
return -EINVAL;
pctl->eint->dev = &pdev->dev;
- pctl->eint->regs = &pctl->devdata->eint_regs;
+ /*
+ * If pctl->eint->regs == NULL, it would fall back into using a generic
+ * register map in mtk_eint_do_init calls.
+ */
+ pctl->eint->regs = pctl->devdata->eint_regs;
pctl->eint->hw = &pctl->devdata->eint_hw;
pctl->eint->pctl = pctl;
pctl->eint->gpio_xlate = &mtk_eint_xt;
diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common.h b/drivers/pinctrl/mediatek/pinctrl-mtk-common.h
index 346e3db..bf13eb0 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common.h
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.h
@@ -261,7 +261,7 @@ struct mtk_pinctrl_devdata {
unsigned char port_mask;
unsigned char port_align;
struct mtk_eint_hw eint_hw;
- struct mtk_eint_regs eint_regs;
+ struct mtk_eint_regs *eint_regs;
};
struct mtk_pinctrl {
--
2.7.4
^ permalink raw reply related
* [PATCH v1 5/7] pinctrl: mediatek: remove unused fields in struct mtk_eint_hw
From: sean.wang @ 2018-05-20 17:01 UTC (permalink / raw)
To: robh+dt, mark.rutland, linus.walleij, matthias.bgg, devicetree,
linux-mediatek
Cc: linux-arm-kernel, linux-gpio, linux-kernel, Sean Wang
In-Reply-To: <cover.1526835466.git.sean.wang@mediatek.com>
From: Sean Wang <sean.wang@mediatek.com>
The .name field has been not being used in existent code logic, so
it's better that we remove them all.
Signed-off-by: Sean Wang <sean.wang@mediatek.com>
---
drivers/pinctrl/mediatek/mtk-eint.h | 1 -
drivers/pinctrl/mediatek/pinctrl-mt2701.c | 1 -
drivers/pinctrl/mediatek/pinctrl-mt2712.c | 1 -
drivers/pinctrl/mediatek/pinctrl-mt8127.c | 1 -
drivers/pinctrl/mediatek/pinctrl-mt8135.c | 1 -
drivers/pinctrl/mediatek/pinctrl-mt8173.c | 1 -
6 files changed, 6 deletions(-)
diff --git a/drivers/pinctrl/mediatek/mtk-eint.h b/drivers/pinctrl/mediatek/mtk-eint.h
index 55b4d5f..c286a9b 100644
--- a/drivers/pinctrl/mediatek/mtk-eint.h
+++ b/drivers/pinctrl/mediatek/mtk-eint.h
@@ -33,7 +33,6 @@ struct mtk_eint_regs {
};
struct mtk_eint_hw {
- const char *name;
u8 port_mask;
u8 ports;
unsigned int ap_num;
diff --git a/drivers/pinctrl/mediatek/pinctrl-mt2701.c b/drivers/pinctrl/mediatek/pinctrl-mt2701.c
index db22250..e91c314 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mt2701.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mt2701.c
@@ -532,7 +532,6 @@ static const struct mtk_pinctrl_devdata mt2701_pinctrl_data = {
.port_mask = 0x1f,
.port_align = 4,
.eint_hw = {
- .name = "mt2701_eint",
.port_mask = 6,
.ports = 6,
.ap_num = 169,
diff --git a/drivers/pinctrl/mediatek/pinctrl-mt2712.c b/drivers/pinctrl/mediatek/pinctrl-mt2712.c
index 6e2acef..8398d55 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mt2712.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mt2712.c
@@ -577,7 +577,6 @@ static const struct mtk_pinctrl_devdata mt2712_pinctrl_data = {
.port_mask = 0xf,
.port_align = 4,
.eint_hw = {
- .name = "mt2712_eint",
.port_mask = 0xf,
.ports = 8,
.ap_num = 229,
diff --git a/drivers/pinctrl/mediatek/pinctrl-mt8127.c b/drivers/pinctrl/mediatek/pinctrl-mt8127.c
index 949a235..2e4cc92 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mt8127.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mt8127.c
@@ -301,7 +301,6 @@ static const struct mtk_pinctrl_devdata mt8127_pinctrl_data = {
.port_mask = 0xf,
.port_align = 4,
.eint_hw = {
- .name = "mt8127_eint",
.port_mask = 7,
.ports = 6,
.ap_num = 143,
diff --git a/drivers/pinctrl/mediatek/pinctrl-mt8135.c b/drivers/pinctrl/mediatek/pinctrl-mt8135.c
index 974a1f43..7f5edfa 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mt8135.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mt8135.c
@@ -314,7 +314,6 @@ static const struct mtk_pinctrl_devdata mt8135_pinctrl_data = {
.port_mask = 0xf,
.port_align = 4,
.eint_hw = {
- .name = "mt8135_eint",
.port_mask = 7,
.ports = 6,
.ap_num = 192,
diff --git a/drivers/pinctrl/mediatek/pinctrl-mt8173.c b/drivers/pinctrl/mediatek/pinctrl-mt8173.c
index a836cee3..c449c9a 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mt8173.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mt8173.c
@@ -341,7 +341,6 @@ static const struct mtk_pinctrl_devdata mt8173_pinctrl_data = {
.port_mask = 0xf,
.port_align = 4,
.eint_hw = {
- .name = "mt8173_eint",
.port_mask = 7,
.ports = 6,
.ap_num = 224,
--
2.7.4
^ permalink raw reply related
* [PATCH v1 6/7] MAINTAINERS: update entry for PIN CONTROLLER - MEDIATEK
From: sean.wang @ 2018-05-20 17:01 UTC (permalink / raw)
To: robh+dt, mark.rutland, linus.walleij, matthias.bgg, devicetree,
linux-mediatek
Cc: linux-arm-kernel, linux-gpio, linux-kernel, Sean Wang
In-Reply-To: <cover.1526835466.git.sean.wang@mediatek.com>
From: Sean Wang <sean.wang@mediatek.com>
Add new files for the entry
Signed-off-by: Sean Wang <sean.wang@mediatek.com>
---
MAINTAINERS | 1 +
1 file changed, 1 insertion(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index 9051a9c..7f3cced 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -11193,6 +11193,7 @@ L: linux-mediatek@lists.infradead.org (moderated for non-subscribers)
S: Maintained
F: Documentation/devicetree/bindings/pinctrl/pinctrl-mt65xx.txt
F: Documentation/devicetree/bindings/pinctrl/pinctrl-mt7622.txt
+F: drivers/pinctrl/mediatek/mtk-eint.*
F: drivers/pinctrl/mediatek/pinctrl-mtk-common.*
F: drivers/pinctrl/mediatek/pinctrl-mt2701.c
F: drivers/pinctrl/mediatek/pinctrl-mt7622.c
--
2.7.4
^ permalink raw reply related
* [PATCH v1 7/7] arm64: dts: mt7622: add EINT support to pinctrl
From: sean.wang-NuS5LvNUpcJWk0Htik3J/w @ 2018-05-20 17:01 UTC (permalink / raw)
To: robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
linus.walleij-QSEj5FYQhm4dnm+yROfE0A,
matthias.bgg-Re5JQEeQqe8AvxtiuMwx3w,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
Cc: linux-gpio-u79uwXL29TY76Z2rM5mHXA, Sean Wang,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <cover.1526835466.git.sean.wang-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
From: Sean Wang <sean.wang-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
Add EINT support to pinctrl and set those GPIO keys as interrupt-driven
keys.
Signed-off-by: Sean Wang <sean.wang-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
---
arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts | 2 +-
arch/arm64/boot/dts/mediatek/mt7622.dtsi | 8 +++++++-
2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
index b783764..1ff003e 100644
--- a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
+++ b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
@@ -34,7 +34,7 @@
};
gpio-keys {
- compatible = "gpio-keys-polled";
+ compatible = "gpio-keys";
poll-interval = <100>;
factory {
diff --git a/arch/arm64/boot/dts/mediatek/mt7622.dtsi b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
index 9213c96..e2c5450 100644
--- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
@@ -286,9 +286,15 @@
pio: pinctrl@10211000 {
compatible = "mediatek,mt7622-pinctrl";
- reg = <0 0x10211000 0 0x1000>;
+ reg = <0 0x10211000 0 0x1000>,
+ <0 0x10005000 0 0x1000>;
+ reg-names = "base", "eint";
gpio-controller;
#gpio-cells = <2>;
+ interrupt-controller;
+ interrupts = <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&gic>;
+ #interrupt-cells = <2>;
};
watchdog: watchdog@10212000 {
--
2.7.4
^ permalink raw reply related
* Re: [PATCH v3 2/3] arm64: dts: renesas: draak: Describe CVBS input
From: kbuild test robot @ 2018-05-20 23:28 UTC (permalink / raw)
Cc: kbuild-all, niklas.soderlund, laurent.pinchart, horms, geert,
magnus.damm, robh+dt, Jacopo Mondi, linux-renesas-soc, devicetree,
linux-arm-kernel, linux-kernel
In-Reply-To: <1526654878-11143-3-git-send-email-jacopo+renesas@jmondi.org>
[-- Attachment #1: Type: text/plain, Size: 1101 bytes --]
Hi Jacopo,
I love your patch! Yet something to improve:
[auto build test ERROR on linuxtv-media/master]
[cannot apply to renesas/next v4.17-rc6]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Jacopo-Mondi/arm64-dts-Draak-Enable-video-inputs-and-VIN4/20180521-052159
base: git://linuxtv.org/media_tree.git master
config: arm64-defconfig (attached as .config)
compiler: aarch64-linux-gnu-gcc (Debian 7.2.0-11) 7.2.0
reproduce:
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
make.cross ARCH=arm64
All errors (new ones prefixed by >>):
>> Error: arch/arm64/boot/dts/renesas/r8a77995-draak.dts:272.1-6 Label or path vin4 not found
>> FATAL ERROR: Syntax error parsing input tree
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 37440 bytes --]
^ permalink raw reply
* Re: [reset-control] How to initialize hardware state with the shared reset line?
From: Masahiro Yamada @ 2018-05-21 1:27 UTC (permalink / raw)
To: Martin Blumenstingl
Cc: Philipp Zabel, Rob Herring, Lee Jones, Hans de Goede,
Felipe Balbi, DTML, Arnd Bergmann, Linus Walleij,
Linux Kernel Mailing List, linux-arm-kernel
In-Reply-To: <CAFBinCADQsXoc6CUKabH6VX3ZBYb5apo-xBbe1w0BiO8wBAsPw@mail.gmail.com>
Hi.
2018-05-20 19:57 GMT+09:00 Martin Blumenstingl
<martin.blumenstingl@googlemail.com>:
> Hi,
>
> On Thu, May 10, 2018 at 11:16 AM, Masahiro Yamada
> <yamada.masahiro@socionext.com> wrote:
> [snip]
>> I may be missing something, but
>> one solution might be reset hogging on the
>> reset provider side. This allows us to describe
>> the initial state of reset lines in the reset controller.
>>
>> The idea for "reset-hog" is similar to:
>> - "gpio-hog" defined in
>> Documentation/devicetree/bindings/gpio/gpio.txt
>> - "assigned-clocks" defined in
>> Documetation/devicetree/bindings/clock/clock-bindings.txt
>>
>>
>>
>> For example,
>>
>> reset-controller {
>> ....
>>
>> line_a {
>> reset-hog;
>> resets = <1>;
>> reset-assert;
>> };
>> }
>>
>>
>> When the reset controller is registered,
>> the reset ID '1' is asserted.
>>
>>
>> So, all reset consumers that share the reset line '1'
>> will start from the asserted state
>> (i.e. defined state machine state).
> I wonder if a "reset hog" can be board specific:
> - GPIO hogs are definitely board specific (meson-gxbb-odroidc2.dts for
> example uses it to take the USB hub out of reset)
> - assigned-clock-parents (and the like) can also be board specific (I
> made up a use-case since I don't know of any actual examples: board A
> uses an external XTAL while board B uses some other internal
> clock-source because it doesn't have an external XTAL)
>
> however, can reset lines be board specific? or in other words: do we
> need to describe them in device-tree?
Indeed.
I did not come up with board-specific cases.
The problem we are discussing is SoC-specific,
and reset-controller drivers are definitely SoC-specific.
So, I think the initial state can be coded in drivers instead of DT.
> we could extend struct reset_controller_dev (= reset controller
> driver) if they are not board specific:
> - either assert all reset lines by default except if they are listed
> in a new field (may break backwards compatibility, requires testing of
> all reset controller drivers)
This is quite simple, but I am afraid there are some cases where the forcible
reset-assert is not preferred.
For example, the earlycon. When we use earlycon, we would expect it has been
initialized by a boot-loader, or something.
If it is reset-asserted on the while, the console output
will not be good.
> - specify a list of reset lines and their desired state (or to keep it
> easy: specify a list of reset lines that should be asserted)
> (I must admit that this is basically your idea but the definition is
> moved from device-tree to the reset controller driver)
Yes, I think the list of "reset line ID" and "init state" pairs
would be nicer.
> any "chip" specific differences could be expressed by using a
> different of_device_id
>
> one the other hand: your "reset hog" solution looks fine to me if
> reset lines can be board specific
>
>> From the discussion with Martin Blumenstingl
>> (https://lkml.org/lkml/2018/4/28/115),
>> the problem for Amlogic is that
>> the reset line is "de-asserted" by default.
>> If so, the 'reset-hog' would fix the problem,
>> and DWC3 driver would be able to use
>> shared, level reset, I think.
> I think you are right: if we could control the initial state then we
> should be able to use level resets
Even further, can we drop the shared reset_control_reset() support, maybe?
(in other words, revert commit 7da33a37b48f11)
Thanks for your comment!
>
> Regards
> Martin
> --
> To unsubscribe from this list: send the line "unsubscribe devicetree" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
--
Best Regards
Masahiro Yamada
^ permalink raw reply
* RE: [PATCH] ARM: dts: imx7d: use operating-points-v2 for cpu
From: Anson Huang @ 2018-05-21 1:58 UTC (permalink / raw)
To: Shawn Guo
Cc: kernel@pengutronix.de, Fabio Estevam, robh+dt@kernel.org,
mark.rutland@arm.com, dl-linux-imx,
linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org
In-Reply-To: <20180520125048.GX26863@dragon>
Anson Huang
Best Regards!
> -----Original Message-----
> From: Shawn Guo [mailto:shawnguo@kernel.org]
> Sent: Sunday, May 20, 2018 8:51 PM
> To: Anson Huang <anson.huang@nxp.com>
> Cc: kernel@pengutronix.de; Fabio Estevam <fabio.estevam@nxp.com>;
> robh+dt@kernel.org; mark.rutland@arm.com; dl-linux-imx
> <linux-imx@nxp.com>; linux-arm-kernel@lists.infradead.org;
> devicetree@vger.kernel.org; linux-kernel@vger.kernel.org
> Subject: Re: [PATCH] ARM: dts: imx7d: use operating-points-v2 for cpu
>
> On Wed, May 16, 2018 at 12:48:17PM +0800, Anson Huang wrote:
> > This patch uses "operating-points-v2" instead of "operating-points" to
> > be more fit with cpufreq-dt driver.
> >
> > Signed-off-by: Anson Huang <Anson.Huang@nxp.com>
> > ---
> > arch/arm/boot/dts/imx7d.dtsi | 24 +++++++++++++++++++-----
> > 1 file changed, 19 insertions(+), 5 deletions(-)
> >
> > diff --git a/arch/arm/boot/dts/imx7d.dtsi
> > b/arch/arm/boot/dts/imx7d.dtsi index 4c9877e..28980c8 100644
> > --- a/arch/arm/boot/dts/imx7d.dtsi
> > +++ b/arch/arm/boot/dts/imx7d.dtsi
> > @@ -9,12 +9,8 @@
> > / {
> > cpus {
> > cpu0: cpu@0 {
> > - operating-points = <
> > - /* KHz uV */
> > - 996000 1075000
> > - 792000 975000
> > - >;
> > clock-frequency = <996000000>;
> > + operating-points-v2 = <&cpu0_opp_table>;
> > };
> >
> > cpu1: cpu@1 {
> > @@ -22,6 +18,24 @@
> > device_type = "cpu";
> > reg = <1>;
> > clock-frequency = <996000000>;
> > + operating-points-v2 = <&cpu0_opp_table>;
> > + };
> > + };
> > +
> > + cpu0_opp_table: opp_table0 {
>
> Hyphen is recommended in node name. Also the suffix 0 doesn't mean too
> much here. That said, a better node name would be 'opp-table'.
>
> > + compatible = "operating-points-v2";
> > + opp-shared;
> > +
> > + opp-792000000 {
> > + opp-hz = /bits/ 64 <792000000>;
> > + opp-microvolt = <975000>;
> > + clock-latency-ns = <150000>;
> > + };
>
> We recommend to have a newline between nodes.
>
> I fixed them all and applied the patch.
>
> Shawn
Thanks Shawn.
Anson.
>
> > + opp-996000000 {
> > + opp-hz = /bits/ 64 <996000000>;
> > + opp-microvolt = <1075000>;
> > + clock-latency-ns = <150000>;
> > + opp-suspend;
> > };
> > };
> >
> > --
> > 2.7.4
> >
^ permalink raw reply
* RE: [PATCH V2 2/3] clk: imx7d: correct enet clock CCGR registers
From: Anson Huang @ 2018-05-21 2:35 UTC (permalink / raw)
To: Stefan Agner
Cc: shawnguo@kernel.org, kernel@pengutronix.de, Fabio Estevam,
robh+dt@kernel.org, mark.rutland@arm.com, mturquette@baylibre.com,
sboyd@kernel.org, Adriana Reus, rui.silva@linaro.org,
dl-linux-imx, linux-arm-kernel@lists.infradead.org,
devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-clk@vger.kernel.org
In-Reply-To: <c42c4274cfd06297d1699c96d3253125@agner.ch>
Hi, Stefan
Anson Huang
Best Regards!
> -----Original Message-----
> From: Stefan Agner [mailto:stefan@agner.ch]
> Sent: Friday, May 18, 2018 9:02 PM
> To: Anson Huang <anson.huang@nxp.com>
> Cc: shawnguo@kernel.org; kernel@pengutronix.de; Fabio Estevam
> <fabio.estevam@nxp.com>; robh+dt@kernel.org; mark.rutland@arm.com;
> mturquette@baylibre.com; sboyd@kernel.org; Adriana Reus
> <adriana.reus@nxp.com>; rui.silva@linaro.org; dl-linux-imx
> <linux-imx@nxp.com>; linux-arm-kernel@lists.infradead.org;
> devicetree@vger.kernel.org; linux-kernel@vger.kernel.org;
> linux-clk@vger.kernel.org
> Subject: Re: [PATCH V2 2/3] clk: imx7d: correct enet clock CCGR registers
>
> On 18.05.2018 03:01, Anson Huang wrote:
> > Correct enet clock gates as below:
> >
> > CCGR6: IMX7D_ENET_AXI_ROOT_CLK (enet1 and enet2 bus clocks)
> > CCGR112: IMX7D_ENET1_TIME_ROOT_CLK, IMX7D_ENET1_IPG_ROOT_CLK
> > CCGR113: IMX7D_ENET2_TIME_ROOT_CLK, IMX7D_ENET2_IPG_ROOT_CLK
> >
> > Just rename unused IMX7D_ENETx_REF_ROOT_CLK for
> > IMX7D_ENETx_IPG_ROOT_CLK instead of adding new clocks.
>
> Are you sure that IMX7D_ENETx_REF_ROOT_CLK are not used?
>
> I understand that the reference manual does not a gate at 0x44e0...
>
> But in a earlier revision of our Colibri iMX7 we actually used clock out, and
> referenced this clock to enable the reference clock (see also:
> https://emea01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fpatch
> work.kernel.org%2Fpatch%2F9211371%2F&data=02%7C01%7CAnson.Huang%
> 40nxp.com%7Cea0856a68d8e4b921ba608d5bcbf9c02%7C686ea1d3bc2b4c6fa
> 92cd99c5c301635%7C0%7C1%7C636622453508888330&sdata=rEhwj0innLDc
> AEgxJyqd5vtG3SNVS05r2hEFvSc%2BQQs%3D&reserved=0).
>
> I guess if the gate really does not exist, then we should/would have to set
> IMX7D_ENET1_REF_ROOT_DIV to use the SoC provided ref clock.
>
> --
> Stefan
I looked into the RTL and also checked with our design team, they confirm that
there is no CCGR78(0x44e0) and CCGR80(0x4500) on i.MX7D, the register offset
are there, but no hardware wire connection for them. That is why they did NOT
list them in Reference Manual. So I think we can remove them.
For your case of using them as clock input, maybe clock tree auto use its parent
IMX7D_ENETx_REF_ROOT_DIV which is existing, so it works.
Anson.
>
> >
> > Based on Andy Duan's patch from the NXP kernel tree.
> >
> > Signed-off-by: Anson Huang <Anson.Huang@nxp.com>
> > ---
> > drivers/clk/imx/clk-imx7d.c | 10 ++++++----
> > include/dt-bindings/clock/imx7d-clock.h | 4 ++--
> > 2 files changed, 8 insertions(+), 6 deletions(-)
> >
> > diff --git a/drivers/clk/imx/clk-imx7d.c b/drivers/clk/imx/clk-imx7d.c
> > index 23d5090a..d4936b9 100644
> > --- a/drivers/clk/imx/clk-imx7d.c
> > +++ b/drivers/clk/imx/clk-imx7d.c
> > @@ -26,6 +26,8 @@ static u32 share_count_sai1; static u32
> > share_count_sai2; static u32 share_count_sai3; static u32
> > share_count_nand;
> > +static u32 share_count_enet1;
> > +static u32 share_count_enet2;
> >
> > static const struct clk_div_table test_div_table[] = {
> > { .val = 3, .div = 1, },
> > @@ -805,6 +807,10 @@ static void __init imx7d_clocks_init(struct
> > device_node *ccm_node)
> > clks[IMX7D_MIPI_DSI_ROOT_CLK] = imx_clk_gate4("mipi_dsi_root_clk",
> > "mipi_dsi_post_div", base + 0x4650, 0);
> > clks[IMX7D_MIPI_CSI_ROOT_CLK] = imx_clk_gate4("mipi_csi_root_clk",
> > "mipi_csi_post_div", base + 0x4640, 0);
> > clks[IMX7D_MIPI_DPHY_ROOT_CLK] =
> imx_clk_gate4("mipi_dphy_root_clk",
> > "mipi_dphy_post_div", base + 0x4660, 0);
> > + clks[IMX7D_ENET1_IPG_ROOT_CLK] =
> > imx_clk_gate2_shared2("enet1_ipg_root_clk", "enet_axi_post_div", base
> > + 0x4700, 0, &share_count_enet1);
> > + clks[IMX7D_ENET1_TIME_ROOT_CLK] =
> > imx_clk_gate2_shared2("enet1_time_root_clk", "enet1_time_post_div",
> > base + 0x4700, 0, &share_count_enet1);
> > + clks[IMX7D_ENET2_IPG_ROOT_CLK] =
> > imx_clk_gate2_shared2("enet2_ipg_root_clk", "enet_axi_post_div", base
> > + 0x4710, 0, &share_count_enet2);
> > + clks[IMX7D_ENET2_TIME_ROOT_CLK] =
> > imx_clk_gate2_shared2("enet2_time_root_clk", "enet2_time_post_div",
> > base + 0x4710, 0, &share_count_enet2);
> > clks[IMX7D_SAI1_ROOT_CLK] = imx_clk_gate2_shared2("sai1_root_clk",
> > "sai1_post_div", base + 0x48c0, 0, &share_count_sai1);
> > clks[IMX7D_SAI1_IPG_CLK] = imx_clk_gate2_shared2("sai1_ipg_clk",
> > "ipg_root_clk", base + 0x48c0, 0, &share_count_sai1);
> > clks[IMX7D_SAI2_ROOT_CLK] = imx_clk_gate2_shared2("sai2_root_clk",
> > "sai2_post_div", base + 0x48d0, 0, &share_count_sai2); @@ -812,10
> > +818,6 @@ static void __init imx7d_clocks_init(struct device_node
> > *ccm_node)
> > clks[IMX7D_SAI3_ROOT_CLK] = imx_clk_gate2_shared2("sai3_root_clk",
> > "sai3_post_div", base + 0x48e0, 0, &share_count_sai3);
> > clks[IMX7D_SAI3_IPG_CLK] = imx_clk_gate2_shared2("sai3_ipg_clk",
> > "ipg_root_clk", base + 0x48e0, 0, &share_count_sai3);
> > clks[IMX7D_SPDIF_ROOT_CLK] = imx_clk_gate4("spdif_root_clk",
> > "spdif_post_div", base + 0x44d0, 0);
> > - clks[IMX7D_ENET1_REF_ROOT_CLK] =
> imx_clk_gate4("enet1_ref_root_clk",
> > "enet1_ref_post_div", base + 0x44e0, 0);
> > - clks[IMX7D_ENET1_TIME_ROOT_CLK] =
> > imx_clk_gate4("enet1_time_root_clk", "enet1_time_post_div", base +
> > 0x44f0, 0);
> > - clks[IMX7D_ENET2_REF_ROOT_CLK] =
> imx_clk_gate4("enet2_ref_root_clk",
> > "enet2_ref_post_div", base + 0x4500, 0);
> > - clks[IMX7D_ENET2_TIME_ROOT_CLK] =
> > imx_clk_gate4("enet2_time_root_clk", "enet2_time_post_div", base +
> > 0x4510, 0);
> > clks[IMX7D_EIM_ROOT_CLK] = imx_clk_gate4("eim_root_clk",
> > "eim_post_div", base + 0x4160, 0);
> > clks[IMX7D_NAND_RAWNAND_CLK] =
> > imx_clk_gate2_shared2("nand_rawnand_clk", "nand_root_clk", base +
> > 0x4140, 0, &share_count_nand);
> > clks[IMX7D_NAND_USDHC_BUS_RAWNAND_CLK] =
> > imx_clk_gate2_shared2("nand_usdhc_rawnand_clk",
> "nand_usdhc_root_clk",
> > base + 0x4140, 0, &share_count_nand); diff --git
> > a/include/dt-bindings/clock/imx7d-clock.h
> > b/include/dt-bindings/clock/imx7d-clock.h
> > index b2325d3e2..0d67f53 100644
> > --- a/include/dt-bindings/clock/imx7d-clock.h
> > +++ b/include/dt-bindings/clock/imx7d-clock.h
> > @@ -168,7 +168,7 @@
> > #define IMX7D_SPDIF_ROOT_SRC 155
> > #define IMX7D_SPDIF_ROOT_CG 156
> > #define IMX7D_SPDIF_ROOT_DIV 157
> > -#define IMX7D_ENET1_REF_ROOT_CLK 158
> > +#define IMX7D_ENET1_IPG_ROOT_CLK 158
> > #define IMX7D_ENET1_REF_ROOT_SRC 159
> > #define IMX7D_ENET1_REF_ROOT_CG 160
> > #define IMX7D_ENET1_REF_ROOT_DIV 161
> > @@ -176,7 +176,7 @@
> > #define IMX7D_ENET1_TIME_ROOT_SRC 163
> > #define IMX7D_ENET1_TIME_ROOT_CG 164
> > #define IMX7D_ENET1_TIME_ROOT_DIV 165
> > -#define IMX7D_ENET2_REF_ROOT_CLK 166
> > +#define IMX7D_ENET2_IPG_ROOT_CLK 166
> > #define IMX7D_ENET2_REF_ROOT_SRC 167
> > #define IMX7D_ENET2_REF_ROOT_CG 168
> > #define IMX7D_ENET2_REF_ROOT_DIV 169
^ permalink raw reply
* Re: [linux-next PATCH 0/4] Enable network driver on K2G ICE and GP EVMs
From: santosh.shilimkar @ 2018-05-21 3:17 UTC (permalink / raw)
To: Murali Karicheri, ssantosh, robh+dt, mark.rutland, linux,
linux-arm-kernel, devicetree, linux-kernel
In-Reply-To: <1526066952-5230-1-git-send-email-m-karicheri2@ti.com>
On 5/11/18 12:29 PM, Murali Karicheri wrote:
> Now that NetCP driver patches for K2G SoC is merged to linux-next master
> this series add patches to enable network driver on K2G ICE and GP EVMs.
>
> Thanks
>
> Applied the patches on top of latest linux-next master, built kernel and
> booted up on both EVMs. The logs are below
>
> K2G GP EVM: https://pastebin.ubuntu.com/p/ycZDnZXYPx/
> K2G ICE EVM: https://pastebin.ubuntu.com/p/bdCpzgdrXr/
>
> Murali Karicheri (4):
> ARM: dts: k2g: add dt bindings to support network driver
> ARM: dts: keystone-k2g-evm: Enable netcp network driver
> ARM: dts: keystone-k2g-ice: Enable netcp network driver
> ARM: keystone: k2g: enable micrel and dp83867 phys
>
> arch/arm/boot/dts/keystone-k2g-evm.dts | 53 +++++++++++
> arch/arm/boot/dts/keystone-k2g-ice.dts | 59 ++++++++++++
> arch/arm/boot/dts/keystone-k2g-netcp.dtsi | 147 ++++++++++++++++++++++++++++++
> arch/arm/boot/dts/keystone-k2g.dtsi | 13 +++
> arch/arm/configs/keystone_defconfig | 2 +
> 5 files changed, 274 insertions(+)
> create mode 100644 arch/arm/boot/dts/keystone-k2g-netcp.dtsi
>
Looks good. Will add this to the queue for 4.19. Thanks !!
Regards,
Santosh
^ permalink raw reply
* Re: [PATCH] clk: aspeed: Add 24MHz fixed clock
From: Joel Stanley @ 2018-05-21 4:33 UTC (permalink / raw)
To: Lei YU
Cc: Michael Turquette, Stephen Boyd, Andrew Jeffery, Rob Herring,
Mark Rutland, linux-clk, Linux ARM, linux-aspeed,
Linux Kernel Mailing List, devicetree
In-Reply-To: <1526633822-17138-1-git-send-email-mine260309@gmail.com>
On 18 May 2018 at 18:27, Lei YU <mine260309@gmail.com> wrote:
> Add a 24MHz fixed clock.
> This clock will be used for certain devices, e.g. pwm.
>
> Signed-off-by: Lei YU <mine260309@gmail.com>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Cheers,
Joel
> ---
> drivers/clk/clk-aspeed.c | 9 ++++++++-
> include/dt-bindings/clock/aspeed-clock.h | 1 +
> 2 files changed, 9 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/clk/clk-aspeed.c b/drivers/clk/clk-aspeed.c
> index 5eb50c3..4664088 100644
> --- a/drivers/clk/clk-aspeed.c
> +++ b/drivers/clk/clk-aspeed.c
> @@ -14,7 +14,7 @@
>
> #include <dt-bindings/clock/aspeed-clock.h>
>
> -#define ASPEED_NUM_CLKS 35
> +#define ASPEED_NUM_CLKS 36
>
> #define ASPEED_RESET_CTRL 0x04
> #define ASPEED_CLK_SELECTION 0x08
> @@ -474,6 +474,13 @@ static int aspeed_clk_probe(struct platform_device *pdev)
> return PTR_ERR(hw);
> aspeed_clk_data->hws[ASPEED_CLK_BCLK] = hw;
>
> + /* Fixed 24MHz clock */
> + hw = clk_hw_register_fixed_rate(NULL, "fixed-24m", "clkin",
> + 0, 24000000);
> + if (IS_ERR(hw))
> + return PTR_ERR(hw);
> + aspeed_clk_data->hws[ASPEED_CLK_24M] = hw;
> +
> /*
> * TODO: There are a number of clocks that not included in this driver
> * as more information is required:
> diff --git a/include/dt-bindings/clock/aspeed-clock.h b/include/dt-bindings/clock/aspeed-clock.h
> index d3558d8..ff29d8e 100644
> --- a/include/dt-bindings/clock/aspeed-clock.h
> +++ b/include/dt-bindings/clock/aspeed-clock.h
> @@ -38,6 +38,7 @@
> #define ASPEED_CLK_MAC 32
> #define ASPEED_CLK_BCLK 33
> #define ASPEED_CLK_MPLL 34
> +#define ASPEED_CLK_24M 35
>
> #define ASPEED_RESET_XDMA 0
> #define ASPEED_RESET_MCTP 1
> --
> 2.7.4
>
^ permalink raw reply
* Re: [PATCH v8 10/15] cpufreq: Add Kryo CPU scaling driver
From: Viresh Kumar @ 2018-05-21 4:49 UTC (permalink / raw)
To: ilialin
Cc: mturquette, sboyd, robh, mark.rutland, nm, lgirdwood, broonie,
andy.gross, david.brown, catalin.marinas, will.deacon, rjw,
linux-clk, devicetree, linux-kernel, linux-pm, linux-arm-msm,
linux-soc, linux-arm-kernel, rnayak, amit.kucheria,
nicolas.dechesne, celster, tfinkel
In-Reply-To: <019201d3ef66$db97aed0$92c70c70$@codeaurora.org>
On 19-05-18, 14:45, ilialin@codeaurora.org wrote:
> Hi Viresh,
>
> If I send patches in reply, it will produce new patches, instead of answers
> in the thread. Please find below the file dump.
There is one email from you which appears to be just fine and appears
to be in reply to this thread only. Maybe its your email client that
screwed it up for you ? Things look good in mutt.
--
viresh
^ permalink raw reply
* Re: [PATCH] cpufreq: Add Kryo CPU scaling driver
From: Viresh Kumar @ 2018-05-21 5:04 UTC (permalink / raw)
To: Ilia Lin
Cc: mturquette, sboyd, robh, mark.rutland, nm, lgirdwood, broonie,
andy.gross, david.brown, catalin.marinas, will.deacon, rjw,
linux-clk, devicetree, linux-kernel, linux-pm, linux-arm-msm,
linux-soc, linux-arm-kernel, rnayak, amit.kucheria,
nicolas.dechesne, celster, tfinkel
In-Reply-To: <1526729701-8589-1-git-send-email-ilialin@codeaurora.org>
More comments after Russell's reply.
On 19-05-18, 14:35, Ilia Lin wrote:
> +static int __init qcom_cpufreq_kryo_driver_init(void)
> +{
> + struct device *cpu_dev_silver, *cpu_dev_gold;
> + struct opp_table *opp_silver, *opp_gold;
> + enum _msm8996_version msm8996_version;
> + struct nvmem_cell *speedbin_nvmem;
> + struct platform_device *pdev;
> + struct device_node *np;
> + u8 *speedbin;
> + u32 versions;
> + size_t len;
> + int ret;
> +
> + cpu_dev_silver = get_cpu_device(SILVER_LEAD);
> + if (IS_ERR_OR_NULL(cpu_dev_silver))
get_cpu_device() returns only NULL on error.
> + return PTR_ERR(cpu_dev_silver);
> +
> + cpu_dev_gold = get_cpu_device(SILVER_LEAD);
> + if (IS_ERR_OR_NULL(cpu_dev_gold))
> + return PTR_ERR(cpu_dev_gold);
> +
> + msm8996_version = qcom_cpufreq_kryo_get_msm_id();
> + if (NUM_OF_MSM8996_VERSIONS == msm8996_version) {
> + dev_err(cpu_dev_silver, "Not Snapdragon 820/821!");
> + return -ENODEV;
> + }
> +
> + np = dev_pm_opp_of_get_opp_desc_node(cpu_dev_silver);
> + if (IS_ERR_OR_NULL(np))
same here.
> + return PTR_ERR(np);
> +
> + if (!of_device_is_compatible(np, "operating-points-v2-kryo-cpu")) {
> + ret = -ENOENT;
> + goto free_np;
> + }
> +
> + speedbin_nvmem = of_nvmem_cell_get(np, NULL);
> + if (IS_ERR(speedbin_nvmem)) {
> + ret = PTR_ERR(speedbin_nvmem);
> + dev_err(cpu_dev_silver, "Could not get nvmem cell: %d\n", ret);
> + goto free_np;
> + }
> +
> + speedbin = nvmem_cell_read(speedbin_nvmem, &len);
> + nvmem_cell_put(speedbin_nvmem);
> +
> + switch (msm8996_version) {
> + case MSM8996_V3:
> + versions = 1 << (unsigned int)(*speedbin);
> + break;
> + case MSM8996_SG:
> + versions = 1 << ((unsigned int)(*speedbin) + 4);
> + break;
> + default:
> + BUG();
> + break;
> + }
> +
> + opp_silver = dev_pm_opp_set_supported_hw(cpu_dev_silver,&versions,1);
> + if (IS_ERR(opp_silver)) {
> + dev_err(cpu_dev_silver, "Failed to set supported hardware\n");
> + ret = PTR_ERR(opp_silver);
> + goto free_np;
> + }
> +
> + opp_gold = dev_pm_opp_set_supported_hw(cpu_dev_gold,&versions,1);
> + if (IS_ERR(opp_gold)) {
> + dev_err(cpu_dev_gold, "Failed to set supported hardware\n");
> + ret = PTR_ERR(opp_gold);
> + goto free_opp_silver;
> + }
> +
> + pdev = platform_device_register_simple("cpufreq-dt", -1, NULL, 0);
and this only returns ERR_PTR() on error.
> + if (!IS_ERR_OR_NULL(pdev))
> + return 0;
> +
> + ret = PTR_ERR(pdev);
> + dev_err(cpu_dev_silver, "Failed to register platform device\n");
> + dev_pm_opp_put_supported_hw(opp_gold);
> +
> +free_opp_silver:
> + dev_pm_opp_put_supported_hw(opp_silver);
> +
> +free_np:
> + of_node_put(np);
> +
> + return ret;
> +}
> +late_initcall(qcom_cpufreq_kryo_driver_init);
> +
> +MODULE_DESCRIPTION("Qualcomm Technologies, Inc. Kryo CPUfreq driver");
> +MODULE_LICENSE("GPL v2");
> --
> 1.9.1
--
viresh
^ permalink raw reply
* RE: [v4 3/6] dt-bindings: fsl-qdma: Add NXP Layerscpae qDMA controller bindings
From: Wen He @ 2018-05-21 5:52 UTC (permalink / raw)
To: Rob Herring
Cc: vinod.koul@intel.com, dmaengine@vger.kernel.org,
devicetree@vger.kernel.org, Leo Li, Jiafei Pan, Jiaheng Fan
In-Reply-To: <20180518212605.GA1119@rob-hp-laptop>
Hi Rob,
Please see my comments inline.
Best Regards,
Wen
> -----Original Message-----
> From: Rob Herring [mailto:robh@kernel.org]
> Sent: 2018年5月19日 5:26
> To: Wen He <wen.he_1@nxp.com>
> Cc: vinod.koul@intel.com; dmaengine@vger.kernel.org;
> devicetree@vger.kernel.org; Leo Li <leoyang.li@nxp.com>; Jiafei Pan
> <jiafei.pan@nxp.com>; Jiaheng Fan <jiaheng.fan@nxp.com>
> Subject: Re: [v4 3/6] dt-bindings: fsl-qdma: Add NXP Layerscpae qDMA
> controller bindings
>
> On Mon, May 14, 2018 at 08:03:04PM +0800, Wen He wrote:
> > Document the devicetree bindings for NXP Layerscape qDMA controller
> > which could be found on NXP QorIQ Layerscape SoCs.
> >
> > Signed-off-by: Wen He <wen.he_1@nxp.com>
> > ---
> > change in v4:
> > - Rewrite the bindings document that follows generic DMA bindings
> > file
> >
> > change in v3:
> > - no change
> >
> > change in v2:
> > - Remove indentation
> > - Add "Should be" before 'fsl,ls1021a-qdma'
> > - Replace 'channels' by 'dma-channels'
> > - Replace 'qdma@8390000' by 'dma-controller@8390000'
> >
> > Documentation/devicetree/bindings/dma/fsl-qdma.txt | 41
> ++++++++++++++++++++
> > 1 files changed, 41 insertions(+), 0 deletions(-) create mode 100644
> > Documentation/devicetree/bindings/dma/fsl-qdma.txt
> >
> > diff --git a/Documentation/devicetree/bindings/dma/fsl-qdma.txt
> > b/Documentation/devicetree/bindings/dma/fsl-qdma.txt
> > new file mode 100644
> > index 0000000..368c4e7
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/dma/fsl-qdma.txt
> > @@ -0,0 +1,41 @@
> > +NXP Layerscape SoC qDMA Controller
> > +==================================
> > +
> > +This device follows the generic DMA bindings defined in dma/dma.txt.
> > +
> > +Required properties:
> > +
> > +- compatible: Must be one of
> > + "fsl,ls1021a-qdma": for LS1021A Board
> > + "fsl,ls1043a-qdma": for ls1043A Board
> > + "fsl,ls1046a-qdma": for ls1046A Board
> > +- reg: Should contain the register's base address and length.
> > +- interrupts: Should contain a reference to the interrupt used by
> this
> > + device.
> > +- interrupt-names: Should contain interrupt names:
> > + "qdma-error": the error interrupt
> > + "qdma-queue": the queue interrupt
> > +- queues: Should contain number of queues supported.
>
> Needs a vendor prefix.
>
Does means: The queues filed need a vendor prefix ?
like 'fsl-queues' ? right?
> > +
> > +Optional properties:
> > +
> > +- dma-channels: Number of DMA channels supported by the
> controller.
> > +- big-endian: If present registers and hardware scatter/gather
> descriptors
> > + of the qDMA are implemented in big endian mode, otherwise in
> little
> > + mode.
> > +
> > +Examples:
> > +
> > + qdma: dma-controller@8390000 {
> > + compatible = "fsl,ls1021a-qdma";
> > + reg = <0x0 0x8398000 0x0 0x2000 /* Controller registers */
> > + 0x0 0x839a000 0x0 0x2000>; /* Block registers */
> > + interrupts = <GIC_SPI 185 IRQ_TYPE_LEVEL_HIGH>,
> > + <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>;
> > + interrupt-names = "qdma-error", "qdma-queue";
> > + dma-channels = <8>;
> > + queues = <2>;
> > + big-endian;
> > + };
> > +
> > +DMA clients must use the format described in dma/dma.txt file.
> > --
> > 1.7.1
> >
> > --
> > To unsubscribe from this list: send the line "unsubscribe devicetree"
> > in the body of a message to majordomo@vger.kernel.org More majordomo
> > info at
> >
> https://emea01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fvger
> > .kernel.org%2Fmajordomo-info.html&data=02%7C01%7Cwen.he_1%40nxp
> .com%7C
> >
> afe9f30f68654b36085408d5bd05f856%7C686ea1d3bc2b4c6fa92cd99c5c301
> 635%7C
> >
> 0%7C1%7C636622755700659994&sdata=W65hD8ZYUQm2%2F8TdfiUGorgB
> Om8GojXdES2
> > mVNzQpIE%3D&reserved=0
^ permalink raw reply
* Re: [PATCH v2 0/2] Add support for QCOM cpufreq FW driver
From: Viresh Kumar @ 2018-05-21 6:05 UTC (permalink / raw)
To: Taniya Das
Cc: Rafael J. Wysocki, linux-kernel, linux-pm, Stephen Boyd, robh,
Rajendra Nayak, Amit Nischal, devicetree, skannan, amit.kucheria
In-Reply-To: <1526751291-17873-1-git-send-email-tdas@codeaurora.org>
On 19-05-18, 23:04, Taniya Das wrote:
> [v2]
> * Address comments given in v0 series.
That's not how you do it. You need to explain every change in enough
detail here so that the reviewers don't need to go to their previous
emails to see what changed.
> [v1]
> * Fixed compilation reported by Amit K.
>
> The CPUfreq FW present in some QCOM chipsets offloads the steps necessary
> for changing the frequency of CPUs. The driver implements the cpufreq
> driver interface for this firmware.
>
> Taniya Das (2):
> dt-bindings: cpufreq: Introduce QCOM CPUFREQ FW bindings
> cpufreq: qcom-fw: Add support for QCOM cpufreq FW driver
>
> .../bindings/cpufreq/cpufreq-qcom-fw.txt | 68 +++++
> drivers/cpufreq/Kconfig.arm | 9 +
> drivers/cpufreq/Makefile | 1 +
> drivers/cpufreq/qcom-cpufreq-fw.c | 317 +++++++++++++++++++++
> 4 files changed, 395 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/cpufreq/cpufreq-qcom-fw.txt
> create mode 100644 drivers/cpufreq/qcom-cpufreq-fw.c
>
> --
> Qualcomm INDIA, on behalf of Qualcomm Innovation Center, Inc.is a member
> of the Code Aurora Forum, hosted by the Linux Foundation.
--
viresh
^ permalink raw reply
* Re: [RFC 12/13] ARM: dts: ti: add dra71-evm FIT description file
From: Tero Kristo @ 2018-05-21 6:57 UTC (permalink / raw)
To: Tony Lindgren
Cc: mark.rutland, devicetree, trini, Russell King - ARM Linux,
robh+dt, frowand.list, wmills,
linux-arm-kernel@lists.infradead.org
In-Reply-To: <20180417144913.GD5669@atomide.com>
On 17/04/18 17:49, Tony Lindgren wrote:
> * Tero Kristo <t-kristo@ti.com> [180417 09:36]:
>> In typical setup, you can boot a large number of different configs via:
>>
>> bootm 0x82000000#dra71-evm#nand#lcd-auo-g101evn01.0
>>
>> ... assuming the configs were named like that, and assuming they would be
>> compatible with each other. The am57xx-evm example provided is better, as
>> you can chain the different cameras to the available evm configs.
>
> Why not just do it in the bootloader to put together the dtb?
>
> Then for external devices, you could just pass info on the
> kernel cmdline with lcd=foo camera=bar if they cannot be
> detected over I2C.
(Added Linux ARM list to CC, this was not part of the original delivery.)
Ok trying to resurrect this thread a bit. Is there any kind of consensus
how things like this should be handled? Should we add the DT overlay
files to kernel tree or not?
Should we add any kind of build infra to kernel tree, and at what level
would this be? Just DT overlay file building support, and drop the FIT
build support as was proposed in this RFC series or...?
U-boot can obviously parse the base DTB + overlay DTB:s into a single
DTB, but this is somewhat clumsy approach and is relatively error prone
to get it right.
Building the FIT image post kernel build would also be possible, but who
would be doing this, is there any need to get this done in generic
manner or shall we just add SoC vendor specific tools for this?
-Tero
--
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
^ permalink raw reply
* Re: [PATCH v2 0/2] Add support for QCOM cpufreq FW driver
From: Taniya Das @ 2018-05-21 7:35 UTC (permalink / raw)
To: Viresh Kumar
Cc: Rafael J. Wysocki, linux-kernel, linux-pm, Stephen Boyd, robh,
Rajendra Nayak, Amit Nischal, devicetree, skannan, amit.kucheria
In-Reply-To: <20180521060529.kyjkglucbydr6b3f@vireshk-i7>
Hello Viresh,
Sure, will do it next time. Hope updating the fixes in this email is
fine. Do let me know in case you need me to send it across again the
series with cover letter updated.
On 5/21/2018 11:35 AM, Viresh Kumar wrote:
> On 19-05-18, 23:04, Taniya Das wrote:
>> [v2]
>> * Address comments given in v0 series.
>
> That's not how you do it. You need to explain every change in enough
> detail here so that the reviewers don't need to go to their previous
> emails to see what changed.
>
Fixes in [v2]
* Fixed the alignment issues in "qcom_cpufreq_fw_target_index" for
dev_err and also for "qcom_cpu_resources_init".
* Removed ret = 0 from qcom_get_related_cpus and added to check for
cpu_mask_empty to return -ENOENT.
* Fixes qcom_cpu_resources_init function
* Remove initialization of 'index'
* Check for valid 'c'
* Removed initialization of 'prev_cc' from 'qcom_read_lut'.
* Remove initialization of 'ret' from function qcom_resources_init and
add return -ENODEV based on 'of_get_available_child_count'.
* Removed initialization of 'rc' from qcom_cpufreq_fw_driver_probe
* Removed module_exit as this driver would not be used as module, also
updated the Kconfig to bool from tristate.
* Updated the subsystem in device tree bindings.
>> [v1]
>> * Fixed compilation reported by Amit K.
>>
>> The CPUfreq FW present in some QCOM chipsets offloads the steps necessary
>> for changing the frequency of CPUs. The driver implements the cpufreq
>> driver interface for this firmware.
>>
>> Taniya Das (2):
>> dt-bindings: cpufreq: Introduce QCOM CPUFREQ FW bindings
>> cpufreq: qcom-fw: Add support for QCOM cpufreq FW driver
>>
>> .../bindings/cpufreq/cpufreq-qcom-fw.txt | 68 +++++
>> drivers/cpufreq/Kconfig.arm | 9 +
>> drivers/cpufreq/Makefile | 1 +
>> drivers/cpufreq/qcom-cpufreq-fw.c | 317 +++++++++++++++++++++
>> 4 files changed, 395 insertions(+)
>> create mode 100644 Documentation/devicetree/bindings/cpufreq/cpufreq-qcom-fw.txt
>> create mode 100644 drivers/cpufreq/qcom-cpufreq-fw.c
>>
>> --
>> Qualcomm INDIA, on behalf of Qualcomm Innovation Center, Inc.is a member
>> of the Code Aurora Forum, hosted by the Linux Foundation.
>
--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation.
--
^ permalink raw reply
* Re: [PATCH 12/15] drm/sun4i: Add support for second clock parent to DW HDMI PHY clk driver
From: kbuild test robot @ 2018-05-21 7:47 UTC (permalink / raw)
To: Jernej Skrabec
Cc: kbuild-all-JC7UmRfGjtg, maxime.ripard-LDxbnhwyfcJBDgjK7y7TUQ,
wens-jdAy2FN1RRM, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
mark.rutland-5wv7dgnIgG8,
dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-clk-u79uwXL29TY76Z2rM5mHXA,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw
In-Reply-To: <20180519183127.2718-13-jernej.skrabec-gGgVlfcn5nU@public.gmane.org>
[-- Attachment #1: Type: text/plain, Size: 11215 bytes --]
Hi Jernej,
Thank you for the patch! Perhaps something to improve:
[auto build test WARNING on drm/drm-next]
[also build test WARNING on v4.17-rc6 next-20180517]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Jernej-Skrabec/Add-support-for-R40-HDMI-pipeline/20180521-131839
base: git://people.freedesktop.org/~airlied/linux.git drm-next
config: arm64-allmodconfig (attached as .config)
compiler: aarch64-linux-gnu-gcc (Debian 7.2.0-11) 7.2.0
reproduce:
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
make.cross ARCH=arm64
All warnings (new ones prefixed by >>):
In file included from drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h:12:0,
from drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c:9:
drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c: In function 'sun8i_hdmi_phy_config_h3':
>> drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c:191:7: warning: large integer implicitly truncated to unsigned type [-Woverflow]
~SUN8I_HDMI_PHY_PLL_CFG1_CKIN_SEL_MSK,
^
include/linux/regmap.h:76:36: note: in definition of macro 'regmap_update_bits'
regmap_update_bits_base(map, reg, mask, val, NULL, false, false)
^~~~
vim +191 drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
8
> 9 #include "sun8i_dw_hdmi.h"
10
11 /*
12 * Address can be actually any value. Here is set to same value as
13 * it is set in BSP driver.
14 */
15 #define I2C_ADDR 0x69
16
17 static int sun8i_hdmi_phy_config_a83t(struct dw_hdmi *hdmi,
18 struct sun8i_hdmi_phy *phy,
19 unsigned int clk_rate)
20 {
21 regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_REXT_CTRL_REG,
22 SUN8I_HDMI_PHY_REXT_CTRL_REXT_EN,
23 SUN8I_HDMI_PHY_REXT_CTRL_REXT_EN);
24
25 /* power down */
26 dw_hdmi_phy_gen2_txpwron(hdmi, 0);
27 dw_hdmi_phy_gen2_pddq(hdmi, 1);
28
29 dw_hdmi_phy_reset(hdmi);
30
31 dw_hdmi_phy_gen2_pddq(hdmi, 0);
32
33 dw_hdmi_phy_i2c_set_addr(hdmi, I2C_ADDR);
34
35 /*
36 * Values are taken from BSP HDMI driver. Although AW didn't
37 * release any documentation, explanation of this values can
38 * be found in i.MX 6Dual/6Quad Reference Manual.
39 */
40 if (clk_rate <= 27000000) {
41 dw_hdmi_phy_i2c_write(hdmi, 0x01e0, 0x06);
42 dw_hdmi_phy_i2c_write(hdmi, 0x0000, 0x15);
43 dw_hdmi_phy_i2c_write(hdmi, 0x08da, 0x10);
44 dw_hdmi_phy_i2c_write(hdmi, 0x0007, 0x19);
45 dw_hdmi_phy_i2c_write(hdmi, 0x0318, 0x0e);
46 dw_hdmi_phy_i2c_write(hdmi, 0x8009, 0x09);
47 } else if (clk_rate <= 74250000) {
48 dw_hdmi_phy_i2c_write(hdmi, 0x0540, 0x06);
49 dw_hdmi_phy_i2c_write(hdmi, 0x0005, 0x15);
50 dw_hdmi_phy_i2c_write(hdmi, 0x0000, 0x10);
51 dw_hdmi_phy_i2c_write(hdmi, 0x0007, 0x19);
52 dw_hdmi_phy_i2c_write(hdmi, 0x02b5, 0x0e);
53 dw_hdmi_phy_i2c_write(hdmi, 0x8009, 0x09);
54 } else if (clk_rate <= 148500000) {
55 dw_hdmi_phy_i2c_write(hdmi, 0x04a0, 0x06);
56 dw_hdmi_phy_i2c_write(hdmi, 0x000a, 0x15);
57 dw_hdmi_phy_i2c_write(hdmi, 0x0000, 0x10);
58 dw_hdmi_phy_i2c_write(hdmi, 0x0002, 0x19);
59 dw_hdmi_phy_i2c_write(hdmi, 0x0021, 0x0e);
60 dw_hdmi_phy_i2c_write(hdmi, 0x8029, 0x09);
61 } else {
62 dw_hdmi_phy_i2c_write(hdmi, 0x0000, 0x06);
63 dw_hdmi_phy_i2c_write(hdmi, 0x000f, 0x15);
64 dw_hdmi_phy_i2c_write(hdmi, 0x0000, 0x10);
65 dw_hdmi_phy_i2c_write(hdmi, 0x0002, 0x19);
66 dw_hdmi_phy_i2c_write(hdmi, 0x0000, 0x0e);
67 dw_hdmi_phy_i2c_write(hdmi, 0x802b, 0x09);
68 }
69
70 dw_hdmi_phy_i2c_write(hdmi, 0x0000, 0x1e);
71 dw_hdmi_phy_i2c_write(hdmi, 0x0000, 0x13);
72 dw_hdmi_phy_i2c_write(hdmi, 0x0000, 0x17);
73
74 dw_hdmi_phy_gen2_txpwron(hdmi, 1);
75
76 return 0;
77 }
78
79 static int sun8i_hdmi_phy_config_h3(struct dw_hdmi *hdmi,
80 struct sun8i_hdmi_phy *phy,
81 unsigned int clk_rate)
82 {
83 u32 pll_cfg1_init;
84 u32 pll_cfg2_init;
85 u32 ana_cfg1_end;
86 u32 ana_cfg2_init;
87 u32 ana_cfg3_init;
88 u32 b_offset = 0;
89 u32 val;
90
91 /* bandwidth / frequency independent settings */
92
93 pll_cfg1_init = SUN8I_HDMI_PHY_PLL_CFG1_LDO2_EN |
94 SUN8I_HDMI_PHY_PLL_CFG1_LDO1_EN |
95 SUN8I_HDMI_PHY_PLL_CFG1_LDO_VSET(7) |
96 SUN8I_HDMI_PHY_PLL_CFG1_UNKNOWN(1) |
97 SUN8I_HDMI_PHY_PLL_CFG1_PLLDBEN |
98 SUN8I_HDMI_PHY_PLL_CFG1_CS |
99 SUN8I_HDMI_PHY_PLL_CFG1_CP_S(2) |
100 SUN8I_HDMI_PHY_PLL_CFG1_CNT_INT(63) |
101 SUN8I_HDMI_PHY_PLL_CFG1_BWS;
102
103 pll_cfg2_init = SUN8I_HDMI_PHY_PLL_CFG2_SV_H |
104 SUN8I_HDMI_PHY_PLL_CFG2_VCOGAIN_EN |
105 SUN8I_HDMI_PHY_PLL_CFG2_SDIV2;
106
107 ana_cfg1_end = SUN8I_HDMI_PHY_ANA_CFG1_REG_SVBH(1) |
108 SUN8I_HDMI_PHY_ANA_CFG1_AMP_OPT |
109 SUN8I_HDMI_PHY_ANA_CFG1_EMP_OPT |
110 SUN8I_HDMI_PHY_ANA_CFG1_AMPCK_OPT |
111 SUN8I_HDMI_PHY_ANA_CFG1_EMPCK_OPT |
112 SUN8I_HDMI_PHY_ANA_CFG1_ENRCAL |
113 SUN8I_HDMI_PHY_ANA_CFG1_ENCALOG |
114 SUN8I_HDMI_PHY_ANA_CFG1_REG_SCKTMDS |
115 SUN8I_HDMI_PHY_ANA_CFG1_TMDSCLK_EN |
116 SUN8I_HDMI_PHY_ANA_CFG1_TXEN_MASK |
117 SUN8I_HDMI_PHY_ANA_CFG1_TXEN_ALL |
118 SUN8I_HDMI_PHY_ANA_CFG1_BIASEN_TMDSCLK |
119 SUN8I_HDMI_PHY_ANA_CFG1_BIASEN_TMDS2 |
120 SUN8I_HDMI_PHY_ANA_CFG1_BIASEN_TMDS1 |
121 SUN8I_HDMI_PHY_ANA_CFG1_BIASEN_TMDS0 |
122 SUN8I_HDMI_PHY_ANA_CFG1_ENP2S_TMDS2 |
123 SUN8I_HDMI_PHY_ANA_CFG1_ENP2S_TMDS1 |
124 SUN8I_HDMI_PHY_ANA_CFG1_ENP2S_TMDS0 |
125 SUN8I_HDMI_PHY_ANA_CFG1_CKEN |
126 SUN8I_HDMI_PHY_ANA_CFG1_LDOEN |
127 SUN8I_HDMI_PHY_ANA_CFG1_ENVBS |
128 SUN8I_HDMI_PHY_ANA_CFG1_ENBI;
129
130 ana_cfg2_init = SUN8I_HDMI_PHY_ANA_CFG2_M_EN |
131 SUN8I_HDMI_PHY_ANA_CFG2_REG_DENCK |
132 SUN8I_HDMI_PHY_ANA_CFG2_REG_DEN |
133 SUN8I_HDMI_PHY_ANA_CFG2_REG_CKSS(1) |
134 SUN8I_HDMI_PHY_ANA_CFG2_REG_CSMPS(1);
135
136 ana_cfg3_init = SUN8I_HDMI_PHY_ANA_CFG3_REG_WIRE(0x3e0) |
137 SUN8I_HDMI_PHY_ANA_CFG3_SDAEN |
138 SUN8I_HDMI_PHY_ANA_CFG3_SCLEN;
139
140 /* bandwidth / frequency dependent settings */
141 if (clk_rate <= 27000000) {
142 pll_cfg1_init |= SUN8I_HDMI_PHY_PLL_CFG1_HV_IS_33 |
143 SUN8I_HDMI_PHY_PLL_CFG1_CNT_INT(32);
144 pll_cfg2_init |= SUN8I_HDMI_PHY_PLL_CFG2_VCO_S(4) |
145 SUN8I_HDMI_PHY_PLL_CFG2_S(4);
146 ana_cfg1_end |= SUN8I_HDMI_PHY_ANA_CFG1_REG_CALSW;
147 ana_cfg2_init |= SUN8I_HDMI_PHY_ANA_CFG2_REG_SLV(4) |
148 SUN8I_HDMI_PHY_ANA_CFG2_REG_RESDI(phy->rcal);
149 ana_cfg3_init |= SUN8I_HDMI_PHY_ANA_CFG3_REG_AMPCK(3) |
150 SUN8I_HDMI_PHY_ANA_CFG3_REG_AMP(5);
151 } else if (clk_rate <= 74250000) {
152 pll_cfg1_init |= SUN8I_HDMI_PHY_PLL_CFG1_HV_IS_33 |
153 SUN8I_HDMI_PHY_PLL_CFG1_CNT_INT(32);
154 pll_cfg2_init |= SUN8I_HDMI_PHY_PLL_CFG2_VCO_S(4) |
155 SUN8I_HDMI_PHY_PLL_CFG2_S(5);
156 ana_cfg1_end |= SUN8I_HDMI_PHY_ANA_CFG1_REG_CALSW;
157 ana_cfg2_init |= SUN8I_HDMI_PHY_ANA_CFG2_REG_SLV(4) |
158 SUN8I_HDMI_PHY_ANA_CFG2_REG_RESDI(phy->rcal);
159 ana_cfg3_init |= SUN8I_HDMI_PHY_ANA_CFG3_REG_AMPCK(5) |
160 SUN8I_HDMI_PHY_ANA_CFG3_REG_AMP(7);
161 } else if (clk_rate <= 148500000) {
162 pll_cfg1_init |= SUN8I_HDMI_PHY_PLL_CFG1_HV_IS_33 |
163 SUN8I_HDMI_PHY_PLL_CFG1_CNT_INT(32);
164 pll_cfg2_init |= SUN8I_HDMI_PHY_PLL_CFG2_VCO_S(4) |
165 SUN8I_HDMI_PHY_PLL_CFG2_S(6);
166 ana_cfg2_init |= SUN8I_HDMI_PHY_ANA_CFG2_REG_BIGSWCK |
167 SUN8I_HDMI_PHY_ANA_CFG2_REG_BIGSW |
168 SUN8I_HDMI_PHY_ANA_CFG2_REG_SLV(2);
169 ana_cfg3_init |= SUN8I_HDMI_PHY_ANA_CFG3_REG_AMPCK(7) |
170 SUN8I_HDMI_PHY_ANA_CFG3_REG_AMP(9);
171 } else {
172 b_offset = 2;
173 pll_cfg1_init |= SUN8I_HDMI_PHY_PLL_CFG1_CNT_INT(63);
174 pll_cfg2_init |= SUN8I_HDMI_PHY_PLL_CFG2_VCO_S(6) |
175 SUN8I_HDMI_PHY_PLL_CFG2_S(7);
176 ana_cfg2_init |= SUN8I_HDMI_PHY_ANA_CFG2_REG_BIGSWCK |
177 SUN8I_HDMI_PHY_ANA_CFG2_REG_BIGSW |
178 SUN8I_HDMI_PHY_ANA_CFG2_REG_SLV(4);
179 ana_cfg3_init |= SUN8I_HDMI_PHY_ANA_CFG3_REG_AMPCK(9) |
180 SUN8I_HDMI_PHY_ANA_CFG3_REG_AMP(13);
181 }
182
183 regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_ANA_CFG1_REG,
184 SUN8I_HDMI_PHY_ANA_CFG1_TXEN_MASK, 0);
185
186 /*
187 * NOTE: We have to be careful not to overwrite PHY parent
188 * clock selection bit and clock divider.
189 */
190 regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_PLL_CFG1_REG,
> 191 ~SUN8I_HDMI_PHY_PLL_CFG1_CKIN_SEL_MSK,
192 pll_cfg1_init);
193 regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_PLL_CFG2_REG,
194 (u32)~SUN8I_HDMI_PHY_PLL_CFG2_PREDIV_MSK,
195 pll_cfg2_init);
196 usleep_range(10000, 15000);
197 regmap_write(phy->regs, SUN8I_HDMI_PHY_PLL_CFG3_REG,
198 SUN8I_HDMI_PHY_PLL_CFG3_SOUT_DIV2);
199 regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_PLL_CFG1_REG,
200 SUN8I_HDMI_PHY_PLL_CFG1_PLLEN,
201 SUN8I_HDMI_PHY_PLL_CFG1_PLLEN);
202 msleep(100);
203
204 /* get B value */
205 regmap_read(phy->regs, SUN8I_HDMI_PHY_ANA_STS_REG, &val);
206 val = (val & SUN8I_HDMI_PHY_ANA_STS_B_OUT_MSK) >>
207 SUN8I_HDMI_PHY_ANA_STS_B_OUT_SHIFT;
208 val = min(val + b_offset, (u32)0x3f);
209
210 regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_PLL_CFG1_REG,
211 SUN8I_HDMI_PHY_PLL_CFG1_REG_OD1 |
212 SUN8I_HDMI_PHY_PLL_CFG1_REG_OD,
213 SUN8I_HDMI_PHY_PLL_CFG1_REG_OD1 |
214 SUN8I_HDMI_PHY_PLL_CFG1_REG_OD);
215 regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_PLL_CFG1_REG,
216 SUN8I_HDMI_PHY_PLL_CFG1_B_IN_MSK,
217 val << SUN8I_HDMI_PHY_PLL_CFG1_B_IN_SHIFT);
218 msleep(100);
219 regmap_write(phy->regs, SUN8I_HDMI_PHY_ANA_CFG1_REG, ana_cfg1_end);
220 regmap_write(phy->regs, SUN8I_HDMI_PHY_ANA_CFG2_REG, ana_cfg2_init);
221 regmap_write(phy->regs, SUN8I_HDMI_PHY_ANA_CFG3_REG, ana_cfg3_init);
222
223 return 0;
224 }
225
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
--
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: .config.gz --]
[-- Type: application/gzip, Size: 59031 bytes --]
^ permalink raw reply
* Re: [PATCH 04/15] dt-bindings: display: sunxi-drm: Add TCON TOP description
From: Maxime Ripard @ 2018-05-21 8:01 UTC (permalink / raw)
To: Jernej Skrabec
Cc: wens-jdAy2FN1RRM, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
mark.rutland-5wv7dgnIgG8,
dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-clk-u79uwXL29TY76Z2rM5mHXA,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw
In-Reply-To: <20180519183127.2718-5-jernej.skrabec-gGgVlfcn5nU@public.gmane.org>
[-- Attachment #1: Type: text/plain, Size: 2261 bytes --]
Hi,
On Sat, May 19, 2018 at 08:31:16PM +0200, Jernej Skrabec wrote:
> TCON TOP main purpose is to configure whole display pipeline. It
> determines relationships between mixers and TCONs, selects source TCON
> for HDMI, muxes LCD and TV encoder GPIO output,
I'm not sure you mean GPIO here, but rather pin?
> selects TV encoder clock source and contains additional TV TCON and
> DSI gates.
>
> Signed-off-by: Jernej Skrabec <jernej.skrabec-gGgVlfcn5nU@public.gmane.org>
> ---
> .../bindings/display/sunxi/sun4i-drm.txt | 20 +++++++++++++++++++
> 1 file changed, 20 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt b/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt
> index 3346c1e2a7a0..a099957ab62a 100644
> --- a/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt
> +++ b/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt
> @@ -187,6 +187,26 @@ And on the A23, A31, A31s and A33, you need one more clock line:
> - 'lvds-alt': An alternative clock source, separate from the TCON channel 0
> clock, that can be used to drive the LVDS clock
>
> +TCON TOP
> +--------
> +
> +TCON TOPs main purpose is to configure whole display pipeline. It determines
> +relationships between mixers and TCONs, selects source TCON for HDMI, muxes
> +LCD and TV encoder GPIO output, selects TV encoder clock source and contains
> +additional TV TCON and DSI gates.
> +
> +Required properties:
> + - compatible: value must be one of:
> + * allwinner,sun8i-r40-tcon-top
> + - reg: base address and size of the memory-mapped region.
> + - clocks: phandle to the clocks feeding the TCON TOP
> + * bus: TCON TOP interface clock
> + - clock-names: clock name mentioned above
> + - resets: phandle to the reset line driving the DRC
> + * rst: TCON TOP reset line
> + - reset-names: reset name mentioned above
> + - #clock-cells : must contain 1
> +
I guess you should better describe the OF-graph endpoints, and the
clocks output. Just using the binding additions here doesn't allow to
get a clear idea of how the DT should look like.
Maxime
--
Maxime Ripard, Bootlin (formerly Free Electrons)
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply
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