Devicetree
 help / color / mirror / Atom feed
* Re: [PATCHv2] clk: add imx8 clk defines
From: Daniel Baluta @ 2019-07-11 10:09 UTC (permalink / raw)
  To: Oliver Graute
  Cc: Abel Vesa, sboyd@kernel.org, mturquette@baylibre.com, Shawn Guo,
	Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
	dl-linux-imx, Rob Herring, Mark Rutland, Aisheng Dong,
	Ulf Hansson, linux-kernel@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org
In-Reply-To: <20190711085725.GA1385@optiplex>

On Thu, Jul 11, 2019 at 12:19 PM Oliver Graute <oliver.graute@gmail.com> wrote:
>
> On 11/07/19, Abel Vesa wrote:
> > On 19-06-19 09:39:52, Oliver Graute wrote:
> > > From: Oliver Graute <oliver.graute@kococonnector.com>
> > >
> > > added header defines for imx8qm clock
> > >
> > > Signed-off-by: Oliver Graute <oliver.graute@kococonnector.com>
> >
> > Again, this seems to be taken from some vendor tree, so please keep the
> > original author.
>
> yes the header defines is from NXP vendor tree. One of orginal authors is
>
> Author: Anson Huang <Anson.Huang@nxp.com>
> Date:   Thu Jan 19 03:53:31 2017 +0800
>     MLK-13911-3 ARM64: dts: imx8qm: add dtsi
>     Add i.MX8QM dtsi support.
>     https://github.com/ADVANTECH-Corp/linux-imx6.git
>
> Whats is the right way to attribute him?

git commit --amend author="Anson Huang <Anson.Huang@nxp.com>"

Also, modify commit body and add
Signed-off-by: Anson Huang <Anson.Huang@nxp.com>

Then add your Signed-off-by.

thanks,
Daniel.

^ permalink raw reply

* Re: [PATCH v6 11/22] clk: sunxi-ng: a64: Add minimum rate for PLL_MIPI
From: Maxime Ripard @ 2019-07-11 10:01 UTC (permalink / raw)
  To: Michael Nazzareno Trimarchi
  Cc: Jagan Teki, David Airlie, Daniel Vetter, Chen-Yu Tsai,
	Michael Turquette, Rob Herring, Mark Rutland, linux-arm-kernel,
	linux-kernel, linux-clk, dri-devel, devicetree, linux-amarula,
	linux-sunxi
In-Reply-To: <CAOf5uw=ZEvMV1hFQE986rNG_ctpReGbjbZzv0m=OzKPdBh57uQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>

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

On Fri, Jul 05, 2019 at 07:52:27PM +0200, Michael Nazzareno Trimarchi wrote:
> On Wed, Jul 3, 2019 at 1:49 PM Maxime Ripard <maxime.ripard-LDxbnhwyfcJBDgjK7y7TUQ@public.gmane.org> wrote:
> >
> > On Tue, Jun 25, 2019 at 09:00:36PM +0530, Jagan Teki wrote:
> > > On Tue, Jun 25, 2019 at 8:19 PM Maxime Ripard <maxime.ripard-LDxbnhwyfcJBDgjK7y7TUQ@public.gmane.org> wrote:
> > > >
> > > > On Thu, Jun 20, 2019 at 11:57:44PM +0530, Jagan Teki wrote:
> > > > > On Fri, Jun 14, 2019 at 7:54 PM Maxime Ripard <maxime.ripard-LDxbnhwyfcJBDgjK7y7TUQ@public.gmane.org> wrote:
> > > > > >
> > > > > > On Wed, Jun 05, 2019 at 01:03:16PM +0530, Jagan Teki wrote:
> > > > > > > On Wed, Jun 5, 2019 at 12:19 PM Maxime Ripard <maxime.ripard-LDxbnhwyfcJBDgjK7y7TUQ@public.gmane.org> wrote:
> > > > > > > >
> > > > > > > > Hi,
> > > > > > > >
> > > > > > > > I've reordered the mail a bit to work on chunks
> > > > > > > >
> > > > > > > > On Fri, May 24, 2019 at 03:37:42PM +0530, Jagan Teki wrote:
> > > > > > > > > > I wish it was in your commit log in the first place, instead of having
> > > > > > > > > > to exchange multiple mails over this.
> > > > > > > > > >
> > > > > > > > > > However, I don't think that's quite true, and it might be a bug in
> > > > > > > > > > Allwinner's implementation (or rather something quite confusing).
> > > > > > > > > >
> > > > > > > > > > You're right that the lcd_rate and pll_rate seem to be generated from
> > > > > > > > > > the pixel clock, and it indeed looks like the ratio between the pixel
> > > > > > > > > > clock and the TCON dotclock is defined through the number of bits per
> > > > > > > > > > lanes.
> > > > > > > > > >
> > > > > > > > > > However, in this case, dsi_rate is actually the same than lcd_rate,
> > > > > > > > > > since pll_rate is going to be divided by dsi_div:
> > > > > > > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L791
> > > > > > > > > >
> > > > > > > > > > Since lcd_div is 1, it also means that in this case, dsi_rate ==
> > > > > > > > > > dclk_rate.
> > > > > > > > > >
> > > > > > > > > > The DSI module clock however, is always set to 148.5 MHz. Indeed, if
> > > > > > > > > > we look at:
> > > > > > > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L804
> > > > > > > > > >
> > > > > > > > > > We can see that the rate in clk_info is used if it's different than
> > > > > > > > > > 0. This is filled by disp_al_lcd_get_clk_info, which, in the case of a
> > > > > > > > > > DSI panel, will hardcode it to 148.5 MHz:
> > > > > > > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/lowlevel_sun50iw1/disp_al.c#L164
> > > > > > > > >
> > > > > > > > > Let me explain, something more.
> > > > > > > > >
> > > > > > > > > According to bsp there are clk_info.tcon_div which I will explain below.
> > > > > > > > > clk_info.dsi_div which is dynamic and it depends on bpp/lanes, so it
> > > > > > > > > is 6 for 24bpp and 4 lanes devices.
> > > > > > > > >
> > > > > > > > > PLL rate here depends on dsi_div (not tcon_div)
> > > > > > > > >
> > > > > > > > > Code here
> > > > > > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L784
> > > > > > > > >
> > > > > > > > > is computing the actual set rate, which depends on dsi_rate.
> > > > > > > > >
> > > > > > > > > lcd_rate = dclk_rate * clk_info.dsi_div;
> > > > > > > > > dsi_rate = pll_rate / clk_info.dsi_div;
> > > > > > > > >
> > > > > > > > > Say if the dclk_rate 148MHz then the dsi_rate is 888MHz which set rate
> > > > > > > > > for above link you mentioned.
> > > > > > > > >
> > > > > > > > > Here are the evidence with some prints.
> > > > > > > > >
> > > > > > > > > https://gist.github.com/openedev/9bae2d87d2fcc06b999fe48c998b7043
> > > > > > > > > https://gist.github.com/openedev/700de2e3701b2bf3ad1aa0f0fa862c9a
> > > > > > > >
> > > > > > > > Ok, so we agree up to this point, and the prints confirm that the
> > > > > > > > analysis above is the right one.
> > > > > > > >
> > > > > > > > > > So, the DSI clock is set to this here:
> > > > > > > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L805
> > > > > > > >
> > > > > > > > Your patch doesn't address that, so let's leave that one alone.
> > > > > > >
> > > > > > > Basically this is final pll set rate when sun4i_dotclock.c called the
> > > > > > > desired rate with ccu_nkm.c so it ended the final rate with parent as
> > > > > > > Line 8 of
> > > > > > > https://gist.github.com/openedev/700de2e3701b2bf3ad1aa0f0fa862c9a
> > > > > >
> > > > > > If that's important to the driver, it should be set explicitly then,
> > > > > > and not work by accident.
> > > > > >
> > > > > > > > > > The TCON *module* clock (the one in the clock controller) has been set
> > > > > > > > > > to lcd_rate (so the pixel clock times the number of bits per lane) here:
> > > > > > > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L800
> > > > > > > > > >
> > > > > > > > > > And the PLL has been set to the same rate here:
> > > > > > > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L794
> > > > > > > > > >
> > > > > > > > > > Let's take a step back now: that function we were looking at,
> > > > > > > > > > lcd_clk_config, is called by lcd_clk_enable, which is in turn called
> > > > > > > > > > by disp_lcd_enable here:
> > > > > > > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L1328
> > > > > > > > > >
> > > > > > > > > > The next function being called is disp_al_lcd_cfg, and that function
> > > > > > > > > > will hardcode the TCON dotclock divider to 4, here:
> > > > > > > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/lowlevel_sun50iw1/disp_al.c#L240
> > > > > > > > >
> > > > > > > > > tcon_div from BSP point-of-view of there are two variants
> > > > > > > > > 00) clk_info.tcon_div which is 4 and same is set the divider position
> > > > > > > > > in SUN4I_TCON0_DCLK_REG (like above link refer)
> > > > > > > > > 01) tcon_div which is 4 and used for edge timings computation
> > > > > > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/lowlevel_sun50iw1/de_dsi.c#L12
> > > > > > > > >
> > > > > > > > > The real reason for 01) is again 4 is they set the divider to 4 in 00)
> > > > > > > > > which is technically wrong because the dividers which used during
> > > > > > > > > dotclock in above (dsi_div) should be used here as well. Since there
> > > > > > > > > is no dynamic way of doing this BSP hard-coding these values.
> > > > > > > > >
> > > > > > > > > Patches 5,6,7 on this series doing this
> > > > > > > > > https://patchwork.freedesktop.org/series/60847/
> > > > > > > > >
> > > > > > > > > Hope this explanation helps?
> > > > > > > >
> > > > > > > > It doesn't.
> > > > > > > >
> > > > > > > > The clock tree is this one:
> > > > > > > >
> > > > > > > > PLL(s) -> TCON module clock -> TCON dotclock.
> > > > > > > >
> > > > > > > > The links I mentioned above show that the clock set to lcd_rate is the
> > > > > > > > TCON module clocks (and it should be the one taking the bpp and lanes
> > > > > > > > into account), while the TCON dotclock uses a fixed divider of 4.
> > > > > > >
> > > > > > > Sorry, I can argue much other-than giving some code snips, according to [1]
> > > > > > >
> > > > > > > 00) Line 785, 786 with dclk_rate 148000000
> > > > > > >
> > > > > > > lcd_rate = dclk_rate * clk_info.dsi_div;
> > > > > > > pll_rate = lcd_rate * clk_info.lcd_div;
> > > > > > >
> > > > > > > Since dsi_div is 6 (bpp/lanes), lcd_div 1
> > > > > > >
> > > > > > > lcd_rate = 888000000, pll_rate = 888000000
> > > > > > >
> > > > > > > 01)  Line 801, 804 are final rates computed as per clock driver (say
> > > > > > > ccu_nkm in mainline)
> > > > > > >
> > > > > > > lcd_rate_set=891000000
> > > > > > >
> > > > > > > As per your comments if it would be 4 then the desired numbers are
> > > > > > > would be 592000000 not 888000000.
> > > > > > >
> > > > > > > This is what I'm trying to say in all mails, and same as verified with
> > > > > > > 2-lanes devices as well where the dsi_div is 12 so the final rate is
> > > > > > > 290MHz * 12
> > > > > >
> > > > > > In the code you sent, you're forcing a divider on the internal TCON
> > > > > > clock, while that one is fixed in the BSP.
> > > > > >
> > > > > > There's indeed the bpp / lanes divider, but it's used in the *parent*
> > > > > > clock of the one you're changing.
> > > > > >
> > > > > > And the dsi0_clk clock you pointed out in the code snippet is yet
> > > > > > another clock, the MIPI DSI module clock.
> > > > >
> > > > > Correct, look like I refereed wrong reference in the above mail. sorry
> > > > > for the noise.
> > > > >
> > > > > Actually I'm trying to explain about pll_rate here which indeed
> > > > > depends on dsi.div
> > > > > https://github.com/BPI-SINOVOIP/BPI-M64-bsp/blob/master/linux-sunxi/drivers/video/sunxi/disp2/disp/de/disp_lcd.c#L786
> > > > >
> > > > > lcd_rate = dclk_rate * clk_info.dsi_div;
> > > > > pll_rate = lcd_rate * clk_info.lcd_div;
> > > > >
> > > > > Say
> > > > >
> > > > > 1) For 148MHz dclk_rate with dsi_div is 6 (24/4) lcd_div is 1 which
> > > > > resulting pll_rate is 888MHz.
> > > > >
> > > > > 2) For 30MHz dclk_rate with 4 lane and 24 RGB the resulting pll_rate is 180MHz
> > > > >
> > > > > 3) For 27.5MHz dclk_rate with 2 lane and 24 RGB the resulting pll_rate is 330MHz
> > > > >
> > > > > Here is the few more logs in code, for case 2)
> > > > >
> > > > > [    1.920441] sun4i_dclk_round_rate: min_div = 6 max_div = 6, rate = 30000000
> > > > > [    1.920505] ideal = 180000000, rounded = 178200000
> > > > > [    1.920509] sun4i_dclk_round_rate: div = 6 rate = 29700000
> > > > > [    1.920514] sun4i_dclk_round_rate: min_div = 6 max_div = 6, rate = 30000000
> > > > > [    1.920532] ideal = 1800ls and one DSI-RGB bridge. All of them do use
> > > PLL_MIPI (pll_rate) and it indeed depends on bpp/lanes
> > >00000, rounded = 178200000
> > > > > [    1.920535] sun4i_dclk_round_rate: div = 6 rate = 29700000
> > > > > [    1.920572] sun4i_dclk_recalc_rate: val = 1, rate = 178200000
> > > > > [    1.920576] sun4i_dclk_recalc_rate: val = 1, rate = 178200000
> > > > > [    1.920597] rate = 178200000
> > > > > [    1.920599] parent_rate = 297000000
> > > > > [    1.920602] reg = 0x90c00000
> > > > > [    1.920605] _nkm.n = 3, nkm->n.offset = 0x1, nkm->n.shift = 8
> > > > > [    1.920609] _nkm.k = 2, nkm->k.offset = 0x1, nkm->k.shift = 4
> > > > > [    1.920612] _nkm.m = 10, nkm->m.offset = 0x1, nkm->m.shift = 0
> > > > > [    1.920958] sun4i_dclk_set_rate div 6
> > > > > [    1.920966] sun4i_dclk_recalc_rate: val = 6, rate = 29700000
> > > > >
> > > > > and clk_summary:
> > > > >
> > > > >     pll-video0                        1        1        1   297000000
> > > > >         0     0  50000
> > > > >        hdmi                           0        0        0   297000000
> > > > >         0     0  50000
> > > > >        tcon1                          0        0        0   297000000
> > > > >         0     0  50000
> > > > >        pll-mipi                       1        1        1   178200000
> > > > >         0     0  50000
> > > > >           tcon0                       2        2        1   178200000
> > > > >         0     0  50000
> > > > >              tcon-pixel-clock         1        1        1    29700000
> > > > >         0     0  50000
> > > > >        pll-video0-2x                  0        0        0   594000000
> > > > >         0     0  50000
> > > >
> > > > This discussion is going nowhere. I'm telling you that your patch
> > > > doesn't apply the divider you want on the proper clock, and you're
> > > > replying that indeed, you're applying it on the wrong clock.
> > > >
> > > > It might work by accident in your case, but the board I have here
> > > > clearly indicates otherwise, so there's two possible way out here:
> > > >
> > > >   - Either you apply that divider to the TCON *module* clock, and not
> > > >     the dclk
> > > >
> > > >   - Or you point to somewhere in the allwinner code where the bpp /
> > > >     lanes divider is used for the dclk divider.
> > >
> > > I don't know how to proceed further on this, as you say it might work
> > > in accident but I have tested this in A33, A64 and R40 with 4
> > > different DSI panels and one DSI-RGB bridge. All of them do use
> > > PLL_MIPI (pll_rate) and it indeed depends on bpp/lanes
> > >
> > > 4-lane, 24-bit: Novatek NT35596 panel
> > > 4-lane, 24-bit: Feiyang, FY07024di26a30d panel
> > > 4-lane, 24-bit: Bananapi-s070wv20 panel
> > > 2-lane, 24-bit: Techstar,ts8550b panel
> > >
> > > and
> > >
> > > 4-lane, 24-bit, ICN6211 DSI-to-RGB bridge panel
> > >
> > > All above listed panels and bridges are working as per BSP and do
> > > follow bpp/lanes and for DIVIDER 4 no panel is working.
> >
> > Look. I'm not saying that there's no issue, I'm saying that your
> > patch, applied to the clock you're applying it to, doesn't make sense
> > and isn't what the BSP does.
>
> tcon-pixel clock is the rate that you want to achive on display side
> and if you have 4 lanes 32bit or lanes and different bit number that
> you need to have a clock that is able to put outside bits and speed
> equal to pixel-clock * bits / lanes. so If you want a pixel-clock of
> 40 mhz and you have 32bits and 4 lanes you need to have a clock of
> 40 * 32 / 4 in no-burst mode. I think that this is done but most of
> the display.

So this is what the issue is then?

This one does make sense, and you should just change the rate in the
call to clk_set_rate in sun4i_tcon0_mode_set_cpu.

I'm still wondering why that hasn't been brought up in either the
discussion or the commit log before though.

> Now in burst mode I don't know how should work the calculation of
> the clock for the require bandwidth and even I understand your
> comment I would like to have your clock tree after you boot on the
> display side and if it is possible I want to assemble a kit like you
> have.

The setup is probably going to be a bit difficult to reproduce, it's a
prototype that I have that can't really be found anywhere. Jagan asked
me on IRC for the reference, and he found the part, but it's unclear
to me if it can be easily adapted to a common board.

However, I'm not even sure we need this. I'll test the next version
and let you know if it works.

Maxime

--
Maxime Ripard, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com

^ permalink raw reply

* [PATCH] dt-bindings: bus: Convert Allwinner DE2 bus to a schema
From: Maxime Ripard @ 2019-07-11  9:40 UTC (permalink / raw)
  To: Mark Rutland, Rob Herring, Frank Rowand
  Cc: Maxime Ripard, devicetree, Chen-Yu Tsai, linux-arm-kernel

The Allwinner SoCs using the second generation of the display engine have a
bus for that display engine. The bus is supported in Linux, with a matching
Device Tree binding.

Now that we have the DT validation in place, let's convert the device tree
bindings for that controller over to a YAML schemas.

Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
---
 .../bus/allwinner,sun50i-a64-de2.yaml         | 84 +++++++++++++++++++
 .../bindings/bus/sun50i-de2-bus.txt           | 40 ---------
 2 files changed, 84 insertions(+), 40 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/bus/allwinner,sun50i-a64-de2.yaml
 delete mode 100644 Documentation/devicetree/bindings/bus/sun50i-de2-bus.txt

diff --git a/Documentation/devicetree/bindings/bus/allwinner,sun50i-a64-de2.yaml b/Documentation/devicetree/bindings/bus/allwinner,sun50i-a64-de2.yaml
new file mode 100644
index 000000000000..b9734f8109c6
--- /dev/null
+++ b/Documentation/devicetree/bindings/bus/allwinner,sun50i-a64-de2.yaml
@@ -0,0 +1,84 @@
+# SPDX-License-Identifier: GPL2
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/bus/allwinner,sun50i-a64-de2.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Allwinner A64 Display Engine Bus Device Tree Bindings
+
+maintainers:
+  - Chen-Yu Tsai <wens@csie.org>
+  - Maxime Ripard <maxime.ripard@bootlin.com>
+
+properties:
+  $nodename:
+    pattern: "^bus(@[0-9a-f]+)?$"
+
+  "#address-cells":
+    const: 1
+
+  "#size-cells":
+    const: 1
+
+  compatible:
+    oneOf:
+      - const: allwinner,sun50i-a64-de2
+      - items:
+          - const: allwinner,sun50i-h6-de3
+          - const: allwinner,sun50i-a64-de2
+
+  reg:
+    maxItems: 1
+
+  allwinner,sram:
+    allOf:
+      - $ref: /schemas/types.yaml#definitions/phandle-array
+      - maxItems: 1
+    description:
+      The SRAM that needs to be claimed to access the display engine
+      bus.
+
+  ranges: true
+
+patternProperties:
+  # All other properties should be child nodes with unit-address and 'reg'
+  "^[a-zA-Z][a-zA-Z0-9,+\\-._]{0,63}@[0-9a-fA-F]+$":
+    properties:
+      reg:
+        maxItems: 1
+
+    required:
+      - reg
+
+required:
+  - compatible
+  - reg
+  - "#address-cells"
+  - "#size-cells"
+  - ranges
+  - allwinner,sram
+
+additionalProperties: false
+
+examples:
+  - |
+    bus@1000000 {
+        compatible = "allwinner,sun50i-a64-de2";
+        reg = <0x1000000 0x400000>;
+        allwinner,sram = <&de2_sram 1>;
+        #address-cells = <1>;
+        #size-cells = <1>;
+        ranges = <0 0x1000000 0x400000>;
+
+        display_clocks: clock@0 {
+            compatible = "allwinner,sun50i-a64-de2-clk";
+            reg = <0x0 0x100000>;
+            clocks = <&ccu 52>, <&ccu 99>;
+            clock-names = "bus", "mod";
+            resets = <&ccu 30>;
+            #clock-cells = <1>;
+            #reset-cells = <1>;
+        };
+    };
+
+...
diff --git a/Documentation/devicetree/bindings/bus/sun50i-de2-bus.txt b/Documentation/devicetree/bindings/bus/sun50i-de2-bus.txt
deleted file mode 100644
index b9d533717dff..000000000000
--- a/Documentation/devicetree/bindings/bus/sun50i-de2-bus.txt
+++ /dev/null
@@ -1,40 +0,0 @@
-Device tree bindings for Allwinner DE2/3 bus
-
-The Allwinner A64 DE2 is on a special bus, which needs a SRAM region (SRAM C)
-to be claimed for enabling the access. The DE3 on Allwinner H6 is at the same
-situation, and the binding also applies.
-
-Required properties:
-
- - compatible:		Should be one of:
-				- "allwinner,sun50i-a64-de2"
-				- "allwinner,sun50i-h6-de3", "allwinner,sun50i-a64-de2"
- - reg:			A resource specifier for the register space
- - #address-cells:	Must be set to 1
- - #size-cells:		Must be set to 1
- - ranges:		Must be set up to map the address space inside the
-			DE2, for the sub-blocks of DE2.
- - allwinner,sram:	the SRAM that needs to be claimed
-
-Example:
-
-	de2@1000000 {
-		compatible = "allwinner,sun50i-a64-de2";
-		reg = <0x1000000 0x400000>;
-		allwinner,sram = <&de2_sram 1>;
-		#address-cells = <1>;
-		#size-cells = <1>;
-		ranges = <0 0x1000000 0x400000>;
-
-		display_clocks: clock@0 {
-			compatible = "allwinner,sun50i-a64-de2-clk";
-			reg = <0x0 0x100000>;
-			clocks = <&ccu CLK_DE>,
-				 <&ccu CLK_BUS_DE>;
-			clock-names = "mod",
-				      "bus";
-			resets = <&ccu RST_BUS_DE>;
-			#clock-cells = <1>;
-			#reset-cells = <1>;
-		};
-	};
-- 
2.21.0

^ permalink raw reply related

* [PATCH] dt-bindings: input: Convert Allwinner LRADC to a schema
From: Maxime Ripard @ 2019-07-11  9:38 UTC (permalink / raw)
  To: Mark Rutland, Rob Herring, Frank Rowand, Dmitry Torokhov
  Cc: Maxime Ripard, devicetree, Chen-Yu Tsai, linux-arm-kernel,
	linux-input

The Allwinner SoCs have an LRADC used to report keys and supported in
Linux, with a matching Device Tree binding.

Now that we have the DT validation in place, let's convert the device tree
bindings for that controller over to a YAML schemas.

Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
---
 .../input/allwinner,sun4i-a10-lradc-keys.yaml | 95 +++++++++++++++++++
 .../bindings/input/sun4i-lradc-keys.txt       | 65 -------------
 2 files changed, 95 insertions(+), 65 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/input/allwinner,sun4i-a10-lradc-keys.yaml
 delete mode 100644 Documentation/devicetree/bindings/input/sun4i-lradc-keys.txt

diff --git a/Documentation/devicetree/bindings/input/allwinner,sun4i-a10-lradc-keys.yaml b/Documentation/devicetree/bindings/input/allwinner,sun4i-a10-lradc-keys.yaml
new file mode 100644
index 000000000000..b3bd8ef7fbd6
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/allwinner,sun4i-a10-lradc-keys.yaml
@@ -0,0 +1,95 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/input/allwinner,sun4i-a10-lradc-keys.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Allwinner A10 LRADC Device Tree Bindings
+
+maintainers:
+  - Chen-Yu Tsai <wens@csie.org>
+  - Maxime Ripard <maxime.ripard@bootlin.com>
+
+properties:
+  compatible:
+    oneOf:
+      - const: allwinner,sun4i-a10-lradc-keys
+      - const: allwinner,sun8i-a83t-r-lradc
+      - items:
+        - const: allwinner,sun50i-a64-lradc
+        - const: allwinner,sun8i-a83t-r-lradc
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  vref-supply:
+    description:
+      Regulator for the LRADC reference voltage
+
+patternProperties:
+  "^button-[0-9]+$":
+    type: object
+    properties:
+      label:
+        $ref: /schemas/types.yaml#/definitions/string
+        description: Descriptive name of the key
+
+      linux,code:
+        $ref: /schemas/types.yaml#/definitions/uint32
+        description: Keycode to emit
+
+      channel:
+        allOf:
+          - $ref: /schemas/types.yaml#/definitions/uint32
+          - enum: [0, 1]
+        description: ADC Channel this key is attached to
+
+      voltage:
+        $ref: /schemas/types.yaml#/definitions/uint32
+        description:
+          Voltage in microvolts at LRADC input when this key is
+          pressed
+
+    required:
+      - label
+      - linux,code
+      - channel
+      - voltage
+
+    additionalProperties: false
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - vref-supply
+
+additionalProperties: false
+
+examples:
+  - |
+    lradc: lradc@1c22800 {
+        compatible = "allwinner,sun4i-a10-lradc-keys";
+        reg = <0x01c22800 0x100>;
+        interrupts = <31>;
+        vref-supply = <&reg_vcc3v0>;
+
+        button-191 {
+            label = "Volume Up";
+            linux,code = <115>;
+            channel = <0>;
+            voltage = <191274>;
+        };
+
+        button-392 {
+            label = "Volume Down";
+            linux,code = <114>;
+            channel = <0>;
+            voltage = <392644>;
+        };
+    };
+
+...
diff --git a/Documentation/devicetree/bindings/input/sun4i-lradc-keys.txt b/Documentation/devicetree/bindings/input/sun4i-lradc-keys.txt
deleted file mode 100644
index 507b737612ea..000000000000
--- a/Documentation/devicetree/bindings/input/sun4i-lradc-keys.txt
+++ /dev/null
@@ -1,65 +0,0 @@
-Allwinner sun4i low res adc attached tablet keys
-------------------------------------------------
-
-Required properties:
- - compatible: should be one of the following string:
-		"allwinner,sun4i-a10-lradc-keys"
-		"allwinner,sun8i-a83t-r-lradc"
-		"allwinner,sun50i-a64-lradc", "allwinner,sun8i-a83t-r-lradc"
- - reg: mmio address range of the chip
- - interrupts: interrupt to which the chip is connected
- - vref-supply: powersupply for the lradc reference voltage
-
-Each key is represented as a sub-node of the compatible mentioned above:
-
-Required subnode-properties:
-	- label: Descriptive name of the key.
-	- linux,code: Keycode to emit.
-	- channel: Channel this key is attached to, must be 0 or 1.
-	- voltage: Voltage in µV at lradc input when this key is pressed.
-
-Example:
-
-#include <dt-bindings/input/input.h>
-
-	lradc: lradc@1c22800 {
-		compatible = "allwinner,sun4i-a10-lradc-keys";
-		reg = <0x01c22800 0x100>;
-		interrupts = <31>;
-		vref-supply = <&reg_vcc3v0>;
-
-		button@191 {
-			label = "Volume Up";
-			linux,code = <KEY_VOLUMEUP>;
-			channel = <0>;
-			voltage = <191274>;
-		};
-
-		button@392 {
-			label = "Volume Down";
-			linux,code = <KEY_VOLUMEDOWN>;
-			channel = <0>;
-			voltage = <392644>;
-		};
-
-		button@601 {
-			label = "Menu";
-			linux,code = <KEY_MENU>;
-			channel = <0>;
-			voltage = <601151>;
-		};
-
-		button@795 {
-			label = "Enter";
-			linux,code = <KEY_ENTER>;
-			channel = <0>;
-			voltage = <795090>;
-		};
-
-		button@987 {
-			label = "Home";
-			linux,code = <KEY_HOMEPAGE>;
-			channel = <0>;
-			voltage = <987387>;
-		};
-	};
-- 
2.21.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* Re: [PATCH 5/8] dt-bindings: PCI: Add Amazon's Annapurna Labs PCIe host bridge binding
From: Lorenzo Pieralisi @ 2019-07-11  9:32 UTC (permalink / raw)
  To: Shenhar, Talel
  Cc: Jonathan Chocron, bhelgaas, jingoohan1, gustavo.pimentel, robh+dt,
	mark.rutland, dwmw, benh, alisaidi, ronenk, barakw, hanochu,
	hhhawa, linux-pci, linux-kernel, devicetree
In-Reply-To: <36e8c3b0-feeb-db8f-3808-0218b54adcec@amazon.com>

On Thu, Jul 11, 2019 at 10:12:35AM +0300, Shenhar, Talel wrote:
> 
> On 7/10/2019 7:45 PM, Jonathan Chocron wrote:
> > Document Amazon's Annapurna Labs PCIe host bridge.
> 
> That is the way! (best to keep same wordings (Amazon's)

Guys,

as a heads-up, the original posting, for whatever reason, did not hit
linux-pci@vger, which means that from a PCI patches queue review point
of view it does not exist.

It ought to be fixed otherwise we won't be able to review the code.

Lorenzo

> > 
> > Signed-off-by: Jonathan Chocron <jonnyc@amazon.com>
> > ---
> >   .../devicetree/bindings/pci/pcie-al.txt       | 45 +++++++++++++++++++
> >   MAINTAINERS                                   |  1 +
> >   2 files changed, 46 insertions(+)
> >   create mode 100644 Documentation/devicetree/bindings/pci/pcie-al.txt
> > 
> > diff --git a/Documentation/devicetree/bindings/pci/pcie-al.txt b/Documentation/devicetree/bindings/pci/pcie-al.txt
> > new file mode 100644
> > index 000000000000..d92cc529490e
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/pci/pcie-al.txt
> > @@ -0,0 +1,45 @@
> > +* Amazon Annapurna Labs PCIe host bridge
> > +
> > +Annapurna Labs' PCIe Host Controller is based on the Synopsys DesignWare
> 
> Amazon's
> 
> 
> and what is the s' ? should it be for all
> 
> > +Example:
> > +
> > +	pcie-external0 {
> probably should have a reference with the address
> > +		compatible = "amazon,al-pcie";
> > +		reg = <0x0 0xfb600000 0x0 0x00100000
> > +		       0x0 0xfd800000 0x0 0x00010000
> > +		       0x0 0xfd810000 0x0 0x00001000>;
> > +		reg-names = "config", "controller", "dbi";
> > +		bus-range = <0 255>;
> > +		device_type = "pci";
> > +		#address-cells = <3>;
> > +		#size-cells = <2>;
> > +		#interrupt-cells = <1>;
> > +		interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>;
> > +		interrupt-map-mask = <0x00 0 0 7>;
> > +		interrupt-map = <0x0000 0 0 1 &gic_main GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>; /* INTa */
> gic_main->gic
> > +		ranges = <0x02000000 0x0 0xc0010000 0x0 0xc0010000 0x0 0x07ff0000>;
> > +	};
> > diff --git a/MAINTAINERS b/MAINTAINERS
> > index 5a6137df3f0e..d555beb794bb 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -12205,6 +12205,7 @@ PCIE DRIVER FOR ANNAPURNA LABS
> AMAZON!
> >   M:	Jonathan Chocron <jonnyc@amazon.com>
> >   L:	linux-pci@vger.kernel.org
> >   S:	Maintained
> > +F:	Documentation/devicetree/bindings/pci/pcie-al.txt
> >   F:	drivers/pci/controller/dwc/pcie-al.c
> >   PCIE DRIVER FOR AMLOGIC MESON

^ permalink raw reply

* [PATCH 3/3] dt-bindings: dma: Convert Allwinner A31 and A64 DMA to a schema
From: Maxime Ripard @ 2019-07-11  9:21 UTC (permalink / raw)
  To: Mark Rutland, Rob Herring, Frank Rowand, Vinod Koul
  Cc: dmaengine, devicetree, Chen-Yu Tsai, Maxime Ripard,
	linux-arm-kernel
In-Reply-To: <20190711092158.14678-1-maxime.ripard@bootlin.com>

The newer Allwinner SoCs have a DMA controller supported in Linux, with a
matching Device Tree binding.

Now that we have the DT validation in place, let's convert the device tree
bindings for that controller over to a YAML schemas.

Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
---
 .../dma/allwinner,sun50i-a64-dma.yaml         | 88 +++++++++++++++++++
 .../bindings/dma/allwinner,sun6i-a31-dma.yaml | 62 +++++++++++++
 .../devicetree/bindings/dma/sun6i-dma.txt     | 81 -----------------
 3 files changed, 150 insertions(+), 81 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/dma/allwinner,sun50i-a64-dma.yaml
 create mode 100644 Documentation/devicetree/bindings/dma/allwinner,sun6i-a31-dma.yaml
 delete mode 100644 Documentation/devicetree/bindings/dma/sun6i-dma.txt

diff --git a/Documentation/devicetree/bindings/dma/allwinner,sun50i-a64-dma.yaml b/Documentation/devicetree/bindings/dma/allwinner,sun50i-a64-dma.yaml
new file mode 100644
index 000000000000..4cb9d6b93138
--- /dev/null
+++ b/Documentation/devicetree/bindings/dma/allwinner,sun50i-a64-dma.yaml
@@ -0,0 +1,88 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/dma/allwinner,sun50i-a64-dma.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Allwinner A64 DMA Controller Device Tree Bindings
+
+maintainers:
+  - Chen-Yu Tsai <wens@csie.org>
+  - Maxime Ripard <maxime.ripard@bootlin.com>
+
+allOf:
+  - $ref: "dma-controller.yaml#"
+
+properties:
+  "#dma-cells":
+    const: 1
+    description: The cell is the request line number.
+
+  compatible:
+    enum:
+      - allwinner,sun50i-a64-dma
+      - allwinner,sun50i-h6-dma
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    minItems: 1
+    maxItems: 2
+
+  clock-names:
+    items:
+      - const: bus
+      - const: mbus
+
+  resets:
+    maxItems: 1
+
+required:
+  - "#dma-cells"
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - resets
+  - dma-channels
+
+if:
+  properties:
+    compatible:
+      const: allwinner,sun50i-h6-dma
+
+then:
+  properties:
+    clocks:
+      maxItems: 2
+
+  required:
+    - clock-names
+
+else:
+  properties:
+    clocks:
+      maxItems: 1
+
+# FIXME: We should set it, but it would report all the generic
+# properties as additional properties.
+# additionalProperties: false
+
+examples:
+  - |
+    dma: dma-controller@1c02000 {
+        compatible = "allwinner,sun50i-a64-dma";
+        reg = <0x01c02000 0x1000>;
+        interrupts = <0 50 4>;
+        clocks = <&ccu 30>;
+        dma-channels = <8>;
+        dma-requests = <27>;
+        resets = <&ccu 7>;
+        #dma-cells = <1>;
+    };
+
+...
diff --git a/Documentation/devicetree/bindings/dma/allwinner,sun6i-a31-dma.yaml b/Documentation/devicetree/bindings/dma/allwinner,sun6i-a31-dma.yaml
new file mode 100644
index 000000000000..740b7f9b535b
--- /dev/null
+++ b/Documentation/devicetree/bindings/dma/allwinner,sun6i-a31-dma.yaml
@@ -0,0 +1,62 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/dma/allwinner,sun6i-a31-dma.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Allwinner A31 DMA Controller Device Tree Bindings
+
+maintainers:
+  - Chen-Yu Tsai <wens@csie.org>
+  - Maxime Ripard <maxime.ripard@bootlin.com>
+
+allOf:
+  - $ref: "dma-controller.yaml#"
+
+properties:
+  "#dma-cells":
+    const: 1
+    description: The cell is the request line number.
+
+  compatible:
+    oneOf:
+      - const: allwinner,sun6i-a31-dma
+      - const: allwinner,sun8i-a23-dma
+      - const: allwinner,sun8i-a83t-dma
+      - const: allwinner,sun8i-h3-dma
+      - const: allwinner,sun8i-v3s-dma
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  resets:
+    maxItems: 1
+
+required:
+  - "#dma-cells"
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - resets
+
+additionalProperties: false
+
+examples:
+  - |
+    dma: dma-controller@1c02000 {
+        compatible = "allwinner,sun6i-a31-dma";
+        reg = <0x01c02000 0x1000>;
+        interrupts = <0 50 4>;
+        clocks = <&ahb1_gates 6>;
+        resets = <&ahb1_rst 6>;
+        #dma-cells = <1>;
+    };
+
+...
diff --git a/Documentation/devicetree/bindings/dma/sun6i-dma.txt b/Documentation/devicetree/bindings/dma/sun6i-dma.txt
deleted file mode 100644
index cae31f4e77ba..000000000000
--- a/Documentation/devicetree/bindings/dma/sun6i-dma.txt
+++ /dev/null
@@ -1,81 +0,0 @@
-Allwinner A31 DMA Controller
-
-This driver follows the generic DMA bindings defined in dma.txt.
-
-Required properties:
-
-- compatible:	Must be one of
-		  "allwinner,sun6i-a31-dma"
-		  "allwinner,sun8i-a23-dma"
-		  "allwinner,sun8i-a83t-dma"
-		  "allwinner,sun8i-h3-dma"
-		  "allwinner,sun8i-v3s-dma"
-- reg:		Should contain the registers base address and length
-- interrupts:	Should contain a reference to the interrupt used by this device
-- clocks:	Should contain a reference to the parent AHB clock
-- resets:	Should contain a reference to the reset controller asserting
-		this device in reset
-- #dma-cells :	Should be 1, a single cell holding a line request number
-
-Example:
-	dma: dma-controller@1c02000 {
-		compatible = "allwinner,sun6i-a31-dma";
-		reg = <0x01c02000 0x1000>;
-		interrupts = <0 50 4>;
-		clocks = <&ahb1_gates 6>;
-		resets = <&ahb1_rst 6>;
-		#dma-cells = <1>;
-	};
-
-------------------------------------------------------------------------------
-For A64 and H6 DMA controller:
-
-Required properties:
-- compatible:	Must be one of
-		  "allwinner,sun50i-a64-dma"
-		  "allwinner,sun50i-h6-dma"
-- dma-channels: Number of DMA channels supported by the controller.
-		Refer to Documentation/devicetree/bindings/dma/dma.txt
-- clocks:	In addition to parent AHB clock, it should also contain mbus
-		clock (H6 only)
-- clock-names:	Should contain "bus" and "mbus" (H6 only)
-- all properties above, i.e. reg, interrupts, clocks, resets and #dma-cells
-
-Optional properties:
-- dma-requests: Number of DMA request signals supported by the controller.
-		Refer to Documentation/devicetree/bindings/dma/dma.txt
-
-Example:
-	dma: dma-controller@1c02000 {
-		compatible = "allwinner,sun50i-a64-dma";
-		reg = <0x01c02000 0x1000>;
-		interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&ccu CLK_BUS_DMA>;
-		dma-channels = <8>;
-		dma-requests = <27>;
-		resets = <&ccu RST_BUS_DMA>;
-		#dma-cells = <1>;
-	};
-------------------------------------------------------------------------------
-
-Clients:
-
-DMA clients connected to the A31 DMA controller must use the format
-described in the dma.txt file, using a two-cell specifier for each
-channel: a phandle plus one integer cells.
-The two cells in order are:
-
-1. A phandle pointing to the DMA controller.
-2. The port ID as specified in the datasheet
-
-Example:
-spi2: spi@1c6a000 {
-	compatible = "allwinner,sun6i-a31-spi";
-	reg = <0x01c6a000 0x1000>;
-	interrupts = <0 67 4>;
-	clocks = <&ahb1_gates 22>, <&spi2_clk>;
-	clock-names = "ahb", "mod";
-	dmas = <&dma 25>, <&dma 25>;
-	dma-names = "rx", "tx";
-	resets = <&ahb1_rst 22>;
-};
-- 
2.21.0

^ permalink raw reply related

* [PATCH 2/3] dt-bindings: dma: Convert Allwinner A10 DMA to a schema
From: Maxime Ripard @ 2019-07-11  9:21 UTC (permalink / raw)
  To: Mark Rutland, Rob Herring, Frank Rowand, Vinod Koul
  Cc: dmaengine, devicetree, Chen-Yu Tsai, Maxime Ripard,
	linux-arm-kernel
In-Reply-To: <20190711092158.14678-1-maxime.ripard@bootlin.com>

The older Allwinner SoCs have a DMA controller supported in Linux, with a
matching Device Tree binding.

Now that we have the DT validation in place, let's convert the device tree
bindings for that controller over to a YAML schemas.

Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
---
 .../bindings/dma/allwinner,sun4i-a10-dma.yaml | 55 +++++++++++++++++++
 .../devicetree/bindings/dma/sun4i-dma.txt     | 45 ---------------
 2 files changed, 55 insertions(+), 45 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/dma/allwinner,sun4i-a10-dma.yaml
 delete mode 100644 Documentation/devicetree/bindings/dma/sun4i-dma.txt

diff --git a/Documentation/devicetree/bindings/dma/allwinner,sun4i-a10-dma.yaml b/Documentation/devicetree/bindings/dma/allwinner,sun4i-a10-dma.yaml
new file mode 100644
index 000000000000..15abc0f9429f
--- /dev/null
+++ b/Documentation/devicetree/bindings/dma/allwinner,sun4i-a10-dma.yaml
@@ -0,0 +1,55 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/dma/allwinner,sun4i-a10-dma.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Allwinner A10 DMA Controller Device Tree Bindings
+
+maintainers:
+  - Chen-Yu Tsai <wens@csie.org>
+  - Maxime Ripard <maxime.ripard@bootlin.com>
+
+allOf:
+  - $ref: "dma-controller.yaml#"
+
+properties:
+  "#dma-cells":
+    const: 2
+    description:
+      The first cell is either 0 or 1, the former to use the normal
+      DMA, 1 for dedicated DMA. The second cell is the request line
+      number.
+
+  compatible:
+    const: allwinner,sun4i-a10-dma
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+required:
+  - "#dma-cells"
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+    dma: dma-controller@1c02000 {
+        compatible = "allwinner,sun4i-a10-dma";
+        reg = <0x01c02000 0x1000>;
+        interrupts = <27>;
+        clocks = <&ahb_gates 6>;
+        #dma-cells = <2>;
+    };
+
+...
diff --git a/Documentation/devicetree/bindings/dma/sun4i-dma.txt b/Documentation/devicetree/bindings/dma/sun4i-dma.txt
deleted file mode 100644
index 8ad556aca70b..000000000000
--- a/Documentation/devicetree/bindings/dma/sun4i-dma.txt
+++ /dev/null
@@ -1,45 +0,0 @@
-Allwinner A10 DMA Controller
-
-This driver follows the generic DMA bindings defined in dma.txt.
-
-Required properties:
-
-- compatible:	Must be "allwinner,sun4i-a10-dma"
-- reg:		Should contain the registers base address and length
-- interrupts:	Should contain a reference to the interrupt used by this device
-- clocks:	Should contain a reference to the parent AHB clock
-- #dma-cells :	Should be 2, first cell denoting normal or dedicated dma,
-		second cell holding the request line number.
-
-Example:
-	dma: dma-controller@1c02000 {
-		compatible = "allwinner,sun4i-a10-dma";
-		reg = <0x01c02000 0x1000>;
-		interrupts = <27>;
-		clocks = <&ahb_gates 6>;
-		#dma-cells = <2>;
-	};
-
-Clients:
-
-DMA clients connected to the Allwinner A10 DMA controller must use the
-format described in the dma.txt file, using a three-cell specifier for
-each channel: a phandle plus two integer cells.
-The three cells in order are:
-
-1. A phandle pointing to the DMA controller.
-2. Whether it is using normal (0) or dedicated (1) channels
-3. The port ID as specified in the datasheet
-
-Example:
-	spi2: spi@1c17000 {
-		compatible = "allwinner,sun4i-a10-spi";
-		reg = <0x01c17000 0x1000>;
-		interrupts = <0 12 4>;
-		clocks = <&ahb_gates 22>, <&spi2_clk>;
-		clock-names = "ahb", "mod";
-		dmas = <&dma 1 29>, <&dma 1 28>;
-		dma-names = "rx", "tx";
-		#address-cells = <1>;
-		#size-cells = <0>;
-	};
-- 
2.21.0

^ permalink raw reply related

* [PATCH 1/3] dt-bindings: dma: Add YAML schemas for the generic DMA bindings
From: Maxime Ripard @ 2019-07-11  9:21 UTC (permalink / raw)
  To: Mark Rutland, Rob Herring, Frank Rowand, Vinod Koul
  Cc: dmaengine, devicetree, Chen-Yu Tsai, Maxime Ripard,
	linux-arm-kernel

The DMA controllers and consumers have a bunch of generic properties that
are needed in a device tree. Add a YAML schemas for those.

Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
---
 .../devicetree/bindings/dma/dma-consumer.yaml |  60 +++++++++
 .../bindings/dma/dma-controller.yaml          |  79 ++++++++++++
 Documentation/devicetree/bindings/dma/dma.txt | 114 +-----------------
 3 files changed, 140 insertions(+), 113 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/dma/dma-consumer.yaml
 create mode 100644 Documentation/devicetree/bindings/dma/dma-controller.yaml

diff --git a/Documentation/devicetree/bindings/dma/dma-consumer.yaml b/Documentation/devicetree/bindings/dma/dma-consumer.yaml
new file mode 100644
index 000000000000..2f6315863ad1
--- /dev/null
+++ b/Documentation/devicetree/bindings/dma/dma-consumer.yaml
@@ -0,0 +1,60 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/dma/dma-consumer.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: DMA Consumer Generic Binding
+
+maintainers:
+  - Vinod Koul <vkoul@kernel.org>
+
+select: true
+
+properties:
+  dmas:
+    description:
+      List of one or more DMA specifiers, each consisting of
+          - A phandle pointing to DMA controller node
+          - A number of integer cells, as determined by the
+            \#dma-cells property in the node referenced by phandle
+            containing DMA controller specific information. This
+            typically contains a DMA request line number or a
+            channel number, but can contain any data that is
+            required for configuring a channel.
+
+  dma-names:
+    description:
+      Contains one identifier string for each DMA specifier in the
+      dmas property. The specific strings that can be used are defined
+      in the binding of the DMA client device.  Multiple DMA
+      specifiers can be used to represent alternatives and in this
+      case the dma-names for those DMA specifiers must be identical
+      (see examples).
+
+dependencies:
+  dma-names: [ dmas ]
+
+examples:
+  - |
+    /* A device with one DMA read channel, one DMA write channel */
+    i2c1: i2c@1 {
+         /* ... */
+         dmas = <&dma 2>, 	/* read channel */
+                <&dma 3>;	/* write channel */
+        dma-names = "rx", "tx";
+        /* ... */
+    };
+
+  - |
+    /* A single read-write channel with three alternative DMA controllers */
+    dmas = <&dma1 5>, <&dma2 7>, <&dma3 2>;
+    dma-names = "rx-tx", "rx-tx", "rx-tx";
+
+  - |
+    /* A device with three channels, one of which has two alternatives */
+    dmas = <&dma1 2>,		/* read channel */
+           <&dma1 3>,		/* write channel */
+           <&dma2 0>,		/* error read */
+           <&dma3 0>;		/* alternative error read */
+    dma-names = "rx", "tx", "error", "error";
diff --git a/Documentation/devicetree/bindings/dma/dma-controller.yaml b/Documentation/devicetree/bindings/dma/dma-controller.yaml
new file mode 100644
index 000000000000..17c650131b78
--- /dev/null
+++ b/Documentation/devicetree/bindings/dma/dma-controller.yaml
@@ -0,0 +1,79 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/dma/dma-controller.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: DMA Controller Generic Binding
+
+maintainers:
+  - Vinod Koul <vkoul@kernel.org>
+
+description:
+  Generic binding to provide a way for a driver using DMA Engine to
+  retrieve the DMA request or channel information that goes from a
+  hardware device to a DMA controller.
+
+properties:
+  $nodename:
+    pattern: "^dma-controller(@.*)?$"
+
+  "#dma-cells":
+    # minimum: 1
+    description:
+      Used to provide DMA controller specific information.
+
+  dma-channel-masks:
+    $ref: /schemas/types.yaml#definitions/uint32
+    description:
+      Bitmask of available DMA channels in ascending order that are
+      not reserved by firmware and are available to the
+      kernel. i.e. first channel corresponds to LSB.
+
+  dma-channels:
+    $ref: /schemas/types.yaml#definitions/uint32
+    description:
+      Number of DMA channels supported by the controller.
+
+  dma-masters:
+    $ref: /schemas/types.yaml#definitions/phandle-array
+    description:
+      DMA routers are transparent IP blocks used to route DMA request
+      lines from devices to the DMA controller. Some SoCs (like TI
+      DRA7x) have more peripherals integrated with DMA requests than
+      what the DMA controller can handle directly.
+
+      In such a case, dma-masters is an array of phandle to the DMA
+      controllers the router can direct the signal to.
+
+  dma-requests:
+    $ref: /schemas/types.yaml#definitions/uint32
+    description:
+      Number of DMA request signals supported by the controller.
+
+examples:
+  - |
+    dma: dma@48000000 {
+        compatible = "ti,omap-sdma";
+        reg = <0x48000000 0x1000>;
+        interrupts = <0 12 0x4
+                      0 13 0x4
+                      0 14 0x4
+                      0 15 0x4>;
+        #dma-cells = <1>;
+        dma-channels = <32>;
+        dma-requests = <127>;
+        dma-channel-mask = <0xfffe>;
+    };
+
+  - |
+    sdma_xbar: dma-router@4a002b78 {
+        compatible = "ti,dra7-dma-crossbar";
+        reg = <0x4a002b78 0xfc>;
+        #dma-cells = <1>;
+        dma-requests = <205>;
+        ti,dma-safe-map = <0>;
+        dma-masters = <&sdma>;
+    };
+
+...
diff --git a/Documentation/devicetree/bindings/dma/dma.txt b/Documentation/devicetree/bindings/dma/dma.txt
index eeb4e4d1771e..90a67a016a48 100644
--- a/Documentation/devicetree/bindings/dma/dma.txt
+++ b/Documentation/devicetree/bindings/dma/dma.txt
@@ -1,113 +1 @@
-* Generic DMA Controller and DMA request bindings
-
-Generic binding to provide a way for a driver using DMA Engine to retrieve the
-DMA request or channel information that goes from a hardware device to a DMA
-controller.
-
-
-* DMA controller
-
-Required property:
-- #dma-cells: 		Must be at least 1. Used to provide DMA controller
-			specific information. See DMA client binding below for
-			more details.
-
-Optional properties:
-- dma-channels: 	Number of DMA channels supported by the controller.
-- dma-requests: 	Number of DMA request signals supported by the
-			controller.
-- dma-channel-mask:	Bitmask of available DMA channels in ascending order
-			that are not reserved by firmware and are available to
-			the kernel. i.e. first channel corresponds to LSB.
-
-Example:
-
-	dma: dma@48000000 {
-		compatible = "ti,omap-sdma";
-		reg = <0x48000000 0x1000>;
-		interrupts = <0 12 0x4
-			      0 13 0x4
-			      0 14 0x4
-			      0 15 0x4>;
-		#dma-cells = <1>;
-		dma-channels = <32>;
-		dma-requests = <127>;
-		dma-channel-mask = <0xfffe>
-	};
-
-* DMA router
-
-DMA routers are transparent IP blocks used to route DMA request lines from
-devices to the DMA controller. Some SoCs (like TI DRA7x) have more peripherals
-integrated with DMA requests than what the DMA controller can handle directly.
-
-Required property:
-- dma-masters:		phandle of the DMA controller or list of phandles for
-			the DMA controllers the router can direct the signal to.
-- #dma-cells: 		Must be at least 1. Used to provide DMA router specific
-			information. See DMA client binding below for more
-			details.
-
-Optional properties:
-- dma-requests: 	Number of incoming request lines the router can handle.
-- In the node pointed by the dma-masters:
-	- dma-requests:	The router driver might need to look for this in order
-			to configure the routing.
-
-Example:
-	sdma_xbar: dma-router@4a002b78 {
-		compatible = "ti,dra7-dma-crossbar";
-		reg = <0x4a002b78 0xfc>;
-		#dma-cells = <1>;
-		dma-requests = <205>;
-		ti,dma-safe-map = <0>;
-		dma-masters = <&sdma>;
-	};
-
-* DMA client
-
-Client drivers should specify the DMA property using a phandle to the controller
-followed by DMA controller specific data.
-
-Required property:
-- dmas:			List of one or more DMA specifiers, each consisting of
-			- A phandle pointing to DMA controller node
-			- A number of integer cells, as determined by the
-			  #dma-cells property in the node referenced by phandle
-			  containing DMA controller specific information. This
-			  typically contains a DMA request line number or a
-			  channel number, but can contain any data that is
-			  required for configuring a channel.
-- dma-names: 		Contains one identifier string for each DMA specifier in
-			the dmas property. The specific strings that can be used
-			are defined in the binding of the DMA client device.
-			Multiple DMA specifiers can be used to represent
-			alternatives and in this case the dma-names for those
-			DMA specifiers must be identical (see examples).
-
-Examples:
-
-1. A device with one DMA read channel, one DMA write channel:
-
-	i2c1: i2c@1 {
-		...
-		dmas = <&dma 2		/* read channel */
-			&dma 3>;	/* write channel */
-		dma-names = "rx", "tx";
-		...
-	};
-
-2. A single read-write channel with three alternative DMA controllers:
-
-	dmas = <&dma1 5
-		&dma2 7
-		&dma3 2>;
-	dma-names = "rx-tx", "rx-tx", "rx-tx";
-
-3. A device with three channels, one of which has two alternatives:
-
-	dmas = <&dma1 2			/* read channel */
-		&dma1 3			/* write channel */
-		&dma2 0			/* error read */
-		&dma3 0>;		/* alternative error read */
-	dma-names = "rx", "tx", "error", "error";
+This file has been moved to dma-controller.yaml.
-- 
2.21.0

^ permalink raw reply related

* [PATCH v10 2/2] media: v4l: xilinx: Add Xilinx MIPI CSI-2 Rx Subsystem driver
From: Vishal Sagar @ 2019-07-11  9:16 UTC (permalink / raw)
  To: Hyun Kwon, laurent.pinchart, mchehab, robh+dt, mark.rutland,
	Michal Simek, linux-media, devicetree, hans.verkuil,
	linux-arm-kernel, linux-kernel, Dinesh Kumar, Sandip Kothari,
	Luca Ceresoli, Jacopo Mondi
  Cc: Vishal Sagar, Hyun Kwon
In-Reply-To: <20190711091612.98175-1-vishal.sagar@xilinx.com>

The Xilinx MIPI CSI-2 Rx Subsystem soft IP is used to capture images
from MIPI CSI-2 camera sensors and output AXI4-Stream video data ready
for image processing. Please refer to PG232 for details.

The CSI2 Rx controller filters out all packets except for the packets
with data type fixed in hardware. RAW8 packets are always allowed to
pass through.

It is also used to setup and handle interrupts and enable the core. It
logs all the events in respective counters between streaming on and off.

The driver supports only the video format bridge enabled configuration.
Some data types like YUV 422 10bpc, RAW16, RAW20 are supported when the
CSI v2.0 feature is enabled in design. When the VCX feature is enabled,
the maximum number of virtual channels becomes 16 from 4.

Signed-off-by: Vishal Sagar <vishal.sagar@xilinx.com>
Reviewed-by: Hyun Kwon <hyun.kwon@xilinx.com>
---
v10
- Removed all V4L2 controls and events based on Sakari's comments.
- Now stop_stream() before toggling rst_gpio
- Updated init_mbus() to throw error on array out of bound access
- Make events and vcx_events as counters instead of structures
- Minor fixes in set_format() enum_mbus_code() as suggested by Sakari

v9
- Moved all controls and events to xilinx-csi2rxss.h
- Updated name and description of controls and events
- Get control base address from v4l2-controls.h (0x10c0)
- Fix KConfig for dependency on VIDEO_XILINX
- Added enum_mbus_code() support
- Added default format to be returned on open()
- Mark variables are const
- Remove references to short packet in comments
- Add check for streaming before setting active lanes control
- strlcpy -> strscpy
- Fix xcsi2rxss_set_format()

v8
- Use clk_bulk* APIs
- Add gpio reset for asserting video_aresetn when stream line buffer occurs
- Removed short packet related events and irq handling
  - V4L2_EVENT_XLNXCSIRX_SPKT and V4L2_EVENT_XLNXCSIRX_SPKT_OVF removed
- Removed frame counter control V4L2_CID_XILINX_MIPICSISS_FRAME_COUNTER
  and xcsi2rxss_g_volatile_ctrl()
- Minor formatting fixes

v7
- No change

v6
- No change

v5
- Removed bayer and updated related parts like set default format based
  on Luca Cersoli's comments.
- Added correct YUV422 10bpc media bus format

v4
- Removed irq member from core structure
- Consolidated IP config prints in xcsi2rxss_log_ipconfig()
- Return -EINVAL in case of invalid ioctl
- Code formatting
- Added reviewed by Hyun Kwon

v3
- Fixed comments given by Hyun.
- Removed DPHY 200 MHz clock. This will be controlled by DPHY driver
- Minor code formatting
- en_csi_v20 and vfb members removed from struct and made local to dt parsing
- lock description updated
- changed to ratelimited type for all dev prints in irq handler
- Removed YUV 422 10bpc media format

v2
- Fixed comments given by Hyun and Sakari.
- Made all bitmask using BIT() and GENMASK()
- Removed unused definitions
- Removed DPHY access. This will be done by separate DPHY PHY driver.
- Added support for CSI v2.0 for YUV 422 10bpc, RAW16, RAW20 and extra
  virtual channels
- Fixed the ports as sink and source
- Now use the v4l2fwnode API to get number of data-lanes
- Added clock framework support
- Removed the close() function
- updated the set format function
- support only VFB enabled configuration
 drivers/media/platform/xilinx/Kconfig         |   11 +
 drivers/media/platform/xilinx/Makefile        |    1 +
 .../media/platform/xilinx/xilinx-csi2rxss.c   | 1230 +++++++++++++++++
 3 files changed, 1242 insertions(+)
 create mode 100644 drivers/media/platform/xilinx/xilinx-csi2rxss.c

diff --git a/drivers/media/platform/xilinx/Kconfig b/drivers/media/platform/xilinx/Kconfig
index a2773ad7c185..349da877c846 100644
--- a/drivers/media/platform/xilinx/Kconfig
+++ b/drivers/media/platform/xilinx/Kconfig
@@ -10,6 +10,17 @@ config VIDEO_XILINX
 
 if VIDEO_XILINX
 
+config VIDEO_XILINX_CSI2RXSS
+	tristate "Xilinx CSI2 Rx Subsystem"
+	depends on VIDEO_XILINX
+	help
+	  Driver for Xilinx MIPI CSI2 Rx Subsystem. This is a V4L sub-device
+	  based driver that takes input from CSI2 Tx source and converts
+	  it into an AXI4-Stream. The subsystem comprises of a CSI2 Rx
+	  controller, DPHY, an optional I2C controller and a Video Format
+	  Bridge. The driver is used to set the number of active lanes and
+	  get short packet data.
+
 config VIDEO_XILINX_TPG
 	tristate "Xilinx Video Test Pattern Generator"
 	depends on VIDEO_XILINX
diff --git a/drivers/media/platform/xilinx/Makefile b/drivers/media/platform/xilinx/Makefile
index 4cdc0b1ec7a5..6119a34f3043 100644
--- a/drivers/media/platform/xilinx/Makefile
+++ b/drivers/media/platform/xilinx/Makefile
@@ -3,5 +3,6 @@
 xilinx-video-objs += xilinx-dma.o xilinx-vip.o xilinx-vipp.o
 
 obj-$(CONFIG_VIDEO_XILINX) += xilinx-video.o
+obj-$(CONFIG_VIDEO_XILINX_CSI2RXSS) += xilinx-csi2rxss.o
 obj-$(CONFIG_VIDEO_XILINX_TPG) += xilinx-tpg.o
 obj-$(CONFIG_VIDEO_XILINX_VTC) += xilinx-vtc.o
diff --git a/drivers/media/platform/xilinx/xilinx-csi2rxss.c b/drivers/media/platform/xilinx/xilinx-csi2rxss.c
new file mode 100644
index 000000000000..1a22ca80382e
--- /dev/null
+++ b/drivers/media/platform/xilinx/xilinx-csi2rxss.c
@@ -0,0 +1,1230 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Driver for Xilinx MIPI CSI2 Rx Subsystem
+ *
+ * Copyright (C) 2016 - 2019 Xilinx, Inc.
+ *
+ * Contacts: Vishal Sagar <vishal.sagar@xilinx.com>
+ *
+ */
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/gpio/consumer.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/platform_device.h>
+#include <linux/v4l2-subdev.h>
+#include <media/media-entity.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-fwnode.h>
+#include <media/v4l2-subdev.h>
+#include "xilinx-vip.h"
+
+/* Register register map */
+#define XCSI_CCR_OFFSET		0x00
+#define XCSI_CCR_SOFTRESET	BIT(1)
+#define XCSI_CCR_ENABLE		BIT(0)
+
+#define XCSI_PCR_OFFSET		0x04
+#define XCSI_PCR_MAXLANES_MASK	GENMASK(4, 3)
+#define XCSI_PCR_ACTLANES_MASK	GENMASK(1, 0)
+
+#define XCSI_CSR_OFFSET		0x10
+#define XCSI_CSR_PKTCNT		GENMASK(31, 16)
+#define XCSI_CSR_SPFIFOFULL	BIT(3)
+#define XCSI_CSR_SPFIFONE	BIT(2)
+#define XCSI_CSR_SLBF		BIT(1)
+#define XCSI_CSR_RIPCD		BIT(0)
+
+#define XCSI_GIER_OFFSET	0x20
+#define XCSI_GIER_GIE		BIT(0)
+
+#define XCSI_ISR_OFFSET		0x24
+#define XCSI_IER_OFFSET		0x28
+
+#define XCSI_ISR_FR		BIT(31)
+#define XCSI_ISR_VCXFE		BIT(30)
+#define XCSI_ISR_WCC		BIT(22)
+#define XCSI_ISR_ILC		BIT(21)
+#define XCSI_ISR_SPFIFOF	BIT(20)
+#define XCSI_ISR_SPFIFONE	BIT(19)
+#define XCSI_ISR_SLBF		BIT(18)
+#define XCSI_ISR_STOP		BIT(17)
+#define XCSI_ISR_SOTERR		BIT(13)
+#define XCSI_ISR_SOTSYNCERR	BIT(12)
+#define XCSI_ISR_ECC2BERR	BIT(11)
+#define XCSI_ISR_ECC1BERR	BIT(10)
+#define XCSI_ISR_CRCERR		BIT(9)
+#define XCSI_ISR_DATAIDERR	BIT(8)
+#define XCSI_ISR_VC3FSYNCERR	BIT(7)
+#define XCSI_ISR_VC3FLVLERR	BIT(6)
+#define XCSI_ISR_VC2FSYNCERR	BIT(5)
+#define XCSI_ISR_VC2FLVLERR	BIT(4)
+#define XCSI_ISR_VC1FSYNCERR	BIT(3)
+#define XCSI_ISR_VC1FLVLERR	BIT(2)
+#define XCSI_ISR_VC0FSYNCERR	BIT(1)
+#define XCSI_ISR_VC0FLVLERR	BIT(0)
+
+#define XCSI_INTR_PROT_MASK	(XCSI_ISR_VC3FSYNCERR |	XCSI_ISR_VC3FLVLERR |\
+				 XCSI_ISR_VC2FSYNCERR | XCSI_ISR_VC2FLVLERR |\
+				 XCSI_ISR_VC1FSYNCERR | XCSI_ISR_VC1FLVLERR |\
+				 XCSI_ISR_VC0FSYNCERR |	XCSI_ISR_VC0FLVLERR |\
+				 XCSI_ISR_VCXFE)
+
+#define XCSI_INTR_PKTLVL_MASK	(XCSI_ISR_ECC2BERR | XCSI_ISR_ECC1BERR |\
+				 XCSI_ISR_CRCERR | XCSI_ISR_DATAIDERR)
+
+#define XCSI_INTR_DPHY_MASK	(XCSI_ISR_SOTERR | XCSI_ISR_SOTSYNCERR)
+
+#define XCSI_INTR_SPKT_MASK	(XCSI_ISR_SPFIFOF | XCSI_ISR_SPFIFONE)
+
+#define XCSI_INTR_ERR_MASK	(XCSI_ISR_WCC | XCSI_ISR_ILC | XCSI_ISR_SLBF |\
+				 XCSI_ISR_STOP)
+
+#define XCSI_INTR_FRAMERCVD_MASK	(XCSI_ISR_FR)
+
+#define XCSI_ISR_ALLINTR_MASK	(XCSI_INTR_PROT_MASK | XCSI_INTR_PKTLVL_MASK |\
+				 XCSI_INTR_DPHY_MASK | XCSI_INTR_SPKT_MASK |\
+				 XCSI_INTR_ERR_MASK | XCSI_INTR_FRAMERCVD_MASK)
+
+/*
+ * Removed VCXFE mask as it doesn't exist in IER
+ * Removed STOP state irq as this will keep driver in irq handler only
+ */
+#define XCSI_IER_INTR_MASK	(XCSI_ISR_ALLINTR_MASK &\
+				 ~(XCSI_ISR_STOP | XCSI_ISR_VCXFE))
+
+#define XCSI_SPKTR_OFFSET	0x30
+#define XCSI_SPKTR_DATA		GENMASK(23, 8)
+#define XCSI_SPKTR_VC		GENMASK(7, 6)
+#define XCSI_SPKTR_DT		GENMASK(5, 0)
+
+#define XCSI_VCXR_OFFSET	0x34
+#define XCSI_VCXR_VCERR		GENMASK(23, 0)
+#define XCSI_VCXR_VCSTART	4
+#define XCSI_VCXR_VCEND		15
+#define XCSI_VCXR_FSYNCERR	BIT(1)
+#define XCSI_VCXR_FLVLERR	BIT(0)
+
+#define XCSI_CLKINFR_OFFSET	0x3C
+#define XCSI_CLKINFR_STOP	BIT(1)
+
+#define XCSI_DLXINFR_OFFSET	0x40
+#define XCSI_DLXINFR_STOP	BIT(5)
+#define XCSI_DLXINFR_SOTERR	BIT(1)
+#define XCSI_DLXINFR_SOTSYNCERR	BIT(0)
+#define XCSI_MAXDL_COUNT	0x4
+
+#define XCSI_VCXINF1R_OFFSET		0x60
+#define XCSI_VCXINF1R_LINECOUNT		GENMASK(31, 16)
+#define XCSI_VCXINF1R_LINECOUNT_SHIFT	16
+#define XCSI_VCXINF1R_BYTECOUNT		GENMASK(15, 0)
+
+#define XCSI_VCXINF2R_OFFSET	0x64
+#define XCSI_VCXINF2R_DT	GENMASK(5, 0)
+#define XCSI_MAXVCX_COUNT	16
+
+/*
+ * The core takes less than 100 video clock cycles to reset.
+ * So choosing a timeout value larger than this.
+ */
+#define XCSI_TIMEOUT_VAL	1000 /* us */
+
+/*
+ * Sink pad connected to sensor source pad.
+ * Source pad connected to next module like demosaic.
+ */
+#define XCSI_MEDIA_PADS		2
+#define XCSI_DEFAULT_WIDTH	1920
+#define XCSI_DEFAULT_HEIGHT	1080
+
+/* Max media bus formats supported for enumeration */
+#define XCSI_MAX_MBUS_FMTS	16
+
+/* Max string length for CSI Data type string */
+#define XCSI_PXLFMT_STRLEN_MAX	16
+
+/* MIPI CSI2 Data Types from spec */
+#define XCSI_DT_YUV4228B	0x1E
+#define XCSI_DT_YUV42210B	0x1F
+#define XCSI_DT_RGB444		0x20
+#define XCSI_DT_RGB555		0x21
+#define XCSI_DT_RGB565		0x22
+#define XCSI_DT_RGB666		0x23
+#define XCSI_DT_RGB888		0x24
+#define XCSI_DT_RAW6		0x28
+#define XCSI_DT_RAW7		0x29
+#define XCSI_DT_RAW8		0x2A
+#define XCSI_DT_RAW10		0x2B
+#define XCSI_DT_RAW12		0x2C
+#define XCSI_DT_RAW14		0x2D
+#define XCSI_DT_RAW16		0x2E
+#define XCSI_DT_RAW20		0x2F
+
+#define XCSI_VCX_START		4
+#define XCSI_MAX_VC		4
+#define XCSI_MAX_VCX		16
+
+#define XCSI_NEXTREG_OFFSET	4
+
+/* There are 2 events frame sync and frame level error per VC */
+#define XCSI_VCX_NUM_EVENTS	((XCSI_MAX_VCX - XCSI_MAX_VC) * 2)
+
+/* Macro to return "true" or "false" string if bit is set */
+#define XCSI_GET_BITSET_STR(val, mask)	(val) & (mask) ? "true" : "false"
+
+#define XADD_MBUS(state, mbus_fmt)					\
+	do {								\
+		if ((state)->mbus_fmts_count < XCSI_MAX_MBUS_FMTS) {	\
+			(state)->mbus_fmts[(state)->mbus_fmts_count++] =\
+				(mbus_fmt);				\
+		} else {						\
+			dev_err((state)->core.dev,			\
+				"accessing array out of bounds!\n");	\
+		}							\
+	} while (0)
+
+/**
+ * struct xcsi2rxss_event - Event log structure
+ * @mask: Event mask
+ * @name: Name of the event
+ */
+struct xcsi2rxss_event {
+	u32 mask;
+	const char *name;
+};
+
+static const struct xcsi2rxss_event xcsi2rxss_events[] = {
+	{ XCSI_ISR_FR, "Frame Received" },
+	{ XCSI_ISR_VCXFE, "VCX Frame Errors" },
+	{ XCSI_ISR_WCC, "Word Count Errors" },
+	{ XCSI_ISR_ILC, "Invalid Lane Count Error" },
+	{ XCSI_ISR_SPFIFOF, "Short Packet FIFO OverFlow Error" },
+	{ XCSI_ISR_SPFIFONE, "Short Packet FIFO Not Empty" },
+	{ XCSI_ISR_SLBF, "Streamline Buffer Full Error" },
+	{ XCSI_ISR_STOP, "Lane Stop State" },
+	{ XCSI_ISR_SOTERR, "SOT Error" },
+	{ XCSI_ISR_SOTSYNCERR, "SOT Sync Error" },
+	{ XCSI_ISR_ECC2BERR, "2 Bit ECC Unrecoverable Error" },
+	{ XCSI_ISR_ECC1BERR, "1 Bit ECC Recoverable Error" },
+	{ XCSI_ISR_CRCERR, "CRC Error" },
+	{ XCSI_ISR_DATAIDERR, "Data Id Error" },
+	{ XCSI_ISR_VC3FSYNCERR, "Virtual Channel 3 Frame Sync Error" },
+	{ XCSI_ISR_VC3FLVLERR, "Virtual Channel 3 Frame Level Error" },
+	{ XCSI_ISR_VC2FSYNCERR, "Virtual Channel 2 Frame Sync Error" },
+	{ XCSI_ISR_VC2FLVLERR, "Virtual Channel 2 Frame Level Error" },
+	{ XCSI_ISR_VC1FSYNCERR, "Virtual Channel 1 Frame Sync Error" },
+	{ XCSI_ISR_VC1FLVLERR, "Virtual Channel 1 Frame Level Error" },
+	{ XCSI_ISR_VC0FSYNCERR, "Virtual Channel 0 Frame Sync Error" },
+	{ XCSI_ISR_VC0FLVLERR, "Virtual Channel 0 Frame Level Error" }
+};
+
+#define XCSI_NUM_EVENTS		ARRAY_SIZE(xcsi2rxss_events)
+
+/*
+ * struct xcsi2rxss_core - Core configuration CSI2 Rx Subsystem device structure
+ * @dev: Platform structure
+ * @iomem: Base address of subsystem
+ * @enable_active_lanes: If number of active lanes can be modified
+ * @max_num_lanes: Maximum number of lanes present
+ * @datatype: Data type filter
+ * @events: counter for events
+ * @vcx_events: counter for vcx_events
+ * @en_vcx: If more than 4 VC are enabled
+ * @clks: array of clocks
+ * @num_clks: number of clocks
+ * @rst_gpio: reset to video_aresetn
+ */
+struct xcsi2rxss_core {
+	struct device *dev;
+	void __iomem *iomem;
+	bool enable_active_lanes;
+	u32 max_num_lanes;
+	u32 datatype;
+	u32 events[XCSI_NUM_EVENTS];
+	u32 vcx_events[XCSI_VCX_NUM_EVENTS];
+	bool en_vcx;
+	struct clk_bulk_data *clks;
+	int num_clks;
+	struct gpio_desc *rst_gpio;
+};
+
+/**
+ * struct xcsi2rxss_state - CSI2 Rx Subsystem device structure
+ * @core: Core structure for MIPI CSI2 Rx Subsystem
+ * @subdev: The v4l2 subdev structure
+ * @format: Active V4L2 formats on each pad
+ * @default_format: Default V4L2 format
+ * @lock: mutex for accessing this structure
+ * @pads: media pads
+ * @mbus_fmts: List of media bus formats for enum_mbus_code
+ * @mbus_fmts_count: Number of media bus formats
+ * @streaming: Flag for storing streaming state
+ *
+ * This structure contains the device driver related parameters
+ */
+struct xcsi2rxss_state {
+	struct xcsi2rxss_core core;
+	struct v4l2_subdev subdev;
+	struct v4l2_mbus_framefmt format;
+	struct v4l2_mbus_framefmt default_format;
+	/* used to protect access to this struct */
+	struct mutex lock;
+	struct media_pad pads[XCSI_MEDIA_PADS];
+	u32 mbus_fmts[XCSI_MAX_MBUS_FMTS];
+	u32 mbus_fmts_count;
+	bool streaming;
+};
+
+static const struct clk_bulk_data xcsi2rxss_clks[] = {
+	{ .id = "lite_aclk" },
+	{ .id = "video_aclk" },
+};
+
+static inline struct xcsi2rxss_state *
+to_xcsi2rxssstate(struct v4l2_subdev *subdev)
+{
+	return container_of(subdev, struct xcsi2rxss_state, subdev);
+}
+
+/*
+ * Register related operations
+ */
+static inline u32 xcsi2rxss_read(struct xcsi2rxss_core *xcsi2rxss, u32 addr)
+{
+	return ioread32(xcsi2rxss->iomem + addr);
+}
+
+static inline void xcsi2rxss_write(struct xcsi2rxss_core *xcsi2rxss, u32 addr,
+				   u32 value)
+{
+	iowrite32(value, xcsi2rxss->iomem + addr);
+}
+
+static inline void xcsi2rxss_clr(struct xcsi2rxss_core *xcsi2rxss, u32 addr,
+				 u32 clr)
+{
+	xcsi2rxss_write(xcsi2rxss, addr,
+			xcsi2rxss_read(xcsi2rxss, addr) & ~clr);
+}
+
+static inline void xcsi2rxss_set(struct xcsi2rxss_core *xcsi2rxss, u32 addr,
+				 u32 set)
+{
+	xcsi2rxss_write(xcsi2rxss, addr,
+			xcsi2rxss_read(xcsi2rxss, addr) | set);
+}
+
+static void xcsi2rxss_enable(struct xcsi2rxss_core *core)
+{
+	xcsi2rxss_set(core, XCSI_CCR_OFFSET, XCSI_CCR_ENABLE);
+}
+
+static void xcsi2rxss_disable(struct xcsi2rxss_core *core)
+{
+	xcsi2rxss_clr(core, XCSI_CCR_OFFSET, XCSI_CCR_ENABLE);
+}
+
+static void xcsi2rxss_intr_enable(struct xcsi2rxss_core *core)
+{
+	xcsi2rxss_clr(core, XCSI_GIER_OFFSET, XCSI_GIER_GIE);
+	xcsi2rxss_write(core, XCSI_IER_OFFSET, XCSI_IER_INTR_MASK);
+	xcsi2rxss_set(core, XCSI_GIER_OFFSET, XCSI_GIER_GIE);
+}
+
+static void xcsi2rxss_intr_disable(struct xcsi2rxss_core *core)
+{
+	xcsi2rxss_clr(core, XCSI_IER_OFFSET, XCSI_IER_INTR_MASK);
+	xcsi2rxss_clr(core, XCSI_GIER_OFFSET, XCSI_GIER_GIE);
+}
+
+/**
+ * xcsi2rxss_reset - Does a soft reset of the MIPI CSI2 Rx Subsystem
+ * @core: Core Xilinx CSI2 Rx Subsystem structure pointer
+ *
+ * Core takes less than 100 video clock cycles to reset.
+ * So a larger timeout value is chosen for margin.
+ *
+ * Return: 0 - on success OR -ETIME if reset times out
+ */
+static int xcsi2rxss_reset(struct xcsi2rxss_core *core)
+{
+	u32 timeout = XCSI_TIMEOUT_VAL;
+
+	xcsi2rxss_set(core, XCSI_CCR_OFFSET, XCSI_CCR_SOFTRESET);
+
+	while (xcsi2rxss_read(core, XCSI_CSR_OFFSET) & XCSI_CSR_RIPCD) {
+		if (timeout == 0) {
+			dev_err(core->dev, "soft reset timed out!\n");
+			return -ETIME;
+		}
+
+		timeout--;
+		udelay(1);
+	}
+
+	xcsi2rxss_clr(core, XCSI_CCR_OFFSET, XCSI_CCR_SOFTRESET);
+	return 0;
+}
+
+static void xcsi2rxss_reset_event_counters(struct xcsi2rxss_state *state)
+{
+	unsigned int i;
+
+	for (i = 0; i < XCSI_NUM_EVENTS; i++)
+		state->core.events[i] = 0;
+
+	for (i = 0; i < XCSI_VCX_NUM_EVENTS; i++)
+		state->core.vcx_events[i] = 0;
+}
+
+/* Print event counters */
+static void xcsi2rxss_log_counters(struct xcsi2rxss_state *state)
+{
+	struct xcsi2rxss_core *core = &state->core;
+	unsigned int i;
+
+	for (i = 0; i < XCSI_NUM_EVENTS; i++) {
+		if (core->events[i] > 0) {
+			dev_info(core->dev, "%s events: %d\n",
+				 xcsi2rxss_events[i].name,
+				 core->events[i]);
+		}
+	}
+
+	if (core->en_vcx) {
+		for (i = 0; i < XCSI_VCX_NUM_EVENTS; i++) {
+			if (core->vcx_events[i] > 0) {
+				dev_info(core->dev,
+					 "VC %d Frame %s err vcx events: %d\n",
+					 (i / 2) + XCSI_VCX_START,
+					 i & 1 ? "Sync" : "Level",
+					 core->vcx_events[i]);
+			}
+		}
+	}
+}
+
+static void xcsi2rxss_log_ipconfig(struct xcsi2rxss_state *state)
+{
+	struct xcsi2rxss_core *core = &state->core;
+
+	dev_dbg(core->dev, "****** Xilinx MIPI CSI2 Rx SS IP Config ******\n");
+	dev_dbg(core->dev, "vcx is %s", core->en_vcx ? "enabled" : "disabled");
+	dev_dbg(core->dev, "Enable active lanes property is %s\n",
+		core->enable_active_lanes ? "present" : "absent");
+	dev_dbg(core->dev, "Max lanes = %d", core->max_num_lanes);
+	dev_dbg(core->dev, "Pixel format set as 0x%x\n", core->datatype);
+	dev_dbg(core->dev, "**********************************************\n");
+}
+
+/**
+ * xcsi2rxss_log_status - Logs the status of the CSI-2 Receiver
+ * @sd: Pointer to V4L2 subdevice structure
+ *
+ * This function prints the current status of Xilinx MIPI CSI-2
+ *
+ * Return: 0 on success
+ */
+static int xcsi2rxss_log_status(struct v4l2_subdev *sd)
+{
+	struct xcsi2rxss_state *xcsi2rxss = to_xcsi2rxssstate(sd);
+	struct xcsi2rxss_core *core = &xcsi2rxss->core;
+	u32 reg, data;
+	unsigned int i, max_vc;
+
+	mutex_lock(&xcsi2rxss->lock);
+
+	xcsi2rxss_log_ipconfig(xcsi2rxss);
+
+	xcsi2rxss_log_counters(xcsi2rxss);
+
+	dev_info(core->dev, "***** Core Status *****\n");
+	data = xcsi2rxss_read(core, XCSI_CSR_OFFSET);
+	dev_info(core->dev, "Short Packet FIFO Full = %s\n",
+		 XCSI_GET_BITSET_STR(data, XCSI_CSR_SPFIFOFULL));
+	dev_info(core->dev, "Short Packet FIFO Not Empty = %s\n",
+		 XCSI_GET_BITSET_STR(data, XCSI_CSR_SPFIFONE));
+	dev_info(core->dev, "Stream line buffer full = %s\n",
+		 XCSI_GET_BITSET_STR(data, XCSI_CSR_SLBF));
+	dev_info(core->dev, "Soft reset/Core disable in progress = %s\n",
+		 XCSI_GET_BITSET_STR(data, XCSI_CSR_RIPCD));
+
+	/* Clk & Lane Info  */
+	dev_info(core->dev, "******** Clock Lane Info *********\n");
+	data = xcsi2rxss_read(core, XCSI_CLKINFR_OFFSET);
+	dev_info(core->dev, "Clock Lane in Stop State = %s\n",
+		 XCSI_GET_BITSET_STR(data, XCSI_CLKINFR_STOP));
+
+	dev_info(core->dev, "******** Data Lane Info *********\n");
+	dev_info(core->dev, "Lane\tSoT Error\tSoT Sync Error\tStop State\n");
+	reg = XCSI_DLXINFR_OFFSET;
+	for (i = 0; i < XCSI_MAXDL_COUNT; i++) {
+		data = xcsi2rxss_read(core, reg);
+
+		dev_info(core->dev, "%d\t%s\t\t%s\t\t%s\n", i,
+			 XCSI_GET_BITSET_STR(data, XCSI_DLXINFR_SOTERR),
+			 XCSI_GET_BITSET_STR(data, XCSI_DLXINFR_SOTSYNCERR),
+			 XCSI_GET_BITSET_STR(data, XCSI_DLXINFR_STOP));
+
+		reg += XCSI_NEXTREG_OFFSET;
+	}
+
+	/* Virtual Channel Image Information */
+	dev_info(core->dev, "********** Virtual Channel Info ************\n");
+	dev_info(core->dev, "VC\tLine Count\tByte Count\tData Type\n");
+	if (core->en_vcx)
+		max_vc = XCSI_MAX_VCX;
+	else
+		max_vc = XCSI_MAX_VC;
+
+	reg = XCSI_VCXINF1R_OFFSET;
+	for (i = 0; i < max_vc; i++) {
+		u32 line_count, byte_count, data_type;
+
+		/* Get line and byte count from VCXINFR1 Register */
+		data = xcsi2rxss_read(core, reg);
+		byte_count = data & XCSI_VCXINF1R_BYTECOUNT;
+		line_count = data & XCSI_VCXINF1R_LINECOUNT;
+		line_count >>= XCSI_VCXINF1R_LINECOUNT_SHIFT;
+
+		/* Get data type from VCXINFR2 Register */
+		reg += XCSI_NEXTREG_OFFSET;
+		data = xcsi2rxss_read(core, reg);
+		data_type = data & XCSI_VCXINF2R_DT;
+
+		dev_info(core->dev, "%d\t%d\t\t%d\t\t0x%x\n", i, line_count,
+			 byte_count, data_type);
+
+		/* Move to next pair of VC Info registers */
+		reg += XCSI_NEXTREG_OFFSET;
+	}
+
+	mutex_unlock(&xcsi2rxss->lock);
+
+	return 0;
+}
+
+static int xcsi2rxss_start_stream(struct xcsi2rxss_state *state)
+{
+	struct xcsi2rxss_core *core = &state->core;
+	int ret = 0;
+
+	xcsi2rxss_enable(core);
+
+	ret = xcsi2rxss_reset(core);
+	if (ret < 0) {
+		state->streaming = false;
+		return ret;
+	}
+
+	xcsi2rxss_intr_enable(core);
+	state->streaming = true;
+
+	return ret;
+}
+
+static void xcsi2rxss_stop_stream(struct xcsi2rxss_state *state)
+{
+	struct xcsi2rxss_core *core = &state->core;
+
+	xcsi2rxss_intr_disable(core);
+	xcsi2rxss_disable(core);
+	state->streaming = false;
+}
+
+/**
+ * xcsi2rxss_irq_handler - Interrupt handler for CSI-2
+ * @irq: IRQ number
+ * @dev_id: Pointer to device state
+ *
+ * In the interrupt handler, a list of event counters are updated for
+ * corresponding interrupts. This is useful to get status / debug.
+ *
+ * Return: IRQ_HANDLED after handling interrupts
+ *         IRQ_NONE is no interrupts
+ */
+static irqreturn_t xcsi2rxss_irq_handler(int irq, void *dev_id)
+{
+	struct xcsi2rxss_state *state = (struct xcsi2rxss_state *)dev_id;
+	struct xcsi2rxss_core *core = &state->core;
+	u32 status;
+
+	status = xcsi2rxss_read(core, XCSI_ISR_OFFSET) & XCSI_ISR_ALLINTR_MASK;
+	dev_dbg_ratelimited(core->dev, "interrupt status = 0x%08x\n", status);
+
+	if (!status)
+		return IRQ_NONE;
+
+	/* Received a short packet */
+	if (status & XCSI_ISR_SPFIFONE) {
+		dev_dbg_ratelimited(core->dev, "Short packet = 0x%08x\n",
+				    xcsi2rxss_read(core, XCSI_SPKTR_OFFSET));
+	}
+
+	/* Short packet FIFO overflow */
+	if (status & XCSI_ISR_SPFIFOF)
+		dev_dbg_ratelimited(core->dev, "Short packet FIFO overflowed\n");
+
+	/*
+	 * Stream line buffer full
+	 * This means there is a backpressure from downstream IP
+	 */
+	if (status & XCSI_ISR_SLBF) {
+		dev_alert_ratelimited(core->dev, "Stream Line Buffer Full!\n");
+		xcsi2rxss_stop_stream(state);
+		if (core->rst_gpio) {
+			gpiod_set_value(core->rst_gpio, 1);
+			/* minimum 40 dphy_clk_200M cycles */
+			ndelay(250);
+			gpiod_set_value(core->rst_gpio, 0);
+		}
+	}
+
+	/* Increment event counters */
+	if (status & XCSI_ISR_ALLINTR_MASK) {
+		unsigned int i;
+
+		for (i = 0; i < XCSI_NUM_EVENTS; i++) {
+			if (!(status & xcsi2rxss_events[i].mask))
+				continue;
+			core->events[i]++;
+			dev_dbg_ratelimited(core->dev, "%s: %d\n",
+					    xcsi2rxss_events[i].name,
+					    core->events[i]);
+		}
+
+		if (status & XCSI_ISR_VCXFE && core->en_vcx) {
+			u32 vcxstatus;
+
+			vcxstatus = xcsi2rxss_read(core, XCSI_VCXR_OFFSET);
+			vcxstatus &= XCSI_VCXR_VCERR;
+			for (i = 0; i < XCSI_VCX_NUM_EVENTS; i++) {
+				if (!(vcxstatus & (1 << i)))
+					continue;
+				core->vcx_events[i]++;
+			}
+			xcsi2rxss_write(core, XCSI_VCXR_OFFSET, vcxstatus);
+		}
+	}
+
+	xcsi2rxss_write(core, XCSI_ISR_OFFSET, status);
+	return IRQ_HANDLED;
+}
+
+/**
+ * xcsi2rxss_s_stream - It is used to start/stop the streaming.
+ * @sd: V4L2 Sub device
+ * @enable: Flag (True / False)
+ *
+ * This function controls the start or stop of streaming for the
+ * Xilinx MIPI CSI-2 Rx Subsystem.
+ *
+ * Return: 0 on success, errors otherwise
+ */
+static int xcsi2rxss_s_stream(struct v4l2_subdev *sd, int enable)
+{
+	struct xcsi2rxss_state *xcsi2rxss = to_xcsi2rxssstate(sd);
+	int ret = 0;
+
+	mutex_lock(&xcsi2rxss->lock);
+
+	if (enable) {
+		if (!xcsi2rxss->streaming) {
+			/* reset the event counters */
+			xcsi2rxss_reset_event_counters(xcsi2rxss);
+			ret = xcsi2rxss_start_stream(xcsi2rxss);
+		}
+	} else {
+		if (xcsi2rxss->streaming) {
+			struct gpio_desc *rst = xcsi2rxss->core.rst_gpio;
+
+			xcsi2rxss_stop_stream(xcsi2rxss);
+			if (rst) {
+				gpiod_set_value_cansleep(rst, 1);
+				usleep_range(1, 2);
+				gpiod_set_value_cansleep(rst, 0);
+			}
+		}
+	}
+
+	mutex_unlock(&xcsi2rxss->lock);
+	return ret;
+}
+
+static struct v4l2_mbus_framefmt *
+__xcsi2rxss_get_pad_format(struct xcsi2rxss_state *xcsi2rxss,
+			   struct v4l2_subdev_pad_config *cfg,
+			   unsigned int pad, u32 which)
+{
+	switch (which) {
+	case V4L2_SUBDEV_FORMAT_TRY:
+		return v4l2_subdev_get_try_format(&xcsi2rxss->subdev, cfg, pad);
+	case V4L2_SUBDEV_FORMAT_ACTIVE:
+		return &xcsi2rxss->format;
+	default:
+		return NULL;
+	}
+}
+
+/**
+ * xcsi2rxss_get_format - Get the pad format
+ * @sd: Pointer to V4L2 Sub device structure
+ * @cfg: Pointer to sub device pad information structure
+ * @fmt: Pointer to pad level media bus format
+ *
+ * This function is used to get the pad format information.
+ *
+ * Return: 0 on success
+ */
+static int xcsi2rxss_get_format(struct v4l2_subdev *sd,
+				struct v4l2_subdev_pad_config *cfg,
+				struct v4l2_subdev_format *fmt)
+{
+	struct xcsi2rxss_state *xcsi2rxss = to_xcsi2rxssstate(sd);
+
+	mutex_lock(&xcsi2rxss->lock);
+	fmt->format = *__xcsi2rxss_get_pad_format(xcsi2rxss, cfg, fmt->pad,
+						  fmt->which);
+	mutex_unlock(&xcsi2rxss->lock);
+
+	return 0;
+}
+
+/**
+ * xcsi2rxss_set_format - This is used to set the pad format
+ * @sd: Pointer to V4L2 Sub device structure
+ * @cfg: Pointer to sub device pad information structure
+ * @fmt: Pointer to pad level media bus format
+ *
+ * This function is used to set the pad format. Since the pad format is fixed
+ * in hardware, it can't be modified on run time. So when a format set is
+ * requested by application, all parameters except the format type is saved
+ * for the pad and the original pad format is sent back to the application.
+ *
+ * Return: 0 on success
+ */
+static int xcsi2rxss_set_format(struct v4l2_subdev *sd,
+				struct v4l2_subdev_pad_config *cfg,
+				struct v4l2_subdev_format *fmt)
+{
+	struct xcsi2rxss_state *xcsi2rxss = to_xcsi2rxssstate(sd);
+	struct xcsi2rxss_core *core = &xcsi2rxss->core;
+	struct v4l2_mbus_framefmt *__format;
+
+	/* only sink pad format can be updated */
+	mutex_lock(&xcsi2rxss->lock);
+
+	/*
+	 * Only the format->code parameter matters for CSI as the
+	 * CSI format cannot be changed at runtime.
+	 * Ensure that format to set is copied to over to CSI pad format
+	 */
+	__format = __xcsi2rxss_get_pad_format(xcsi2rxss, cfg,
+					      fmt->pad, fmt->which);
+
+	if (fmt->pad == XVIP_PAD_SOURCE) {
+		fmt->format = *__format;
+		mutex_unlock(&xcsi2rxss->lock);
+		return 0;
+	}
+
+	/*
+	 * RAW8 is supported in all datatypes. So if requested media bus format
+	 * is of RAW8 type, then allow to be set. In case core is configured to
+	 * other RAW, YUV422 8/10 or RGB888, set appropriate media bus format.
+	 */
+	if (!((fmt->format.code == MEDIA_BUS_FMT_SBGGR8_1X8 ||
+	       fmt->format.code == MEDIA_BUS_FMT_SGBRG8_1X8 ||
+	       fmt->format.code == MEDIA_BUS_FMT_SGRBG8_1X8 ||
+	       fmt->format.code == MEDIA_BUS_FMT_SRGGB8_1X8) ||
+	      (core->datatype == XCSI_DT_RAW10 &&
+	       (fmt->format.code == MEDIA_BUS_FMT_SBGGR10_1X10 ||
+		fmt->format.code == MEDIA_BUS_FMT_SGBRG10_1X10 ||
+		fmt->format.code == MEDIA_BUS_FMT_SGRBG10_1X10 ||
+		fmt->format.code == MEDIA_BUS_FMT_SRGGB10_1X10)) ||
+	      (core->datatype == XCSI_DT_RAW12 &&
+	       (fmt->format.code == MEDIA_BUS_FMT_SBGGR12_1X12 ||
+		fmt->format.code == MEDIA_BUS_FMT_SGBRG12_1X12 ||
+		fmt->format.code == MEDIA_BUS_FMT_SGRBG12_1X12 ||
+		fmt->format.code == MEDIA_BUS_FMT_SRGGB12_1X12)) ||
+	      (core->datatype == XCSI_DT_RAW14 &&
+	       (fmt->format.code == MEDIA_BUS_FMT_SBGGR14_1X14 ||
+		fmt->format.code == MEDIA_BUS_FMT_SGBRG14_1X14 ||
+		fmt->format.code == MEDIA_BUS_FMT_SGRBG14_1X14 ||
+		fmt->format.code == MEDIA_BUS_FMT_SRGGB14_1X14)) ||
+	      (core->datatype == XCSI_DT_RAW16 &&
+	       (fmt->format.code == MEDIA_BUS_FMT_SBGGR16_1X16 ||
+		fmt->format.code == MEDIA_BUS_FMT_SGBRG16_1X16 ||
+		fmt->format.code == MEDIA_BUS_FMT_SGRBG16_1X16 ||
+		fmt->format.code == MEDIA_BUS_FMT_SRGGB16_1X16)) ||
+	      (core->datatype == XCSI_DT_YUV4228B &&
+	       fmt->format.code == MEDIA_BUS_FMT_UYVY8_1X16) ||
+	      (core->datatype == XCSI_DT_YUV42210B &&
+	       fmt->format.code == MEDIA_BUS_FMT_UYVY10_1X20) ||
+	      (core->datatype == XCSI_DT_RGB888 &&
+	       fmt->format.code == MEDIA_BUS_FMT_RBG888_1X24))) {
+		/* Restore the original pad format code */
+		dev_dbg(core->dev, "Unsupported media bus format");
+		fmt->format.code = __format->code;
+	}
+
+	*__format = fmt->format;
+	mutex_unlock(&xcsi2rxss->lock);
+
+	return 0;
+}
+
+/*
+ * xcsi2rxss_enum_mbus_code - Handle pixel format enumeration
+ * @sd : pointer to v4l2 subdev structure
+ * @cfg: V4L2 subdev pad configuration
+ * @code : pointer to v4l2_subdev_mbus_code_enum structure
+ *
+ * Return: -EINVAL or zero on success
+ */
+int xcsi2rxss_enum_mbus_code(struct v4l2_subdev *sd,
+			     struct v4l2_subdev_pad_config *cfg,
+			     struct v4l2_subdev_mbus_code_enum *code)
+{
+	struct xcsi2rxss_state *state = to_xcsi2rxssstate(sd);
+
+	if (code->index >= state->mbus_fmts_count)
+		return -EINVAL;
+
+	code->code = state->mbus_fmts[code->index];
+
+	return 0;
+}
+
+/**
+ * xcsi2rxss_open - Called on v4l2_open()
+ * @sd: Pointer to V4L2 sub device structure
+ * @fh: Pointer to V4L2 File handle
+ *
+ * This function is called on v4l2_open(). It sets the default format
+ * for both pads.
+ *
+ * Return: 0 on success
+ */
+static int xcsi2rxss_open(struct v4l2_subdev *sd,
+			  struct v4l2_subdev_fh *fh)
+{
+	struct xcsi2rxss_state *xcsi2rxss = to_xcsi2rxssstate(sd);
+	struct v4l2_mbus_framefmt *format;
+	unsigned int i;
+
+	for (i = 0; i < XCSI_MEDIA_PADS; i++) {
+		format = v4l2_subdev_get_try_format(sd, fh->pad, i);
+		*format = xcsi2rxss->default_format;
+	}
+
+	return 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * Media Operations
+ */
+
+static const struct media_entity_operations xcsi2rxss_media_ops = {
+	.link_validate = v4l2_subdev_link_validate
+};
+
+static const struct v4l2_subdev_core_ops xcsi2rxss_core_ops = {
+	.log_status = xcsi2rxss_log_status,
+};
+
+static const struct v4l2_subdev_video_ops xcsi2rxss_video_ops = {
+	.s_stream = xcsi2rxss_s_stream
+};
+
+static const struct v4l2_subdev_pad_ops xcsi2rxss_pad_ops = {
+	.get_fmt = xcsi2rxss_get_format,
+	.set_fmt = xcsi2rxss_set_format,
+	.enum_mbus_code = xcsi2rxss_enum_mbus_code,
+};
+
+static const struct v4l2_subdev_ops xcsi2rxss_ops = {
+	.core = &xcsi2rxss_core_ops,
+	.video = &xcsi2rxss_video_ops,
+	.pad = &xcsi2rxss_pad_ops
+};
+
+static const struct v4l2_subdev_internal_ops xcsi2rxss_internal_ops = {
+	.open = xcsi2rxss_open,
+};
+
+static void xcsi2rxss_set_default_format(struct xcsi2rxss_state *state)
+{
+	struct xcsi2rxss_core *core = &state->core;
+
+	memset(&state->default_format, 0, sizeof(state->default_format));
+
+	switch (core->datatype) {
+	case XCSI_DT_YUV4228B:
+		state->default_format.code = MEDIA_BUS_FMT_UYVY8_1X16;
+		break;
+	case XCSI_DT_RGB888:
+		state->default_format.code = MEDIA_BUS_FMT_RBG888_1X24;
+		break;
+	case XCSI_DT_YUV42210B:
+		state->default_format.code = MEDIA_BUS_FMT_UYVY10_1X20;
+		break;
+	case XCSI_DT_RAW10:
+		state->default_format.code = MEDIA_BUS_FMT_SRGGB10_1X10;
+		break;
+	case XCSI_DT_RAW12:
+		state->default_format.code = MEDIA_BUS_FMT_SRGGB12_1X12;
+		break;
+	case XCSI_DT_RAW14:
+		state->default_format.code = MEDIA_BUS_FMT_SRGGB14_1X14;
+		break;
+	case XCSI_DT_RAW16:
+		state->default_format.code = MEDIA_BUS_FMT_SRGGB16_1X16;
+		break;
+	case XCSI_DT_RAW8:
+	case XCSI_DT_RGB444:
+	case XCSI_DT_RGB555:
+	case XCSI_DT_RGB565:
+	case XCSI_DT_RGB666:
+		state->default_format.code = MEDIA_BUS_FMT_SRGGB8_1X8;
+		break;
+	}
+
+	state->default_format.field = V4L2_FIELD_NONE;
+	state->default_format.colorspace = V4L2_COLORSPACE_SRGB;
+	state->default_format.width = XCSI_DEFAULT_WIDTH;
+	state->default_format.height = XCSI_DEFAULT_HEIGHT;
+
+	dev_dbg(core->dev, "default mediabus format = 0x%x",
+		state->default_format.code);
+}
+
+static void xcsi2rxss_init_mbus_fmts(struct xcsi2rxss_state *state)
+{
+	struct xcsi2rxss_core *core = &state->core;
+
+	XADD_MBUS(state, MEDIA_BUS_FMT_SRGGB8_1X8);
+	XADD_MBUS(state, MEDIA_BUS_FMT_SBGGR8_1X8);
+	XADD_MBUS(state, MEDIA_BUS_FMT_SGRBG8_1X8);
+	XADD_MBUS(state, MEDIA_BUS_FMT_SGBRG8_1X8);
+
+	switch (core->datatype) {
+	case XCSI_DT_RAW10:
+		XADD_MBUS(state, MEDIA_BUS_FMT_SRGGB10_1X10);
+		XADD_MBUS(state, MEDIA_BUS_FMT_SBGGR10_1X10);
+		XADD_MBUS(state, MEDIA_BUS_FMT_SGRBG10_1X10);
+		XADD_MBUS(state, MEDIA_BUS_FMT_SGBRG10_1X10);
+		break;
+	case XCSI_DT_RAW12:
+		XADD_MBUS(state, MEDIA_BUS_FMT_SRGGB12_1X12);
+		XADD_MBUS(state, MEDIA_BUS_FMT_SBGGR12_1X12);
+		XADD_MBUS(state, MEDIA_BUS_FMT_SGRBG12_1X12);
+		XADD_MBUS(state, MEDIA_BUS_FMT_SGBRG12_1X12);
+		break;
+	case XCSI_DT_RAW14:
+		XADD_MBUS(state, MEDIA_BUS_FMT_SRGGB14_1X14);
+		XADD_MBUS(state, MEDIA_BUS_FMT_SBGGR14_1X14);
+		XADD_MBUS(state, MEDIA_BUS_FMT_SGRBG14_1X14);
+		XADD_MBUS(state, MEDIA_BUS_FMT_SGBRG14_1X14);
+		break;
+	case XCSI_DT_RAW16:
+		XADD_MBUS(state, MEDIA_BUS_FMT_SRGGB16_1X16);
+		XADD_MBUS(state, MEDIA_BUS_FMT_SBGGR16_1X16);
+		XADD_MBUS(state, MEDIA_BUS_FMT_SGRBG16_1X16);
+		XADD_MBUS(state, MEDIA_BUS_FMT_SGBRG16_1X16);
+		break;
+	case XCSI_DT_YUV4228B:
+		XADD_MBUS(state, MEDIA_BUS_FMT_UYVY8_1X16);
+		break;
+	case XCSI_DT_RGB888:
+		XADD_MBUS(state, MEDIA_BUS_FMT_RBG888_1X24);
+		break;
+	case XCSI_DT_YUV42210B:
+		XADD_MBUS(state, MEDIA_BUS_FMT_UYVY10_1X20);
+		break;
+	default:
+		dev_err(core->dev, "Invalid data type!\n");
+	}
+}
+
+static int xcsi2rxss_parse_of(struct xcsi2rxss_state *xcsi2rxss)
+{
+	struct xcsi2rxss_core *core = &xcsi2rxss->core;
+	struct device_node *node = xcsi2rxss->core.dev->of_node;
+	struct device_node *ports = NULL;
+	struct device_node *port = NULL;
+	unsigned int nports, irq;
+	bool en_csi_v20, vfb;
+	int ret;
+
+	en_csi_v20 = of_property_read_bool(node, "xlnx,en-csi-v2-0");
+	if (en_csi_v20)
+		core->en_vcx = of_property_read_bool(node, "xlnx,en-vcx");
+
+	core->enable_active_lanes =
+		of_property_read_bool(node, "xlnx,en-active-lanes");
+
+	ret = of_property_read_u32(node, "xlnx,csi-pxl-format",
+				   &core->datatype);
+	if (ret < 0) {
+		dev_err(core->dev, "missing xlnx,csi-pxl-format property\n");
+		return ret;
+	}
+
+	switch (core->datatype) {
+	case XCSI_DT_YUV4228B:
+	case XCSI_DT_RGB444:
+	case XCSI_DT_RGB555:
+	case XCSI_DT_RGB565:
+	case XCSI_DT_RGB666:
+	case XCSI_DT_RGB888:
+	case XCSI_DT_RAW6:
+	case XCSI_DT_RAW7:
+	case XCSI_DT_RAW8:
+	case XCSI_DT_RAW10:
+	case XCSI_DT_RAW12:
+	case XCSI_DT_RAW14:
+		break;
+	case XCSI_DT_YUV42210B:
+	case XCSI_DT_RAW16:
+	case XCSI_DT_RAW20:
+		if (!en_csi_v20) {
+			ret = -EINVAL;
+			dev_dbg(core->dev, "enable csi v2 for this pixel format");
+		}
+		break;
+	default:
+		ret = -EINVAL;
+	}
+	if (ret < 0) {
+		dev_err(core->dev, "invalid csi-pxl-format property!\n");
+		return ret;
+	}
+
+	vfb = of_property_read_bool(node, "xlnx,vfb");
+	if (!vfb) {
+		dev_err(core->dev, "failed as VFB is disabled!\n");
+		return -EINVAL;
+	}
+
+	ports = of_get_child_by_name(node, "ports");
+	if (!ports)
+		ports = node;
+
+	nports = 0;
+	for_each_child_of_node(ports, port) {
+		struct device_node *endpoint;
+		struct v4l2_fwnode_endpoint v4lendpoint;
+		int ret;
+
+		if (!port->name || of_node_cmp(port->name, "port"))
+			continue;
+
+		endpoint = of_get_next_child(port, NULL);
+		if (!endpoint) {
+			dev_err(core->dev, "No port at\n");
+			return -EINVAL;
+		}
+
+		/*
+		 * since first port is sink port and it contains
+		 * all info about data-lanes and cfa-pattern,
+		 * don't parse second port but only check if exists
+		 */
+		if (nports == XVIP_PAD_SOURCE) {
+			dev_dbg(core->dev, "no need to parse source port");
+			nports++;
+			of_node_put(endpoint);
+			continue;
+		}
+
+		ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(endpoint),
+						 &v4lendpoint);
+		of_node_put(endpoint);
+		if (ret)
+			return ret;
+
+		dev_dbg(core->dev, "%s : port %d bus type = %d\n",
+			__func__, nports, v4lendpoint.bus_type);
+
+		if (v4lendpoint.bus_type == V4L2_MBUS_CSI2_DPHY) {
+			dev_dbg(core->dev, "%s : base.port = %d base.id = %d\n",
+				__func__, v4lendpoint.base.port,
+				v4lendpoint.base.id);
+
+			dev_dbg(core->dev, "%s : mipi number lanes = %d\n",
+				__func__,
+				v4lendpoint.bus.mipi_csi2.num_data_lanes);
+
+			core->max_num_lanes =
+				v4lendpoint.bus.mipi_csi2.num_data_lanes;
+		}
+
+		/* Count the number of ports. */
+		nports++;
+	}
+
+	if (nports != XCSI_MEDIA_PADS) {
+		dev_err(core->dev, "invalid number of ports %u\n", nports);
+		return -EINVAL;
+	}
+
+	/* Register interrupt handler */
+	irq = irq_of_parse_and_map(node, 0);
+	ret = devm_request_irq(core->dev, irq, xcsi2rxss_irq_handler,
+			       IRQF_SHARED, "xilinx-csi2rxss", xcsi2rxss);
+	if (ret) {
+		dev_err(core->dev, "Err = %d Interrupt handler reg failed!\n",
+			ret);
+		return ret;
+	}
+
+	xcsi2rxss_log_ipconfig(xcsi2rxss);
+
+	return 0;
+}
+
+static int xcsi2rxss_probe(struct platform_device *pdev)
+{
+	struct v4l2_subdev *subdev;
+	struct xcsi2rxss_state *xcsi2rxss;
+	struct xcsi2rxss_core *core;
+	struct resource *res;
+	int ret;
+
+	xcsi2rxss = devm_kzalloc(&pdev->dev, sizeof(*xcsi2rxss), GFP_KERNEL);
+	if (!xcsi2rxss)
+		return -ENOMEM;
+
+	core = &xcsi2rxss->core;
+	core->dev = &pdev->dev;
+
+	core->clks = devm_kmemdup(core->dev, xcsi2rxss_clks,
+				  sizeof(xcsi2rxss_clks), GFP_KERNEL);
+	if (!core->clks)
+		return -ENOMEM;
+
+	/* Reset GPIO */
+	core->rst_gpio = devm_gpiod_get_optional(core->dev, "reset",
+						 GPIOD_OUT_HIGH);
+	if (IS_ERR(core->rst_gpio)) {
+		if (PTR_ERR(core->rst_gpio) != -EPROBE_DEFER)
+			dev_err(core->dev, "Video Reset GPIO not setup in DT");
+		return PTR_ERR(core->rst_gpio);
+	}
+
+	mutex_init(&xcsi2rxss->lock);
+
+	ret = xcsi2rxss_parse_of(xcsi2rxss);
+	if (ret < 0)
+		return ret;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	core->iomem = devm_ioremap_resource(core->dev, res);
+	if (IS_ERR(core->iomem))
+		return PTR_ERR(core->iomem);
+
+	core->num_clks = ARRAY_SIZE(xcsi2rxss_clks);
+
+	ret = clk_bulk_get(core->dev, core->num_clks, core->clks);
+	if (ret)
+		return ret;
+
+	ret = clk_bulk_prepare_enable(core->num_clks, core->clks);
+	if (ret)
+		goto err_clk_put;
+
+	if (core->rst_gpio) {
+		gpiod_set_value_cansleep(core->rst_gpio, 1);
+		/* minimum of 40 dphy_clk_200M cycles */
+		usleep_range(1, 2);
+		gpiod_set_value_cansleep(core->rst_gpio, 0);
+	}
+
+	xcsi2rxss_reset(core);
+
+	/* Initialize V4L2 subdevice and media entity */
+	xcsi2rxss->pads[XVIP_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
+	xcsi2rxss->pads[XVIP_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
+
+	/* Initialize the default format */
+	xcsi2rxss_set_default_format(xcsi2rxss);
+
+	/* Initialize the mbus formats supported */
+	xcsi2rxss_init_mbus_fmts(xcsi2rxss);
+
+	/* Initialize V4L2 subdevice and media entity */
+	subdev = &xcsi2rxss->subdev;
+	v4l2_subdev_init(subdev, &xcsi2rxss_ops);
+	subdev->dev = &pdev->dev;
+	subdev->internal_ops = &xcsi2rxss_internal_ops;
+	strscpy(subdev->name, dev_name(&pdev->dev), sizeof(subdev->name));
+	subdev->flags |= V4L2_SUBDEV_FL_HAS_EVENTS | V4L2_SUBDEV_FL_HAS_DEVNODE;
+	subdev->entity.ops = &xcsi2rxss_media_ops;
+	v4l2_set_subdevdata(subdev, xcsi2rxss);
+
+	ret = media_entity_pads_init(&subdev->entity, XCSI_MEDIA_PADS,
+				     xcsi2rxss->pads);
+	if (ret < 0)
+		goto error;
+
+	platform_set_drvdata(pdev, xcsi2rxss);
+
+	ret = v4l2_async_register_subdev(subdev);
+	if (ret < 0) {
+		dev_err(core->dev, "failed to register subdev\n");
+		goto error;
+	}
+
+	dev_info(core->dev, "Xilinx CSI2 Rx Subsystem device found!\n");
+
+	return 0;
+error:
+	media_entity_cleanup(&subdev->entity);
+	mutex_destroy(&xcsi2rxss->lock);
+	clk_bulk_disable_unprepare(core->num_clks, core->clks);
+err_clk_put:
+	clk_bulk_put(core->num_clks, core->clks);
+	return ret;
+}
+
+static int xcsi2rxss_remove(struct platform_device *pdev)
+{
+	struct xcsi2rxss_state *xcsi2rxss = platform_get_drvdata(pdev);
+	struct xcsi2rxss_core *core = &xcsi2rxss->core;
+	struct v4l2_subdev *subdev = &xcsi2rxss->subdev;
+
+	v4l2_async_unregister_subdev(subdev);
+	media_entity_cleanup(&subdev->entity);
+	mutex_destroy(&xcsi2rxss->lock);
+	clk_bulk_disable_unprepare(core->num_clks, core->clks);
+	clk_bulk_put(core->num_clks, core->clks);
+
+	return 0;
+}
+
+static const struct of_device_id xcsi2rxss_of_id_table[] = {
+	{ .compatible = "xlnx,mipi-csi2-rx-subsystem-4.0", },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, xcsi2rxss_of_id_table);
+
+static struct platform_driver xcsi2rxss_driver = {
+	.driver = {
+		.name		= "xilinx-csi2rxss",
+		.of_match_table	= xcsi2rxss_of_id_table,
+	},
+	.probe			= xcsi2rxss_probe,
+	.remove			= xcsi2rxss_remove,
+};
+
+module_platform_driver(xcsi2rxss_driver);
+
+MODULE_AUTHOR("Vishal Sagar <vsagar@xilinx.com>");
+MODULE_DESCRIPTION("Xilinx MIPI CSI2 Rx Subsystem Driver");
+MODULE_LICENSE("GPL v2");
-- 
2.21.0

^ permalink raw reply related

* [PATCH v10 1/2] media: dt-bindings: media: xilinx: Add Xilinx MIPI CSI-2 Rx Subsystem
From: Vishal Sagar @ 2019-07-11  9:16 UTC (permalink / raw)
  To: Hyun Kwon, laurent.pinchart, mchehab, robh+dt, mark.rutland,
	Michal Simek, linux-media, devicetree, hans.verkuil,
	linux-arm-kernel, linux-kernel, Dinesh Kumar, Sandip Kothari,
	Luca Ceresoli, Jacopo Mondi
  Cc: Vishal Sagar, Hyun Kwon, Rob Herring
In-Reply-To: <20190711091612.98175-1-vishal.sagar@xilinx.com>

Add bindings documentation for Xilinx MIPI CSI-2 Rx Subsystem.

The Xilinx MIPI CSI-2 Rx Subsystem consists of a CSI-2 Rx controller, a
DPHY in Rx mode, an optional I2C controller and a Video Format Bridge.

Signed-off-by: Vishal Sagar <vishal.sagar@xilinx.com>
Reviewed-by: Hyun Kwon <hyun.kwon@xilinx.com>
Reviewed-by: Rob Herring <robh@kernel.org>
Reviewed-by: Luca Ceresoli <luca@lucaceresoli.net>
---
v10
- No changes

v9
- Fix xlnx,vfb description.
- s/Optional/Required endpoint property.
- Move data-lanes description from Ports to endpoint property section.

v8
- Added reset-gpios optional property to assert video_aresetn

v7
- Removed the control name from dt bindings
- Updated the example dt node name to csi2rx

v6
- Added "control" after V4L2_CID_XILINX_MIPICSISS_ACT_LANES as suggested by Luca
- Added reviewed by Rob Herring

v5
- Incorporated comments by Luca Cersoli
- Removed DPHY clock from description and example
- Removed bayer pattern from device tree MIPI CSI IP
  doesn't deal with bayer pattern.

v4
- Added reviewed by Hyun Kwon

v3
- removed interrupt parent as suggested by Rob
- removed dphy clock
- moved vfb to optional properties
- Added required and optional port properties section
- Added endpoint property section

v2
- updated the compatible string to latest version supported
- removed DPHY related parameters
- added CSI v2.0 related property (including VCX for supporting upto 16
  virtual channels).
- modified csi-pxl-format from string to unsigned int type where the value
  is as per the CSI specification
- Defined port 0 and port 1 as sink and source ports.
- Removed max-lanes property as suggested by Rob and Sakari
 .../bindings/media/xilinx/xlnx,csi2rxss.txt   | 116 ++++++++++++++++++
 1 file changed, 116 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/media/xilinx/xlnx,csi2rxss.txt

diff --git a/Documentation/devicetree/bindings/media/xilinx/xlnx,csi2rxss.txt b/Documentation/devicetree/bindings/media/xilinx/xlnx,csi2rxss.txt
new file mode 100644
index 000000000000..913b28d543c8
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/xilinx/xlnx,csi2rxss.txt
@@ -0,0 +1,116 @@
+Xilinx MIPI CSI2 Receiver Subsystem Device Tree Bindings
+--------------------------------------------------------
+
+The Xilinx MIPI CSI2 Receiver Subsystem is used to capture MIPI CSI2 traffic
+from compliant camera sensors and send the output as AXI4 Stream video data
+for image processing.
+
+The subsystem consists of a MIPI DPHY in slave mode which captures the
+data packets. This is passed along the MIPI CSI2 Rx IP which extracts the
+packet data. The optional Video Format Bridge (VFB) converts this data to
+AXI4 Stream video data.
+
+For more details, please refer to PG232 Xilinx MIPI CSI-2 Receiver Subsystem.
+
+Required properties:
+--------------------
+- compatible: Must contain "xlnx,mipi-csi2-rx-subsystem-4.0".
+- reg: Physical base address and length of the registers set for the device.
+- interrupts: Property with a value describing the interrupt number.
+- clocks: List of phandles to AXI Lite and Video clocks.
+- clock-names: Must contain "lite_aclk" and "video_aclk" in the same order
+  as clocks listed in clocks property.
+- xlnx,csi-pxl-format: This denotes the CSI Data type selected in hw design.
+  Packets other than this data type (except for RAW8 and User defined data
+  types) will be filtered out. Possible values are as below -
+  0x1E - YUV4228B
+  0x1F - YUV42210B
+  0x20 - RGB444
+  0x21 - RGB555
+  0x22 - RGB565
+  0x23 - RGB666
+  0x24 - RGB888
+  0x28 - RAW6
+  0x29 - RAW7
+  0x2A - RAW8
+  0x2B - RAW10
+  0x2C - RAW12
+  0x2D - RAW14
+  0x2E - RAW16
+  0x2F - RAW20
+
+
+Optional properties:
+--------------------
+- xlnx,vfb: Present when Video Format Bridge is enabled in IP configuration
+- xlnx,en-csi-v2-0: Present if CSI v2 is enabled in IP configuration.
+- xlnx,en-vcx: When present, there are maximum 16 virtual channels, else
+  only 4. This is present only if xlnx,en-csi-v2-0 is present.
+- xlnx,en-active-lanes: present if the number of active lanes can be
+  re-configured at runtime in the Protocol Configuration Register.
+  Otherwise all lanes, as set in IP configuration, are always active.
+- reset-gpios: Optional specifier for a GPIO that asserts video_aresetn.
+
+Ports
+-----
+The device node shall contain two 'port' child nodes as defined in
+Documentation/devicetree/bindings/media/video-interfaces.txt.
+
+The port@0 is a sink port and shall connect to CSI2 source like camera.
+
+The port@1 is a source port and can be connected to any video processing IP
+which can work with AXI4 Stream data.
+
+Required port properties:
+--------------------
+- reg: 0 - for sink port.
+       1 - for source port.
+
+Required endpoint property:
+---------------------------
+- data-lanes: specifies MIPI CSI-2 data lanes as covered in video-interfaces.txt.
+  This is required only in the sink port 0 endpoint which connects to MIPI CSI2
+  source like sensor. The possible values are:
+  1       - For 1 lane enabled in IP.
+  1 2     - For 2 lanes enabled in IP.
+  1 2 3   - For 3 lanes enabled in IP.
+  1 2 3 4 - For 4 lanes enabled in IP.
+
+Example:
+
+	xcsi2rxss_1: csi2rx@a0020000 {
+		compatible = "xlnx,mipi-csi2-rx-subsystem-4.0";
+		reg = <0x0 0xa0020000 0x0 0x10000>;
+		interrupt-parent = <&gic>;
+		interrupts = <0 95 4>;
+		xlnx,csi-pxl-format = <0x2a>;
+		xlnx,vfb;
+		xlnx,en-active-lanes;
+		xlnx,en-csi-v2-0;
+		xlnx,en-vcx;
+		clock-names = "lite_aclk", "video_aclk";
+		clocks = <&misc_clk_0>, <&misc_clk_1>;
+		reset-gpios = <&gpio 86 GPIO_ACTIVE_LOW>;
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port@0 {
+				/* Sink port */
+				reg = <0>;
+				csiss_in: endpoint {
+					data-lanes = <1 2 3 4>;
+					/* MIPI CSI2 Camera handle */
+					remote-endpoint = <&camera_out>;
+				};
+			};
+			port@1 {
+				/* Source port */
+				reg = <1>;
+				csiss_out: endpoint {
+					remote-endpoint = <&vproc_in>;
+				};
+			};
+		};
+	};
-- 
2.21.0

^ permalink raw reply related

* [PATCH v10 0/2] Add support for Xilinx CSI2 Receiver Subsystem
From: Vishal Sagar @ 2019-07-11  9:16 UTC (permalink / raw)
  To: Hyun Kwon, laurent.pinchart, mchehab, robh+dt, mark.rutland,
	Michal Simek, linux-media, devicetree, hans.verkuil,
	linux-arm-kernel, linux-kernel, Dinesh Kumar, Sandip Kothari,
	Luca Ceresoli, Jacopo Mondi
  Cc: Vishal Sagar

Xilinx MIPI CSI-2 Receiver Subsystem
------------------------------------

The Xilinx MIPI CSI-2 Receiver Subsystem Soft IP consists of a DPHY which
gets the data, an optional I2C, a CSI-2 Receiver which parses the data and
converts it into AXIS data.
This stream output maybe connected to a Xilinx Video Format Bridge.
The maximum number of lanes supported is fixed in the design.

The pixel format set in design acts as a filter allowing only the selected
data type or RAW8 data packets. The D-PHY register access can be gated in
the design. The base address of the DPHY depends on whether the internal
Xilinx I2C controller is enabled or not in design.

The device driver registers the MIPI CSI2 Rx Subsystem as a V4L2 sub device
having 2 pads. The sink pad is connected to the MIPI camera sensor and
output pad is connected to the video node.
Refer to xlnx,csi2rxss.txt for device tree node details.

This driver helps enable the core, setting and handling interrupts.
It logs the number of events occurring according to their type between
streaming ON and OFF.

The Xilinx CSI-2 Rx Subsystem outputs an AXI4 Stream data which can be
used for image processing. This data follows the video formats mentioned
in Xilinx UG934 when the Video Format Bridge is enabled.

v10
- 1/2
  - No changes
- 2/2
  - Removed all V4L2 controls and events.
  - Now stop_stream() before toggling rst_gpio
  - Updated init_mbus() to throw error on array out of bound access
  - Added XADD_MBUS macro
  - Make events and vcx_events as counters instead of structures
  - Minor fixes in set_format() enum_mbus_code() as suggested by Sakari

v9
- 1/2
  - Fix xlnx,vfb description.
  - s/Optional/Required endpoint property.
  - Move data-lanes description from Ports to endpoint property section.
- 2/2
  - Moved all controls and events to xilinx-csi2rxss.h
  - Updated name and description of controls and events
  - Get control base address from v4l2-controls.h (0x10c0)
  - Fix KConfig for dependency on VIDEO_XILINX
  - Added enum_mbus_code() support
  - Added default format to be returned on open()
  - Mark variables are const
  - Remove references to short packet in comments
  - Add check for streaming before setting active lanes control
  - strlcpy -> strscpy
  - Fix xcsi2rxss_set_format()

v8
- 1/2
  - Added reset-gpios optional property
- 2/2
  - Use clk_bulk* APIs
  - Add gpio reset for asserting video_aresetn when stream line buffer occurs
  - Removed short packet related events and irq handling
    - V4L2_EVENT_XLNXCSIRX_SPKT and V4L2_EVENT_XLNXCSIRX_SPKT_OVF removed
  - Removed frame counter control V4L2_CID_XILINX_MIPICSISS_FRAME_COUNTER
    and xcsi2rxss_g_volatile_ctrl()
  - Minor formatting fixes

v7
- 1/2
  - Removed the name of control from en-active-lanes as suggested by Sakari
  - Updated the dt node name to csi2rx
- 2/2
  - No change

v6
- 1/2
  - Added minor comment by Luca
  - Added Reviewed by Rob Herring
- 2/2
  - No change

v5
- 1/2
  - Removed the DPHY clock description and dt node.
  - removed bayer pattern as CSI doesn't deal with it.
- 2/2
  - removed bayer pattern as CSI doesn't deal with it.
  - add YUV422 10bpc media bus format.

v4
- 1/2
  - Added reviewed by Hyun Kwon
- 2/2
  - Removed irq member from core structure
  - Consolidated IP config prints in xcsi2rxss_log_ipconfig()
  - Return -EINVAL in case of invalid ioctl
  - Code formatting
  - Added reviewed by Hyun Kwon

v3
- 1/2
  - removed interrupt parent as suggested by Rob
  - removed dphy clock
  - moved vfb to optional properties
  - Added required and optional port properties section
  - Added endpoint property section
- 2/2
 - Fixed comments given by Hyun.
 - Removed DPHY 200 MHz clock. This will be controlled by DPHY driver
 - Minor code formatting
 - en_csi_v20 and vfb members removed from struct and made local to dt parsing
 - lock description updated
 - changed to ratelimited type for all dev prints in irq handler
 - Removed YUV 422 10bpc media format

v2
- 1/2
  - updated the compatible string to latest version supported
  - removed DPHY related parameters
  - added CSI v2.0 related property (including VCX for supporting upto 16
    virtual channels).
  - modified csi-pxl-format from string to unsigned int type where the value
    is as per the CSI specification
  - Defined port 0 and port 1 as sink and source ports.
  - Removed max-lanes property as suggested by Rob and Sakari

- 2/2
  - Fixed comments given by Hyun and Sakari.
  - Made all bitmask using BIT() and GENMASK()
  - Removed unused definitions
  - Removed DPHY access. This will be done by separate DPHY PHY driver.
  - Added support for CSI v2.0 for YUV 422 10bpc, RAW16, RAW20 and extra
    virtual channels
  - Fixed the ports as sink and source
  - Now use the v4l2fwnode API to get number of data-lanes
  - Added clock framework support
  - Removed the close() function
  - updated the set format function
  - Support only VFB enabled config

Vishal Sagar (2):
  media: dt-bindings: media: xilinx: Add Xilinx MIPI CSI-2 Rx Subsystem
  media: v4l: xilinx: Add Xilinx MIPI CSI-2 Rx Subsystem driver

 .../bindings/media/xilinx/xlnx,csi2rxss.txt   |  116 ++
 drivers/media/platform/xilinx/Kconfig         |   11 +
 drivers/media/platform/xilinx/Makefile        |    1 +
 .../media/platform/xilinx/xilinx-csi2rxss.c   | 1230 +++++++++++++++++
 4 files changed, 1358 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/media/xilinx/xlnx,csi2rxss.txt
 create mode 100644 drivers/media/platform/xilinx/xilinx-csi2rxss.c

-- 
2.21.0

^ permalink raw reply

* RE: [PATCH v9 2/2] media: v4l: xilinx: Add Xilinx MIPI CSI-2 Rx Subsystem driver
From: Vishal Sagar @ 2019-07-11  9:09 UTC (permalink / raw)
  To: Sakari Ailus, Vishal Sagar
  Cc: mark.rutland@arm.com, devicetree@vger.kernel.org, Jacopo Mondi,
	Dinesh Kumar, Hyun Kwon, Sandip Kothari,
	linux-kernel@vger.kernel.org, robh+dt@kernel.org, Michal Simek,
	laurent.pinchart@ideasonboard.com, Luca Ceresoli,
	hans.verkuil@cisco.com, mchehab@kernel.org,
	linux-arm-kernel@lists.infradead.org, linux-media@vger.kernel.org
In-Reply-To: <20190618151933.zqepfqdjjjlhea7h@valkosipuli.retiisi.org.uk>

Hi Sakari,

Thanks for reviewing.

> -----Original Message-----
> From: Sakari Ailus [mailto:sakari.ailus@iki.fi]
> Sent: Tuesday, June 18, 2019 8:50 PM
> To: Vishal Sagar <vishal.sagar@xilinx.com>
> Cc: Hyun Kwon <hyunk@xilinx.com>; laurent.pinchart@ideasonboard.com;
> mchehab@kernel.org; robh+dt@kernel.org; mark.rutland@arm.com; Michal
> Simek <michals@xilinx.com>; linux-media@vger.kernel.org;
> devicetree@vger.kernel.org; hans.verkuil@cisco.com; linux-arm-
> kernel@lists.infradead.org; linux-kernel@vger.kernel.org; Dinesh Kumar
> <dineshk@xilinx.com>; Sandip Kothari <sandipk@xilinx.com>; Luca Ceresoli
> <luca@lucaceresoli.net>; Jacopo Mondi <jacopo@jmondi.org>
> Subject: Re: [PATCH v9 2/2] media: v4l: xilinx: Add Xilinx MIPI CSI-2 Rx
> Subsystem driver
> 
> EXTERNAL EMAIL
> 
> Hi Vishal,
> 
> On Tue, Jun 11, 2019 at 03:40:09PM +0530, Vishal Sagar wrote:
> > The Xilinx MIPI CSI-2 Rx Subsystem soft IP is used to capture images
> > from MIPI CSI-2 camera sensors and output AXI4-Stream video data ready
> > for image processing. Please refer to PG232 for details.
> >
> > The driver is used to set the number of active lanes, if enabled
> > in hardware. The CSI2 Rx controller filters out all packets except for
> > the packets with data type fixed in hardware. RAW8 packets are always
> > allowed to pass through.
> >
> > It is also used to setup and handle interrupts and enable the core. It
> > logs all the events in respective counters between streaming on and off.
> >
> > The driver supports only the video format bridge enabled configuration.
> > Some data types like YUV 422 10bpc, RAW16, RAW20 are supported when
> the
> > CSI v2.0 feature is enabled in design. When the VCX feature is enabled,
> > the maximum number of virtual channels becomes 16 from 4.
> >
> > Signed-off-by: Vishal Sagar <vishal.sagar@xilinx.com>
> > Reviewed-by: Hyun Kwon <hyun.kwon@xilinx.com>
> > ---
> > v9
> > - Moved all controls and events to xilinx-csi2rxss.h
> > - Updated name and description of controls and events
> > - Get control base address from v4l2-controls.h (0x10c0)
> > - Fix KConfig for dependency on VIDEO_XILINX
> > - Added enum_mbus_code() support
> > - Added default format to be returned on open()
> > - Mark variables are const
> > - Remove references to short packet in comments
> > - Add check for streaming before setting active lanes control
> > - strlcpy -> strscpy
> > - Fix xcsi2rxss_set_format()
> >
> > v8
> > - Use clk_bulk* APIs
> > - Add gpio reset for asserting video_aresetn when stream line buffer occurs
> > - Removed short packet related events and irq handling
> >   - V4L2_EVENT_XLNXCSIRX_SPKT and V4L2_EVENT_XLNXCSIRX_SPKT_OVF
> removed
> > - Removed frame counter control
> V4L2_CID_XILINX_MIPICSISS_FRAME_COUNTER
> >   and xcsi2rxss_g_volatile_ctrl()
> > - Minor formatting fixes
> >
> > v7
> > - No change
> >
> > v6
> > - No change
> >
> > v5
> > - Removed bayer and updated related parts like set default format based
> >   on Luca Cersoli's comments.
> > - Added correct YUV422 10bpc media bus format
> >
> > v4
> > - Removed irq member from core structure
> > - Consolidated IP config prints in xcsi2rxss_log_ipconfig()
> > - Return -EINVAL in case of invalid ioctl
> > - Code formatting
> > - Added reviewed by Hyun Kwon
> >
> > v3
> > - Fixed comments given by Hyun.
> > - Removed DPHY 200 MHz clock. This will be controlled by DPHY driver
> > - Minor code formatting
> > - en_csi_v20 and vfb members removed from struct and made local to dt
> parsing
> > - lock description updated
> > - changed to ratelimited type for all dev prints in irq handler
> > - Removed YUV 422 10bpc media format
> >
> > v2
> > - Fixed comments given by Hyun and Sakari.
> > - Made all bitmask using BIT() and GENMASK()
> > - Removed unused definitions
> > - Removed DPHY access. This will be done by separate DPHY PHY driver.
> > - Added support for CSI v2.0 for YUV 422 10bpc, RAW16, RAW20 and extra
> >   virtual channels
> > - Fixed the ports as sink and source
> > - Now use the v4l2fwnode API to get number of data-lanes
> > - Added clock framework support
> > - Removed the close() function
> > - updated the set format function
> > - support only VFB enabled configuration
> >
> >  drivers/media/platform/xilinx/Kconfig           |   11 +
> >  drivers/media/platform/xilinx/Makefile          |    1 +
> >  drivers/media/platform/xilinx/xilinx-csi2rxss.c | 1488
> +++++++++++++++++++++++
> >  include/uapi/linux/v4l2-controls.h              |    4 +
> >  include/uapi/linux/xilinx-csi2rxss.h            |   52 +
> >  5 files changed, 1556 insertions(+)
> >  create mode 100644 drivers/media/platform/xilinx/xilinx-csi2rxss.c
> >  create mode 100644 include/uapi/linux/xilinx-csi2rxss.h
> >
> > diff --git a/drivers/media/platform/xilinx/Kconfig
> b/drivers/media/platform/xilinx/Kconfig
> > index a2773ad..349da87 100644
> > --- a/drivers/media/platform/xilinx/Kconfig
> > +++ b/drivers/media/platform/xilinx/Kconfig
> > @@ -10,6 +10,17 @@ config VIDEO_XILINX
> >
> >  if VIDEO_XILINX
> >
> > +config VIDEO_XILINX_CSI2RXSS
> > +     tristate "Xilinx CSI2 Rx Subsystem"
> > +     depends on VIDEO_XILINX
> > +     help
> > +       Driver for Xilinx MIPI CSI2 Rx Subsystem. This is a V4L sub-device
> > +       based driver that takes input from CSI2 Tx source and converts
> > +       it into an AXI4-Stream. The subsystem comprises of a CSI2 Rx
> > +       controller, DPHY, an optional I2C controller and a Video Format
> > +       Bridge. The driver is used to set the number of active lanes and
> > +       get short packet data.
> > +
> >  config VIDEO_XILINX_TPG
> >       tristate "Xilinx Video Test Pattern Generator"
> >       depends on VIDEO_XILINX
> > diff --git a/drivers/media/platform/xilinx/Makefile
> b/drivers/media/platform/xilinx/Makefile
> > index 4cdc0b1..6119a34 100644
> > --- a/drivers/media/platform/xilinx/Makefile
> > +++ b/drivers/media/platform/xilinx/Makefile
> > @@ -3,5 +3,6 @@
> >  xilinx-video-objs += xilinx-dma.o xilinx-vip.o xilinx-vipp.o
> >
> >  obj-$(CONFIG_VIDEO_XILINX) += xilinx-video.o
> > +obj-$(CONFIG_VIDEO_XILINX_CSI2RXSS) += xilinx-csi2rxss.o
> >  obj-$(CONFIG_VIDEO_XILINX_TPG) += xilinx-tpg.o
> >  obj-$(CONFIG_VIDEO_XILINX_VTC) += xilinx-vtc.o
> > diff --git a/drivers/media/platform/xilinx/xilinx-csi2rxss.c
> b/drivers/media/platform/xilinx/xilinx-csi2rxss.c
> > new file mode 100644
> > index 0000000..373d91f
> > --- /dev/null
> > +++ b/drivers/media/platform/xilinx/xilinx-csi2rxss.c
> > @@ -0,0 +1,1488 @@
> > +// SPDX-License-Identifier: GPL-2.0+
> > +/*
> > + * Driver for Xilinx MIPI CSI2 Rx Subsystem
> > + *
> > + * Copyright (C) 2016 - 2019 Xilinx, Inc.
> > + *
> > + * Contacts: Vishal Sagar <vishal.sagar@xilinx.com>
> > + *
> > + */

<snip>

> > +/**
> > + * struct xcsi2rxss_event - Event log structure
> > + * @mask: Event mask
> > + * @name: Name of the event
> > + * @counter: Count number of events
> > + */
> > +struct xcsi2rxss_event {
> > +     u32 mask;
> > +     const char *name;
> > +     unsigned int counter;
> 
> You can now omit the counter field that is not used anymore. The counter
> should be a separate integer array.
>

Agreed. I will make the counters into separate integer array.
 
> > +};
> > +
> > +/*
> > + * struct xcsi2rxss_core - Core configuration CSI2 Rx Subsystem device
> structure
> > + * @dev: Platform structure
> > + * @iomem: Base address of subsystem
> > + * @enable_active_lanes: If number of active lanes can be modified
> > + * @max_num_lanes: Maximum number of lanes present
> > + * @datatype: Data type filter
> > + * @events: Structure to maintain event logs
> > + * @vcx_events: Structure to maintain VCX event logs
> > + * @en_vcx: If more than 4 VC are enabled
> > + * @clks: array of clocks
> > + * @num_clks: number of clocks
> > + * @rst_gpio: reset to video_aresetn
> > + */

<snip>

> > +
> > +/* Print event counters */
> > +static void xcsi2rxss_log_counters(struct xcsi2rxss_state *state)
> > +{
> > +     struct xcsi2rxss_core *core = &state->core;
> > +     int i;
> 
> unsigned int
>

Noted. Will fix in next version.
 
> > +
> > +     for (i = 0; i < XCSI_NUM_EVENTS; i++) {
> > +             if (core->events[i].counter > 0) {
> > +                     dev_info(core->dev, "%s events: %d\n",
> > +                              core->events[i].name,
> > +                              core->events[i].counter);
> > +             }
> > +     }
> > +
> > +     if (core->en_vcx) {
> > +             for (i = 0; i < XCSI_VCX_NUM_EVENTS; i++) {
> > +                     if (core->vcx_events[i].counter > 0) {
> > +                             dev_info(core->dev,
> > +                                      "VC %d Frame %s err vcx events: %d\n",
> > +                                      (i / 2) + XCSI_VCX_START,
> > +                                      i & 1 ? "Sync" : "Level",
> > +                                      core->vcx_events[i].counter);
> > +                     }
> > +             }
> > +     }
> > +}
> > +
> > +static void xcsi2rxss_log_ipconfig(struct xcsi2rxss_state *state)
> > +{
> > +     struct xcsi2rxss_core *core = &state->core;
> > +
> > +     dev_dbg(core->dev, "****** Xilinx MIPI CSI2 Rx SS IP Config ******\n");
> > +     dev_dbg(core->dev, "vcx is %s", core->en_vcx ? "enabled" : "disabled");
> > +     dev_dbg(core->dev, "Enable active lanes property is %s\n",
> > +             core->enable_active_lanes ? "present" : "absent");
> > +     dev_dbg(core->dev, "Max lanes = %d", core->max_num_lanes);
> > +     dev_dbg(core->dev, "Pixel format set as 0x%x\n", core->datatype);
> > +     dev_dbg(core->dev,
> "**********************************************\n");
> > +}
> > +
> > +/**
> > + * xcsi2rxss_log_status - Logs the status of the CSI-2 Receiver
> > + * @sd: Pointer to V4L2 subdevice structure
> > + *
> > + * This function prints the current status of Xilinx MIPI CSI-2
> > + *
> > + * Return: 0 on success
> > + */
> > +static int xcsi2rxss_log_status(struct v4l2_subdev *sd)
> > +{
> > +     struct xcsi2rxss_state *xcsi2rxss = to_xcsi2rxssstate(sd);
> > +     struct xcsi2rxss_core *core = &xcsi2rxss->core;
> > +     unsigned int reg, data, i, max_vc;
> 
> Please use u32 for 32-bit register values.
> 

Noted. Will fix in next version.

> > +
> > +     mutex_lock(&xcsi2rxss->lock);
> > +
> > +     xcsi2rxss_log_ipconfig(xcsi2rxss);
> > +
> > +     xcsi2rxss_log_counters(xcsi2rxss);
> > +
> > +     dev_info(core->dev, "***** Core Status *****\n");
> > +     data = xcsi2rxss_read(core, XCSI_CSR_OFFSET);
> > +     dev_info(core->dev, "Short Packet FIFO Full = %s\n",
> > +              XCSI_GET_BITSET_STR(data, XCSI_CSR_SPFIFOFULL));
> > +     dev_info(core->dev, "Short Packet FIFO Not Empty = %s\n",
> > +              XCSI_GET_BITSET_STR(data, XCSI_CSR_SPFIFONE));
> > +     dev_info(core->dev, "Stream line buffer full = %s\n",
> > +              XCSI_GET_BITSET_STR(data, XCSI_CSR_SLBF));
> > +     dev_info(core->dev, "Soft reset/Core disable in progress = %s\n",
> > +              XCSI_GET_BITSET_STR(data, XCSI_CSR_RIPCD));
> > +
> > +     /* Clk & Lane Info  */
> > +     dev_info(core->dev, "******** Clock Lane Info *********\n");
> > +     data = xcsi2rxss_read(core, XCSI_CLKINFR_OFFSET);
> > +     dev_info(core->dev, "Clock Lane in Stop State = %s\n",
> > +              XCSI_GET_BITSET_STR(data, XCSI_CLKINFR_STOP));
> > +
> > +     dev_info(core->dev, "******** Data Lane Info *********\n");
> > +     dev_info(core->dev, "Lane\tSoT Error\tSoT Sync Error\tStop State\n");
> > +     reg = XCSI_DLXINFR_OFFSET;
> > +     for (i = 0; i < XCSI_MAXDL_COUNT; i++) {
> > +             data = xcsi2rxss_read(core, reg);
> > +
> > +             dev_info(core->dev, "%d\t%s\t\t%s\t\t%s\n", i,
> > +                      XCSI_GET_BITSET_STR(data, XCSI_DLXINFR_SOTERR),
> > +                      XCSI_GET_BITSET_STR(data, XCSI_DLXINFR_SOTSYNCERR),
> > +                      XCSI_GET_BITSET_STR(data, XCSI_DLXINFR_STOP));
> > +
> > +             reg += XCSI_NEXTREG_OFFSET;
> > +     }
> > +
> > +     /* Virtual Channel Image Information */
> > +     dev_info(core->dev, "********** Virtual Channel Info
> ************\n");
> > +     dev_info(core->dev, "VC\tLine Count\tByte Count\tData Type\n");
> > +     if (core->en_vcx)
> > +             max_vc = XCSI_MAX_VCX;
> > +     else
> > +             max_vc = XCSI_MAX_VC;
> > +
> > +     reg = XCSI_VCXINF1R_OFFSET;
> > +     for (i = 0; i < max_vc; i++) {
> > +             u32 line_count, byte_count, data_type;
> > +
> > +             /* Get line and byte count from VCXINFR1 Register */
> > +             data = xcsi2rxss_read(core, reg);
> > +             byte_count = data & XCSI_VCXINF1R_BYTECOUNT;
> > +             line_count = data & XCSI_VCXINF1R_LINECOUNT;
> > +             line_count >>= XCSI_VCXINF1R_LINECOUNT_SHIFT;
> > +
> > +             /* Get data type from VCXINFR2 Register */
> > +             reg += XCSI_NEXTREG_OFFSET;
> > +             data = xcsi2rxss_read(core, reg);
> > +             data_type = data & XCSI_VCXINF2R_DT;
> > +
> > +             dev_info(core->dev, "%d\t%d\t\t%d\t\t0x%x\n", i, line_count,
> > +                      byte_count, data_type);
> > +
> > +             /* Move to next pair of VC Info registers */
> > +             reg += XCSI_NEXTREG_OFFSET;
> > +     }
> > +
> > +     mutex_unlock(&xcsi2rxss->lock);
> > +
> > +     return 0;
> > +}
> > +
> > +/*
> > + * xcsi2rxss_subscribe_event - Subscribe to custom events
> > + * receive event.
> > + * @sd: V4L2 Sub device
> > + * @fh: V4L2 File Handle
> > + * @sub: Subcribe event structure
> > + *
> > + * The driver generates a line buffer full event which the application may
> > + * subscribe to. On getting this event, application may stop streaming and
> > + * intimate user that something is incorrect in downstream pipeline which
> > + * is causing this event.
> > + *
> > + * Return: 0 on success, errors otherwise
> > + */
> > +static int xcsi2rxss_subscribe_event(struct v4l2_subdev *sd,
> > +                                  struct v4l2_fh *fh,
> > +                                  struct v4l2_event_subscription *sub)
> > +{
> > +     struct xcsi2rxss_state *xcsi2rxss = to_xcsi2rxssstate(sd);
> > +     int ret;
> > +
> > +     mutex_lock(&xcsi2rxss->lock);
> > +
> > +     switch (sub->type) {
> > +     case V4L2_EVENT_XILINX_CSI2RX_SLBF:
> > +             ret = v4l2_event_subscribe(fh, sub, XCSI_MAX_EVENT, NULL);
> 
> Please either use dev_dbg() or propose an API for conveying this
> information downstream in the pipeline.
> 

I will use a dev_alert() in the irq handler for this for now and remove this event.

> > +             break;
> > +     default:
> > +             ret = -EINVAL;
> > +     }
> > +
> > +     mutex_unlock(&xcsi2rxss->lock);
> > +
> > +     return ret;
> > +}
> > +
> > +/**
> > + * xcsi2rxss_unsubscribe_event - Unsubscribe from all events registered
> > + * @sd: V4L2 Sub device
> > + * @fh: V4L2 file handle
> > + * @sub: pointer to Event unsubscription structure
> > + *
> > + * Return: zero on success, else a negative error code.
> > + */
> > +static int xcsi2rxss_unsubscribe_event(struct v4l2_subdev *sd,
> > +                                    struct v4l2_fh *fh,
> > +                                    struct v4l2_event_subscription *sub)
> > +{
> > +     struct xcsi2rxss_state *xcsi2rxss = to_xcsi2rxssstate(sd);
> > +     int ret;
> > +
> > +     mutex_lock(&xcsi2rxss->lock);
> > +     ret = v4l2_event_unsubscribe(fh, sub);
> > +     mutex_unlock(&xcsi2rxss->lock);
> > +
> > +     return ret;
> > +}
> > +
> > +/**
> > + * xcsi2rxss_s_ctrl - This is used to set the Xilinx MIPI CSI-2 V4L2 controls
> > + * @ctrl: V4L2 control to be set
> > + *
> > + * This function is used to set the V4L2 controls for the Xilinx MIPI
> > + * CSI-2 Rx Subsystem. It is used to set the active lanes in the system.
> > + * The event counters can be reset.
> > + *
> > + * Return: 0 on success, errors otherwise
> > + */
> > +static int xcsi2rxss_s_ctrl(struct v4l2_ctrl *ctrl)
> > +{
> > +     struct xcsi2rxss_state *xcsi2rxss =
> > +             container_of(ctrl->handler, struct xcsi2rxss_state,
> > +                          ctrl_handler);
> > +     struct xcsi2rxss_core *core = &xcsi2rxss->core;
> > +     int ret = 0;
> > +
> > +     mutex_lock(&xcsi2rxss->lock);
> > +
> > +     switch (ctrl->id) {
> > +     case V4L2_CID_XILINX_CSI2RX_ACT_LANES:
> > +             /*
> > +              * This will be called only when "Enable Active Lanes" parameter
> > +              * is set in design.
> > +              */
> > +             if (core->enable_active_lanes && !xcsi2rxss->streaming) {
> > +                     u32 active_lanes;
> > +
> > +                     xcsi2rxss_clr_and_set(core, XCSI_PCR_OFFSET,
> > +                                           XCSI_PCR_ACTLANES_MASK,
> > +                                           ctrl->val - 1);
> > +                     /*
> > +                      * This delay is to allow the value to reflect as write
> > +                      * and read paths are different.
> > +                      */
> > +                     udelay(1);
> > +                     active_lanes = xcsi2rxss_read(core, XCSI_PCR_OFFSET);
> > +                     active_lanes &= XCSI_PCR_ACTLANES_MASK;
> > +                     active_lanes++;
> > +                     if (active_lanes != ctrl->val)
> > +                             dev_info(core->dev, "RxByteClkHS absent\n");
> > +                     dev_dbg(core->dev, "active lanes = %d\n", ctrl->val);
> > +             } else {
> > +                     ret = -EINVAL;
> > +             }
> > +             break;
> > +     case V4L2_CID_XILINX_CSI2RX_RESET_COUNTERS:
> 
> This is also a debug feature. I'd suggest to remove it.
> 

Will remove it in next version.

> > +             xcsi2rxss_reset_event_counters(xcsi2rxss);
> > +             break;
> > +     default:
> > +             ret = -EINVAL;
> > +             break;
> > +     }
> > +
> > +     mutex_unlock(&xcsi2rxss->lock);
> > +
> > +     return ret;
> > +}
> > +
> > +static int xcsi2rxss_start_stream(struct xcsi2rxss_state *state)
> > +{
> > +     struct xcsi2rxss_core *core = &state->core;
> > +     int ret = 0;
> > +
> > +     xcsi2rxss_enable(core);
> > +
> > +     ret = xcsi2rxss_reset(core);
> > +     if (ret < 0) {
> > +             state->streaming = false;
> > +             return ret;
> > +     }
> > +
> > +     xcsi2rxss_intr_enable(core);
> > +     state->streaming = true;
> > +
> > +     return ret;
> > +}
> > +
> > +static void xcsi2rxss_stop_stream(struct xcsi2rxss_state *state)
> > +{
> > +     struct xcsi2rxss_core *core = &state->core;
> > +
> > +     xcsi2rxss_intr_disable(core);
> > +     xcsi2rxss_disable(core);
> > +     state->streaming = false;
> > +}
> > +
> > +/**
> > + * xcsi2rxss_irq_handler - Interrupt handler for CSI-2
> > + * @irq: IRQ number
> > + * @dev_id: Pointer to device state
> > + *
> > + * In the interrupt handler, a list of event counters are updated for
> > + * corresponding interrupts. This is useful to get status / debug.
> > + *
> > + * In case of stream line buffer full condition, the IP is reset, stopped and
> > + * an event is raised.
> > + *
> > + * Return: IRQ_HANDLED after handling interrupts
> > + *         IRQ_NONE is no interrupts
> > + */
> > +static irqreturn_t xcsi2rxss_irq_handler(int irq, void *dev_id)
> > +{
> > +     struct xcsi2rxss_state *state = (struct xcsi2rxss_state *)dev_id;
> > +     struct xcsi2rxss_core *core = &state->core;
> > +     u32 status;
> > +
> > +     status = xcsi2rxss_read(core, XCSI_ISR_OFFSET) &
> XCSI_ISR_ALLINTR_MASK;
> > +     dev_dbg_ratelimited(core->dev, "interrupt status = 0x%08x\n", status);
> > +
> > +     if (!status)
> > +             return IRQ_NONE;
> > +
> > +     /* Received a short packet */
> > +     if (status & XCSI_ISR_SPFIFONE) {
> > +             dev_dbg_ratelimited(core->dev, "Short packet = 0x%08x\n",
> > +                                 xcsi2rxss_read(core, XCSI_SPKTR_OFFSET));
> > +     }
> > +
> > +     /* Short packet FIFO overflow */
> > +     if (status & XCSI_ISR_SPFIFOF)
> > +             dev_alert_ratelimited(core->dev, "Short packet FIFO overflowed\n");
> > +
> > +     /*
> > +      * Stream line buffer full
> > +      * This means there is a backpressure from downstream IP
> > +      */
> > +     if (status & XCSI_ISR_SLBF) {
> > +             dev_alert_ratelimited(core->dev, "Stream Line Buffer Full!\n");
> > +             if (core->rst_gpio) {
> > +                     gpiod_set_value(core->rst_gpio, 1);
> > +                     /* minimum 40 dphy_clk_200M cycles */
> > +                     ndelay(250);
> > +                     gpiod_set_value(core->rst_gpio, 0);
> > +             }
> > +             xcsi2rxss_stop_stream(state);
> > +             memset(&state->event, 0, sizeof(state->event));
> > +             state->event.type = V4L2_EVENT_XILINX_CSI2RX_SLBF;
> > +             v4l2_subdev_notify_event(&state->subdev, &state->event);
> > +     }
> > +
> > +     /* Increment event counters */
> > +     if (status & XCSI_ISR_ALLINTR_MASK) {
> > +             unsigned int i;
> > +
> > +             for (i = 0; i < XCSI_NUM_EVENTS; i++) {
> > +                     if (!(status & core->events[i].mask))
> > +                             continue;
> > +                     core->events[i].counter++;
> > +                     dev_dbg_ratelimited(core->dev, "%s: %d\n",
> > +                                         core->events[i].name,
> > +                                         core->events[i].counter);
> > +             }
> > +
> > +             if (status & XCSI_ISR_VCXFE && core->en_vcx) {
> > +                     u32 vcxstatus;
> > +
> > +                     vcxstatus = xcsi2rxss_read(core, XCSI_VCXR_OFFSET);
> > +                     vcxstatus &= XCSI_VCXR_VCERR;
> > +                     for (i = 0; i < XCSI_VCX_NUM_EVENTS; i++) {
> > +                             if (!(vcxstatus & core->vcx_events[i].mask))
> > +                                     continue;
> > +                             core->vcx_events[i].counter++;
> > +                     }
> > +                     xcsi2rxss_write(core, XCSI_VCXR_OFFSET, vcxstatus);
> > +             }
> > +     }
> > +
> > +     xcsi2rxss_write(core, XCSI_ISR_OFFSET, status);
> > +     return IRQ_HANDLED;
> > +}
> > +
> > +/**
> > + * xcsi2rxss_s_stream - It is used to start/stop the streaming.
> > + * @sd: V4L2 Sub device
> > + * @enable: Flag (True / False)
> > + *
> > + * This function controls the start or stop of streaming for the
> > + * Xilinx MIPI CSI-2 Rx Subsystem.
> > + *
> > + * Return: 0 on success, errors otherwise
> > + */
> > +static int xcsi2rxss_s_stream(struct v4l2_subdev *sd, int enable)
> > +{
> > +     struct xcsi2rxss_state *xcsi2rxss = to_xcsi2rxssstate(sd);
> > +     int ret = 0;
> > +
> > +     mutex_lock(&xcsi2rxss->lock);
> > +
> > +     if (enable) {
> > +             if (!xcsi2rxss->streaming) {
> > +                     /* reset the event counters */
> > +                     xcsi2rxss_reset_event_counters(xcsi2rxss);
> > +                     ret = xcsi2rxss_start_stream(xcsi2rxss);
> > +             }
> > +     } else {
> > +             if (xcsi2rxss->streaming) {
> > +                     struct gpio_desc *rst = xcsi2rxss->core.rst_gpio;
> > +
> > +                     if (rst) {
> > +                             gpiod_set_value_cansleep(rst, 1);
> > +                             usleep_range(1, 2);
> > +                             gpiod_set_value_cansleep(rst, 0);
> > +                     }
> > +                     xcsi2rxss_stop_stream(xcsi2rxss);
> > +             }
> > +     }
> > +
> > +     mutex_unlock(&xcsi2rxss->lock);
> > +     return ret;
> > +}
> > +
> > +static struct v4l2_mbus_framefmt *
> > +__xcsi2rxss_get_pad_format(struct xcsi2rxss_state *xcsi2rxss,
> > +                        struct v4l2_subdev_pad_config *cfg,
> > +                        unsigned int pad, u32 which)
> > +{
> > +     switch (which) {
> > +     case V4L2_SUBDEV_FORMAT_TRY:
> > +             return v4l2_subdev_get_try_format(&xcsi2rxss->subdev, cfg, pad);
> > +     case V4L2_SUBDEV_FORMAT_ACTIVE:
> > +             return &xcsi2rxss->format;
> > +     default:
> > +             return NULL;
> > +     }
> > +}
> > +
> > +/**
> > + * xcsi2rxss_get_format - Get the pad format
> > + * @sd: Pointer to V4L2 Sub device structure
> > + * @cfg: Pointer to sub device pad information structure
> > + * @fmt: Pointer to pad level media bus format
> > + *
> > + * This function is used to get the pad format information.
> > + *
> > + * Return: 0 on success
> > + */
> > +static int xcsi2rxss_get_format(struct v4l2_subdev *sd,
> > +                             struct v4l2_subdev_pad_config *cfg,
> > +                             struct v4l2_subdev_format *fmt)
> > +{
> > +     struct xcsi2rxss_state *xcsi2rxss = to_xcsi2rxssstate(sd);
> > +
> > +     mutex_lock(&xcsi2rxss->lock);
> > +     fmt->format = *__xcsi2rxss_get_pad_format(xcsi2rxss, cfg, fmt->pad,
> > +                                               fmt->which);
> > +     mutex_unlock(&xcsi2rxss->lock);
> > +
> > +     return 0;
> > +}
> > +
> > +/**
> > + * xcsi2rxss_set_format - This is used to set the pad format
> > + * @sd: Pointer to V4L2 Sub device structure
> > + * @cfg: Pointer to sub device pad information structure
> > + * @fmt: Pointer to pad level media bus format
> > + *
> > + * This function is used to set the pad format. Since the pad format is fixed
> > + * in hardware, it can't be modified on run time. So when a format set is
> > + * requested by application, all parameters except the format type is saved
> > + * for the pad and the original pad format is sent back to the application.
> > + *
> > + * Return: 0 on success
> > + */
> > +static int xcsi2rxss_set_format(struct v4l2_subdev *sd,
> > +                             struct v4l2_subdev_pad_config *cfg,
> > +                             struct v4l2_subdev_format *fmt)
> > +{
> > +     struct xcsi2rxss_state *xcsi2rxss = to_xcsi2rxssstate(sd);
> > +     struct xcsi2rxss_core *core = &xcsi2rxss->core;
> > +     struct v4l2_mbus_framefmt *__format;
> > +
> > +     /* only sink pad format can be updated */
> > +     mutex_lock(&xcsi2rxss->lock);
> > +
> > +     /*
> > +      * Only the format->code parameter matters for CSI as the
> > +      * CSI format cannot be changed at runtime.
> > +      * Ensure that format to set is copied to over to CSI pad format
> > +      */
> > +     __format = __xcsi2rxss_get_pad_format(xcsi2rxss, cfg,
> > +                                           fmt->pad, fmt->which);
> > +
> > +     if (fmt->pad == XVIP_PAD_SOURCE) {
> > +             fmt->format = *__format;
> > +             mutex_unlock(&xcsi2rxss->lock);
> > +             return 0;
> > +     }
> > +
> > +     /*
> > +      * RAW8 is supported in all datatypes. So if requested media bus format
> > +      * is of RAW8 type, then allow to be set. In case core is configured to
> > +      * other RAW, YUV422 8/10 or RGB888, set appropriate media bus
> format.
> > +      */
> > +     if ((fmt->format.code == MEDIA_BUS_FMT_SBGGR8_1X8 ||
> > +          fmt->format.code == MEDIA_BUS_FMT_SGBRG8_1X8 ||
> > +          fmt->format.code == MEDIA_BUS_FMT_SGRBG8_1X8 ||
> > +          fmt->format.code == MEDIA_BUS_FMT_SRGGB8_1X8) ||
> > +         (core->datatype == XCSI_DT_RAW10 &&
> > +          (fmt->format.code == MEDIA_BUS_FMT_SBGGR10_1X10 ||
> > +           fmt->format.code == MEDIA_BUS_FMT_SGBRG10_1X10 ||
> > +           fmt->format.code == MEDIA_BUS_FMT_SGRBG10_1X10 ||
> > +           fmt->format.code == MEDIA_BUS_FMT_SRGGB10_1X10)) ||
> > +         (core->datatype == XCSI_DT_RAW12 &&
> > +          (fmt->format.code == MEDIA_BUS_FMT_SBGGR12_1X12 ||
> > +           fmt->format.code == MEDIA_BUS_FMT_SGBRG12_1X12 ||
> > +           fmt->format.code == MEDIA_BUS_FMT_SGRBG12_1X12 ||
> > +           fmt->format.code == MEDIA_BUS_FMT_SRGGB12_1X12)) ||
> > +         (core->datatype == XCSI_DT_RAW14 &&
> > +          (fmt->format.code == MEDIA_BUS_FMT_SBGGR14_1X14 ||
> > +           fmt->format.code == MEDIA_BUS_FMT_SGBRG14_1X14 ||
> > +           fmt->format.code == MEDIA_BUS_FMT_SGRBG14_1X14 ||
> > +           fmt->format.code == MEDIA_BUS_FMT_SRGGB14_1X14)) ||
> > +         (core->datatype == XCSI_DT_RAW16 &&
> > +          (fmt->format.code == MEDIA_BUS_FMT_SBGGR16_1X16 ||
> > +           fmt->format.code == MEDIA_BUS_FMT_SGBRG16_1X16 ||
> > +           fmt->format.code == MEDIA_BUS_FMT_SGRBG16_1X16 ||
> > +           fmt->format.code == MEDIA_BUS_FMT_SRGGB16_1X16)) ||
> > +         (core->datatype == XCSI_DT_YUV4228B &&
> > +          fmt->format.code == MEDIA_BUS_FMT_UYVY8_1X16) ||
> > +         (core->datatype == XCSI_DT_YUV42210B &&
> > +          fmt->format.code == MEDIA_BUS_FMT_UYVY10_1X20) ||
> > +         (core->datatype == XCSI_DT_RGB888 &&
> > +          fmt->format.code == MEDIA_BUS_FMT_RBG888_1X24)) {
> > +             /* Copy over the format to be set */
> > +             *__format = fmt->format;
> > +     } else {
> > +             /* Restore the original pad format code */
> > +             dev_dbg(core->dev, "Unsupported media bus format");
> > +             fmt->format.code = __format->code;
> > +             *__format = fmt->format;
> 
> You can do the assignment outside the conditional expression.
> 

Ok I will take care of this in next version.

> > +     }
> > +
> > +     mutex_unlock(&xcsi2rxss->lock);
> > +
> > +     return 0;
> > +}
> > +
> > +/*
> > + * xcsi2rxss_enum_mbus_code - Handle pixel format enumeration
> > + * @sd : pointer to v4l2 subdev structure
> > + * @cfg: V4L2 subdev pad configuration
> > + * @code : pointer to v4l2_subdev_mbus_code_enum structure
> > + *
> > + * Return: -EINVAL or zero on success
> > + */
> > +int xcsi2rxss_enum_mbus_code(struct v4l2_subdev *sd,
> > +                          struct v4l2_subdev_pad_config *cfg,
> > +                          struct v4l2_subdev_mbus_code_enum *code)
> > +{
> > +     struct xcsi2rxss_state *state = to_xcsi2rxssstate(sd);
> > +
> > +     if (code->pad >= XCSI_MEDIA_PADS ||
> 
> The pad is already checked by the IOCTL handler. Please remove it from
> here.
> 

Ok. I will remove it in next version.

> > +         code->index > state->mbus_fmts_count)
> > +             return -EINVAL;
> > +
> > +     code->code = state->mbus_fmts[code->index];
> > +
> > +     return 0;
> > +}
> > +
> > +/**
> > + * xcsi2rxss_open - Called on v4l2_open()
> > + * @sd: Pointer to V4L2 sub device structure
> > + * @fh: Pointer to V4L2 File handle
> > + *
> > + * This function is called on v4l2_open(). It sets the default format
> > + * for both pads.
> > + *
> > + * Return: 0 on success
> > + */
> > +static int xcsi2rxss_open(struct v4l2_subdev *sd,
> > +                       struct v4l2_subdev_fh *fh)
> > +{
> > +     struct xcsi2rxss_state *xcsi2rxss = to_xcsi2rxssstate(sd);
> > +     struct v4l2_mbus_framefmt *format;
> > +     unsigned int i;
> > +
> > +     for (i = 0; i < XCSI_MEDIA_PADS; i++) {
> > +             format = v4l2_subdev_get_try_format(sd, fh->pad, i);
> > +             *format = xcsi2rxss->default_format;
> > +     }
> > +
> > +     return 0;
> > +}
> > +
> > +/* -----------------------------------------------------------------------------
> > + * Media Operations
> > + */
> > +
> > +static const struct media_entity_operations xcsi2rxss_media_ops = {
> > +     .link_validate = v4l2_subdev_link_validate
> > +};
> > +
> > +static const struct v4l2_ctrl_ops xcsi2rxss_ctrl_ops = {
> > +     .s_ctrl = xcsi2rxss_s_ctrl
> > +};
> > +
> > +static struct v4l2_ctrl_config xcsi2rxss_ctrls[] = {
> > +     {
> > +             .ops    = &xcsi2rxss_ctrl_ops,
> > +             .id     = V4L2_CID_XILINX_CSI2RX_ACT_LANES,
> > +             .name   = "Active Lanes",
> > +             .type   = V4L2_CTRL_TYPE_INTEGER,
> > +             .min    = 1,
> > +             .max    = 4,
> > +             .step   = 1,
> > +             .def    = 1,
> > +     }, {
> > +             .ops    = &xcsi2rxss_ctrl_ops,
> > +             .id     = V4L2_CID_XILINX_CSI2RX_RESET_COUNTERS,
> > +             .name   = "Reset Counters",
> > +             .type   = V4L2_CTRL_TYPE_BUTTON,
> > +             .min    = 0,
> > +             .max    = 1,
> > +             .step   = 1,
> > +             .def    = 0,
> > +             .flags  = V4L2_CTRL_FLAG_WRITE_ONLY,
> > +     }
> > +};
> > +
> > +static const struct v4l2_subdev_core_ops xcsi2rxss_core_ops = {
> > +     .log_status = xcsi2rxss_log_status,
> > +     .subscribe_event = xcsi2rxss_subscribe_event,
> > +     .unsubscribe_event = xcsi2rxss_unsubscribe_event
> > +};
> > +
> > +static const struct v4l2_subdev_video_ops xcsi2rxss_video_ops = {
> > +     .s_stream = xcsi2rxss_s_stream
> > +};
> > +
> > +static const struct v4l2_subdev_pad_ops xcsi2rxss_pad_ops = {
> > +     .get_fmt = xcsi2rxss_get_format,
> > +     .set_fmt = xcsi2rxss_set_format,
> > +     .enum_mbus_code = xcsi2rxss_enum_mbus_code,
> > +};
> > +
> > +static const struct v4l2_subdev_ops xcsi2rxss_ops = {
> > +     .core = &xcsi2rxss_core_ops,
> > +     .video = &xcsi2rxss_video_ops,
> > +     .pad = &xcsi2rxss_pad_ops
> > +};
> > +
> > +static const struct v4l2_subdev_internal_ops xcsi2rxss_internal_ops = {
> > +     .open = xcsi2rxss_open,
> > +};
> > +
> > +static void xcsi2rxss_set_default_format(struct xcsi2rxss_state *state)
> > +{
> > +     struct xcsi2rxss_core *core = &state->core;
> > +
> > +     memset(&state->default_format, 0, sizeof(state->default_format));
> > +
> > +     switch (core->datatype) {
> > +     case XCSI_DT_YUV4228B:
> > +             state->default_format.code = MEDIA_BUS_FMT_UYVY8_1X16;
> > +             break;
> > +     case XCSI_DT_RGB888:
> > +             state->default_format.code = MEDIA_BUS_FMT_RBG888_1X24;
> > +             break;
> > +     case XCSI_DT_YUV42210B:
> > +             state->default_format.code = MEDIA_BUS_FMT_UYVY10_1X20;
> > +             break;
> > +     case XCSI_DT_RAW10:
> > +             state->default_format.code = MEDIA_BUS_FMT_SRGGB10_1X10;
> > +             break;
> > +     case XCSI_DT_RAW12:
> > +             state->default_format.code = MEDIA_BUS_FMT_SRGGB12_1X12;
> > +             break;
> > +     case XCSI_DT_RAW14:
> > +             state->default_format.code = MEDIA_BUS_FMT_SRGGB14_1X14;
> > +             break;
> > +     case XCSI_DT_RAW16:
> > +             state->default_format.code = MEDIA_BUS_FMT_SRGGB16_1X16;
> > +             break;
> > +     case XCSI_DT_RAW8:
> > +     case XCSI_DT_RGB444:
> > +     case XCSI_DT_RGB555:
> > +     case XCSI_DT_RGB565:
> > +     case XCSI_DT_RGB666:
> > +             state->default_format.code = MEDIA_BUS_FMT_SRGGB8_1X8;
> > +             break;
> > +     }
> > +
> > +     state->default_format.field = V4L2_FIELD_NONE;
> > +     state->default_format.colorspace = V4L2_COLORSPACE_SRGB;
> > +     state->default_format.width = XCSI_DEFAULT_WIDTH;
> > +     state->default_format.height = XCSI_DEFAULT_HEIGHT;
> > +
> > +     dev_dbg(core->dev, "default mediabus format = 0x%x",
> > +             state->default_format.code);
> > +}
> > +
> > +static void xcsi2rxss_init_mbus_fmts(struct xcsi2rxss_state *state)
> > +{
> > +     struct xcsi2rxss_core *core = &state->core;
> > +     u32 i = 0;
> > +
> > +     state->mbus_fmts[i++] = MEDIA_BUS_FMT_SRGGB8_1X8;
> > +     state->mbus_fmts[i++] = MEDIA_BUS_FMT_SBGGR8_1X8;
> > +     state->mbus_fmts[i++] = MEDIA_BUS_FMT_SGRBG8_1X8;
> > +     state->mbus_fmts[i++] = MEDIA_BUS_FMT_SGBRG8_1X8;
> > +
> > +     switch (core->datatype) {
> > +     case XCSI_DT_RAW10:
> > +             state->mbus_fmts[i++] = MEDIA_BUS_FMT_SRGGB10_1X10;
> > +             state->mbus_fmts[i++] = MEDIA_BUS_FMT_SBGGR10_1X10;
> > +             state->mbus_fmts[i++] = MEDIA_BUS_FMT_SGRBG10_1X10;
> > +             state->mbus_fmts[i++] = MEDIA_BUS_FMT_SGBRG10_1X10;
> > +             break;
> > +     case XCSI_DT_RAW12:
> > +             state->mbus_fmts[i++] = MEDIA_BUS_FMT_SRGGB12_1X12;
> > +             state->mbus_fmts[i++] = MEDIA_BUS_FMT_SBGGR12_1X12;
> > +             state->mbus_fmts[i++] = MEDIA_BUS_FMT_SGRBG12_1X12;
> > +             state->mbus_fmts[i++] = MEDIA_BUS_FMT_SGBRG12_1X12;
> > +             break;
> > +     case XCSI_DT_RAW14:
> > +             state->mbus_fmts[i++] = MEDIA_BUS_FMT_SRGGB14_1X14;
> > +             state->mbus_fmts[i++] = MEDIA_BUS_FMT_SBGGR14_1X14;
> > +             state->mbus_fmts[i++] = MEDIA_BUS_FMT_SGRBG14_1X14;
> > +             state->mbus_fmts[i++] = MEDIA_BUS_FMT_SGBRG14_1X14;
> > +             break;
> > +     case XCSI_DT_RAW16:
> > +             state->mbus_fmts[i++] = MEDIA_BUS_FMT_SRGGB16_1X16;
> > +             state->mbus_fmts[i++] = MEDIA_BUS_FMT_SBGGR16_1X16;
> > +             state->mbus_fmts[i++] = MEDIA_BUS_FMT_SGRBG16_1X16;
> > +             state->mbus_fmts[i++] = MEDIA_BUS_FMT_SGBRG16_1X16;
> > +             break;
> > +     case XCSI_DT_YUV4228B:
> > +             state->mbus_fmts[i++] = MEDIA_BUS_FMT_UYVY8_1X16;
> > +             break;
> > +     case XCSI_DT_RGB888:
> > +             state->mbus_fmts[i++] = MEDIA_BUS_FMT_RBG888_1X24;
> > +             break;
> > +     case XCSI_DT_YUV42210B:
> > +             state->mbus_fmts[i++] = MEDIA_BUS_FMT_UYVY10_1X20;
> > +             break;
> 
> This is only used for mbus format enumeration. Could you instead construct
> the enumeration on fly based on the data type?
> 
> Alternatively, it'd be good to have something here to avoid proceeding past
> the end of the array (although that doesn't currently happen).
> 

I will add a check to throw an error in case array out of bounds access occurs.

> > +     }
> > +
> > +     state->mbus_fmts_count = i;
> > +}
> > +
> > +static int xcsi2rxss_parse_of(struct xcsi2rxss_state *xcsi2rxss)
> > +{
> > +     struct xcsi2rxss_core *core = &xcsi2rxss->core;
> > +     struct device_node *node = xcsi2rxss->core.dev->of_node;
> > +     struct device_node *ports = NULL;
> > +     struct device_node *port = NULL;
> > +     unsigned int nports, irq;
> > +     bool en_csi_v20, vfb;
> > +     int ret;
> > +
> > +     en_csi_v20 = of_property_read_bool(node, "xlnx,en-csi-v2-0");
> > +     if (en_csi_v20)
> > +             core->en_vcx = of_property_read_bool(node, "xlnx,en-vcx");
> > +
> > +     core->enable_active_lanes =
> > +             of_property_read_bool(node, "xlnx,en-active-lanes");
> > +
> > +     ret = of_property_read_u32(node, "xlnx,csi-pxl-format",
> > +                                &core->datatype);
> > +     if (ret < 0) {
> > +             dev_err(core->dev, "missing xlnx,csi-pxl-format property\n");
> > +             return ret;
> > +     }
> > +
> > +     switch (core->datatype) {
> > +     case XCSI_DT_YUV4228B:
> > +     case XCSI_DT_RGB444:
> > +     case XCSI_DT_RGB555:
> > +     case XCSI_DT_RGB565:
> > +     case XCSI_DT_RGB666:
> > +     case XCSI_DT_RGB888:
> > +     case XCSI_DT_RAW6:
> > +     case XCSI_DT_RAW7:
> > +     case XCSI_DT_RAW8:
> > +     case XCSI_DT_RAW10:
> > +     case XCSI_DT_RAW12:
> > +     case XCSI_DT_RAW14:
> > +             break;
> > +     case XCSI_DT_YUV42210B:
> > +     case XCSI_DT_RAW16:
> > +     case XCSI_DT_RAW20:
> > +             if (!en_csi_v20) {
> > +                     ret = -EINVAL;
> > +                     dev_dbg(core->dev, "enable csi v2 for this pixel format");
> > +             }
> > +             break;
> > +     default:
> > +             ret = -EINVAL;
> > +     }
> > +     if (ret < 0) {
> > +             dev_err(core->dev, "invalid csi-pxl-format property!\n");
> > +             return ret;
> > +     }
> > +
> > +     vfb = of_property_read_bool(node, "xlnx,vfb");
> > +     if (!vfb) {
> > +             dev_err(core->dev, "failed as VFB is disabled!\n");
> > +             return -EINVAL;
> > +     }
> > +
> > +     ports = of_get_child_by_name(node, "ports");
> > +     if (!ports)
> > +             ports = node;
> > +
> > +     nports = 0;
> > +     for_each_child_of_node(ports, port) {
> > +             struct device_node *endpoint;
> > +             struct v4l2_fwnode_endpoint v4lendpoint;
> > +             int ret;
> > +
> > +             if (!port->name || of_node_cmp(port->name, "port"))
> > +                     continue;
> > +
> > +             endpoint = of_get_next_child(port, NULL);
> > +             if (!endpoint) {
> > +                     dev_err(core->dev, "No port at\n");
> > +                     return -EINVAL;
> > +             }
> > +
> > +             /*
> > +              * since first port is sink port and it contains
> > +              * all info about data-lanes and cfa-pattern,
> > +              * don't parse second port but only check if exists
> > +              */
> > +             if (nports == XVIP_PAD_SOURCE) {
> > +                     dev_dbg(core->dev, "no need to parse source port");
> > +                     nports++;
> > +                     of_node_put(endpoint);
> > +                     continue;
> > +             }
> > +
> > +             ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(endpoint),
> > +                                              &v4lendpoint);
> > +             of_node_put(endpoint);
> > +             if (ret)
> > +                     return ret;
> > +
> > +             dev_dbg(core->dev, "%s : port %d bus type = %d\n",
> > +                     __func__, nports, v4lendpoint.bus_type);
> > +
> > +             if (v4lendpoint.bus_type == V4L2_MBUS_CSI2_DPHY) {
> > +                     dev_dbg(core->dev, "%s : base.port = %d base.id = %d\n",
> > +                             __func__, v4lendpoint.base.port,
> > +                             v4lendpoint.base.id);
> > +
> > +                     dev_dbg(core->dev, "%s : mipi number lanes = %d\n",
> > +                             __func__,
> > +                             v4lendpoint.bus.mipi_csi2.num_data_lanes);
> > +
> > +                     core->max_num_lanes =
> > +                             v4lendpoint.bus.mipi_csi2.num_data_lanes;
> > +             }
> > +
> > +             /* Count the number of ports. */
> > +             nports++;
> > +     }
> > +
> > +     if (nports != XCSI_MEDIA_PADS) {
> > +             dev_err(core->dev, "invalid number of ports %u\n", nports);
> > +             return -EINVAL;
> > +     }
> > +
> > +     /* Register interrupt handler */
> > +     irq = irq_of_parse_and_map(node, 0);
> > +     ret = devm_request_irq(core->dev, irq, xcsi2rxss_irq_handler,
> > +                            IRQF_SHARED, "xilinx-csi2rxss", xcsi2rxss);
> > +     if (ret) {
> > +             dev_err(core->dev, "Err = %d Interrupt handler reg failed!\n",
> > +                     ret);
> > +             return ret;
> > +     }
> > +
> > +     xcsi2rxss_log_ipconfig(xcsi2rxss);
> > +
> > +     return 0;
> > +}
> > +
> > +static int xcsi2rxss_probe(struct platform_device *pdev)
> > +{
> > +     struct v4l2_subdev *subdev;
> > +     struct xcsi2rxss_state *xcsi2rxss;
> > +     struct xcsi2rxss_core *core;
> > +     struct resource *res;
> > +     int ret, num_ctrls, i;
> > +
> > +     xcsi2rxss = devm_kzalloc(&pdev->dev, sizeof(*xcsi2rxss), GFP_KERNEL);
> > +     if (!xcsi2rxss)
> > +             return -ENOMEM;
> > +
> > +     core = &xcsi2rxss->core;
> > +     core->dev = &pdev->dev;
> > +
> > +     core->clks = devm_kmemdup(core->dev, xcsi2rxss_clks,
> > +                               sizeof(xcsi2rxss_clks), GFP_KERNEL);
> > +     if (!core->clks)
> > +             return -ENOMEM;
> > +
> > +     /* Reset GPIO */
> > +     core->rst_gpio = devm_gpiod_get_optional(core->dev, "reset",
> > +                                              GPIOD_OUT_HIGH);
> > +     if (IS_ERR(core->rst_gpio)) {
> > +             if (PTR_ERR(core->rst_gpio) != -EPROBE_DEFER)
> > +                     dev_err(core->dev, "Video Reset GPIO not setup in DT");
> > +             return PTR_ERR(core->rst_gpio);
> > +     }
> > +
> > +     mutex_init(&xcsi2rxss->lock);
> > +
> > +     ret = xcsi2rxss_parse_of(xcsi2rxss);
> > +     if (ret < 0)
> > +             return ret;
> > +
> > +     res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> > +     core->iomem = devm_ioremap_resource(core->dev, res);
> > +     if (IS_ERR(core->iomem))
> > +             return PTR_ERR(core->iomem);
> > +
> > +     core->num_clks = ARRAY_SIZE(xcsi2rxss_clks);
> > +
> > +     ret = clk_bulk_get(core->dev, core->num_clks, core->clks);
> > +     if (ret)
> > +             return ret;
> > +
> > +     ret = clk_bulk_prepare_enable(core->num_clks, core->clks);
> > +     if (ret)
> > +             goto err_clk_put;
> > +
> > +     if (xcsi2rxss->core.rst_gpio) {
> > +             gpiod_set_value_cansleep(xcsi2rxss->core.rst_gpio, 1);
> > +             /* minimum of 40 dphy_clk_200M cycles */
> > +             usleep_range(1, 2);
> > +             gpiod_set_value_cansleep(xcsi2rxss->core.rst_gpio, 0);
> > +     }
> > +
> > +     xcsi2rxss_reset(core);
> > +
> > +     core->events = devm_kzalloc(&pdev->dev, sizeof(xcsi2rxss_events),
> > +                                 GFP_KERNEL);
> > +     for (i = 0; i < XCSI_NUM_EVENTS; i++) {
> > +             core->events[i].name = xcsi2rxss_events[i].name;
> > +             core->events[i].mask = xcsi2rxss_events[i].mask;
> > +     }
> > +
> > +     if (core->en_vcx) {
> > +             u32 alloc_size;
> > +
> > +             alloc_size = sizeof(struct xcsi2rxss_event) *
> > +                          XCSI_VCX_NUM_EVENTS;
> > +             core->vcx_events = devm_kzalloc(&pdev->dev, alloc_size,
> > +                                             GFP_KERNEL);
> > +             if (!core->vcx_events) {
> > +                     mutex_destroy(&xcsi2rxss->lock);
> > +                     ret = -ENOMEM;
> > +                     goto err_clk_disable;
> > +             }
> > +
> > +             for (i = 0; i < XCSI_VCX_NUM_EVENTS; i++)
> > +                     core->vcx_events[i].mask = 1 << i;
> > +     }
> > +
> > +     /* Initialize V4L2 subdevice and media entity */
> > +     xcsi2rxss->pads[XVIP_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
> > +     xcsi2rxss->pads[XVIP_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
> > +
> > +     /* Initialize the default format */
> > +     xcsi2rxss_set_default_format(xcsi2rxss);
> > +
> > +     /* Initialize the mbus formats supported */
> > +     xcsi2rxss_init_mbus_fmts(xcsi2rxss);
> > +
> > +     /* Initialize V4L2 subdevice and media entity */
> > +     subdev = &xcsi2rxss->subdev;
> > +     v4l2_subdev_init(subdev, &xcsi2rxss_ops);
> > +     subdev->dev = &pdev->dev;
> > +     subdev->internal_ops = &xcsi2rxss_internal_ops;
> > +     strscpy(subdev->name, dev_name(&pdev->dev), sizeof(subdev->name));
> > +     subdev->flags |= V4L2_SUBDEV_FL_HAS_EVENTS |
> V4L2_SUBDEV_FL_HAS_DEVNODE;
> > +     subdev->entity.ops = &xcsi2rxss_media_ops;
> > +     v4l2_set_subdevdata(subdev, xcsi2rxss);
> > +
> > +     ret = media_entity_pads_init(&subdev->entity, XCSI_MEDIA_PADS,
> > +                                  xcsi2rxss->pads);
> > +     if (ret < 0)
> > +             goto error;
> > +
> > +     /*
> > +      * In case the Enable Active Lanes config parameter is not set,
> > +      * dynamic lane reconfiguration is not allowed.
> > +      * So V4L2_CID_XILINX_CSI2RX_ACT_LANES ctrl will not be registered.
> > +      * Accordingly allocate the number of controls
> > +      */
> > +     num_ctrls = ARRAY_SIZE(xcsi2rxss_ctrls);
> > +
> > +     if (!core->enable_active_lanes)
> > +             num_ctrls--;
> > +
> > +     v4l2_ctrl_handler_init(&xcsi2rxss->ctrl_handler, num_ctrls);
> > +     for (i = 0; i < ARRAY_SIZE(xcsi2rxss_ctrls); i++) {
> > +             struct v4l2_ctrl *ctrl;
> > +
> > +             if (xcsi2rxss_ctrls[i].id ==
> > +                     V4L2_CID_XILINX_CSI2RX_ACT_LANES) {
> > +                     if (!core->enable_active_lanes) {
> > +                             /* Don't register control */
> > +                             dev_dbg(core->dev,
> > +                                     "Skip active lane control\n");
> > +                             continue;
> > +                     }
> > +                     xcsi2rxss_ctrls[i].max = core->max_num_lanes;
> > +                     xcsi2rxss_ctrls[i].def = core->max_num_lanes;
> > +             }
> > +
> > +             dev_dbg(core->dev, "%d ctrl = 0x%x\n", i,
> > +                     xcsi2rxss_ctrls[i].id);
> > +             ctrl = v4l2_ctrl_new_custom(&xcsi2rxss->ctrl_handler,
> > +                                         &xcsi2rxss_ctrls[i], NULL);
> > +             if (!ctrl) {
> > +                     dev_err(core->dev, "Failed for %s ctrl\n",
> > +                             xcsi2rxss_ctrls[i].name);
> > +                     goto error;
> > +             }
> > +     }
> > +
> > +     if (xcsi2rxss->ctrl_handler.error) {
> > +             dev_err(core->dev, "failed to add controls\n");
> > +             ret = xcsi2rxss->ctrl_handler.error;
> > +             goto error;
> > +     }
> > +
> > +     subdev->ctrl_handler = &xcsi2rxss->ctrl_handler;
> > +     ret = v4l2_ctrl_handler_setup(&xcsi2rxss->ctrl_handler);
> > +     if (ret < 0) {
> > +             dev_err(core->dev, "failed to set controls\n");
> > +             goto error;
> > +     }
> > +
> > +     platform_set_drvdata(pdev, xcsi2rxss);
> > +
> > +     ret = v4l2_async_register_subdev(subdev);
> > +     if (ret < 0) {
> > +             dev_err(core->dev, "failed to register subdev\n");
> > +             goto error;
> > +     }
> > +
> > +     dev_info(core->dev, "Xilinx CSI2 Rx Subsystem device found!\n");
> > +
> > +     return 0;
> > +error:
> > +     v4l2_ctrl_handler_free(&xcsi2rxss->ctrl_handler);
> > +     media_entity_cleanup(&subdev->entity);
> > +     mutex_destroy(&xcsi2rxss->lock);
> > +err_clk_disable:
> > +     clk_bulk_disable_unprepare(core->num_clks, core->clks);
> > +err_clk_put:
> > +     clk_bulk_put(core->num_clks, core->clks);
> > +     return ret;
> > +}
> > +
> > +static int xcsi2rxss_remove(struct platform_device *pdev)
> > +{
> > +     struct xcsi2rxss_state *xcsi2rxss = platform_get_drvdata(pdev);
> > +     struct xcsi2rxss_core *core = &xcsi2rxss->core;
> > +     struct v4l2_subdev *subdev = &xcsi2rxss->subdev;
> > +
> > +     v4l2_async_unregister_subdev(subdev);
> > +     v4l2_ctrl_handler_free(&xcsi2rxss->ctrl_handler);
> > +     media_entity_cleanup(&subdev->entity);
> > +     mutex_destroy(&xcsi2rxss->lock);
> > +     clk_bulk_disable_unprepare(core->num_clks, core->clks);
> > +     clk_bulk_put(core->num_clks, core->clks);
> > +
> > +     return 0;
> > +}
> > +
> > +static const struct of_device_id xcsi2rxss_of_id_table[] = {
> > +     { .compatible = "xlnx,mipi-csi2-rx-subsystem-4.0",},
> 
> Space before closing parenthesis.
> 

I will fix this in next version. 

> > +     { }
> > +};
> > +MODULE_DEVICE_TABLE(of, xcsi2rxss_of_id_table);
> > +
> > +static struct platform_driver xcsi2rxss_driver = {
> > +     .driver = {
> > +             .name           = "xilinx-csi2rxss",
> > +             .of_match_table = xcsi2rxss_of_id_table,
> > +     },
> > +     .probe                  = xcsi2rxss_probe,
> > +     .remove                 = xcsi2rxss_remove,
> > +};
> > +
> > +module_platform_driver(xcsi2rxss_driver);
> > +
> > +MODULE_AUTHOR("Vishal Sagar <vsagar@xilinx.com>");
> > +MODULE_DESCRIPTION("Xilinx MIPI CSI2 Rx Subsystem Driver");
> > +MODULE_LICENSE("GPL v2");
> > diff --git a/include/uapi/linux/v4l2-controls.h b/include/uapi/linux/v4l2-
> controls.h
> > index a2669b7..98074f2 100644
> > --- a/include/uapi/linux/v4l2-controls.h
> > +++ b/include/uapi/linux/v4l2-controls.h
> > @@ -192,6 +192,10 @@ enum v4l2_colorfx {
> >   * We reserve 16 controls for this driver. */
> >  #define V4L2_CID_USER_IMX_BASE                       (V4L2_CID_USER_BASE +
> 0x10b0)
> >
> > +/* The base for the Xilinx MIPI CSI2 Rx Subsystem driver controls.
> > + * We reserve 16 controls for this driver. */
> > +#define V4L2_CID_XILINX_CSI2RX_BASE          (V4L2_CID_USER_BASE +
> 0x10c0)
> > +
> >  /* MPEG-class control IDs */
> >  /* The MPEG controls are applicable to all codec controls
> >   * and the 'MPEG' part of the define is historical */
> > diff --git a/include/uapi/linux/xilinx-csi2rxss.h b/include/uapi/linux/xilinx-
> csi2rxss.h
> > new file mode 100644
> > index 0000000..79e2797
> > --- /dev/null
> > +++ b/include/uapi/linux/xilinx-csi2rxss.h
> > @@ -0,0 +1,52 @@
> > +/* SPDX-License-Identifier: GPL-2.0 */
> > +/*
> > + * Xilinx MIPI CSI2 Rx Subsystem events and controls
> > + *
> > + * Copyright (C) 2019 Xilinx, Inc.
> > + *
> > + * Contacts: Vishal Sagar <vishal.sagar@xilinx.com>
> > + *
> > + */
> > +
> > +#ifndef __XILINX_CSI2RXSS_H__
> > +#define __XILINX_CSI2RXSS_H__
> > +
> > +#include <linux/v4l2-controls.h>
> > +#include <linux/videodev2.h>
> > +
> > +/* Xilinx MIPI CSI2 Rx Subsystem controls */
> > +
> > +/* Active Lanes
> > + *
> > + * This control is used to dynamically set the number of active lanes.
> > + * This is present only when the "Enable Active Lanes" is set in design.
> > + * It should be called when IP is not streaming.
> > + */
> > +#define V4L2_CID_XILINX_CSI2RX_ACT_LANES
> (V4L2_CID_XILINX_CSI2RX_BASE + 1)
> > +
> > +/* Reset all event counters
> > + *
> > + * The driver has counters to keep a track of different events. These counters
> > + * can be printed using the log_status. This control is used to reset these
> > + * counters.
> > + */
> > +#define V4L2_CID_XILINX_CSI2RX_RESET_COUNTERS
> (V4L2_CID_XILINX_CSI2RX_BASE + 2)
> > +
> > +/* Xilinx MIPI CSI2 Rx Subsystem events */
> > +
> > +/* Base class */
> > +#define V4L2_EVENT_XILINX_CSI2RX_CLASS
> (V4L2_EVENT_PRIVATE_START | 0x200)
> > +
> > +/* Stream Line Buffer full event
> > + *
> > + * This event occurs when the MIPI CSI2 Rx Subsystem's line buffer is full.
> > + * This occurs because of back pressure from some downstream IP i.e.
> > + * the downstream IP isn't ready to accept data. This is usually due to some
> > + * system design issue.
> > + *
> > + * When this event occurs, application may stop streaming, inform the user
> > + * about the issue and exit.
> > + */
> > +#define V4L2_EVENT_XILINX_CSI2RX_SLBF
> (V4L2_EVENT_XILINX_CSI2RX_CLASS | 0x1)
> > +
> > +#endif /* __XILINX_CSI2RXSS_H__ */
> 
> --
> Regards,
> 
> Sakari Ailus

Regards
Vishal Sagar

^ permalink raw reply

* RE: [PATCH v8 2/2] media: v4l: xilinx: Add Xilinx MIPI CSI-2 Rx Subsystem driver
From: Vishal Sagar @ 2019-07-11  9:09 UTC (permalink / raw)
  To: Sakari Ailus
  Cc: Sakari Ailus, Vishal Sagar, Hyun Kwon,
	laurent.pinchart@ideasonboard.com, mchehab@kernel.org,
	robh+dt@kernel.org, mark.rutland@arm.com, Michal Simek,
	linux-media@vger.kernel.org, devicetree@vger.kernel.org,
	hans.verkuil@cisco.com, linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org, Dinesh Kumar, Sandip Kothari
In-Reply-To: <20190618145922.sq4jovxoz2khs3tq@valkosipuli.retiisi.org.uk>

Hi Sakari,

> -----Original Message-----
> From: Sakari Ailus [mailto:sakari.ailus@iki.fi]
> Sent: Tuesday, June 18, 2019 8:29 PM
> To: Vishal Sagar <vsagar@xilinx.com>
> Cc: Sakari Ailus <sakari.ailus@linux.intel.com>; Vishal Sagar
> <vishal.sagar@xilinx.com>; Hyun Kwon <hyunk@xilinx.com>;
> laurent.pinchart@ideasonboard.com; mchehab@kernel.org;
> robh+dt@kernel.org; mark.rutland@arm.com; Michal Simek
> <michals@xilinx.com>; linux-media@vger.kernel.org;
> devicetree@vger.kernel.org; hans.verkuil@cisco.com; linux-arm-
> kernel@lists.infradead.org; linux-kernel@vger.kernel.org; Dinesh Kumar
> <dineshk@xilinx.com>; Sandip Kothari <sandipk@xilinx.com>; Luca Ceresoli
> <luca@lucaceresoli.net>; Jacopo Mondi <jacopo@jmondi.org>
> Subject: Re: [PATCH v8 2/2] media: v4l: xilinx: Add Xilinx MIPI CSI-2 Rx
> Subsystem driver
> 
> Hi Vishal,
> 
> On Fri, Jun 07, 2019 at 07:11:47AM +0000, Vishal Sagar wrote:
> ...
> > > > +/**
> > > > + * xcsi2rxss_s_ctrl - This is used to set the Xilinx MIPI CSI-2 V4L2 controls
> > > > + * @ctrl: V4L2 control to be set
> > > > + *
> > > > + * This function is used to set the V4L2 controls for the Xilinx MIPI
> > > > + * CSI-2 Rx Subsystem. It is used to set the active lanes in the system.
> > > > + * The event counters can be reset.
> > > > + *
> > > > + * Return: 0 on success, errors otherwise
> > > > + */
> > > > +static int xcsi2rxss_s_ctrl(struct v4l2_ctrl *ctrl)
> > > > +{
> > > > +     struct xcsi2rxss_state *xcsi2rxss =
> > > > +             container_of(ctrl->handler, struct xcsi2rxss_state,
> > > > +                          ctrl_handler);
> > > > +     struct xcsi2rxss_core *core = &xcsi2rxss->core;
> > > > +     int ret = 0;
> > > > +
> > > > +     mutex_lock(&xcsi2rxss->lock);
> > > > +
> > > > +     switch (ctrl->id) {
> > > > +     case V4L2_CID_XILINX_MIPICSISS_ACT_LANES:
> > > > +             /*
> > > > +              * This will be called only when "Enable Active Lanes" parameter
> > > > +              * is set in design
> > > > +              */
> > >
> > > You generally get the number of lanes from firmware. There's no need to
> add
> > > a control for it.
> > >
> >
> > I don't understand what firmware means here. There is no other code
> running.
> > I don't see how to modify the number of lanes apart from using v4l control.
> 
> It's not the user that provides this information. Again, if you want this
> feature right from the time the driver is merged to mainline, then rebase
> the set on top of Jacopo's frame descriptor set. But it may take a while.
> 

Thanks for reviewing again and sharing this. 
Since Jacopo's frame descriptor set will take a while, I will remove this control for now from the driver so that the driver can get into upstream.

Regards
Vishal Sagar

> >
> > > > +             if (core->enable_active_lanes) {
> > > > +                     u32 active_lanes;
> > > > +
> > > > +                     xcsi2rxss_clr_and_set(core, XCSI_PCR_OFFSET,
> > > > +                                           XCSI_PCR_ACTLANES_MASK,
> > > > +                                           ctrl->val - 1);
> > > > +                     /*
> > > > +                      * This delay is to allow the value to reflect as write
> > > > +                      * and read paths are different.
> > > > +                      */
> > > > +                     udelay(1);
> > > > +                     active_lanes = xcsi2rxss_read(core, XCSI_PCR_OFFSET);
> > > > +                     active_lanes &= XCSI_PCR_ACTLANES_MASK;
> > > > +                     active_lanes++;
> > > > +                     if (active_lanes != ctrl->val)
> > > > +                             dev_info(core->dev, "RxByteClkHS absent\n");
> > > > +                     dev_dbg(core->dev, "active lanes = %d\n", ctrl->val);
> > > > +             } else {
> > > > +                     ret = -EINVAL;
> > > > +             }
> > > > +             break;
> > > > +     case V4L2_CID_XILINX_MIPICSISS_RESET_COUNTERS:
> > > > +             xcsi2rxss_reset_event_counters(xcsi2rxss);
> > > > +             break;
> > > > +     default:
> > > > +             ret = -EINVAL;
> > > > +             break;
> > > > +     }
> > > > +
> > > > +     mutex_unlock(&xcsi2rxss->lock);
> > > > +
> > > > +     return ret;
> > > > +}
> 
> --
> Regards,
> 
> Sakari Ailus

^ permalink raw reply

* Re: [PATCHv2] clk: add imx8 clk defines
From: Oliver Graute @ 2019-07-11  8:57 UTC (permalink / raw)
  To: Abel Vesa
  Cc: sboyd@kernel.org, mturquette@baylibre.com, Shawn Guo,
	Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
	dl-linux-imx, Rob Herring, Mark Rutland, Aisheng Dong,
	Ulf Hansson, linux-kernel@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org
In-Reply-To: <20190711082039.zze4t22rvlgdxzow@fsr-ub1664-175>

On 11/07/19, Abel Vesa wrote:
> On 19-06-19 09:39:52, Oliver Graute wrote:
> > From: Oliver Graute <oliver.graute@kococonnector.com>
> > 
> > added header defines for imx8qm clock
> > 
> > Signed-off-by: Oliver Graute <oliver.graute@kococonnector.com>
> 
> Again, this seems to be taken from some vendor tree, so please keep the
> original author.

yes the header defines is from NXP vendor tree. One of orginal authors is

Author: Anson Huang <Anson.Huang@nxp.com>
Date:   Thu Jan 19 03:53:31 2017 +0800
    MLK-13911-3 ARM64: dts: imx8qm: add dtsi
    Add i.MX8QM dtsi support.
    https://github.com/ADVANTECH-Corp/linux-imx6.git

Whats is the right way to attribute him?

Best regards,
Oliver

^ permalink raw reply

* Re: [PATCHv2] clk: add imx8 clk defines
From: Abel Vesa @ 2019-07-11  8:20 UTC (permalink / raw)
  To: Oliver Graute
  Cc: Mark Rutland, Aisheng Dong, Ulf Hansson, Sascha Hauer,
	devicetree@vger.kernel.org, sboyd@kernel.org, Fabio Estevam,
	mturquette@baylibre.com, linux-kernel@vger.kernel.org,
	Rob Herring, dl-linux-imx, Pengutronix Kernel Team, Shawn Guo,
	Oliver Graute, linux-arm-kernel@lists.infradead.org
In-Reply-To: <20190619074000.30852-1-oliver.graute@gmail.com>

On 19-06-19 09:39:52, Oliver Graute wrote:
> From: Oliver Graute <oliver.graute@kococonnector.com>
> 
> added header defines for imx8qm clock
> 
> Signed-off-by: Oliver Graute <oliver.graute@kococonnector.com>

Again, this seems to be taken from some vendor tree, so please keep the
original author.

> ---
>  include/dt-bindings/clock/imx8qm-clock.h | 851 +++++++++++++++++++++++
>  1 file changed, 851 insertions(+)
>  create mode 100644 include/dt-bindings/clock/imx8qm-clock.h
> 
> diff --git a/include/dt-bindings/clock/imx8qm-clock.h b/include/dt-bindings/clock/imx8qm-clock.h
> new file mode 100644
> index 000000000000..47217e4eaa6b
> --- /dev/null
> +++ b/include/dt-bindings/clock/imx8qm-clock.h
> @@ -0,0 +1,851 @@
> +/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
> +/*
> + * Copyright (C) 2016 Freescale Semiconductor, Inc.
> + * Copyright 2017 NXP
> +*/
> +
> +#ifndef __DT_BINDINGS_CLOCK_IMX8QM_H
> +#define __DT_BINDINGS_CLOCK_IMX8QM_H
> +
> +#define IMX8QM_CLK_DUMMY				0
> +
> +#define IMX8QM_A53_DIV					1
> +#define IMX8QM_A53_CLK					2
> +#define IMX8QM_A72_DIV					3
> +#define IMX8QM_A72_CLK					4
> +
> +/* SC Clocks. */
> +#define IMX8QM_SC_I2C_DIV				5
> +#define IMX8QM_SC_I2C_CLK				6
> +#define IMX8QM_SC_PID0_DIV				7
> +#define IMX8QM_SC_PID0_CLK				8
> +#define IMX8QM_SC_PIT_DIV				9
> +#define IMX8QM_SC_PIT_CLK				10
> +#define IMX8QM_SC_TPM_DIV				11
> +#define IMX8QM_SC_TPM_CLK				12
> +#define IMX8QM_SC_UART_DIV				13
> +#define IMX8QM_SC_UART_CLK				14
> +
> +/* LSIO */
> +#define IMX8QM_PWM0_DIV					15
> +#define IMX8QM_PWM0_CLK					16
> +#define IMX8QM_PWM1_DIV					17
> +#define IMX8QM_PWM1_CLK					18
> +#define IMX8QM_PWM2_DIV					19
> +#define IMX8QM_PWM2_CLK					20
> +#define IMX8QM_PWM3_DIV					21
> +#define IMX8QM_PWM3_CLK					22
> +#define IMX8QM_PWM4_DIV					23
> +#define IMX8QM_PWM4_CLK					24
> +#define IMX8QM_PWM5_DIV					26
> +#define IMX8QM_PWM5_CLK					27
> +#define IMX8QM_PWM6_DIV					28
> +#define IMX8QM_PWM6_CLK					29
> +#define IMX8QM_PWM7_DIV					30
> +#define IMX8QM_PWM7_CLK					31
> +#define IMX8QM_FSPI0_DIV				32
> +#define IMX8QM_FSPI0_CLK				33
> +#define IMX8QM_FSPI1_DIV				34
> +#define IMX8QM_FSPI1_CLK				35
> +#define IMX8QM_GPT0_DIV					36
> +//#define IMX8QM_GPT0_CLK				37
> +#define IMX8QM_GPT1_DIV					38
> +//#define IMX8QM_GPT1_CLK				39
> +#define IMX8QM_GPT2_DIV					40
> +#define IMX8QM_GPT2_CLK					41
> +#define IMX8QM_GPT3_DIV					42
> +#define IMX8QM_GPT3_CLK					43
> +#define IMX8QM_GPT4_DIV					44
> +#define IMX8QM_GPT4_CLK					45
> +
> +/* Connectivity */
> +#define IMX8QM_APBHDMA_CLK				46
> +#define IMX8QM_GPMI_APB_CLK				47
> +#define IMX8QM_GPMI_APB_BCH_CLK				48
> +#define IMX8QM_GPMI_BCH_IO_DIV				49
> +#define IMX8QM_GPMI_BCH_IO_CLK				50
> +#define IMX8QM_GPMI_BCH_DIV				51
> +#define IMX8QM_GPMI_BCH_CLK				52
> +#define IMX8QM_SDHC0_IPG_CLK				53
> +#define IMX8QM_SDHC0_DIV				54
> +#define IMX8QM_SDHC0_CLK				55
> +#define IMX8QM_SDHC1_IPG_CLK				56
> +#define IMX8QM_SDHC1_DIV				57
> +#define IMX8QM_SDHC1_CLK				58
> +#define IMX8QM_SDHC2_IPG_CLK				59
> +#define IMX8QM_SDHC2_DIV				60
> +#define IMX8QM_SDHC2_CLK				61
> +#define IMX8QM_USB2_OH_AHB_CLK				62
> +#define IMX8QM_USB2_OH_IPG_S_CL				63
> +#define IMX8QM_USB2_OH_IPG_S_PL301_CLK			64
> +#define IMX8QM_USB2_PHY_IPG_CLK				65
> +#define IMX8QM_USB3_IPG_CLK				66
> +#define IMX8QM_USB3_CORE_PCLK				67
> +#define IMX8QM_USB3_PHY_CLK				68
> +#define IMX8QM_USB3_ACLK_DIV				69
> +#define IMX8QM_USB3_ACLK				70
> +#define IMX8QM_USB3_BUS_DIV				71
> +#define IMX8QM_USB3_BUS_CLK				72
> +#define IMX8QM_USB3_LPM_DIV				73
> +#define IMX8QM_USB3_LPM_CLK				74
> +#define IMX8QM_ENET0_AHB_CLK				75
> +#define IMX8QM_ENET0_IPG_S_CLK				76
> +#define IMX8QM_ENET0_IPG_CLK				77
> +#define IMX8QM_ENET0_RGMII_DIV				78
> +#define IMX8QM_ENET0_RGMII_TX_CLK			79
> +#define IMX8QM_ENET0_ROOT_DIV				80
> +#define IMX8QM_ENET0_TX_CLK				81
> +#define IMX8QM_ENET0_ROOT_CLK				82
> +#define IMX8QM_ENET0_PTP_CLK				83
> +#define IMX8QM_ENET0_BYPASS_DIV				84
> +#define IMX8QM_ENET1_AHB_CLK				85
> +#define IMX8QM_ENET1_IPG_S_CLK				86
> +#define IMX8QM_ENET1_IPG_CLK				87
> +#define IMX8QM_ENET1_RGMII_DIV				88
> +#define IMX8QM_ENET1_RGMII_TX_CLK			89
> +#define IMX8QM_ENET1_ROOT_DIV				90
> +#define IMX8QM_ENET1_TX_CLK				91
> +#define IMX8QM_ENET1_ROOT_CLK				92
> +#define IMX8QM_ENET1_PTP_CLK				93
> +#define IMX8QM_ENET1_BYPASS_DIV				94
> +//#define IMX8QM_MLB_CLK				95
> +#define IMX8QM_MLB_HCLK					96
> +#define IMX8QM_MLB_IPG_CLK				97
> +#define IMX8QM_EDMA_CLK					98
> +#define IMX8QM_EDMA_IPG_CLK				99
> +
> +/* DMA */
> +#define IMX8QM_SPI0_IPG_CLK				100
> +#define IMX8QM_SPI0_DIV					101
> +#define IMX8QM_SPI0_CLK					102
> +#define IMX8QM_SPI1_IPG_CLK				103
> +#define IMX8QM_SPI1_DIV					104
> +#define IMX8QM_SPI1_CLK					105
> +#define IMX8QM_SPI2_IPG_CLK				106
> +#define IMX8QM_SPI2_DIV					107
> +#define IMX8QM_SPI2_CLK					108
> +#define IMX8QM_SPI3_IPG_CLK				109
> +#define IMX8QM_SPI3_DIV					110
> +#define IMX8QM_SPI3_CLK					111
> +#define IMX8QM_UART0_IPG_CLK				112
> +#define IMX8QM_UART0_DIV				113
> +#define IMX8QM_UART0_CLK				114
> +#define IMX8QM_UART1_IPG_CLK				115
> +#define IMX8QM_UART1_DIV				116
> +#define IMX8QM_UART1_CLK				117
> +#define IMX8QM_UART2_IPG_CLK				118
> +#define IMX8QM_UART2_DIV				119
> +#define IMX8QM_UART2_CLK				120
> +#define IMX8QM_UART3_IPG_CLK				121
> +#define IMX8QM_UART3_DIV				122
> +#define IMX8QM_UART3_CLK				123
> +#define IMX8QM_UART4_IPG_CLK				124
> +#define IMX8QM_UART4_DIV				125
> +#define IMX8QM_EMVSIM0_IPG_CLK				126
> +#define IMX8QM_UART4_CLK				127
> +#define IMX8QM_EMVSIM0_DIV				128
> +#define IMX8QM_EMVSIM0_CLK				129
> +#define IMX8QM_EMVSIM1_IPG_CLK				130
> +#define IMX8QM_EMVSIM1_DIV				131
> +#define IMX8QM_EMVSIM1_CLK				132
> +#define IMX8QM_CAN0_IPG_CHI_CLK				133
> +#define IMX8QM_CAN0_IPG_CLK				134
> +#define IMX8QM_CAN0_DIV					135
> +#define IMX8QM_CAN0_CLK					136
> +#define IMX8QM_CAN1_IPG_CHI_CLK				137
> +#define IMX8QM_CAN1_IPG_CLK				138
> +#define IMX8QM_CAN1_DIV					139
> +#define IMX8QM_CAN1_CLK					140
> +#define IMX8QM_CAN2_IPG_CHI_CLK				141
> +#define IMX8QM_CAN2_IPG_CLK				142
> +#define IMX8QM_CAN2_DIV					143
> +#define IMX8QM_CAN2_CLK					144
> +#define IMX8QM_I2C0_IPG_CLK				145
> +#define IMX8QM_I2C0_DIV					146
> +#define IMX8QM_I2C0_CLK					147
> +#define IMX8QM_I2C1_IPG_CLK				148
> +#define IMX8QM_I2C1_DIV					149
> +#define IMX8QM_I2C1_CLK					150
> +#define IMX8QM_I2C2_IPG_CLK				151
> +#define IMX8QM_I2C2_DIV					152
> +#define IMX8QM_I2C2_CLK					153
> +#define IMX8QM_I2C3_IPG_CLK				154
> +#define IMX8QM_I2C3_DIV					155
> +#define IMX8QM_I2C3_CLK					156
> +#define IMX8QM_I2C4_IPG_CLK				157
> +#define IMX8QM_I2C4_DIV					158
> +#define IMX8QM_I2C4_CLK					159
> +#define IMX8QM_FTM0_IPG_CLK				160
> +#define IMX8QM_FTM0_DIV					161
> +#define IMX8QM_FTM0_CLK					162
> +#define IMX8QM_FTM1_IPG_CLK				163
> +#define IMX8QM_FTM1_DIV					164
> +#define IMX8QM_FTM1_CLK					165
> +#define IMX8QM_ADC0_IPG_CLK				166
> +#define IMX8QM_ADC0_DIV					167
> +#define IMX8QM_ADC0_CLK					168
> +#define IMX8QM_ADC1_IPG_CLK				169
> +#define IMX8QM_ADC1_DIV					170
> +#define IMX8QM_ADC1_CLK					171
> +
> +/* Audio */
> +#define IMX8QM_AUD_PLL0_DIV				172
> +#define IMX8QM_AUD_PLL0					173
> +#define IMX8QM_AUD_PLL1_DIV				174
> +#define IMX8QM_AUD_PLL1					175
> +#define IMX8QM_AUD_AMIX_IPG				182
> +#define IMX8QM_AUD_ESAI_0_IPG				183
> +#define IMX8QM_AUD_ESAI_1_IPG				184
> +#define IMX8QM_AUD_ESAI_0_EXTAL_IPG			185
> +#define IMX8QM_AUD_ESAI_1_EXTAL_IPG			186
> +#define IMX8QM_AUD_SAI_0_IPG				187
> +#define IMX8QM_AUD_SAI_0_IPG_S				188
> +#define IMX8QM_AUD_SAI_0_MCLK				189
> +#define IMX8QM_AUD_SAI_1_IPG				190
> +#define IMX8QM_AUD_SAI_1_IPG_S				191
> +#define IMX8QM_AUD_SAI_1_MCLK				192
> +#define IMX8QM_AUD_SAI_2_IPG				193
> +#define IMX8QM_AUD_SAI_2_IPG_S				194
> +#define IMX8QM_AUD_SAI_2_MCLK				195
> +#define IMX8QM_AUD_SAI_3_IPG				196
> +#define IMX8QM_AUD_SAI_3_IPG_S				197
> +#define IMX8QM_AUD_SAI_3_MCLK				198
> +#define IMX8QM_AUD_SAI_6_IPG				199
> +#define IMX8QM_AUD_SAI_6_IPG_S				200
> +#define IMX8QM_AUD_SAI_6_MCLK				201
> +#define IMX8QM_AUD_SAI_7_IPG				202
> +#define IMX8QM_AUD_SAI_7_IPG_S				203
> +#define IMX8QM_AUD_SAI_7_MCLK				204
> +#define IMX8QM_AUD_SAI_HDMIRX0_IPG			205
> +#define IMX8QM_AUD_SAI_HDMIRX0_IPG_S			206
> +#define IMX8QM_AUD_SAI_HDMIRX0_MCLK			207
> +#define IMX8QM_AUD_SAI_HDMITX0_IPG			208
> +#define IMX8QM_AUD_SAI_HDMITX0_IPG_S			209
> +#define IMX8QM_AUD_SAI_HDMITX0_MCLK			210
> +#define IMX8QM_AUD_MQS_IPG				211
> +#define IMX8QM_AUD_MQS_HMCLK				212
> +#define IMX8QM_AUD_GPT5_IPG_S				213
> +#define IMX8QM_AUD_GPT5_CLKIN				214
> +#define IMX8QM_AUD_GPT5_24M_CLK				215
> +#define IMX8QM_AUD_GPT6_IPG_S				216
> +#define IMX8QM_AUD_GPT6_CLKIN				217
> +#define IMX8QM_AUD_GPT6_24M_CLK				218
> +#define IMX8QM_AUD_GPT7_IPG_S				219
> +#define IMX8QM_AUD_GPT7_CLKIN				220
> +#define IMX8QM_AUD_GPT7_24M_CLK				221
> +#define IMX8QM_AUD_GPT8_IPG_S				222
> +#define IMX8QM_AUD_GPT8_CLKIN				223
> +#define IMX8QM_AUD_GPT8_24M_CLK				224
> +#define IMX8QM_AUD_GPT9_IPG_S				225
> +#define IMX8QM_AUD_GPT9_CLKIN				226
> +#define IMX8QM_AUD_GPT9_24M_CLK				227
> +#define IMX8QM_AUD_GPT10_IPG_S				228
> +#define IMX8QM_AUD_GPT10_CLKIN				229
> +#define IMX8QM_AUD_GPT10_24M_CLK			230
> +#define IMX8QM_AUD_ACM_AUD_PLL_CLK0_DIV			232
> +#define IMX8QM_AUD_ACM_AUD_PLL_CLK0_CLK			233
> +#define IMX8QM_AUD_ACM_AUD_PLL_CLK1_DIV			234
> +#define IMX8QM_AUD_ACM_AUD_PLL_CLK1_CLK			235
> +#define IMX8QM_AUD_ACM_AUD_REC_CLK0_DIV			236
> +#define IMX8QM_AUD_ACM_AUD_REC_CLK0_CLK			237
> +#define IMX8QM_AUD_ACM_AUD_REC_CLK1_DIV			238
> +#define IMX8QM_AUD_ACM_AUD_REC_CLK1_CLK			239
> +#define IMX8QM_AUD_MCLKOUT0				240
> +#define IMX8QM_AUD_MCLKOUT1				241
> +#define IMX8QM_AUD_SPDIF_0_TX_CLK			242
> +#define IMX8QM_AUD_SPDIF_0_GCLKW			243
> +#define IMX8QM_AUD_SPDIF_0_IPG_S			244
> +#define IMX8QM_AUD_SPDIF_1_TX_CLK			245
> +#define IMX8QM_AUD_SPDIF_1_GCLKW			246
> +#define IMX8QM_AUD_SPDIF_1_IPG_S			247
> +#define IMX8QM_AUD_ASRC_0_IPG				248
> +#define IMX8QM_AUD_ASRC_0_MEM				249
> +#define IMX8QM_AUD_ASRC_1_IPG				250
> +#define IMX8QM_AUD_ASRC_1_MEM				251
> +
> +
> +/* VPU */
> +#define IMX8QM_VPU_CORE_DIV				252
> +#define IMX8QM_VPU_CORE_CLK				253
> +#define IMX8QM_VPU_UART_DIV				254
> +#define IMX8QM_VPU_UART_CLK				255
> +#define IMX8QM_VPU_DDR_DIV				256
> +#define IMX8QM_VPU_DDR_CLK				257
> +#define IMX8QM_VPU_SYS_DIV				258
> +#define IMX8QM_VPU_SYS_CLK				259
> +#define IMX8QM_VPU_XUVI_DIV				260
> +#define IMX8QM_VPU_XUVI_CLK				261
> +
> +/* GPU Clocks. */
> +#define IMX8QM_GPU0_CORE_DIV				262
> +#define IMX8QM_GPU0_CORE_CLK				263
> +#define IMX8QM_GPU0_SHADER_DIV				264
> +#define IMX8QM_GPU0_SHADER_CLK				265
> +#define IMX8QM_GPU1_CORE_DIV				266
> +#define IMX8QM_GPU1_CORE_CLK				267
> +#define IMX8QM_GPU1_SHADER_DIV				268
> +#define IMX8QM_GPU1_SHADER_CLK				269
> +
> +
> +/* MIPI CSI */
> +#define IMX8QM_CSI0_IPG_CLK_S				270
> +#define IMX8QM_CSI0_LIS_IPG_CLK				271
> +#define IMX8QM_CSI0_APB_CLK				272
> +#define IMX8QM_CSI0_I2C0_DIV				273
> +#define IMX8QM_CSI0_I2C0_CLK				274
> +#define IMX8QM_CSI0_PWM0_DIV				275
> +#define IMX8QM_CSI0_PWM0_CLK				276
> +#define IMX8QM_CSI0_CORE_DIV				277
> +#define IMX8QM_CSI0_CORE_CLK				278
> +#define IMX8QM_CSI0_ESC_DIV				279
> +#define IMX8QM_CSI0_ESC_CLK				280
> +#define IMX8QM_CSI1_IPG_CLK_S				281
> +#define IMX8QM_CSI1_LIS_IPG_CLK				282
> +#define IMX8QM_CSI1_APB_CLK				283
> +#define IMX8QM_CSI1_I2C0_DIV				284
> +#define IMX8QM_CSI1_I2C0_CLK				285
> +#define IMX8QM_CSI1_PWM0_DIV				286
> +#define IMX8QM_CSI1_PWM0_CLK				287
> +#define IMX8QM_CSI1_CORE_DIV				288
> +#define IMX8QM_CSI1_CORE_CLK				289
> +#define IMX8QM_CSI1_ESC_DIV				290
> +#define IMX8QM_CSI1_ESC_CLK				291
> +
> +
> +/* Display */
> +#define IMX8QM_DC0_PLL0_DIV				292
> +#define IMX8QM_DC0_PLL0_CLK				293
> +#define IMX8QM_DC0_PLL1_DIV				294
> +#define IMX8QM_DC0_PLL1_CLK				295
> +#define IMX8QM_DC0_DISP0_DIV				296
> +#define IMX8QM_DC0_DISP0_CLK				297
> +#define IMX8QM_DC0_DISP1_DIV				298
> +#define IMX8QM_DC0_DISP1_CLK				299
> +#define IMX8QM_DC0_BYPASS_0_DIV				300
> +#define IMX8QM_DC0_BYPASS_1_DIV				301
> +#define IMX8QM_DC0_IRIS_AXI_CLK				302
> +#define IMX8AM_DC0_IRIS_MVPL_CLK			303
> +#define IMX8QM_DC0_DISP0_MSI_CLK			304
> +#define IMX8QM_DC0_LIS_IPG_CLK				305
> +#define IMX8QM_DC0_PXL_CMB_APB_CLK			306
> +#define IMX8QM_DC0_PRG0_RTRAM_CLK			307
> +#define IMX8QM_DC0_PRG1_RTRAM_CLK			308
> +#define IMX8QM_DC0_PRG2_RTRAM_CLK			309
> +#define IMX8QM_DC0_PRG3_RTRAM_CLK			310
> +#define IMX8QM_DC0_PRG4_RTRAM_CLK			311
> +#define IMX8QM_DC0_PRG5_RTRAM_CLK			312
> +#define IMX8QM_DC0_PRG6_RTRAM_CLK			313
> +#define IMX8QM_DC0_PRG7_RTRAM_CLK			314
> +#define IMX8QM_DC0_PRG8_RTRAM_CLK			315
> +#define IMX8QM_DC0_PRG0_APB_CLK				316
> +#define IMX8QM_DC0_PRG1_APB_CLK				317
> +#define IMX8QM_DC0_PRG2_APB_CLK				318
> +#define IMX8QM_DC0_PRG3_APB_CLK				319
> +#define IMX8QM_DC0_PRG4_APB_CLK				320
> +#define IMX8QM_DC0_PRG5_APB_CLK				321
> +#define IMX8QM_DC0_PRG6_APB_CLK				322
> +#define IMX8QM_DC0_PRG7_APB_CLK				323
> +#define IMX8QM_DC0_PRG8_APB_CLK				324
> +#define IMX8QM_DC0_DPR0_APB_CLK				325
> +#define IMX8QM_DC0_DPR1_APB_CLK				326
> +#define IMX8QM_DC0_RTRAM0_CLK				327
> +#define IMX8QM_DC0_RTRAM1_CLK				328
> +#define IMX8QM_DC1_PLL0_DIV				329
> +#define IMX8QM_DC1_PLL0_CLK				330
> +#define IMX8QM_DC1_PLL1_DIV				331
> +#define IMX8QM_DC1_PLL1_CLK				332
> +#define IMX8QM_DC1_DISP0_DIV				333
> +#define IMX8QM_DC1_DISP0_CLK				334
> +#define IMX8QM_DC1_BYPASS_0_DIV				335
> +#define IMX8QM_DC1_BYPASS_1_DIV				336
> +#define IMX8QM_DC1_DISP1_DIV				337
> +#define IMX8QM_DC1_DISP1_CLK				338
> +#define IMX8QM_DC1_IRIS_AXI_CLK				339
> +#define IMX8AM_DC1_IRIS_MVPL_CLK			340
> +#define IMX8QM_DC1_DISP0_MSI_CLK			341
> +#define IMX8QM_DC1_LIS_IPG_CLK				342
> +#define IMX8QM_DC1_PXL_CMB_APB_CLK			343
> +#define IMX8QM_DC1_PRG0_RTRAM_CLK			344
> +#define IMX8QM_DC1_PRG1_RTRAM_CLK			345
> +#define IMX8QM_DC1_PRG2_RTRAM_CLK			346
> +#define IMX8QM_DC1_PRG3_RTRAM_CLK			347
> +#define IMX8QM_DC1_PRG4_RTRAM_CLK			348
> +#define IMX8QM_DC1_PRG5_RTRAM_CLK			349
> +#define IMX8QM_DC1_PRG6_RTRAM_CLK			350
> +#define IMX8QM_DC1_PRG7_RTRAM_CLK			351
> +#define IMX8QM_DC1_PRG8_RTRAM_CLK			352
> +#define IMX8QM_DC1_PRG0_APB_CLK				353
> +#define IMX8QM_DC1_PRG1_APB_CLK				354
> +#define IMX8QM_DC1_PRG2_APB_CLK				355
> +#define IMX8QM_DC1_PRG3_APB_CLK				356
> +#define IMX8QM_DC1_PRG4_APB_CLK				357
> +#define IMX8QM_DC1_PRG5_APB_CLK				358
> +#define IMX8QM_DC1_PRG6_APB_CLK				359
> +#define IMX8QM_DC1_PRG7_APB_CLK				360
> +#define IMX8QM_DC1_PRG8_APB_CLK				361
> +#define IMX8QM_DC1_DPR0_APB_CLK				362
> +#define IMX8QM_DC1_DPR1_APB_CLK				363
> +#define IMX8QM_DC1_RTRAM0_CLK				364
> +#define IMX8QM_DC1_RTRAM1_CLK				365
> +
> +/* DRC */
> +#define IMX8QM_DRC0_PLL0_DIV				366
> +#define IMX8QM_DRC0_PLL0_CLK				367
> +#define IMX8QM_DRC0_DIV					368
> +#define IMX8QM_DRC0_CLK					369
> +#define IMX8QM_DRC1_PLL0_DIV				370
> +#define IMX8QM_DRC1_PLL0_CLK				371
> +#define IMX8QM_DRC1_DIV					372
> +#define IMX8QM_DRC1_CLK					373
> +
> +/* HDMI */
> +#define IMX8QM_HDMI_AV_PLL_DIV				374
> +#define IMX8QM_HDMI_AV_PLL_CLK				375
> +#define IMX8QM_HDMI_I2S_BYPASS_CLK			376
> +#define IMX8QM_HDMI_I2C0_DIV				377
> +#define IMX8QM_HDMI_I2C0_CLK				378
> +#define IMX8QM_HDMI_PXL_DIV				379
> +#define IMX8QM_HDMI_PXL_CLK				380
> +#define IMX8QM_HDMI_PXL_LINK_DIV			381
> +#define IMX8QM_HDMI_PXL_LINK_CLK			382
> +#define IMX8QM_HDMI_PXL_MUX_DIV				383
> +#define IMX8QM_HDMI_PXL_MUX_CLK				384
> +#define IMX8QM_HDMI_I2S_DIV				385
> +#define IMX8QM_HDMI_I2S_CLK				386
> +#define IMX8QM_HDMI_HDP_CORE_DIV			387
> +#define IMX8QM_HDMI_HDP_CORE_CLK			388
> +#define IMX8QM_HDMI_I2C_IPG_S_CLK			389
> +#define IMX8QM_HDMI_I2C_IPG_CLK				390
> +#define IMX8QM_HDMI_PWM_IPG_S_CLK			391
> +#define IMX8QM_HDMI_PWM_IPG_CLK				392
> +#define IMX8QM_HDMI_PWM_32K_CLK				393
> +#define IMX8QM_HDMI_GPIO_IPG_CLK			394
> +#define IMX8QM_HDMI_PXL_LINK_SLV_ODD_CLK		395
> +#define IMX8QM_HDMI_PXL_LINK_SLV_EVEN_CLK		396
> +#define IMX8QM_HDMI_LIS_IPG_CLK				397
> +#define IMX8QM_HDMI_MSI_HCLK				398
> +#define IMX8QM_HDMI_PXL_EVEN_CLK			399
> +#define IMX8QM_HDMI_HDP_CLK				400
> +#define IMX8QM_HDMI_PXL_DBL_CLK				401
> +#define IMX8QM_HDMI_APB_CLK				402
> +#define IMX8QM_HDMI_PXL_LPCG_CLK			403
> +#define IMX8QM_HDMI_HDP_PHY_CLK				404
> +#define IMX8QM_HDMI_IPG_DIV				405
> +#define IMX8QM_HDMI_VIF_CLK				406
> +#define IMX8QM_HDMI_DIG_PLL_DIV				407
> +#define IMX8QM_HDMI_DIG_PLL_CLK				408
> +#define IMX8QM_HDMI_APB_MUX_CSR_CLK			409
> +#define IMX8QM_HDMI_APB_MUX_CTRL_CLK			410
> +
> +/* RX-HDMI */
> +#define IMX8QM_HDMI_RX_I2S_BYPASS_CLK			411
> +#define IMX8QM_HDMI_RX_BYPASS_CLK			412
> +#define IMX8QM_HDMI_RX_SPDIF_BYPASS_CLK			413
> +#define IMX8QM_HDMI_RX_I2C0_DIV				414
> +#define IMX8QM_HDMI_RX_I2C0_CLK				415
> +#define IMX8QM_HDMI_RX_SPDIF_DIV			416
> +#define IMX8QM_HDMI_RX_SPDIF_CLK			417
> +#define IMX8QM_HDMI_RX_HD_REF_DIV			418
> +#define IMX8QM_HDMI_RX_HD_REF_CLK			419
> +#define IMX8QM_HDMI_RX_HD_CORE_DIV			420
> +#define IMX8QM_HDMI_RX_HD_CORE_CLK			421
> +#define IMX8QM_HDMI_RX_PXL_DIV				422
> +#define IMX8QM_HDMI_RX_PXL_CLK				423
> +#define IMX8QM_HDMI_RX_I2S_DIV				424
> +#define IMX8QM_HDMI_RX_I2S_CLK				425
> +#define IMX8QM_HDMI_RX_PWM_DIV				426
> +#define IMX8QM_HDMI_RX_PWM_CLK				427
> +
> +/* LVDS */
> +#define IMX8QM_LVDS0_BYPASS_CLK				428
> +#define IMX8QM_LVDS0_PIXEL_DIV				429
> +#define IMX8QM_LVDS0_PIXEL_CLK				430
> +#define IMX8QM_LVDS0_PHY_DIV				431
> +#define IMX8QM_LVDS0_PHY_CLK				432
> +#define IMX8QM_LVDS0_I2C0_IPG_CLK			433
> +#define IMX8QM_LVDS0_I2C0_DIV				434
> +#define IMX8QM_LVDS0_I2C0_CLK				435
> +#define IMX8QM_LVDS0_I2C1_IPG_CLK			436
> +#define IMX8QM_LVDS0_I2C1_DIV				437
> +#define IMX8QM_LVDS0_I2C1_CLK				438
> +#define IMX8QM_LVDS0_PWM0_IPG_CLK			439
> +#define IMX8QM_LVDS0_PWM0_DIV				440
> +#define IMX8QM_LVDS0_PWM0_CLK				441
> +#define IMX8QM_LVDS0_GPIO_IPG_CLK			444
> +#define IMX8QM_LVDS1_BYPASS_DIV				445
> +#define IMX8QM_LVDS1_BYPASS_CLK				446
> +#define IMX8QM_LVDS1_PIXEL_DIV				447
> +#define IMX8QM_LVDS1_PIXEL_CLK				448
> +#define IMX8QM_LVDS1_PHY_DIV				449
> +#define IMX8QM_LVDS1_PHY_CLK				450
> +#define IMX8QM_LVDS1_I2C0_IPG_CLK			451
> +#define IMX8QM_LVDS1_I2C0_DIV				452
> +#define IMX8QM_LVDS1_I2C0_CLK				453
> +#define IMX8QM_LVDS1_I2C1_IPG_CLK			454
> +#define IMX8QM_LVDS1_I2C1_DIV				455
> +#define IMX8QM_LVDS1_I2C1_CLK				456
> +#define IMX8QM_LVDS1_PWM0_IPG_CLK			457
> +#define IMX8QM_LVDS1_PWM0_DIV				458
> +#define IMX8QM_LVDS1_PWM0_CLK				459
> +#define IMX8QM_LVDS1_GPIO_IPG_CLK			462
> +
> +/* MIPI */
> +#define IMX8QM_MIPI0_BYPASS_CLK				465
> +#define IMX8QM_MIPI0_I2C0_DIV				466
> +#define IMX8QM_MIPI0_I2C0_CLK				467
> +#define IMX8QM_MIPI0_I2C1_DIV				468
> +#define IMX8QM_MIPI0_I2C1_CLK				469
> +#define IMX8QM_MIPI0_PWM0_DIV				470
> +#define IMX8QM_MIPI0_PWM0_CLK				471
> +#define IMX8QM_MIPI0_DSI_TX_ESC_DIV			472
> +#define IMX8QM_MIPI0_DSI_TX_ESC_CLK			473
> +#define IMX8QM_MIPI0_DSI_RX_ESC_DIV			474
> +#define IMX8QM_MIPI0_DSI_RX_ESC_CLK			475
> +#define IMX8QM_MIPI0_PXL_DIV				476
> +#define IMX8QM_MIPI0_PXL_CLK				477
> +#define IMX8QM_MIPI1_BYPASS_CLK				479
> +#define IMX8QM_MIPI1_I2C0_DIV				480
> +#define IMX8QM_MIPI1_I2C0_CLK				481
> +#define IMX8QM_MIPI1_I2C1_DIV				482
> +#define IMX8QM_MIPI1_I2C1_CLK				483
> +#define IMX8QM_MIPI1_PWM0_DIV				484
> +#define IMX8QM_MIPI1_PWM0_CLK				485
> +#define IMX8QM_MIPI1_DSI_TX_ESC_DIV			486
> +#define IMX8QM_MIPI1_DSI_TX_ESC_CLK			487
> +#define IMX8QM_MIPI1_DSI_RX_ESC_DIV			488
> +#define IMX8QM_MIPI1_DSI_RX_ESC_CLK			489
> +#define IMX8QM_MIPI1_PXL_DIV				490
> +#define IMX8QM_MIPI1_PXL_CLK				491
> +
> +/* Imaging */
> +#define IMX8QM_IMG_JPEG_ENC_IPG_CLK			492
> +#define IMX8QM_IMG_JPEG_ENC_CLK				493
> +#define IMX8QM_IMG_JPEG_DEC_IPG_CLK			494
> +#define IMX8QM_IMG_JPEG_DEC_CLK				495
> +#define IMX8QM_IMG_PXL_LINK_DC0_CLK			496
> +#define IMX8QM_IMG_PXL_LINK_DC1_CLK			497
> +#define IMX8QM_IMG_PXL_LINK_CSI0_CLK			498
> +#define IMX8QM_IMG_PXL_LINK_CSI1_CLK			499
> +#define IMX8QM_IMG_PXL_LINK_HDMI_IN_CLK			500
> +#define IMX8QM_IMG_PDMA_0_CLK				501
> +#define IMX8QM_IMG_PDMA_1_CLK				502
> +#define IMX8QM_IMG_PDMA_2_CLK				503
> +#define IMX8QM_IMG_PDMA_3_CLK				504
> +#define IMX8QM_IMG_PDMA_4_CLK				505
> +#define IMX8QM_IMG_PDMA_5_CLK				506
> +#define IMX8QM_IMG_PDMA_6_CLK				507
> +#define IMX8QM_IMG_PDMA_7_CLK				508
> +
> +/* HSIO */
> +#define IMX8QM_HSIO_PCIE_A_MSTR_AXI_CLK			509
> +#define IMX8QM_HSIO_PCIE_A_SLV_AXI_CLK			510
> +#define IMX8QM_HSIO_PCIE_A_DBI_AXI_CLK			511
> +#define IMX8QM_HSIO_PCIE_B_MSTR_AXI_CLK			512
> +#define IMX8QM_HSIO_PCIE_B_SLV_AXI_CLK			513
> +#define IMX8QM_HSIO_PCIE_B_DBI_AXI_CLK			514
> +#define IMX8QM_HSIO_PCIE_X1_PER_CLK			515
> +#define IMX8QM_HSIO_PCIE_X2_PER_CLK			516
> +#define IMX8QM_HSIO_SATA_PER_CLK			517
> +#define IMX8QM_HSIO_PHY_X1_PER_CLK			518
> +#define IMX8QM_HSIO_PHY_X2_PER_CLK			519
> +#define IMX8QM_HSIO_MISC_PER_CLK			520
> +#define IMX8QM_HSIO_PHY_X1_APB_CLK			521
> +#define IMX8QM_HSIO_PHY_X2_APB_0_CLK			522
> +#define IMX8QM_HSIO_PHY_X2_APB_1_CLK			523
> +#define IMX8QM_HSIO_SATA_CLK				524
> +#define IMX8QM_HSIO_GPIO_CLK				525
> +#define IMX8QM_HSIO_PHY_X1_PCLK				526
> +#define IMX8QM_HSIO_PHY_X2_PCLK_0			527
> +#define IMX8QM_HSIO_PHY_X2_PCLK_1			528
> +#define IMX8QM_HSIO_SATA_EPCS_RX_CLK			529
> +#define IMX8QM_HSIO_SATA_EPCS_TX_CLK			530
> +
> +
> +/* M4 */
> +#define IMX8QM_M4_0_CORE_DIV				531
> +#define IMX8QM_M4_0_CORE_CLK				532
> +#define IMX8QM_M4_0_I2C_DIV				533
> +#define IMX8QM_M4_0_I2C_CLK				534
> +#define IMX8QM_M4_0_PIT_DIV				535
> +#define IMX8QM_M4_0_PIT_CLK				536
> +#define IMX8QM_M4_0_TPM_DIV				537
> +#define IMX8QM_M4_0_TPM_CLK				538
> +#define IMX8QM_M4_0_UART_DIV				539
> +#define IMX8QM_M4_0_UART_CLK				540
> +#define IMX8QM_M4_0_WDOG_DIV				541
> +#define IMX8QM_M4_0_WDOG_CLK				542
> +#define IMX8QM_M4_1_CORE_DIV				543
> +#define IMX8QM_M4_1_CORE_CLK				544
> +#define IMX8QM_M4_1_I2C_DIV				545
> +#define IMX8QM_M4_1_I2C_CLK				546
> +#define IMX8QM_M4_1_PIT_DIV				547
> +#define IMX8QM_M4_1_PIT_CLK				548
> +#define IMX8QM_M4_1_TPM_DIV				549
> +#define IMX8QM_M4_1_TPM_CLK				550
> +#define IMX8QM_M4_1_UART_DIV				551
> +#define IMX8QM_M4_1_UART_CLK				552
> +#define IMX8QM_M4_1_WDOG_DIV				553
> +#define IMX8QM_M4_1_WDOG_CLK				554
> +
> +/* IPG clocks */
> +#define IMX8QM_24MHZ					555
> +#define IMX8QM_GPT_3M					556
> +#define IMX8QM_IPG_DMA_CLK_ROOT				557
> +#define IMX8QM_IPG_AUD_CLK_ROOT				558
> +#define IMX8QM_IPG_CONN_CLK_ROOT			559
> +#define IMX8QM_AHB_CONN_CLK_ROOT			560
> +#define IMX8QM_AXI_CONN_CLK_ROOT			561
> +#define IMX8QM_IPG_MIPI_CSI_CLK_ROOT			562
> +#define IMX8QM_DC_AXI_EXT_CLK				563
> +#define IMX8QM_DC_AXI_INT_CLK				564
> +#define IMX8QM_DC_CFG_CLK				565
> +#define IMX8QM_HDMI_IPG_CLK				566
> +#define IMX8QM_LVDS_IPG_CLK				567
> +#define IMX8QM_IMG_AXI_CLK				568
> +#define IMX8QM_IMG_IPG_CLK				569
> +#define IMX8QM_IMG_PXL_CLK				570
> +#define IMX8QM_CSI0_I2C0_IPG_CLK			571
> +#define IMX8QM_CSI0_PWM0_IPG_CLK			572
> +#define IMX8QM_CSI1_I2C0_IPG_CLK			573
> +#define IMX8QM_CSI1_PWM0_IPG_CLK			574
> +#define IMX8QM_DC0_DPR0_B_CLK				575
> +#define IMX8QM_DC0_DPR1_B_CLK				576
> +#define IMX8QM_DC1_DPR0_B_CLK				577
> +#define IMX8QM_DC1_DPR1_B_CLK				578
> +#define IMX8QM_32KHZ					579
> +#define IMX8QM_HSIO_AXI_CLK				580
> +#define IMX8QM_HSIO_PER_CLK				581
> +#define IMX8QM_HDMI_RX_GPIO_IPG_S_CLK			582
> +#define IMX8QM_HDMI_RX_PWM_IPG_S_CLK			583
> +#define IMX8QM_HDMI_RX_PWM_IPG_CLK			584
> +#define IMX8QM_HDMI_RX_I2C_DIV_CLK			585
> +#define IMX8QM_HDMI_RX_I2C_IPG_S_CLK			586
> +#define IMX8QM_HDMI_RX_I2C_IPG_CLK			587
> +#define IMX8QM_HDMI_RX_SINK_PCLK			588
> +#define IMX8QM_HDMI_RX_SINK_SCLK			589
> +#define IMX8QM_HDMI_RX_PXL_ENC_CLK			590
> +#define IMX8QM_HDMI_RX_IPG_CLK				591
> +
> +/* ACM */
> +#define IMX8QM_HDMI_RX_MCLK				592
> +#define IMX8QM_EXT_AUD_MCLK0				593
> +#define IMX8QM_EXT_AUD_MCLK1				594
> +#define IMX8QM_ESAI0_RX_CLK				595
> +#define IMX8QM_ESAI0_RX_HF_CLK				596
> +#define IMX8QM_ESAI0_TX_CLK				597
> +#define IMX8QM_ESAI0_TX_HF_CLK				598
> +#define IMX8QM_ESAI1_RX_CLK				599
> +#define IMX8QM_ESAI1_RX_HF_CLK				600
> +#define IMX8QM_ESAI1_TX_CLK				601
> +#define IMX8QM_ESAI1_TX_HF_CLK				602
> +//#define IMX8QM_SPDIF0_RX				603
> +#define IMX8QM_SPDIF1_RX				604
> +#define IMX8QM_SAI0_RX_BCLK				605
> +#define IMX8QM_SAI0_TX_BCLK				606
> +#define IMX8QM_SAI1_RX_BCLK				607
> +#define IMX8QM_SAI1_TX_BCLK				608
> +#define IMX8QM_SAI2_RX_BCLK				609
> +#define IMX8QM_SAI3_RX_BCLK				610
> +#define IMX8QM_HDMI_RX_SAI0_RX_BCLK			611
> +#define IMX8QM_SAI6_RX_BCLK				612
> +#define IMX8QM_HDMI_TX_SAI0_TX_BCLK			613
> +
> +#define IMX8QM_ACM_AUD_CLK0_SEL				614
> +#define IMX8QM_ACM_AUD_CLK0_CLK				615
> +#define IMX8QM_ACM_AUD_CLK1_SEL				616
> +#define IMX8QM_ACM_AUD_CLK1_CLK				617
> +#define IMX8QM_ACM_MCLKOUT0_SEL				618
> +#define IMX8QM_ACM_MCLKOUT0_CLK				619
> +#define IMX8QM_ACM_MCLKOUT1_SEL				620
> +#define IMX8QM_ACM_MCLKOUT1_CLK				621
> +#define IMX8QM_ACM_ASRC0_MUX_CLK_SEL			622
> +#define IMX8QM_ACM_ASRC0_MUX_CLK_CLK			623
> +#define IMX8QM_ACM_ASRC1_MUX_CLK_SEL			624
> +#define IMX8QM_ACM_ASRC1_MUX_CLK_CLK			625
> +#define IMX8QM_ACM_ESAI0_MCLK_SEL			626
> +#define IMX8QM_ACM_ESAI0_MCLK_CLK			627
> +#define IMX8QM_ACM_ESAI1_MCLK_SEL			628
> +#define IMX8QM_ACM_ESAI1_MCLK_CLK			629
> +#define IMX8QM_ACM_GPT0_MUX_CLK_SEL			630
> +#define IMX8QM_ACM_GPT0_MUX_CLK_CLK			631
> +#define IMX8QM_ACM_GPT1_MUX_CLK_SEL			632
> +#define IMX8QM_ACM_GPT1_MUX_CLK_CLK			633
> +#define IMX8QM_ACM_GPT2_MUX_CLK_SEL			634
> +#define IMX8QM_ACM_GPT2_MUX_CLK_CLK			635
> +#define IMX8QM_ACM_GPT3_MUX_CLK_SEL			636
> +#define IMX8QM_ACM_GPT3_MUX_CLK_CLK			637
> +#define IMX8QM_ACM_GPT4_MUX_CLK_SEL			638
> +#define IMX8QM_ACM_GPT4_MUX_CLK_CLK			639
> +#define IMX8QM_ACM_GPT5_MUX_CLK_SEL			640
> +#define IMX8QM_ACM_GPT5_MUX_CLK_CLK			641
> +#define IMX8QM_ACM_SAI0_MCLK_SEL			642
> +#define IMX8QM_ACM_SAI0_MCLK_CLK			643
> +#define IMX8QM_ACM_SAI1_MCLK_SEL			644
> +#define IMX8QM_ACM_SAI1_MCLK_CLK			645
> +#define IMX8QM_ACM_SAI2_MCLK_SEL			646
> +#define IMX8QM_ACM_SAI2_MCLK_CLK			647
> +#define IMX8QM_ACM_SAI3_MCLK_SEL			648
> +#define IMX8QM_ACM_SAI3_MCLK_CLK			649
> +#define IMX8QM_ACM_HDMI_RX_SAI0_MCLK_SEL		650
> +#define IMX8QM_ACM_HDMI_RX_SAI0_MCLK_CLK		651
> +#define IMX8QM_ACM_HDMI_TX_SAI0_MCLK_SEL		652
> +#define IMX8QM_ACM_HDMI_TX_SAI0_MCLK_CLK		653
> +#define IMX8QM_ACM_SAI6_MCLK_SEL			654
> +#define IMX8QM_ACM_SAI6_MCLK_CLK			655
> +#define IMX8QM_ACM_SAI7_MCLK_SEL			656
> +#define IMX8QM_ACM_SAI7_MCLK_CLK			657
> +#define IMX8QM_ACM_SPDIF0_TX_CLK_SEL			658
> +#define IMX8QM_ACM_SPDIF0_TX_CLK_CLK			659
> +#define IMX8QM_ACM_SPDIF1_TX_CLK_SEL			660
> +#define IMX8QM_ACM_SPDIF1_TX_CLK_CLK			661
> +#define IMX8QM_ACM_MQS_TX_CLK_SEL			662
> +#define IMX8QM_ACM_MQS_TX_CLK_CLK			663
> +
> +#define IMX8QM_ENET0_REF_25MHZ_125MHZ_SEL		664
> +#define IMX8QM_ENET0_REF_25MHZ_125MHZ_CLK		665
> +#define IMX8QM_ENET1_REF_25MHZ_125MHZ_SEL		666
> +#define IMX8QM_ENET1_REF_25MHZ_125MHZ_CLK		667
> +#define IMX8QM_ENET0_REF_50MHZ_CLK			668
> +#define IMX8QM_ENET1_REF_50MHZ_CLK			669
> +#define IMX8QM_ENET_25MHZ_CLK				670
> +#define IMX8QM_ENET_125MHZ_CLK				671
> +#define IMX8QM_ENET0_REF_DIV				672
> +#define IMX8QM_ENET0_REF_CLK				673
> +#define IMX8QM_ENET1_REF_DIV				674
> +#define IMX8QM_ENET1_REF_CLK				675
> +#define IMX8QM_ENET0_RMII_TX_CLK			676
> +#define IMX8QM_ENET1_RMII_TX_CLK			677
> +#define IMX8QM_ENET0_RMII_TX_SEL			678
> +#define IMX8QM_ENET1_RMII_TX_SEL			679
> +#define IMX8QM_ENET0_RMII_RX_CLK			680
> +#define IMX8QM_ENET1_RMII_RX_CLK			681
> +
> +#define IMX8QM_KPP_CLK					683
> +#define IMX8QM_GPT0_HF_CLK				684
> +#define IMX8QM_GPT0_IPG_S_CLK				685
> +#define IMX8QM_GPT0_IPG_SLV_CLK				686
> +#define IMX8QM_GPT0_IPG_MSTR_CLK			687
> +#define IMX8QM_GPT1_HF_CLK				688
> +#define IMX8QM_GPT1_IPG_S_CLK				689
> +#define IMX8QM_GPT1_IPG_SLV_CLK				690
> +#define IMX8QM_GPT1_IPG_MSTR_CLK			691
> +#define IMX8QM_GPT2_HF_CLK				692
> +#define IMX8QM_GPT2_IPG_S_CLK				693
> +#define IMX8QM_GPT2_IPG_SLV_CLK				694
> +#define IMX8QM_GPT2_IPG_MSTR_CLK			695
> +#define IMX8QM_GPT3_HF_CLK				696
> +#define IMX8QM_GPT3_IPG_S_CLK				697
> +#define IMX8QM_GPT3_IPG_SLV_CLK				698
> +#define IMX8QM_GPT3_IPG_MSTR_CLK			699
> +#define IMX8QM_GPT4_HF_CLK				700
> +#define IMX8QM_GPT4_IPG_S_CLK				701
> +#define IMX8QM_GPT4_IPG_SLV_CLK				702
> +#define IMX8QM_GPT4_IPG_MSTR_CLK			703
> +#define IMX8QM_PWM0_HF_CLK				704
> +#define IMX8QM_PWM0_IPG_S_CLK				705
> +#define IMX8QM_PWM0_IPG_SLV_CLK				706
> +#define IMX8QM_PWM0_IPG_MSTR_CLK			707
> +#define IMX8QM_PWM1_HF_CLK				708
> +#define IMX8QM_PWM1_IPG_S_CLK				709
> +#define IMX8QM_PWM1_IPG_SLV_CLK				710
> +#define IMX8QM_PWM1_IPG_MSTR_CLK			711
> +#define IMX8QM_PWM2_HF_CLK				712
> +#define IMX8QM_PWM2_IPG_S_CLK				713
> +#define IMX8QM_PWM2_IPG_SLV_CLK				714
> +#define IMX8QM_PWM2_IPG_MSTR_CLK			715
> +#define IMX8QM_PWM3_HF_CLK				716
> +#define IMX8QM_PWM3_IPG_S_CLK				717
> +#define IMX8QM_PWM3_IPG_SLV_CLK				718
> +#define IMX8QM_PWM3_IPG_MSTR_CLK			719
> +#define IMX8QM_PWM4_HF_CLK				720
> +#define IMX8QM_PWM4_IPG_S_CLK				721
> +#define IMX8QM_PWM4_IPG_SLV_CLK				722
> +#define IMX8QM_PWM4_IPG_MSTR_CLK			723
> +#define IMX8QM_PWM5_HF_CLK				724
> +#define IMX8QM_PWM5_IPG_S_CLK				725
> +#define IMX8QM_PWM5_IPG_SLV_CLK				726
> +#define IMX8QM_PWM5_IPG_MSTR_CLK			727
> +#define IMX8QM_PWM6_HF_CLK				728
> +#define IMX8QM_PWM6_IPG_S_CLK				729
> +#define IMX8QM_PWM6_IPG_SLV_CLK				730
> +#define IMX8QM_PWM6_IPG_MSTR_CLK			731
> +#define IMX8QM_PWM7_HF_CLK				732
> +#define IMX8QM_PWM7_IPG_S_CLK				733
> +#define IMX8QM_PWM7_IPG_SLV_CLK				734
> +#define IMX8QM_PWM7_IPG_MSTR_CLK			735
> +#define IMX8QM_FSPI0_HCLK				736
> +#define IMX8QM_FSPI0_IPG_CLK				737
> +#define IMX8QM_FSPI0_IPG_S_CLK				738
> +#define IMX8QM_FSPI1_HCLK				736
> +#define IMX8QM_FSPI1_IPG_CLK				737
> +#define IMX8QM_FSPI1_IPG_S_CLK				738
> +#define IMX8QM_GPIO0_IPG_S_CLK				739
> +#define IMX8QM_GPIO1_IPG_S_CLK				740
> +#define IMX8QM_GPIO2_IPG_S_CLK				741
> +#define IMX8QM_GPIO3_IPG_S_CLK				742
> +#define IMX8QM_GPIO4_IPG_S_CLK				743
> +#define IMX8QM_GPIO5_IPG_S_CLK				744
> +#define IMX8QM_GPIO6_IPG_S_CLK				745
> +#define IMX8QM_GPIO7_IPG_S_CLK				746
> +#define IMX8QM_ROMCP_CLK				747
> +#define IMX8QM_ROMCP_REG_CLK				748
> +#define IMX8QM_96KROM_CLK				749
> +#define IMX8QM_OCRAM_MEM_CLK				750
> +#define IMX8QM_OCRAM_CTRL_CLK				751
> +#define IMX8QM_LSIO_BUS_CLK				752
> +#define IMX8QM_LSIO_MEM_CLK				753
> +#define IMX8QM_LVDS0_LIS_IPG_CLK			754
> +#define IMX8QM_LVDS1_LIS_IPG_CLK			755
> +#define IMX8QM_MIPI0_LIS_IPG_CLK			756
> +#define IMX8QM_MIPI0_I2C0_IPG_S_CLK			757
> +#define IMX8QM_MIPI0_I2C0_IPG_CLK			758
> +#define IMX8QM_MIPI0_I2C1_IPG_S_CLK			759
> +#define IMX8QM_MIPI0_I2C1_IPG_CLK			760
> +#define IMX8QM_MIPI0_CLK_ROOT				761
> +#define IMX8QM_MIPI1_LIS_IPG_CLK			762
> +#define IMX8QM_MIPI1_I2C0_IPG_S_CLK			763
> +#define IMX8QM_MIPI1_I2C0_IPG_CLK			764
> +#define IMX8QM_MIPI1_I2C1_IPG_S_CLK			765
> +#define IMX8QM_MIPI1_I2C1_IPG_CLK			766
> +#define IMX8QM_MIPI1_CLK_ROOT				767
> +#define IMX8QM_DC0_DISP0_SEL				768
> +#define IMX8QM_DC0_DISP1_SEL				769
> +#define IMX8QM_DC1_DISP0_SEL				770
> +#define IMX8QM_DC1_DISP1_SEL				771
> +
> +/* CM40 */
> +#define IMX8QM_CM40_IPG_CLK				772
> +#define IMX8QM_CM40_I2C_DIV				773
> +#define IMX8QM_CM40_I2C_CLK				774
> +#define IMX8QM_CM40_I2C_IPG_CLK				775
> +
> +/* CM41 */
> +#define IMX8QM_CM41_IPG_CLK				776
> +#define IMX8QM_CM41_I2C_DIV				777
> +#define IMX8QM_CM41_I2C_CLK				778
> +#define IMX8QM_CM41_I2C_IPG_CLK				779
> +
> +#define IMX8QM_HDMI_PXL_SEL				780
> +#define IMX8QM_HDMI_PXL_LINK_SEL			781
> +#define IMX8QM_HDMI_PXL_MUX_SEL				782
> +#define IMX8QM_HDMI_AV_PLL_BYPASS_CLK			783
> +
> +#define IMX8QM_HDMI_RX_PXL_SEL				784
> +#define IMX8QM_HDMI_RX_HD_REF_SEL			785
> +#define IMX8QM_HDMI_RX_HD_CORE_SEL			786
> +#define IMX8QM_HDMI_RX_DIG_PLL_CLK			787
> +
> +#define IMX8QM_LSIO_MU5A_IPG_S_CLK			788
> +#define IMX8QM_LSIO_MU5A_IPG_CLK			789
> +#define IMX8QM_LSIO_MU6A_IPG_S_CLK			790
> +#define IMX8QM_LSIO_MU6A_IPG_CLK			791
> +
> +/* DSP */
> +#define IMX8QM_AUD_DSP_ADB_ACLK				792
> +#define IMX8QM_AUD_DSP_IPG				793
> +#define IMX8QM_AUD_DSP_CORE_CLK				794
> +#define IMX8QM_AUD_OCRAM_IPG				795
> +
> +#define IMX8QM_CLK_END					796
> +
> +#endif /* __DT_BINDINGS_CLOCK_IMX8QM_H */
> -- 
> 2.17.1
> 

^ permalink raw reply

* Re: [PATCH 3/4] clk: imx8mm: Add system counter to clock tree
From: Abel Vesa @ 2019-07-11  8:19 UTC (permalink / raw)
  To: Anson Huang
  Cc: mark.rutland@arm.com, Aisheng Dong, Peng Fan, festevam@gmail.com,
	Jacky Bai, devicetree@vger.kernel.org, sboyd@kernel.org,
	catalin.marinas@arm.com, s.hauer@pengutronix.de,
	linux-kernel@vger.kernel.org, Daniel Baluta,
	linux-clk@vger.kernel.org, robh+dt@kernel.org, dl-linux-imx,
	kernel@pengutronix.de, shawnguo@kernel.org, Leonard Crestez,
	will@kernel.org, mturquette@baylibre.com, linux-arm-kernel
In-Reply-To: <20190621070720.12395-3-Anson.Huang@nxp.com>

On 19-06-21 15:07:19, Anson.Huang@nxp.com wrote:
> From: Anson Huang <Anson.Huang@nxp.com>
> 
> i.MX8MM timer-imx-sysctr driver needs system counter clock
> for proper function, add it into clock tree.
> 
> Signed-off-by: Anson Huang <Anson.Huang@nxp.com>

Reviewed-by: Abel Vesa <abel.vesa@nxp.com>

> ---
>  drivers/clk/imx/clk-imx8mm.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/drivers/clk/imx/clk-imx8mm.c b/drivers/clk/imx/clk-imx8mm.c
> index 43fa9c3..56d53dd 100644
> --- a/drivers/clk/imx/clk-imx8mm.c
> +++ b/drivers/clk/imx/clk-imx8mm.c
> @@ -645,6 +645,8 @@ static int __init imx8mm_clocks_init(struct device_node *ccm_node)
>  	clks[IMX8MM_CLK_DRAM_ALT_ROOT] = imx_clk_fixed_factor("dram_alt_root", "dram_alt", 1, 4);
>  	clks[IMX8MM_CLK_DRAM_CORE] = imx_clk_mux2_flags("dram_core_clk", base + 0x9800, 24, 1, imx8mm_dram_core_sels, ARRAY_SIZE(imx8mm_dram_core_sels), CLK_IS_CRITICAL);
>  
> +	clks[IMX8MM_CLK_SYS_CTR] = imx_clk_fixed_factor("sys_ctr", "osc_24m", 1, 3);
> +
>  	clks[IMX8MM_CLK_ARM] = imx_clk_cpu("arm", "arm_a53_div",
>  					   clks[IMX8MM_CLK_A53_DIV],
>  					   clks[IMX8MM_CLK_A53_SRC],
> -- 
> 2.7.4
> 

^ permalink raw reply

* Re: [PATCH 1/2] clk: imx8mq: set correct parent for usb ctrl clocks
From: Abel Vesa @ 2019-07-11  8:16 UTC (permalink / raw)
  To: Jun Li
  Cc: mark.rutland@arm.com, Peter Chen, agx@sigxcpu.org, Jacky Bai,
	Anson Huang, ccaione@baylibre.com, sboyd@kernel.org,
	festevam@gmail.com, s.hauer@pengutronix.de, angus@akkea.ca,
	linux-clk@vger.kernel.org, andrew.smirnov@gmail.com,
	devicetree@vger.kernel.org, robh+dt@kernel.org, dl-linux-imx,
	kernel@pengutronix.de, shawnguo@kernel.org,
	mturquette@baylibre.com, linux-arm-kernel@lists.infradead.org,
	l.stach@
In-Reply-To: <20190710111917.6615-1-jun.li@nxp.com>

On 19-07-10 19:19:16, jun.li@nxp.com wrote:
> From: Li Jun <jun.li@nxp.com>
> 
> Per latest imx8mq datasheet of CCM, the parent of usb1_ctrl_root_clk
> and usb2_ctrl_root_clk is usb_bus.
> 
> Signed-off-by: Li Jun <jun.li@nxp.com>

For the entire series.

Reviewed-by: Abel Vesa <abel.vesa@nxp.com>

> ---
>  drivers/clk/imx/clk-imx8mq.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/clk/imx/clk-imx8mq.c b/drivers/clk/imx/clk-imx8mq.c
> index d407a07..c7d1546 100644
> --- a/drivers/clk/imx/clk-imx8mq.c
> +++ b/drivers/clk/imx/clk-imx8mq.c
> @@ -523,8 +523,8 @@ static int imx8mq_clocks_probe(struct platform_device *pdev)
>  	clks[IMX8MQ_CLK_UART2_ROOT] = imx_clk_gate4("uart2_root_clk", "uart2", base + 0x44a0, 0);
>  	clks[IMX8MQ_CLK_UART3_ROOT] = imx_clk_gate4("uart3_root_clk", "uart3", base + 0x44b0, 0);
>  	clks[IMX8MQ_CLK_UART4_ROOT] = imx_clk_gate4("uart4_root_clk", "uart4", base + 0x44c0, 0);
> -	clks[IMX8MQ_CLK_USB1_CTRL_ROOT] = imx_clk_gate4("usb1_ctrl_root_clk", "usb_core_ref", base + 0x44d0, 0);
> -	clks[IMX8MQ_CLK_USB2_CTRL_ROOT] = imx_clk_gate4("usb2_ctrl_root_clk", "usb_core_ref", base + 0x44e0, 0);
> +	clks[IMX8MQ_CLK_USB1_CTRL_ROOT] = imx_clk_gate4("usb1_ctrl_root_clk", "usb_bus", base + 0x44d0, 0);
> +	clks[IMX8MQ_CLK_USB2_CTRL_ROOT] = imx_clk_gate4("usb2_ctrl_root_clk", "usb_bus", base + 0x44e0, 0);
>  	clks[IMX8MQ_CLK_USB1_PHY_ROOT] = imx_clk_gate4("usb1_phy_root_clk", "usb_phy_ref", base + 0x44f0, 0);
>  	clks[IMX8MQ_CLK_USB2_PHY_ROOT] = imx_clk_gate4("usb2_phy_root_clk", "usb_phy_ref", base + 0x4500, 0);
>  	clks[IMX8MQ_CLK_USDHC1_ROOT] = imx_clk_gate4("usdhc1_root_clk", "usdhc1", base + 0x4510, 0);
> -- 
> 2.7.4
> 

^ permalink raw reply

* Re: [PATCH v2 2/2] dt-bindings: usb: renesas_gen3: Rename bindings documentation file
From: Simon Horman @ 2019-07-11  8:03 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: Greg Kroah-Hartman, Yoshihiro Shimoda, Kuninori Morimoto,
	Magnus Damm, USB list, Linux-Renesas, Rob Herring, Mark Rutland,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Niklas Söderlund
In-Reply-To: <CAMuHMdVgx9N0yeeei5qcg1yz2WEdDf0gQ6GcwUOAz7u09S_D4A@mail.gmail.com>

On Wed, Jul 03, 2019 at 02:28:51PM +0200, Geert Uytterhoeven wrote:
> Hi Simon,
> 
> On Wed, Jul 3, 2019 at 10:35 AM Simon Horman <horms+renesas@verge.net.au> wrote:
> > For consistency with the naming of (most) other documentation files for DT
> > bindings for Renesas IP blocks rename the Renesas USB3.0 peripheral
> > documentation file from renesas-gen3.txt to renesas,usb3-peri.txt
> >
> > Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
> > Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
> > Reviewed-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
> > Reviewed-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
> >
> > ---
> > v2
> > * Accumulate review tags
> > * Use renesas,usb3-peri.txt as new filename as suggested by Shimoda-san
> 
> Unfortunately the previous version has already made it into usb-next
> 23c46801d14cb647 dt-bindings: usb: renesas_gen3: Rename bindings
> documentation file

Ok, I guess we should go with that version.

^ permalink raw reply

* Re: [PATCH v2] arm: dts: mediatek: add basic support for MT7629 SoC
From: Matthias Brugger @ 2019-07-11  8:02 UTC (permalink / raw)
  To: ryder.lee, Rob Herring
  Cc: Weijie Gao, Sean Wang, Mark-MC Lee, devicetree, linux-kernel,
	linux-arm-kernel, linux-mediatek, Ryder Lee
In-Reply-To: <ca3f4c3c25c3856e75dfb06f6a3b0e764cdc073d.1562750668.git.ryder.lee@mediatek.com>



On 11/07/2019 04:14, ryder.lee@kernel.org wrote:
> From: Ryder Lee <ryder.lee@mediatek.com>
> 
> This adds basic support for MT7629 reference board.
> 
> Tested-by: Kevin Hilman <khilman@baylibre.com>
> Signed-off-by: Ryder Lee <ryder.lee@mediatek.com>

applied to v5.3-next/dts32

Thanks!

> ---
> Changes since v2:
> - fix 'no newline at end of file'.
> - fix addresses/sizes cells.
> - update u3phy0 node.
> - add eth/pcie related nodes.
> - add the 'fixed-partitions' nodes in flash node.
> - remove arm,cpu-registers-not-fw-configured.
> 
> Changes since v1:
> -Fix unit-address warnings.
> -Put all the mmio peripherals under a simple-bus node.
> -Drop all the 'partitions' nodes in flash node.
> ---
>  arch/arm/boot/dts/Makefile                |   1 +
>  arch/arm/boot/dts/mt7629-rfb.dts          | 263 ++++++++++++
>  arch/arm/boot/dts/mt7629.dtsi             | 481 ++++++++++++++++++++++
>  include/dt-bindings/reset/mt7629-resets.h |  71 ++++
>  4 files changed, 816 insertions(+)
>  create mode 100644 arch/arm/boot/dts/mt7629-rfb.dts
>  create mode 100644 arch/arm/boot/dts/mt7629.dtsi
>  create mode 100644 include/dt-bindings/reset/mt7629-resets.h
> 
> diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
> index dab2914fa293..080784da8ae1 100644
> --- a/arch/arm/boot/dts/Makefile
> +++ b/arch/arm/boot/dts/Makefile
> @@ -1258,6 +1258,7 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += \
>  	mt7623a-rfb-nand.dtb \
>  	mt7623n-rfb-emmc.dtb \
>  	mt7623n-bananapi-bpi-r2.dtb \
> +	mt7629-rfb.dtb \
>  	mt8127-moose.dtb \
>  	mt8135-evbp1.dtb
>  dtb-$(CONFIG_ARCH_MILBEAUT) += milbeaut-m10v-evb.dtb
> diff --git a/arch/arm/boot/dts/mt7629-rfb.dts b/arch/arm/boot/dts/mt7629-rfb.dts
> new file mode 100644
> index 000000000000..3621b7d2b22a
> --- /dev/null
> +++ b/arch/arm/boot/dts/mt7629-rfb.dts
> @@ -0,0 +1,263 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2019 MediaTek Inc.
> + * Author: Ryder Lee <ryder.lee@mediatek.com>
> + */
> +
> +/dts-v1/;
> +#include <dt-bindings/input/input.h>
> +#include "mt7629.dtsi"
> +
> +/ {
> +	model = "MediaTek MT7629 reference board";
> +	compatible = "mediatek,mt7629-rfb", "mediatek,mt7629";
> +
> +	aliases {
> +		serial0 = &uart0;
> +	};
> +
> +	chosen {
> +		stdout-path = "serial0:115200n8";
> +	};
> +
> +	gpio-keys {
> +		compatible = "gpio-keys";
> +
> +		reset {
> +			label = "factory";
> +			linux,code = <KEY_RESTART>;
> +			gpios = <&pio 60 GPIO_ACTIVE_LOW>;
> +		};
> +
> +		wps {
> +			label = "wps";
> +			linux,code = <KEY_WPS_BUTTON>;
> +			gpios = <&pio 58 GPIO_ACTIVE_LOW>;
> +		};
> +	};
> +
> +	memory@40000000 {
> +		device_type = "memory";
> +		reg = <0x40000000 0x10000000>;
> +	};
> +
> +	reg_3p3v: regulator-3p3v {
> +		compatible = "regulator-fixed";
> +		regulator-name = "fixed-3.3V";
> +		regulator-min-microvolt = <3300000>;
> +		regulator-max-microvolt = <3300000>;
> +		regulator-boot-on;
> +		regulator-always-on;
> +	};
> +
> +	reg_5v: regulator-5v {
> +		compatible = "regulator-fixed";
> +		regulator-name = "fixed-5V";
> +		regulator-min-microvolt = <5000000>;
> +		regulator-max-microvolt = <5000000>;
> +		regulator-boot-on;
> +		regulator-always-on;
> +	};
> +};
> +
> +&eth {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&eth_pins>;
> +	pinctrl-1 = <&ephy_leds_pins>;
> +	status = "okay";
> +
> +	gmac1: mac@1 {
> +		compatible = "mediatek,eth-mac";
> +		reg = <1>;
> +		phy-handle = <&phy0>;
> +	};
> +
> +	mdio: mdio-bus {
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +
> +		phy0: ethernet-phy@0 {
> +			reg = <0>;
> +			phy-mode = "gmii";
> +		};
> +	};
> +};
> +
> +&i2c {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&i2c_pins>;
> +	status = "okay";
> +};
> +
> +&qspi {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&qspi_pins>;
> +	status = "okay";
> +
> +	flash@0 {
> +		compatible = "jedec,spi-nor";
> +		reg = <0>;
> +
> +		partitions {
> +			compatible = "fixed-partitions";
> +			#address-cells = <1>;
> +			#size-cells = <1>;
> +
> +			partition@0 {
> +				label = "u-boot";
> +				reg = <0x00000 0x60000>;
> +				read-only;
> +			};
> +
> +			partition@60000 {
> +				label = "u-boot-env";
> +				reg = <0x60000 0x10000>;
> +				read-only;
> +			};
> +
> +			factory: partition@70000 {
> +				label = "factory";
> +				reg = <0x70000 0x40000>;
> +				read-only;
> +			};
> +
> +			partition@b0000 {
> +				label = "kernel";
> +				reg = <0xb0000 0xb50000>;
> +			};
> +		};
> +	};
> +};
> +
> +&pcie {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pcie_pins>;
> +};
> +
> +&pciephy1 {
> +	status = "okay";
> +};
> +
> +&pio {
> +	eth_pins: eth-pins {
> +		mux {
> +			function = "eth";
> +			groups = "mdc_mdio";
> +		};
> +	};
> +
> +	ephy_leds_pins: ephy-leds-pins {
> +		mux {
> +			function = "led";
> +			groups = "gphy_leds_0", "ephy_leds";
> +		};
> +	};
> +
> +	i2c_pins: i2c-pins {
> +		mux {
> +			function = "i2c";
> +			groups =  "i2c_0";
> +		};
> +
> +		conf {
> +			pins = "I2C_SDA", "I2C_SCL";
> +			drive-strength = <4>;
> +			bias-disable;
> +		};
> +	};
> +
> +	pcie_pins: pcie-pins {
> +		mux {
> +			function = "pcie";
> +			groups = "pcie_clkreq",
> +				 "pcie_pereset",
> +				 "pcie_wake";
> +		};
> +	};
> +
> +	pwm_pins: pwm-pins {
> +		mux {
> +			function = "pwm";
> +			groups = "pwm_0";
> +		};
> +	};
> +
> +	/* SPI-NOR is shared pin with serial NAND */
> +	qspi_pins: qspi-pins {
> +		mux {
> +			function = "flash";
> +			groups = "spi_nor";
> +		};
> +	};
> +
> +	/* Serial NAND is shared pin with SPI-NOR */
> +	serial_nand_pins: serial-nand-pins {
> +		mux {
> +			function = "flash";
> +			groups = "snfi";
> +		};
> +	};
> +
> +	spi_pins: spi-pins {
> +		mux {
> +			function = "spi";
> +			groups = "spi_0";
> +		};
> +	};
> +
> +	uart0_pins: uart0-pins {
> +		mux {
> +			function = "uart";
> +			groups = "uart0_txd_rxd" ;
> +		};
> +	};
> +
> +	uart1_pins: uart1-pins {
> +		mux {
> +			function = "uart";
> +			groups = "uart1_0_tx_rx" ;
> +		};
> +	};
> +
> +	uart2_pins: uart2-pins {
> +		mux {
> +			function = "uart";
> +			groups = "uart2_0_txd_rxd" ;
> +		};
> +	};
> +
> +	watchdog_pins: watchdog-pins {
> +		mux {
> +			function = "watchdog";
> +			groups = "watchdog";
> +		};
> +	};
> +};
> +
> +&spi {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&spi_pins>;
> +	status = "okay";
> +};
> +
> +&ssusb {
> +	vusb33-supply = <&reg_3p3v>;
> +	vbus-supply = <&reg_5v>;
> +	status = "okay";
> +};
> +
> +&u3phy0 {
> +	status = "okay";
> +};
> +
> +&uart0 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&uart0_pins>;
> +	status = "okay";
> +};
> +
> +&watchdog {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&watchdog_pins>;
> +	status = "okay";
> +};
> diff --git a/arch/arm/boot/dts/mt7629.dtsi b/arch/arm/boot/dts/mt7629.dtsi
> new file mode 100644
> index 000000000000..9608bc2ccb3f
> --- /dev/null
> +++ b/arch/arm/boot/dts/mt7629.dtsi
> @@ -0,0 +1,481 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2019 MediaTek Inc.
> + *
> + * Author: Ryder Lee <ryder.lee@mediatek.com>
> + */
> +
> +#include <dt-bindings/interrupt-controller/irq.h>
> +#include <dt-bindings/interrupt-controller/arm-gic.h>
> +#include <dt-bindings/clock/mt7629-clk.h>
> +#include <dt-bindings/power/mt7622-power.h>
> +#include <dt-bindings/gpio/gpio.h>
> +#include <dt-bindings/phy/phy.h>
> +#include <dt-bindings/reset/mt7629-resets.h>
> +
> +/ {
> +	compatible = "mediatek,mt7629";
> +	interrupt-parent = <&sysirq>;
> +	#address-cells = <1>;
> +	#size-cells = <1>;
> +
> +	cpus {
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +		enable-method = "mediatek,mt6589-smp";
> +
> +		cpu0: cpu@0 {
> +			device_type = "cpu";
> +			compatible = "arm,cortex-a7";
> +			reg = <0x0>;
> +			clock-frequency = <1250000000>;
> +			cci-control-port = <&cci_control2>;
> +		};
> +
> +		cpu1: cpu@1 {
> +			device_type = "cpu";
> +			compatible = "arm,cortex-a7";
> +			reg = <0x1>;
> +			clock-frequency = <1250000000>;
> +			cci-control-port = <&cci_control2>;
> +		};
> +	};
> +
> +	pmu {
> +		compatible = "arm,cortex-a7-pmu";
> +		interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_LOW>,
> +			     <GIC_SPI 9 IRQ_TYPE_LEVEL_LOW>;
> +		interrupt-affinity = <&cpu0>, <&cpu1>;
> +	};
> +
> +	clk20m: oscillator-0 {
> +		compatible = "fixed-clock";
> +		#clock-cells = <0>;
> +		clock-frequency = <20000000>;
> +		clock-output-names = "clk20m";
> +	};
> +
> +	clk40m: oscillator-1 {
> +		compatible = "fixed-clock";
> +		#clock-cells = <0>;
> +		clock-frequency = <40000000>;
> +		clock-output-names = "clkxtal";
> +	};
> +
> +	timer {
> +		compatible = "arm,armv7-timer";
> +		interrupt-parent = <&gic>;
> +		interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
> +			     <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
> +			     <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
> +			     <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
> +		clock-frequency = <20000000>;
> +	};
> +
> +	soc {
> +		compatible = "simple-bus";
> +		#address-cells = <1>;
> +		#size-cells = <1>;
> +		ranges;
> +
> +		infracfg: syscon@10000000 {
> +			compatible = "mediatek,mt7629-infracfg", "syscon";
> +			reg = <0x10000000 0x1000>;
> +			#clock-cells = <1>;
> +		};
> +
> +		pericfg: syscon@10002000 {
> +			compatible = "mediatek,mt7629-pericfg", "syscon";
> +			reg = <0x10002000 0x1000>;
> +			#clock-cells = <1>;
> +		};
> +
> +		scpsys: scpsys@10006000 {
> +			compatible = "mediatek,mt7629-scpsys",
> +				     "mediatek,mt7622-scpsys";
> +			#power-domain-cells = <1>;
> +			reg = <0x10006000 0x1000>;
> +			clocks = <&topckgen CLK_TOP_HIF_SEL>;
> +			clock-names = "hif_sel";
> +			assigned-clocks = <&topckgen CLK_TOP_HIF_SEL>;
> +			assigned-clock-parents = <&topckgen CLK_TOP_UNIVPLL1_D2>;
> +			infracfg = <&infracfg>;
> +		};
> +
> +		timer: timer@10009000 {
> +			compatible = "mediatek,mt7629-timer",
> +				     "mediatek,mt6765-timer";
> +			reg = <0x10009000 0x60>;
> +			interrupts = <GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH>,
> +				     <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&clk20m>;
> +			clock-names = "clk20m";
> +		};
> +
> +		sysirq: interrupt-controller@10200a80 {
> +			compatible = "mediatek,mt7629-sysirq",
> +				     "mediatek,mt6577-sysirq";
> +			reg = <0x10200a80 0x20>;
> +			interrupt-controller;
> +			#interrupt-cells = <3>;
> +			interrupt-parent = <&gic>;
> +		};
> +
> +		apmixedsys: syscon@10209000 {
> +			compatible = "mediatek,mt7629-apmixedsys", "syscon";
> +			reg = <0x10209000 0x1000>;
> +			#clock-cells = <1>;
> +		};
> +
> +		rng: rng@1020f000 {
> +			compatible = "mediatek,mt7629-rng",
> +				     "mediatek,mt7623-rng";
> +			reg = <0x1020f000 0x100>;
> +			clocks = <&infracfg CLK_INFRA_TRNG_PD>;
> +			clock-names = "rng";
> +		};
> +
> +		topckgen: syscon@10210000 {
> +			compatible = "mediatek,mt7629-topckgen", "syscon";
> +			reg = <0x10210000 0x1000>;
> +			#clock-cells = <1>;
> +		};
> +
> +		watchdog: watchdog@10212000 {
> +			compatible = "mediatek,mt7629-wdt",
> +				     "mediatek,mt6589-wdt";
> +			reg = <0x10212000 0x100>;
> +		};
> +
> +		pio: pinctrl@10217000 {
> +			compatible = "mediatek,mt7629-pinctrl";
> +			reg = <0x10217000 0x8000>,
> +			      <0x10005000 0x1000>;
> +			reg-names = "base", "eint";
> +			gpio-controller;
> +			gpio-ranges = <&pio 0 0 79>;
> +			#gpio-cells = <2>;
> +			#interrupt-cells = <2>;
> +			interrupt-controller;
> +			interrupts = <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>;
> +			interrupt-parent = <&gic>;
> +		};
> +
> +		gic: interrupt-controller@10300000 {
> +			compatible = "arm,gic-400";
> +			interrupt-controller;
> +			#interrupt-cells = <3>;
> +			interrupt-parent = <&gic>;
> +			reg = <0x10310000 0x1000>,
> +			      <0x10320000 0x1000>,
> +			      <0x10340000 0x2000>,
> +			      <0x10360000 0x2000>;
> +		};
> +
> +		cci: cci@10390000 {
> +			compatible = "arm,cci-400";
> +			#address-cells = <1>;
> +			#size-cells = <1>;
> +			reg = <0x10390000 0x1000>;
> +			ranges = <0 0x10390000 0x10000>;
> +
> +			cci_control0: slave-if@1000 {
> +				compatible = "arm,cci-400-ctrl-if";
> +				interface-type = "ace-lite";
> +				reg = <0x1000 0x1000>;
> +			};
> +
> +			cci_control1: slave-if@4000 {
> +				compatible = "arm,cci-400-ctrl-if";
> +				interface-type = "ace";
> +				reg = <0x4000 0x1000>;
> +			};
> +
> +			cci_control2: slave-if@5000 {
> +				compatible = "arm,cci-400-ctrl-if";
> +				interface-type = "ace";
> +				reg = <0x5000 0x1000>;
> +			};
> +
> +			pmu@9000 {
> +				compatible = "arm,cci-400-pmu,r1";
> +				reg = <0x9000 0x5000>;
> +				interrupts = <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>,
> +					     <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>,
> +					     <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>,
> +					     <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>,
> +					     <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
> +			};
> +		};
> +
> +		uart0: serial@11002000 {
> +			compatible = "mediatek,mt7629-uart",
> +				     "mediatek,mt6577-uart";
> +			reg = <0x11002000 0x400>;
> +			interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_LOW>;
> +			clocks = <&topckgen CLK_TOP_UART_SEL>,
> +				 <&pericfg CLK_PERI_UART0_PD>;
> +			clock-names = "baud", "bus";
> +			status = "disabled";
> +		};
> +
> +		uart1: serial@11003000 {
> +			compatible = "mediatek,mt7629-uart",
> +				     "mediatek,mt6577-uart";
> +			reg = <0x11003000 0x400>;
> +			interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_LOW>;
> +			clocks = <&topckgen CLK_TOP_UART_SEL>,
> +				 <&pericfg CLK_PERI_UART1_PD>;
> +			clock-names = "baud", "bus";
> +			status = "disabled";
> +		};
> +
> +		uart2: serial@11004000 {
> +			compatible = "mediatek,mt7629-uart",
> +				     "mediatek,mt6577-uart";
> +			reg = <0x11004000 0x400>;
> +			interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_LOW>;
> +			clocks = <&topckgen CLK_TOP_UART_SEL>,
> +				 <&pericfg CLK_PERI_UART2_PD>;
> +			clock-names = "baud", "bus";
> +			status = "disabled";
> +		};
> +
> +		i2c: i2c@11007000 {
> +			compatible = "mediatek,mt7629-i2c",
> +				     "mediatek,mt2712-i2c";
> +			reg = <0x11007000 0x90>,
> +			      <0x11000100 0x80>;
> +			interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_LOW>;
> +			clock-div = <4>;
> +			clocks = <&pericfg CLK_PERI_I2C0_PD>,
> +				 <&pericfg CLK_PERI_AP_DMA_PD>;
> +			clock-names = "main", "dma";
> +			assigned-clocks = <&topckgen CLK_TOP_AXI_SEL>;
> +			assigned-clock-parents = <&topckgen CLK_TOP_SYSPLL1_D2>;
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			status = "disabled";
> +		};
> +
> +		spi: spi@1100a000 {
> +			compatible = "mediatek,mt7629-spi",
> +				     "mediatek,mt7622-spi";
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			reg = <0x1100a000 0x100>;
> +			interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_LOW>;
> +			clocks = <&topckgen CLK_TOP_SYSPLL3_D2>,
> +				 <&topckgen CLK_TOP_SPI0_SEL>,
> +				 <&pericfg CLK_PERI_SPI0_PD>;
> +			clock-names = "parent-clk", "sel-clk", "spi-clk";
> +			status = "disabled";
> +		};
> +
> +		qspi: spi@11014000 {
> +			compatible = "mediatek,mt7629-nor",
> +				     "mediatek,mt8173-nor";
> +			reg = <0x11014000 0xe0>;
> +			clocks = <&pericfg CLK_PERI_FLASH_PD>,
> +				 <&topckgen CLK_TOP_FLASH_SEL>;
> +			clock-names = "spi", "sf";
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			status = "disabled";
> +		};
> +
> +		ssusbsys: syscon@1a000000 {
> +			compatible = "mediatek,mt7629-ssusbsys", "syscon";
> +			reg = <0x1a000000 0x1000>;
> +			#clock-cells = <1>;
> +			#reset-cells = <1>;
> +		};
> +
> +		ssusb: usb@1a0c0000 {
> +			compatible = "mediatek,mt7629-xhci",
> +				     "mediatek,mtk-xhci";
> +			reg = <0x1a0c0000 0x01000>,
> +			      <0x1a0c3e00 0x0100>;
> +			reg-names = "mac", "ippc";
> +			interrupts = <GIC_SPI 232 IRQ_TYPE_LEVEL_LOW>;
> +			clocks = <&ssusbsys CLK_SSUSB_SYS_EN>,
> +				 <&ssusbsys CLK_SSUSB_REF_EN>,
> +				 <&ssusbsys CLK_SSUSB_MCU_EN>,
> +				 <&ssusbsys CLK_SSUSB_DMA_EN>;
> +			clock-names = "sys_ck", "ref_ck", "mcu_ck", "dma_ck";
> +			assigned-clocks = <&topckgen CLK_TOP_AXI_SEL>,
> +					  <&topckgen CLK_TOP_SATA_SEL>,
> +					  <&topckgen CLK_TOP_HIF_SEL>;
> +			assigned-clock-parents = <&topckgen CLK_TOP_SYSPLL1_D2>,
> +						 <&topckgen CLK_TOP_UNIVPLL2_D4>,
> +						 <&topckgen CLK_TOP_UNIVPLL1_D2>;
> +			power-domains = <&scpsys MT7622_POWER_DOMAIN_HIF1>;
> +			phys = <&u2port0 PHY_TYPE_USB2>,
> +			       <&u3port0 PHY_TYPE_USB3>;
> +			status = "disabled";
> +		};
> +
> +		u3phy0: usb-phy@1a0c4000 {
> +			compatible = "mediatek,generic-tphy-v2";
> +			#address-cells = <1>;
> +			#size-cells = <1>;
> +			ranges = <0 0x1a0c4000 0xe00>;
> +			status = "disabled";
> +
> +			u2port0: usb-phy@0 {
> +				reg = <0 0x700>;
> +				clocks = <&ssusbsys CLK_SSUSB_U2_PHY_EN>;
> +				clock-names = "ref";
> +				#phy-cells = <1>;
> +				status = "okay";
> +			};
> +
> +			u3port0: usb-phy@700 {
> +				reg = <0x700 0x700>;
> +				clocks = <&clk20m>;
> +				clock-names = "ref";
> +				#phy-cells = <1>;
> +				status = "okay";
> +			};
> +		};
> +
> +		pciesys: syscon@1a100800 {
> +			compatible = "mediatek,mt7629-pciesys", "syscon";
> +			reg = <0x1a100800 0x1000>;
> +			#clock-cells = <1>;
> +			#reset-cells = <1>;
> +		};
> +
> +		pcie: pcie@1a140000 {
> +			compatible = "mediatek,mt7629-pcie";
> +			device_type = "pci";
> +			reg = <0x1a140000 0x1000>,
> +			      <0x1a145000 0x1000>;
> +			reg-names = "subsys","port1";
> +			#address-cells = <3>;
> +			#size-cells = <2>;
> +			interrupts = <GIC_SPI 176 IRQ_TYPE_LEVEL_LOW>,
> +				     <GIC_SPI 229 IRQ_TYPE_LEVEL_LOW>;
> +			clocks = <&pciesys CLK_PCIE_P1_MAC_EN>,
> +				 <&pciesys CLK_PCIE_P0_AHB_EN>,
> +				 <&pciesys CLK_PCIE_P1_AUX_EN>,
> +				 <&pciesys CLK_PCIE_P1_AXI_EN>,
> +				 <&pciesys CLK_PCIE_P1_OBFF_EN>,
> +				 <&pciesys CLK_PCIE_P1_PIPE_EN>;
> +			clock-names = "sys_ck1", "ahb_ck1",
> +				      "aux_ck1", "axi_ck1",
> +				      "obff_ck1", "pipe_ck1";
> +			assigned-clocks = <&topckgen CLK_TOP_SATA_SEL>,
> +					  <&topckgen CLK_TOP_AXI_SEL>,
> +					  <&topckgen CLK_TOP_HIF_SEL>;
> +			assigned-clock-parents = <&topckgen CLK_TOP_UNIVPLL2_D4>,
> +						 <&topckgen CLK_TOP_SYSPLL1_D2>,
> +						 <&topckgen CLK_TOP_UNIVPLL1_D2>;
> +			phys = <&pcieport1 PHY_TYPE_PCIE>;
> +			phy-names = "pcie-phy1";
> +			power-domains = <&scpsys MT7622_POWER_DOMAIN_HIF0>;
> +			bus-range = <0x00 0xff>;
> +			ranges = <0x82000000 0 0x20000000 0x20000000 0 0x10000000>;
> +
> +			pcie1: pcie@1,0 {
> +				device_type = "pci";
> +				reg = <0x0800 0 0 0 0>;
> +				#address-cells = <3>;
> +				#size-cells = <2>;
> +				#interrupt-cells = <1>;
> +				ranges;
> +				num-lanes = <1>;
> +				interrupt-map-mask = <0 0 0 7>;
> +				interrupt-map = <0 0 0 1 &pcie_intc1 0>,
> +						<0 0 0 2 &pcie_intc1 1>,
> +						<0 0 0 3 &pcie_intc1 2>,
> +						<0 0 0 4 &pcie_intc1 3>;
> +
> +				pcie_intc1: interrupt-controller {
> +					interrupt-controller;
> +					#address-cells = <0>;
> +					#interrupt-cells = <1>;
> +				};
> +			};
> +		};
> +
> +		pciephy1: pcie-phy@1a14a000 {
> +			compatible = "mediatek,generic-tphy-v2";
> +			#address-cells = <1>;
> +			#size-cells = <1>;
> +			ranges = <0 0x1a14a000 0x1000>;
> +			status = "disabled";
> +
> +			pcieport1: port1phy@0 {
> +				reg = <0 0x1000>;
> +				clocks = <&clk20m>;
> +				clock-names = "ref";
> +				#phy-cells = <1>;
> +				status = "okay";
> +			};
> +		};
> +
> +		ethsys: syscon@1b000000 {
> +			compatible = "mediatek,mt7629-ethsys", "syscon";
> +			reg = <0x1b000000 0x1000>;
> +			#clock-cells = <1>;
> +			#reset-cells = <1>;
> +		};
> +
> +		eth: ethernet@1b100000 {
> +			compatible = "mediatek,mt7629-eth","syscon";
> +			reg = <0x1b100000 0x20000>;
> +			interrupts = <GIC_SPI 223 IRQ_TYPE_LEVEL_LOW>,
> +				     <GIC_SPI 224 IRQ_TYPE_LEVEL_LOW>,
> +				     <GIC_SPI 225 IRQ_TYPE_LEVEL_LOW>;
> +			clocks = <&topckgen CLK_TOP_ETH_SEL>,
> +				 <&topckgen CLK_TOP_F10M_REF_SEL>,
> +				 <&ethsys CLK_ETH_ESW_EN>,
> +				 <&ethsys CLK_ETH_GP0_EN>,
> +				 <&ethsys CLK_ETH_GP1_EN>,
> +				 <&ethsys CLK_ETH_GP2_EN>,
> +				 <&ethsys CLK_ETH_FE_EN>,
> +				 <&sgmiisys0 CLK_SGMII_TX_EN>,
> +				 <&sgmiisys0 CLK_SGMII_RX_EN>,
> +				 <&sgmiisys0 CLK_SGMII_CDR_REF>,
> +				 <&sgmiisys0 CLK_SGMII_CDR_FB>,
> +				 <&sgmiisys1 CLK_SGMII_TX_EN>,
> +				 <&sgmiisys1 CLK_SGMII_RX_EN>,
> +				 <&sgmiisys1 CLK_SGMII_CDR_REF>,
> +				 <&sgmiisys1 CLK_SGMII_CDR_FB>,
> +				 <&apmixedsys CLK_APMIXED_SGMIPLL>,
> +				 <&apmixedsys CLK_APMIXED_ETH2PLL>;
> +			clock-names = "ethif", "sgmiitop", "esw", "gp0", "gp1",
> +				      "gp2", "fe", "sgmii_tx250m", "sgmii_rx250m",
> +				      "sgmii_cdr_ref", "sgmii_cdr_fb",
> +				      "sgmii2_tx250m", "sgmii2_rx250m",
> +				      "sgmii2_cdr_ref", "sgmii2_cdr_fb",
> +				      "sgmii_ck", "eth2pll";
> +			assigned-clocks = <&topckgen CLK_TOP_ETH_SEL>,
> +					  <&topckgen CLK_TOP_F10M_REF_SEL>;
> +			assigned-clock-parents = <&topckgen CLK_TOP_UNIVPLL1_D2>,
> +						 <&topckgen CLK_TOP_SGMIIPLL_D2>;
> +			power-domains = <&scpsys MT7622_POWER_DOMAIN_ETHSYS>;
> +			mediatek,ethsys = <&ethsys>;
> +			mediatek,sgmiisys = <&sgmiisys0>, <&sgmiisys1>;
> +			mediatek,infracfg = <&infracfg>;
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			status = "disabled";
> +		};
> +
> +		sgmiisys0: syscon@1b128000 {
> +			compatible = "mediatek,mt7629-sgmiisys", "syscon";
> +			reg = <0x1b128000 0x3000>;
> +			#clock-cells = <1>;
> +			mediatek,physpeed = "2500";
> +		};
> +
> +		sgmiisys1: syscon@1b130000 {
> +			compatible = "mediatek,mt7629-sgmiisys", "syscon";
> +			reg = <0x1b130000 0x3000>;
> +			#clock-cells = <1>;
> +			mediatek,physpeed = "2500";
> +		};
> +	};
> +};
> diff --git a/include/dt-bindings/reset/mt7629-resets.h b/include/dt-bindings/reset/mt7629-resets.h
> new file mode 100644
> index 000000000000..6bb85734f68d
> --- /dev/null
> +++ b/include/dt-bindings/reset/mt7629-resets.h
> @@ -0,0 +1,71 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (C) 2019 MediaTek Inc.
> + */
> +
> +#ifndef _DT_BINDINGS_RESET_CONTROLLER_MT7629
> +#define _DT_BINDINGS_RESET_CONTROLLER_MT7629
> +
> +/* INFRACFG resets */
> +#define MT7629_INFRA_EMI_MPU_RST		0
> +#define MT7629_INFRA_UART5_RST			2
> +#define MT7629_INFRA_CIRQ_EINT_RST		3
> +#define MT7629_INFRA_APXGPT_RST			4
> +#define MT7629_INFRA_SCPSYS_RST			5
> +#define MT7629_INFRA_KP_RST			6
> +#define MT7629_INFRA_SPI1_RST			7
> +#define MT7629_INFRA_SPI4_RST			8
> +#define MT7629_INFRA_SYSTIMER_RST		9
> +#define MT7629_INFRA_IRRX_RST			10
> +#define MT7629_INFRA_AO_BUS_RST			16
> +#define MT7629_INFRA_EMI_RST			32
> +#define MT7629_INFRA_APMIXED_RST		35
> +#define MT7629_INFRA_MIPI_RST			36
> +#define MT7629_INFRA_TRNG_RST			37
> +#define MT7629_INFRA_SYSCIRQ_RST		38
> +#define MT7629_INFRA_MIPI_CSI_RST		39
> +#define MT7629_INFRA_GCE_FAXI_RST		40
> +#define MT7629_INFRA_I2C_SRAM_RST		41
> +#define MT7629_INFRA_IOMMU_RST			47
> +
> +/* PERICFG resets */
> +#define MT7629_PERI_UART0_SW_RST		0
> +#define MT7629_PERI_UART1_SW_RST		1
> +#define MT7629_PERI_UART2_SW_RST		2
> +#define MT7629_PERI_BTIF_SW_RST			6
> +#define MT7629_PERI_PWN_SW_RST			8
> +#define MT7629_PERI_DMA_SW_RST			11
> +#define MT7629_PERI_NFI_SW_RST			14
> +#define MT7629_PERI_I2C0_SW_RST			22
> +#define MT7629_PERI_SPI0_SW_RST			33
> +#define MT7629_PERI_SPI1_SW_RST			34
> +#define MT7629_PERI_FLASHIF_SW_RST		36
> +
> +/* PCIe Subsystem resets */
> +#define MT7629_PCIE1_CORE_RST			19
> +#define MT7629_PCIE1_MMIO_RST			20
> +#define MT7629_PCIE1_HRST			21
> +#define MT7629_PCIE1_USER_RST			22
> +#define MT7629_PCIE1_PIPE_RST			23
> +#define MT7629_PCIE0_CORE_RST			27
> +#define MT7629_PCIE0_MMIO_RST			28
> +#define MT7629_PCIE0_HRST			29
> +#define MT7629_PCIE0_USER_RST			30
> +#define MT7629_PCIE0_PIPE_RST			31
> +
> +/* SSUSB Subsystem resets */
> +#define MT7629_SSUSB_PHY_PWR_RST		3
> +#define MT7629_SSUSB_MAC_PWR_RST		4
> +
> +/* ETH Subsystem resets */
> +#define MT7629_ETHSYS_SYS_RST			0
> +#define MT7629_ETHSYS_MCM_RST			2
> +#define MT7629_ETHSYS_HSDMA_RST			5
> +#define MT7629_ETHSYS_FE_RST			6
> +#define MT7629_ETHSYS_ESW_RST			16
> +#define MT7629_ETHSYS_GMAC_RST			23
> +#define MT7629_ETHSYS_EPHY_RST			24
> +#define MT7629_ETHSYS_CRYPTO_RST		29
> +#define MT7629_ETHSYS_PPE_RST			31
> +
> +#endif  /* _DT_BINDINGS_RESET_CONTROLLER_MT7629 */
> 

^ permalink raw reply

* Re: [PATCH 5/8] dt-bindings: PCI: Add Amazon's Annapurna Labs PCIe host bridge binding
From: Shenhar, Talel @ 2019-07-11  7:12 UTC (permalink / raw)
  To: Jonathan Chocron, lorenzo.pieralisi, bhelgaas, jingoohan1,
	gustavo.pimentel, robh+dt, mark.rutland
  Cc: dwmw, benh, alisaidi, ronenk, barakw, hanochu, hhhawa, linux-pci,
	linux-kernel, devicetree
In-Reply-To: <20190710164519.17883-6-jonnyc@amazon.com>


On 7/10/2019 7:45 PM, Jonathan Chocron wrote:
> Document Amazon's Annapurna Labs PCIe host bridge.

That is the way! (best to keep same wordings (Amazon's)

>
> Signed-off-by: Jonathan Chocron <jonnyc@amazon.com>
> ---
>   .../devicetree/bindings/pci/pcie-al.txt       | 45 +++++++++++++++++++
>   MAINTAINERS                                   |  1 +
>   2 files changed, 46 insertions(+)
>   create mode 100644 Documentation/devicetree/bindings/pci/pcie-al.txt
>
> diff --git a/Documentation/devicetree/bindings/pci/pcie-al.txt b/Documentation/devicetree/bindings/pci/pcie-al.txt
> new file mode 100644
> index 000000000000..d92cc529490e
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/pci/pcie-al.txt
> @@ -0,0 +1,45 @@
> +* Amazon Annapurna Labs PCIe host bridge
> +
> +Annapurna Labs' PCIe Host Controller is based on the Synopsys DesignWare

Amazon's


and what is the s' ? should it be for all

> +Example:
> +
> +	pcie-external0 {
probably should have a reference with the address
> +		compatible = "amazon,al-pcie";
> +		reg = <0x0 0xfb600000 0x0 0x00100000
> +		       0x0 0xfd800000 0x0 0x00010000
> +		       0x0 0xfd810000 0x0 0x00001000>;
> +		reg-names = "config", "controller", "dbi";
> +		bus-range = <0 255>;
> +		device_type = "pci";
> +		#address-cells = <3>;
> +		#size-cells = <2>;
> +		#interrupt-cells = <1>;
> +		interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>;
> +		interrupt-map-mask = <0x00 0 0 7>;
> +		interrupt-map = <0x0000 0 0 1 &gic_main GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>; /* INTa */
gic_main->gic
> +		ranges = <0x02000000 0x0 0xc0010000 0x0 0xc0010000 0x0 0x07ff0000>;
> +	};
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 5a6137df3f0e..d555beb794bb 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -12205,6 +12205,7 @@ PCIE DRIVER FOR ANNAPURNA LABS
AMAZON!
>   M:	Jonathan Chocron <jonnyc@amazon.com>
>   L:	linux-pci@vger.kernel.org
>   S:	Maintained
> +F:	Documentation/devicetree/bindings/pci/pcie-al.txt
>   F:	drivers/pci/controller/dwc/pcie-al.c
>   
>   PCIE DRIVER FOR AMLOGIC MESON

^ permalink raw reply

* Re: [PATCH AUTOSEL 5.1 08/39] arm64: dts: ls1028a: Fix CPU idle fail.
From: Greg KH @ 2019-07-11  6:43 UTC (permalink / raw)
  To: Ran Wang
  Cc: Sasha Levin, linux-kernel@vger.kernel.org, stable@vger.kernel.org,
	Shawn Guo, devicetree@vger.kernel.org, Xiaobo Xie
In-Reply-To: <DB8PR04MB6826A4A8CE604F2570DC1EA7F1F30@DB8PR04MB6826.eurprd04.prod.outlook.com>

On Thu, Jul 11, 2019 at 05:04:24AM +0000, Ran Wang wrote:
> Hi Sasha, 
> 
>     Thanks for helping port this patch to stable.
>     May I know if I can submit other bug fixes which has been accepted by upstream to stable by myself?
>     If yes, where I can find related process for reference?

Sure!, please read:
    https://www.kernel.org/doc/html/latest/process/stable-kernel-rules.html

^ permalink raw reply

* [PATCH 1/1] dt-bindings: interrupt-controller: al-fic: remove redundant binding
From: Talel Shenhar @ 2019-07-11  6:38 UTC (permalink / raw)
  To: robh+dt, marc.zyngier, tglx, jason, mark.rutland, nicolas.ferre,
	mchehab+samsung, shawn.lin, gregkh, dwmw, benh, talel,
	linux-kernel, devicetree

Remove dt binding description for standard binding.

Signed-off-by: Talel Shenhar <talel@amazon.com>
---
 .../bindings/interrupt-controller/amazon,al-fic.txt      | 16 +++++++---------
 1 file changed, 7 insertions(+), 9 deletions(-)

diff --git a/Documentation/devicetree/bindings/interrupt-controller/amazon,al-fic.txt b/Documentation/devicetree/bindings/interrupt-controller/amazon,al-fic.txt
index 4e82fd5..c676b03 100644
--- a/Documentation/devicetree/bindings/interrupt-controller/amazon,al-fic.txt
+++ b/Documentation/devicetree/bindings/interrupt-controller/amazon,al-fic.txt
@@ -5,21 +5,19 @@ Required properties:
 - compatible: should be "amazon,al-fic"
 - reg: physical base address and size of the registers
 - interrupt-controller: identifies the node as an interrupt controller
-- #interrupt-cells: must be 2.
-  First cell defines the index of the interrupt within the controller.
-  Second cell is used to specify the trigger type and must be one of the
-  following:
-    - bits[3:0] trigger type and level flags
-	1 = low-to-high edge triggered
-	4 = active high level-sensitive
-- interrupt-parent: specifies the parent interrupt controller.
+- #interrupt-cells : must be 2. Specifies the number of cells needed to encode
+  an interrupt source. Supported trigger types are low-to-high edge
+  triggered and active high level-sensitive.
 - interrupts: describes which input line in the interrupt parent, this
   fic's output is connected to. This field property depends on the parent's
   binding
 
+Please refer to interrupts.txt in this directory for details of the common
+Interrupt Controllers bindings used by client devices.
+
 Example:
 
-amazon_fic: interrupt-controller@0xfd8a8500 {
+amazon_fic: interrupt-controller@fd8a8500 {
 	compatible = "amazon,al-fic";
 	interrupt-controller;
 	#interrupt-cells = <2>;
-- 
2.7.4

^ permalink raw reply related

* Re: [PATCH 1/3] opp: core: add regulators enable and disable
From: Viresh Kumar @ 2019-07-11  6:22 UTC (permalink / raw)
  To: k.konieczny
  Cc: Bartlomiej Zolnierkiewicz, Marek Szyprowski, Chanwoo Choi,
	Krzysztof Kozlowski, Kukjin Kim, Kyungmin Park, Mark Rutland,
	MyungJoo Ham, Nishanth Menon, Rob Herring, Stephen Boyd,
	Viresh Kumar, devicetree, linux-arm-kernel, linux-kernel,
	linux-pm, linux-samsung-soc
In-Reply-To: <20190708141140.24379-2-k.konieczny@partner.samsung.com>

On 08-07-19, 16:11, k.konieczny@partner.samsung.com wrote:
> From: Kamil Konieczny <k.konieczny@partner.samsung.com>
> 
> Add enable regulators to dev_pm_opp_set_regulators() and disable
> regulators to dev_pm_opp_put_regulators(). This prepares for
> converting exynos-bus devfreq driver to use dev_pm_opp_set_rate().
> 
> Signed-off-by: Kamil Konieczny <k.konieczny@partner.samsung.com>
> ---
>  drivers/opp/core.c | 13 +++++++++++++
>  1 file changed, 13 insertions(+)
> 
> diff --git a/drivers/opp/core.c b/drivers/opp/core.c
> index 0e7703fe733f..947cac452854 100644
> --- a/drivers/opp/core.c
> +++ b/drivers/opp/core.c
> @@ -1580,8 +1580,19 @@ struct opp_table *dev_pm_opp_set_regulators(struct device *dev,
>  	if (ret)
>  		goto free_regulators;
>  
> +	for (i = 0; i < opp_table->regulator_count; i++) {
> +		ret = regulator_enable(opp_table->regulators[i]);
> +		if (ret < 0)
> +			goto disable;
> +	}

What about doing this in the same loop of regulator_get_optional() ?

> +
>  	return opp_table;
>  
> +disable:
> +	while (i != 0)
> +		regulator_disable(opp_table->regulators[--i]);
> +
> +	i = opp_table->regulator_count;

You also need to call _free_set_opp_data() here.

>  free_regulators:
>  	while (i != 0)
>  		regulator_put(opp_table->regulators[--i]);
> @@ -1609,6 +1620,8 @@ void dev_pm_opp_put_regulators(struct opp_table *opp_table)
>  
>  	/* Make sure there are no concurrent readers while updating opp_table */
>  	WARN_ON(!list_empty(&opp_table->opp_list));

Preserve the blank line here.

> +	for (i = opp_table->regulator_count - 1; i >= 0; i--)
> +		regulator_disable(opp_table->regulators[i]);
>  
>  	for (i = opp_table->regulator_count - 1; i >= 0; i--)
>  		regulator_put(opp_table->regulators[i]);

Only single loop should be sufficient for this.

> -- 
> 2.22.0

-- 
viresh

^ permalink raw reply

* RE: [PATCH AUTOSEL 5.1 08/39] arm64: dts: ls1028a: Fix CPU idle fail.
From: Ran Wang @ 2019-07-11  5:04 UTC (permalink / raw)
  To: Sasha Levin, linux-kernel@vger.kernel.org, stable@vger.kernel.org
  Cc: Shawn Guo, devicetree@vger.kernel.org, Xiaobo Xie
In-Reply-To: <20190703021514.17727-8-sashal@kernel.org>

Hi Sasha, 

    Thanks for helping port this patch to stable.
    May I know if I can submit other bug fixes which has been accepted by upstream to stable by myself?
    If yes, where I can find related process for reference?

Thanks & Regards,
Ran

> -----Original Message-----
> From: Sasha Levin <sashal@kernel.org>
> Sent: Wednesday, July 03, 2019 10:15
> To: linux-kernel@vger.kernel.org; stable@vger.kernel.org
> Cc: Ran Wang <ran.wang_1@nxp.com>; Shawn Guo <shawnguo@kernel.org>;
> Sasha Levin <sashal@kernel.org>; devicetree@vger.kernel.org
> Subject: [PATCH AUTOSEL 5.1 08/39] arm64: dts: ls1028a: Fix CPU idle fail.
> 
> From: Ran Wang <ran.wang_1@nxp.com>
> 
> [ Upstream commit 53f2ac9d3aa881ed419054076042898b77c27ee4 ]
> 
> PSCI spec define 1st parameter's bit 16 of function CPU_SUSPEND to indicate
> CPU State Type: 0 for standby, 1 for power down. In this case, we want to select
> standby for CPU idle feature. But current setting wrongly select power down and
> cause CPU SUSPEND fail every time. Need this fix.
> 
> Fixes: 8897f3255c9c ("arm64: dts: Add support for NXP LS1028A SoC")
> Signed-off-by: Ran Wang <ran.wang_1@nxp.com>
> Signed-off-by: Shawn Guo <shawnguo@kernel.org>
> Signed-off-by: Sasha Levin <sashal@kernel.org>
> ---
>  arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi | 18 +++++++++---------
>  1 file changed, 9 insertions(+), 9 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
> b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
> index 2896bbcfa3bb..228872549f01 100644
> --- a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
> +++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
> @@ -28,7 +28,7 @@
>  			enable-method = "psci";
>  			clocks = <&clockgen 1 0>;
>  			next-level-cache = <&l2>;
> -			cpu-idle-states = <&CPU_PH20>;
> +			cpu-idle-states = <&CPU_PW20>;
>  		};
> 
>  		cpu1: cpu@1 {
> @@ -38,7 +38,7 @@
>  			enable-method = "psci";
>  			clocks = <&clockgen 1 0>;
>  			next-level-cache = <&l2>;
> -			cpu-idle-states = <&CPU_PH20>;
> +			cpu-idle-states = <&CPU_PW20>;
>  		};
> 
>  		l2: l2-cache {
> @@ -53,13 +53,13 @@
>  		 */
>  		entry-method = "arm,psci";
> 
> -		CPU_PH20: cpu-ph20 {
> -			compatible = "arm,idle-state";
> -			idle-state-name = "PH20";
> -			arm,psci-suspend-param = <0x00010000>;
> -			entry-latency-us = <1000>;
> -			exit-latency-us = <1000>;
> -			min-residency-us = <3000>;
> +		CPU_PW20: cpu-pw20 {
> +			  compatible = "arm,idle-state";
> +			  idle-state-name = "PW20";
> +			  arm,psci-suspend-param = <0x0>;
> +			  entry-latency-us = <2000>;
> +			  exit-latency-us = <2000>;
> +			  min-residency-us = <6000>;
>  		};
>  	};
> 
> --
> 2.20.1

^ permalink raw reply

* [PATCH 6/6] pinctrl: aspeed: Add AST2600 pinmux support
From: Andrew Jeffery @ 2019-07-11  4:19 UTC (permalink / raw)
  To: linux-gpio
  Cc: Andrew Jeffery, linus.walleij, robh+dt, mark.rutland, joel,
	ryanchen.aspeed, johnny_huang, linux-aspeed, devicetree,
	linux-arm-kernel, linux-kernel
In-Reply-To: <20190711041942.23202-1-andrew@aj.id.au>

The AST2600 pinmux is fairly similar to the previous generations of
ASPEED BMC SoCs in terms of architecture, though differ in some of the
design details. The complexity of the pin expressions is largely reduced
(e.g. there are no-longer signals with multiple expressions muxing them
to the associated pin), and there are now signals and buses with
multiple pin groups.

The driver implements pinmux support for all 244 GPIO-capable pins plus
a further four pins that are not GPIO capable but which expose multiple
signals. pinconf will be implemented in a follow-up patch.

The implementation has been smoke-tested under qemu, and run on hardware
by ASPEED.

Debugged-by: Johnny Huang <johnny_huang@aspeedtech.com>
Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
---
 drivers/pinctrl/aspeed/Kconfig             |    8 +
 drivers/pinctrl/aspeed/Makefile            |    1 +
 drivers/pinctrl/aspeed/pinctrl-aspeed-g6.c | 2395 ++++++++++++++++++++
 3 files changed, 2404 insertions(+)
 create mode 100644 drivers/pinctrl/aspeed/pinctrl-aspeed-g6.c

diff --git a/drivers/pinctrl/aspeed/Kconfig b/drivers/pinctrl/aspeed/Kconfig
index 998eabef3a65..ceb415583dc0 100644
--- a/drivers/pinctrl/aspeed/Kconfig
+++ b/drivers/pinctrl/aspeed/Kconfig
@@ -22,3 +22,11 @@ config PINCTRL_ASPEED_G5
 	help
 	  Say Y here to enable pin controller support for Aspeed's 5th
 	  generation SoCs. GPIO is provided by a separate GPIO driver.
+
+config PINCTRL_ASPEED_G6
+	bool "Aspeed G6 SoC pin control"
+	depends on (MACH_ASPEED_G6 || COMPILE_TEST) && OF
+	select PINCTRL_ASPEED
+	help
+	  Say Y here to enable pin controller support for Aspeed's 6th
+	  generation SoCs. GPIO is provided by a separate GPIO driver.
diff --git a/drivers/pinctrl/aspeed/Makefile b/drivers/pinctrl/aspeed/Makefile
index 3a94e4db0c8e..3888ba601b7b 100644
--- a/drivers/pinctrl/aspeed/Makefile
+++ b/drivers/pinctrl/aspeed/Makefile
@@ -4,3 +4,4 @@ ccflags-y += $(call cc-option,-Woverride-init)
 obj-$(CONFIG_PINCTRL_ASPEED)	+= pinctrl-aspeed.o pinmux-aspeed.o
 obj-$(CONFIG_PINCTRL_ASPEED_G4)	+= pinctrl-aspeed-g4.o
 obj-$(CONFIG_PINCTRL_ASPEED_G5)	+= pinctrl-aspeed-g5.o
+obj-$(CONFIG_PINCTRL_ASPEED_G6)	+= pinctrl-aspeed-g6.o
diff --git a/drivers/pinctrl/aspeed/pinctrl-aspeed-g6.c b/drivers/pinctrl/aspeed/pinctrl-aspeed-g6.c
new file mode 100644
index 000000000000..6012d7d4a22a
--- /dev/null
+++ b/drivers/pinctrl/aspeed/pinctrl-aspeed-g6.c
@@ -0,0 +1,2395 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/* Copyright (C) 2019 IBM Corp. */
+#include <linux/bitops.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/mfd/syscon.h>
+#include <linux/mutex.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/string.h>
+#include <linux/types.h>
+
+#include "../core.h"
+#include "../pinctrl-utils.h"
+#include "pinctrl-aspeed.h"
+
+#define SCU400		0x400 /* Multi-function Pin Control #1  */
+#define SCU404		0x404 /* Multi-function Pin Control #2  */
+#define SCU410		0x410 /* Multi-function Pin Control #4  */
+#define SCU414		0x414 /* Multi-function Pin Control #5  */
+#define SCU418		0x418 /* Multi-function Pin Control #6  */
+#define SCU41C		0x41C /* Multi-function Pin Control #7  */
+#define SCU430		0x430 /* Multi-function Pin Control #8  */
+#define SCU434		0x434 /* Multi-function Pin Control #9  */
+#define SCU438		0x438 /* Multi-function Pin Control #10 */
+#define SCU450		0x450 /* Multi-function Pin Control #14 */
+#define SCU4B0		0x4B0 /* Multi-function Pin Control #17 */
+#define SCU4B4		0x4B4 /* Multi-function Pin Control #18 */
+#define SCU4B8		0x4B8 /* Multi-function Pin Control #19 */
+#define SCU4BC		0x4BC /* Multi-function Pin Control #20 */
+#define SCU4D4		0x4D4 /* Multi-function Pin Control #22 */
+#define SCU4D8		0x4D8 /* Multi-function Pin Control #23 */
+#define SCU500		0x500 /* Hardware Strap 1 */
+#define SCU510		0x510 /* Hardware Strap 2 */
+#define SCU694		0x694 /* Multi-function Pin Control #25 */
+
+#define ASPEED_G6_NR_PINS 248
+
+#define M24 0
+SIG_EXPR_LIST_DECL_SESG(M24, MDC3, MDIO3, SIG_DESC_SET(SCU410, 0));
+SIG_EXPR_LIST_DECL_SESG(M24, SCL11, I2C11, SIG_DESC_SET(SCU4B0, 0));
+PIN_DECL_2(M24, GPIOA0, MDC3, SCL11);
+
+#define M25 1
+SIG_EXPR_LIST_DECL_SESG(M25, MDIO3, MDIO3, SIG_DESC_SET(SCU410, 1));
+SIG_EXPR_LIST_DECL_SESG(M25, SDA11, I2C11, SIG_DESC_SET(SCU4B0, 1));
+PIN_DECL_2(M25, GPIOA1, MDIO3, SDA11);
+
+FUNC_GROUP_DECL(MDIO3, M24, M25);
+FUNC_GROUP_DECL(I2C11, M24, M25);
+
+#define L26 2
+SIG_EXPR_LIST_DECL_SESG(L26, MDC4, MDIO4, SIG_DESC_SET(SCU410, 2));
+SIG_EXPR_LIST_DECL_SESG(L26, SCL12, I2C12, SIG_DESC_SET(SCU4B0, 2));
+PIN_DECL_2(L26, GPIOA2, MDC4, SCL12);
+
+#define K24 3
+SIG_EXPR_LIST_DECL_SESG(K24, MDIO4, MDIO4, SIG_DESC_SET(SCU410, 3));
+SIG_EXPR_LIST_DECL_SESG(K24, SDA12, I2C12, SIG_DESC_SET(SCU4B0, 3));
+PIN_DECL_2(K24, GPIOA3, MDIO4, SDA12);
+
+FUNC_GROUP_DECL(MDIO4, L26, K24);
+FUNC_GROUP_DECL(I2C12, L26, K24);
+
+#define K26 4
+SIG_EXPR_LIST_DECL_SESG(K26, MACLINK1, MACLINK1, SIG_DESC_SET(SCU410, 4));
+SIG_EXPR_LIST_DECL_SESG(K26, SCL13, I2C13, SIG_DESC_SET(SCU4B0, 4));
+PIN_DECL_2(K26, GPIOA4, MACLINK1, SCL13);
+FUNC_GROUP_DECL(MACLINK1, K26);
+
+#define L24 5
+SIG_EXPR_LIST_DECL_SESG(L24, MACLINK2, MACLINK2, SIG_DESC_SET(SCU410, 5));
+SIG_EXPR_LIST_DECL_SESG(L24, SDA13, I2C13, SIG_DESC_SET(SCU4B0, 5));
+PIN_DECL_2(L24, GPIOA5, MACLINK2, SDA13);
+FUNC_GROUP_DECL(MACLINK2, L24);
+
+FUNC_GROUP_DECL(I2C13, K26, L24);
+
+#define L23 6
+SIG_EXPR_LIST_DECL_SESG(L23, MACLINK3, MACLINK3, SIG_DESC_SET(SCU410, 6));
+SIG_EXPR_LIST_DECL_SESG(L23, SCL14, I2C14, SIG_DESC_SET(SCU4B0, 6));
+PIN_DECL_2(L23, GPIOA6, MACLINK3, SCL14);
+FUNC_GROUP_DECL(MACLINK3, L23);
+
+#define K25 7
+SIG_EXPR_LIST_DECL_SESG(K25, MACLINK4, MACLINK4, SIG_DESC_SET(SCU410, 7));
+SIG_EXPR_LIST_DECL_SESG(K25, SDA14, SDA14, SIG_DESC_SET(SCU4B0, 7));
+PIN_DECL_2(K25, GPIOA7, MACLINK4, SDA14);
+FUNC_GROUP_DECL(MACLINK4, K25);
+
+FUNC_GROUP_DECL(I2C14, L23, K25);
+
+#define J26 8
+SIG_EXPR_LIST_DECL_SESG(J26, SALT1, SALT1, SIG_DESC_SET(SCU410, 8));
+SIG_EXPR_LIST_DECL_SESG(J26, LHAD0, LPCHC, SIG_DESC_SET(SCU4B0, 8));
+PIN_DECL_2(J26, GPIOB0, SALT1, LHAD0);
+FUNC_GROUP_DECL(SALT1, J26);
+
+#define K23 9
+SIG_EXPR_LIST_DECL_SESG(K23, SALT2, SALT2, SIG_DESC_SET(SCU410, 9));
+SIG_EXPR_LIST_DECL_SESG(K23, LHAD1, LPCHC, SIG_DESC_SET(SCU4B0, 9));
+PIN_DECL_2(K23, GPIOB1, SALT2, LHAD1);
+FUNC_GROUP_DECL(SALT2, K23);
+
+#define H26 10
+SIG_EXPR_LIST_DECL_SESG(H26, SALT3, SALT3, SIG_DESC_SET(SCU410, 10));
+SIG_EXPR_LIST_DECL_SESG(H26, LHAD2, LPCHC, SIG_DESC_SET(SCU4B0, 10));
+PIN_DECL_2(H26, GPIOB2, SALT3, LHAD2);
+FUNC_GROUP_DECL(SALT3, H26);
+
+#define J25 11
+SIG_EXPR_LIST_DECL_SESG(J25, SALT4, SALT4, SIG_DESC_SET(SCU410, 11));
+SIG_EXPR_LIST_DECL_SESG(J25, LHAD3, LPCHC, SIG_DESC_SET(SCU4B0, 11));
+PIN_DECL_2(J25, GPIOB3, SALT4, LHAD3);
+FUNC_GROUP_DECL(SALT4, J25);
+
+#define J23 12
+SIG_EXPR_LIST_DECL_SESG(J23, MDC2, MDIO2, SIG_DESC_SET(SCU410, 12));
+SIG_EXPR_LIST_DECL_SESG(J23, LHCLK, LPCHC, SIG_DESC_SET(SCU4B0, 12));
+PIN_DECL_2(J23, GPIOB4, MDC2, LHCLK);
+
+#define G26 13
+SIG_EXPR_LIST_DECL_SESG(G26, MDIO2, MDIO2, SIG_DESC_SET(SCU410, 13));
+SIG_EXPR_LIST_DECL_SESG(G26, LHFRAME, LPCHC, SIG_DESC_SET(SCU4B0, 13));
+PIN_DECL_2(G26, GPIOB5, MDIO2, LHFRAME);
+
+FUNC_GROUP_DECL(MDIO2, J23, G26);
+
+#define H25 14
+SIG_EXPR_LIST_DECL_SESG(H25, TXD4, TXD4, SIG_DESC_SET(SCU410, 14));
+SIG_EXPR_LIST_DECL_SESG(H25, LHSIRQ, LHSIRQ, SIG_DESC_SET(SCU4B0, 14));
+PIN_DECL_2(H25, GPIOB6, TXD4, LHSIRQ);
+FUNC_GROUP_DECL(TXD4, H25);
+FUNC_GROUP_DECL(LHSIRQ, H25);
+
+#define J24 15
+SIG_EXPR_LIST_DECL_SESG(J24, RXD4, RXD4, SIG_DESC_SET(SCU410, 15));
+SIG_EXPR_LIST_DECL_SESG(J24, LHRST, LPCHC, SIG_DESC_SET(SCU4B0, 15));
+PIN_DECL_2(J24, GPIOB7, RXD4, LHRST);
+FUNC_GROUP_DECL(RXD4, J24);
+
+FUNC_GROUP_DECL(LPCHC, J26, K23, H26, J25, J23, G26, H25, J24);
+
+#define H24 16
+SIG_EXPR_LIST_DECL_SESG(H24, RGMII3TXCK, RGMII3, SIG_DESC_SET(SCU410, 16),
+			  SIG_DESC_SET(SCU510, 0));
+SIG_EXPR_LIST_DECL_SESG(H24, RMII3RCLKO, RMII3, SIG_DESC_SET(SCU410, 16),
+			  SIG_DESC_CLEAR(SCU510, 0));
+PIN_DECL_2(H24, GPIOC0, RGMII3TXCK, RMII3RCLKO);
+
+#define J22 17
+SIG_EXPR_LIST_DECL_SESG(J22, RGMII3TXCTL, RGMII3, SIG_DESC_SET(SCU410, 17),
+			  SIG_DESC_SET(SCU510, 0));
+SIG_EXPR_LIST_DECL_SESG(J22, RMII3TXEN, RMII3, SIG_DESC_SET(SCU410, 17),
+			  SIG_DESC_CLEAR(SCU510, 0));
+PIN_DECL_2(J22, GPIOC1, RGMII3TXCTL, RMII3TXEN);
+
+#define H22 18
+SIG_EXPR_LIST_DECL_SESG(H22, RGMII3TXD0, RGMII3, SIG_DESC_SET(SCU410, 18),
+			  SIG_DESC_SET(SCU510, 0));
+SIG_EXPR_LIST_DECL_SESG(H22, RMII3TXD0, RMII3, SIG_DESC_SET(SCU410, 18),
+			  SIG_DESC_CLEAR(SCU510, 0));
+PIN_DECL_2(H22, GPIOC2, RGMII3TXD0, RMII3TXD0);
+
+#define H23 19
+SIG_EXPR_LIST_DECL_SESG(H23, RGMII3TXD1, RGMII3, SIG_DESC_SET(SCU410, 19),
+			  SIG_DESC_SET(SCU510, 0));
+SIG_EXPR_LIST_DECL_SESG(H23, RMII3TXD1, RMII3, SIG_DESC_SET(SCU410, 19),
+			  SIG_DESC_CLEAR(SCU510, 0));
+PIN_DECL_2(H23, GPIOC3, RGMII3TXD1, RMII3TXD1);
+
+#define G22 20
+SIG_EXPR_LIST_DECL_SESG(G22, RGMII3TXD2, RGMII3, SIG_DESC_SET(SCU410, 20),
+			  SIG_DESC_SET(SCU510, 0));
+PIN_DECL_1(G22, GPIOC4, RGMII3TXD2);
+
+#define F22 21
+SIG_EXPR_LIST_DECL_SESG(F22, RGMII3TXD3, RGMII3, SIG_DESC_SET(SCU410, 21),
+			  SIG_DESC_SET(SCU510, 0));
+PIN_DECL_1(F22, GPIOC5, RGMII3TXD3);
+
+#define G23 22
+SIG_EXPR_LIST_DECL_SESG(G23, RGMII3RXCK, RGMII3, SIG_DESC_SET(SCU410, 22),
+			  SIG_DESC_SET(SCU510, 0));
+SIG_EXPR_LIST_DECL_SESG(G23, RMII3RCLKI, RMII3, SIG_DESC_SET(SCU410, 22),
+			  SIG_DESC_CLEAR(SCU510, 0));
+PIN_DECL_2(G23, GPIOC6, RGMII3RXCK, RMII3RCLKI);
+
+#define G24 23
+SIG_EXPR_LIST_DECL_SESG(G24, RGMII3RXCTL, RGMII3, SIG_DESC_SET(SCU410, 23),
+			  SIG_DESC_SET(SCU510, 0));
+PIN_DECL_1(G24, GPIOC7, RGMII3RXCTL);
+
+#define F23 24
+SIG_EXPR_LIST_DECL_SESG(F23, RGMII3RXD0, RGMII3, SIG_DESC_SET(SCU410, 24),
+			  SIG_DESC_SET(SCU510, 0));
+SIG_EXPR_LIST_DECL_SESG(F23, RMII3RXD0, RMII3, SIG_DESC_SET(SCU410, 24),
+			  SIG_DESC_CLEAR(SCU510, 0));
+PIN_DECL_2(F23, GPIOD0, RGMII3RXD0, RMII3RXD0);
+
+#define F26 25
+SIG_EXPR_LIST_DECL_SESG(F26, RGMII3RXD1, RGMII3, SIG_DESC_SET(SCU410, 25),
+			  SIG_DESC_SET(SCU510, 0));
+SIG_EXPR_LIST_DECL_SESG(F26, RMII3RXD1, RMII3, SIG_DESC_SET(SCU410, 25),
+			  SIG_DESC_CLEAR(SCU510, 0));
+PIN_DECL_2(F26, GPIOD1, RGMII3RXD1, RMII3RXD1);
+
+#define F25 26
+SIG_EXPR_LIST_DECL_SESG(F25, RGMII3RXD2, RGMII3, SIG_DESC_SET(SCU410, 26),
+			  SIG_DESC_SET(SCU510, 0));
+SIG_EXPR_LIST_DECL_SESG(F25, RMII3CRSDV, RMII3, SIG_DESC_SET(SCU410, 26),
+			  SIG_DESC_CLEAR(SCU510, 0));
+PIN_DECL_2(F25, GPIOD2, RGMII3RXD2, RMII3CRSDV);
+
+#define E26 27
+SIG_EXPR_LIST_DECL_SESG(E26, RGMII3RXD3, RGMII3, SIG_DESC_SET(SCU410, 27),
+			  SIG_DESC_SET(SCU510, 0));
+SIG_EXPR_LIST_DECL_SESG(E26, RMII3RXER, RMII3, SIG_DESC_SET(SCU410, 27),
+			  SIG_DESC_CLEAR(SCU510, 0));
+PIN_DECL_2(E26, GPIOD3, RGMII3RXD3, RMII3RXER);
+
+FUNC_GROUP_DECL(RGMII3, H24, J22, H22, H23, G22, F22, G23, G24, F23, F26, F25,
+		E26);
+FUNC_GROUP_DECL(RMII3, H24, J22, H22, H23, G23, F23, F26, F25, E26);
+
+#define F24 28
+SIG_EXPR_LIST_DECL_SESG(F24, NCTS3, NCTS3, SIG_DESC_SET(SCU410, 28));
+SIG_EXPR_LIST_DECL_SESG(F24, RGMII4TXCK, RGMII4, SIG_DESC_SET(SCU4B0, 28),
+			  SIG_DESC_SET(SCU510, 1));
+SIG_EXPR_LIST_DECL_SESG(F24, RMII4RCLKO, RMII4, SIG_DESC_SET(SCU4B0, 28),
+			  SIG_DESC_CLEAR(SCU510, 1));
+PIN_DECL_3(F24, GPIOD4, NCTS3, RGMII4TXCK, RMII4RCLKO);
+FUNC_GROUP_DECL(NCTS3, F24);
+
+#define E23 29
+SIG_EXPR_LIST_DECL_SESG(E23, NDCD3, NDCD3, SIG_DESC_SET(SCU410, 29));
+SIG_EXPR_LIST_DECL_SESG(E23, RGMII4TXCTL, RGMII4, SIG_DESC_SET(SCU4B0, 29),
+			  SIG_DESC_SET(SCU510, 1));
+SIG_EXPR_LIST_DECL_SESG(E23, RMII4TXEN, RMII4, SIG_DESC_SET(SCU4B0, 29),
+			  SIG_DESC_CLEAR(SCU510, 1));
+PIN_DECL_3(E23, GPIOD5, NDCD3, RGMII4TXCTL, RMII4TXEN);
+FUNC_GROUP_DECL(NDCD3, E23);
+
+#define E24 30
+SIG_EXPR_LIST_DECL_SESG(E24, NDSR3, NDSR3, SIG_DESC_SET(SCU410, 30));
+SIG_EXPR_LIST_DECL_SESG(E24, RGMII4TXD0, RGMII4, SIG_DESC_SET(SCU4B0, 30),
+			  SIG_DESC_SET(SCU510, 1));
+SIG_EXPR_LIST_DECL_SESG(E24, RMII4TXD0, RMII4, SIG_DESC_SET(SCU4B0, 30),
+			  SIG_DESC_CLEAR(SCU510, 1));
+PIN_DECL_3(E24, GPIOD6, NDSR3, RGMII4TXD0, RMII4TXD0);
+FUNC_GROUP_DECL(NDSR3, E24);
+
+#define E25 31
+SIG_EXPR_LIST_DECL_SESG(E25, NRI3, NRI3, SIG_DESC_SET(SCU410, 31));
+SIG_EXPR_LIST_DECL_SESG(E25, RGMII4TXD1, RGMII4, SIG_DESC_SET(SCU4B0, 31),
+			  SIG_DESC_SET(SCU510, 1));
+SIG_EXPR_LIST_DECL_SESG(E25, RMII4TXD1, RMII4, SIG_DESC_SET(SCU4B0, 31),
+			  SIG_DESC_CLEAR(SCU510, 1));
+PIN_DECL_3(E25, GPIOD7, NRI3, RGMII4TXD1, RMII4TXD1);
+FUNC_GROUP_DECL(NRI3, E25);
+
+#define D26 32
+SIG_EXPR_LIST_DECL_SESG(D26, NDTR3, NDTR3, SIG_DESC_SET(SCU414, 0));
+SIG_EXPR_LIST_DECL_SESG(D26, RGMII4TXD2, RGMII4, SIG_DESC_SET(SCU4B4, 0),
+			  SIG_DESC_SET(SCU510, 1));
+PIN_DECL_2(D26, GPIOE0, NDTR3, RGMII4TXD2);
+FUNC_GROUP_DECL(NDTR3, D26);
+
+#define D24 33
+SIG_EXPR_LIST_DECL_SESG(D24, NRTS3, NRTS3, SIG_DESC_SET(SCU414, 1));
+SIG_EXPR_LIST_DECL_SESG(D24, RGMII4TXD3, RGMII4, SIG_DESC_SET(SCU4B4, 1),
+			  SIG_DESC_SET(SCU510, 1));
+PIN_DECL_2(D24, GPIOE1, NRTS3, RGMII4TXD3);
+FUNC_GROUP_DECL(NRTS3, D24);
+
+#define C25 34
+SIG_EXPR_LIST_DECL_SESG(C25, NCTS4, NCTS4, SIG_DESC_SET(SCU414, 2));
+SIG_EXPR_LIST_DECL_SESG(C25, RGMII4RXCK, RGMII4, SIG_DESC_SET(SCU4B4, 2),
+			  SIG_DESC_SET(SCU510, 1));
+SIG_EXPR_LIST_DECL_SESG(C25, RMII4RCLKI, RMII4, SIG_DESC_SET(SCU4B4, 2),
+			  SIG_DESC_CLEAR(SCU510, 1));
+PIN_DECL_3(C25, GPIOE2, NCTS4, RGMII4RXCK, RMII4RCLKI);
+FUNC_GROUP_DECL(NCTS4, C25);
+
+#define C26 35
+SIG_EXPR_LIST_DECL_SESG(C26, NDCD4, NDCD4, SIG_DESC_SET(SCU414, 3));
+SIG_EXPR_LIST_DECL_SESG(C26, RGMII4RXCTL, RGMII4, SIG_DESC_SET(SCU4B4, 3),
+			  SIG_DESC_SET(SCU510, 1));
+PIN_DECL_2(C26, GPIOE3, NDCD4, RGMII4RXCTL);
+FUNC_GROUP_DECL(NDCD4, C26);
+
+#define C24 36
+SIG_EXPR_LIST_DECL_SESG(C24, NDSR4, NDSR4, SIG_DESC_SET(SCU414, 4));
+SIG_EXPR_LIST_DECL_SESG(C24, RGMII4RXD0, RGMII4, SIG_DESC_SET(SCU4B4, 4),
+			  SIG_DESC_SET(SCU510, 1));
+SIG_EXPR_LIST_DECL_SESG(C24, RMII4RXD0, RMII4, SIG_DESC_SET(SCU4B4, 4),
+			  SIG_DESC_CLEAR(SCU510, 1));
+PIN_DECL_3(C24, GPIOE4, NDSR4, RGMII4RXD0, RMII4RXD0);
+FUNC_GROUP_DECL(NDSR4, C24);
+
+#define B26 37
+SIG_EXPR_LIST_DECL_SESG(B26, NRI4, NRI4, SIG_DESC_SET(SCU414, 5));
+SIG_EXPR_LIST_DECL_SESG(B26, RGMII4RXD1, RGMII4, SIG_DESC_SET(SCU4B4, 5),
+			  SIG_DESC_SET(SCU510, 1));
+SIG_EXPR_LIST_DECL_SESG(B26, RMII4RXD1, RMII4, SIG_DESC_SET(SCU4B4, 5),
+			  SIG_DESC_CLEAR(SCU510, 1));
+PIN_DECL_3(B26, GPIOE5, NRI4, RGMII4RXD1, RMII4RXD1);
+FUNC_GROUP_DECL(NRI4, B26);
+
+#define B25 38
+SIG_EXPR_LIST_DECL_SESG(B25, NDTR4, NDTR4, SIG_DESC_SET(SCU414, 6));
+SIG_EXPR_LIST_DECL_SESG(B25, RGMII4RXD2, RGMII4, SIG_DESC_SET(SCU4B4, 6),
+			  SIG_DESC_SET(SCU510, 1));
+SIG_EXPR_LIST_DECL_SESG(B25, RMII4CRSDV, RMII4, SIG_DESC_SET(SCU4B4, 6),
+			  SIG_DESC_CLEAR(SCU510, 1));
+PIN_DECL_3(B25, GPIOE6, NDTR4, RGMII4RXD2, RMII4CRSDV);
+FUNC_GROUP_DECL(NDTR4, B25);
+
+#define B24 39
+SIG_EXPR_LIST_DECL_SESG(B24, NRTS4, NRTS4, SIG_DESC_SET(SCU414, 7));
+SIG_EXPR_LIST_DECL_SESG(B24, RGMII4RXD3, RGMII4, SIG_DESC_SET(SCU4B4, 7),
+			  SIG_DESC_SET(SCU510, 1));
+SIG_EXPR_LIST_DECL_SESG(B24, RMII4RXER, RMII4, SIG_DESC_SET(SCU4B4, 7),
+			  SIG_DESC_CLEAR(SCU510, 1));
+PIN_DECL_3(B24, GPIOE7, NRTS4, RGMII4RXD3, RMII4RXER);
+FUNC_GROUP_DECL(NRTS4, B24);
+
+FUNC_GROUP_DECL(RGMII4, F24, E23, E24, E25, D26, D24, C25, C26, C24, B26, B25,
+		B24);
+FUNC_GROUP_DECL(RMII4, F24, E23, E24, E25, C25, C24, B26, B25, B24);
+
+#define D22 40
+SIG_EXPR_LIST_DECL_SESG(D22, SD1CLK, SD1, SIG_DESC_SET(SCU414, 8));
+SIG_EXPR_LIST_DECL_SEMG(D22, PWM8, PWM8G0, PWM8, SIG_DESC_SET(SCU414, 8));
+PIN_DECL_2(D22, GPIOF0, SD1CLK, PWM8);
+GROUP_DECL(PWM8G0, D22);
+
+#define E22 41
+SIG_EXPR_LIST_DECL_SESG(E22, SD1CMD, SD1, SIG_DESC_SET(SCU414, 9));
+SIG_EXPR_LIST_DECL_SEMG(E22, PWM9, PWM9G0, PWM9, SIG_DESC_SET(SCU4B4, 9));
+PIN_DECL_2(E22, GPIOF1, SD1CMD, PWM9);
+GROUP_DECL(PWM9G0, E22);
+
+#define D23 42
+SIG_EXPR_LIST_DECL_SESG(D23, SD1DAT0, SD1, SIG_DESC_SET(SCU414, 10));
+SIG_EXPR_LIST_DECL_SEMG(D23, PWM10, PWM10G0, PWM10, SIG_DESC_SET(SCU4B4, 10));
+PIN_DECL_2(D23, GPIOF2, SD1DAT0, PWM10);
+GROUP_DECL(PWM10G0, D23);
+
+#define C23 43
+SIG_EXPR_LIST_DECL_SESG(C23, SD1DAT1, SD1, SIG_DESC_SET(SCU414, 11));
+SIG_EXPR_LIST_DECL_SEMG(C23, PWM11, PWM11G0, PWM11, SIG_DESC_SET(SCU4B4, 11));
+PIN_DECL_2(C23, GPIOF3, SD1DAT1, PWM11);
+GROUP_DECL(PWM11G0, C23);
+
+#define C22 44
+SIG_EXPR_LIST_DECL_SESG(C22, SD1DAT2, SD1, SIG_DESC_SET(SCU414, 12));
+SIG_EXPR_LIST_DECL_SEMG(C22, PWM12, PWM12G0, PWM12, SIG_DESC_SET(SCU4B4, 12));
+PIN_DECL_2(C22, GPIOF4, SD1DAT2, PWM12);
+GROUP_DECL(PWM12G0, C22);
+
+#define A25 45
+SIG_EXPR_LIST_DECL_SESG(A25, SD1DAT3, SD1, SIG_DESC_SET(SCU414, 13));
+SIG_EXPR_LIST_DECL_SEMG(A25, PWM13, PWM13G0, PWM13, SIG_DESC_SET(SCU4B4, 13));
+PIN_DECL_2(A25, GPIOF5, SD1DAT3, PWM13);
+GROUP_DECL(PWM13G0, A25);
+
+#define A24 46
+SIG_EXPR_LIST_DECL_SESG(A24, SD1CD, SD1, SIG_DESC_SET(SCU414, 14));
+SIG_EXPR_LIST_DECL_SEMG(A24, PWM14, PWM14G0, PWM14, SIG_DESC_SET(SCU4B4, 14));
+PIN_DECL_2(A24, GPIOF6, SD1CD, PWM14);
+GROUP_DECL(PWM14G0, A24);
+
+#define A23 47
+SIG_EXPR_LIST_DECL_SESG(A23, SD1WP, SD1, SIG_DESC_SET(SCU414, 15));
+SIG_EXPR_LIST_DECL_SEMG(A23, PWM15, PWM15G0, PWM15, SIG_DESC_SET(SCU4B4, 15));
+PIN_DECL_2(A23, GPIOF7, SD1WP, PWM15);
+GROUP_DECL(PWM15G0, A23);
+
+FUNC_GROUP_DECL(SD1, D22, E22, D23, C23, C22, A25, A24, A23);
+
+#define E21 48
+SIG_EXPR_LIST_DECL_SESG(E21, TXD6, UART6, SIG_DESC_SET(SCU414, 16));
+SIG_EXPR_LIST_DECL_SESG(E21, SD2CLK, SD2, SIG_DESC_SET(SCU4B4, 16),
+			  SIG_DESC_SET(SCU450, 1));
+SIG_EXPR_LIST_DECL_SEMG(E21, SALT9, SALT9G0, SALT9, SIG_DESC_SET(SCU694, 16));
+PIN_DECL_3(E21, GPIOG0, TXD6, SD2CLK, SALT9);
+GROUP_DECL(SALT9G0, E21);
+
+#define B22 49
+SIG_EXPR_LIST_DECL_SESG(B22, RXD6, UART6, SIG_DESC_SET(SCU414, 17));
+SIG_EXPR_LIST_DECL_SESG(B22, SD2CMD, SD2, SIG_DESC_SET(SCU4B4, 17),
+			  SIG_DESC_SET(SCU450, 1));
+SIG_EXPR_LIST_DECL_SEMG(B22, SALT10, SALT10G0, SALT10,
+			SIG_DESC_SET(SCU694, 17));
+PIN_DECL_3(B22, GPIOG1, RXD6, SD2CMD, SALT10);
+GROUP_DECL(SALT10G0, B22);
+
+FUNC_GROUP_DECL(UART6, E21, B22);
+
+#define C21 50
+SIG_EXPR_LIST_DECL_SESG(C21, TXD7, UART7, SIG_DESC_SET(SCU414, 18));
+SIG_EXPR_LIST_DECL_SESG(C21, SD2DAT0, SD2, SIG_DESC_SET(SCU4B4, 18),
+			  SIG_DESC_SET(SCU450, 1));
+SIG_EXPR_LIST_DECL_SEMG(C21, SALT11, SALT11G0, SALT11,
+			SIG_DESC_SET(SCU694, 18));
+PIN_DECL_3(C21, GPIOG2, TXD7, SD2DAT0, SALT11);
+GROUP_DECL(SALT11G0, C21);
+
+#define A22 51
+SIG_EXPR_LIST_DECL_SESG(A22, RXD7, UART7, SIG_DESC_SET(SCU414, 19));
+SIG_EXPR_LIST_DECL_SESG(A22, SD2DAT1, SD2, SIG_DESC_SET(SCU4B4, 19),
+			  SIG_DESC_SET(SCU450, 1));
+SIG_EXPR_LIST_DECL_SEMG(A22, SALT12, SALT12G0, SALT12,
+			SIG_DESC_SET(SCU694, 19));
+PIN_DECL_3(A22, GPIOG3, RXD7, SD2DAT1, SALT12);
+GROUP_DECL(SALT12G0, A22);
+
+FUNC_GROUP_DECL(UART7, C21, A22);
+
+#define A21 52
+SIG_EXPR_LIST_DECL_SESG(A21, TXD8, UART8, SIG_DESC_SET(SCU414, 20));
+SIG_EXPR_LIST_DECL_SESG(A21, SD2DAT2, SD2, SIG_DESC_SET(SCU4B4, 20),
+			  SIG_DESC_SET(SCU450, 1));
+SIG_EXPR_LIST_DECL_SEMG(A21, SALT13, SALT13G0, SALT13,
+			SIG_DESC_SET(SCU694, 20));
+PIN_DECL_3(A21, GPIOG4, TXD8, SD2DAT2, SALT13);
+GROUP_DECL(SALT13G0, A21);
+
+#define E20 53
+SIG_EXPR_LIST_DECL_SESG(E20, RXD8, UART8, SIG_DESC_SET(SCU414, 21));
+SIG_EXPR_LIST_DECL_SESG(E20, SD2DAT3, SD2, SIG_DESC_SET(SCU4B4, 21),
+			  SIG_DESC_SET(SCU450, 1));
+SIG_EXPR_LIST_DECL_SEMG(E20, SALT14, SALT14G0, SALT14,
+			SIG_DESC_SET(SCU694, 21));
+PIN_DECL_3(E20, GPIOG5, RXD8, SD2DAT3, SALT14);
+GROUP_DECL(SALT14G0, E20);
+
+FUNC_GROUP_DECL(UART8, A21, E20);
+
+#define D21 54
+SIG_EXPR_LIST_DECL_SESG(D21, TXD9, UART9, SIG_DESC_SET(SCU414, 22));
+SIG_EXPR_LIST_DECL_SESG(D21, SD2CD, SD2, SIG_DESC_SET(SCU4B4, 22),
+			  SIG_DESC_SET(SCU450, 1));
+SIG_EXPR_LIST_DECL_SEMG(D21, SALT15, SALT15G0, SALT15,
+			SIG_DESC_SET(SCU694, 22));
+PIN_DECL_3(D21, GPIOG6, TXD9, SD2CD, SALT15);
+GROUP_DECL(SALT15G0, D21);
+
+#define B21 55
+SIG_EXPR_LIST_DECL_SESG(B21, RXD9, UART9, SIG_DESC_SET(SCU414, 23));
+SIG_EXPR_LIST_DECL_SESG(B21, SD2WP, SD2, SIG_DESC_SET(SCU4B4, 23),
+			SIG_DESC_SET(SCU450, 1));
+SIG_EXPR_LIST_DECL_SEMG(B21, SALT16, SALT16G0, SALT16,
+			SIG_DESC_SET(SCU694, 23));
+PIN_DECL_3(B21, GPIOG7, RXD9, SD2WP, SALT16);
+GROUP_DECL(SALT16G0, B21);
+
+FUNC_GROUP_DECL(UART9, D21, B21);
+
+FUNC_GROUP_DECL(SD2, E21, B22, C21, A22, A21, E20, D21, B21);
+
+#define A18 56
+SIG_EXPR_LIST_DECL_SESG(A18, SGPM1CLK, SGPM1, SIG_DESC_SET(SCU414, 24));
+PIN_DECL_1(A18, GPIOH0, SGPM1CLK);
+
+#define B18 57
+SIG_EXPR_LIST_DECL_SESG(B18, SGPM1LD, SGPM1, SIG_DESC_SET(SCU414, 25));
+PIN_DECL_1(B18, GPIOH1, SGPM1LD);
+
+#define C18 58
+SIG_EXPR_LIST_DECL_SESG(C18, SGPM1O, SGPM1, SIG_DESC_SET(SCU414, 26));
+PIN_DECL_1(C18, GPIOH2, SGPM1O);
+
+#define A17 59
+SIG_EXPR_LIST_DECL_SESG(A17, SGPM1I, SGPM1, SIG_DESC_SET(SCU414, 27));
+PIN_DECL_1(A17, GPIOH3, SGPM1I);
+
+FUNC_GROUP_DECL(SGPM1, A18, B18, C18, A17);
+
+#define D18 60
+SIG_EXPR_LIST_DECL_SESG(D18, SGPS1CK, SGPS1, SIG_DESC_SET(SCU414, 28));
+SIG_EXPR_LIST_DECL_SESG(D18, SCL15, I2C15, SIG_DESC_SET(SCU4B4, 28));
+PIN_DECL_2(D18, GPIOH4, SGPS1CK, SCL15);
+
+#define B17 61
+SIG_EXPR_LIST_DECL_SESG(B17, SGPS1LD, SGPS1, SIG_DESC_SET(SCU414, 29));
+SIG_EXPR_LIST_DECL_SESG(B17, SDA15, I2C15, SIG_DESC_SET(SCU4B4, 29));
+PIN_DECL_2(B17, GPIOH5, SGPS1LD, SDA15);
+
+FUNC_GROUP_DECL(I2C15, D18, B17);
+
+#define C17 62
+SIG_EXPR_LIST_DECL_SESG(C17, SGPS1O, SGPS1, SIG_DESC_SET(SCU414, 30));
+SIG_EXPR_LIST_DECL_SESG(C17, SCL16, I2C16, SIG_DESC_SET(SCU4B4, 30));
+PIN_DECL_2(C17, GPIOH6, SGPS1O, SCL16);
+
+#define E18 63
+SIG_EXPR_LIST_DECL_SESG(E18, SGPS1I, SGPS1, SIG_DESC_SET(SCU414, 31));
+SIG_EXPR_LIST_DECL_SESG(E18, SDA16, I2C16, SIG_DESC_SET(SCU4B4, 31));
+PIN_DECL_2(E18, GPIOH7, SGPS1I, SDA16);
+
+FUNC_GROUP_DECL(I2C16, C17, E18);
+FUNC_GROUP_DECL(SGPS1, D18, B17, C17, E18);
+
+#define D17 64
+SIG_EXPR_LIST_DECL_SESG(D17, MTRSTN, JTAGM, SIG_DESC_SET(SCU418, 0));
+SIG_EXPR_LIST_DECL_SEMG(D17, TXD12, UART12G0, UART12, SIG_DESC_SET(SCU4B8, 0));
+PIN_DECL_2(D17, GPIOI0, MTRSTN, TXD12);
+
+#define A16 65
+SIG_EXPR_LIST_DECL_SESG(A16, MTDI, JTAGM, SIG_DESC_SET(SCU418, 1));
+SIG_EXPR_LIST_DECL_SEMG(A16, RXD12, UART12G0, UART12, SIG_DESC_SET(SCU4B8, 1));
+PIN_DECL_2(A16, GPIOI1, MTDI, RXD12);
+
+GROUP_DECL(UART12G0, D17, A16);
+
+#define E17 66
+SIG_EXPR_LIST_DECL_SESG(E17, MTCK, JTAGM, SIG_DESC_SET(SCU418, 2));
+SIG_EXPR_LIST_DECL_SEMG(E17, TXD13, UART13G0, UART13, SIG_DESC_SET(SCU4B8, 2));
+PIN_DECL_2(E17, GPIOI2, MTCK, TXD13);
+
+#define D16 67
+SIG_EXPR_LIST_DECL_SESG(D16, MTMS, JTAGM, SIG_DESC_SET(SCU418, 3));
+SIG_EXPR_LIST_DECL_SEMG(D16, RXD13, UART13G0, UART13, SIG_DESC_SET(SCU4B8, 3));
+PIN_DECL_2(D16, GPIOI3, MTMS, RXD13);
+
+GROUP_DECL(UART13G0, E17, D16);
+
+#define C16 68
+SIG_EXPR_LIST_DECL_SESG(C16, MTDO, JTAGM, SIG_DESC_SET(SCU418, 4));
+PIN_DECL_1(C16, GPIOI4, MTDO);
+
+FUNC_GROUP_DECL(JTAGM, D17, A16, E17, D16, C16);
+
+#define E16 69
+SIG_EXPR_LIST_DECL_SESG(E16, SIOPBO, SIOPBO, SIG_DESC_SET(SCU418, 5));
+PIN_DECL_1(E16, GPIOI5, SIOPBO);
+FUNC_GROUP_DECL(SIOPBO, E16);
+
+#define B16 70
+SIG_EXPR_LIST_DECL_SESG(B16, SIOPBI, SIOPBI, SIG_DESC_SET(SCU418, 6));
+PIN_DECL_1(B16, GPIOI6, SIOPBI);
+FUNC_GROUP_DECL(SIOPBI, B16);
+
+#define A15 71
+SIG_EXPR_LIST_DECL_SESG(A15, BMCINT, BMCINT, SIG_DESC_SET(SCU418, 7));
+SIG_EXPR_LIST_DECL_SESG(A15, SIOSCI, SIOSCI, SIG_DESC_SET(SCU4B8, 7));
+PIN_DECL_2(A15, GPIOI7, BMCINT, SIOSCI);
+FUNC_GROUP_DECL(BMCINT, A15);
+FUNC_GROUP_DECL(SIOSCI, A15);
+
+#define B20 72
+SIG_EXPR_LIST_DECL_SEMG(B20, I3C3SCL, HVI3C3, I3C3, SIG_DESC_SET(SCU418, 8));
+SIG_EXPR_LIST_DECL_SESG(B20, SCL1, I2C1, SIG_DESC_SET(SCU4B8, 8));
+PIN_DECL_2(B20, GPIOJ0, I3C3SCL, SCL1);
+
+#define A20 73
+SIG_EXPR_LIST_DECL_SEMG(A20, I3C3SDA, HVI3C3, I3C3, SIG_DESC_SET(SCU418, 9));
+SIG_EXPR_LIST_DECL_SESG(A20, SDA1, I2C1, SIG_DESC_SET(SCU4B8, 9));
+PIN_DECL_2(A20, GPIOJ1, I3C3SDA, SDA1);
+
+GROUP_DECL(HVI3C3, B20, A20);
+FUNC_GROUP_DECL(I2C1, B20, A20);
+
+#define E19 74
+SIG_EXPR_LIST_DECL_SEMG(E19, I3C4SCL, HVI3C4, I3C4, SIG_DESC_SET(SCU418, 10));
+SIG_EXPR_LIST_DECL_SESG(E19, SCL2, I2C2, SIG_DESC_SET(SCU4B8, 10));
+PIN_DECL_2(E19, GPIOJ2, I3C4SCL, SCL2);
+
+#define D20 75
+SIG_EXPR_LIST_DECL_SEMG(D20, I3C4SDA, HVI3C4, I3C4, SIG_DESC_SET(SCU418, 11));
+SIG_EXPR_LIST_DECL_SESG(D20, SDA2, I2C2, SIG_DESC_SET(SCU4B8, 11));
+PIN_DECL_2(D20, GPIOJ3, I3C4SDA, SDA2);
+
+GROUP_DECL(HVI3C4, E19, D20);
+FUNC_GROUP_DECL(I2C2, E19, D20);
+
+#define C19 76
+SIG_EXPR_LIST_DECL_SESG(C19, I3C5SCL, I3C5, SIG_DESC_SET(SCU418, 12));
+SIG_EXPR_LIST_DECL_SESG(C19, SCL3, I2C3, SIG_DESC_SET(SCU4B8, 12));
+PIN_DECL_2(C19, GPIOJ4, I3C5SCL, SCL3);
+
+#define A19 77
+SIG_EXPR_LIST_DECL_SESG(A19, I3C5SDA, I3C5, SIG_DESC_SET(SCU418, 13));
+SIG_EXPR_LIST_DECL_SESG(A19, SDA3, I2C3, SIG_DESC_SET(SCU4B8, 13));
+PIN_DECL_2(A19, GPIOJ5, I3C5SDA, SDA3);
+
+FUNC_GROUP_DECL(I3C5, C19, A19);
+FUNC_GROUP_DECL(I2C3, C19, A19);
+
+#define C20 78
+SIG_EXPR_LIST_DECL_SESG(C20, I3C6SCL, I3C6, SIG_DESC_SET(SCU418, 14));
+SIG_EXPR_LIST_DECL_SESG(C20, SCL4, I2C4, SIG_DESC_SET(SCU4B8, 14));
+PIN_DECL_2(C20, GPIOJ6, I3C6SCL, SCL4);
+
+#define D19 79
+SIG_EXPR_LIST_DECL_SESG(D19, I3C6SDA, I3C6, SIG_DESC_SET(SCU418, 15));
+SIG_EXPR_LIST_DECL_SESG(D19, SDA4, I2C4, SIG_DESC_SET(SCU4B8, 15));
+PIN_DECL_2(D19, GPIOJ7, I3C6SDA, SDA4);
+
+FUNC_GROUP_DECL(I3C6, C20, D19);
+FUNC_GROUP_DECL(I2C4, C20, D19);
+
+#define A11 80
+SIG_EXPR_LIST_DECL_SESG(A11, SCL5, I2C5, SIG_DESC_SET(SCU418, 16));
+PIN_DECL_1(A11, GPIOK0, SCL5);
+
+#define C11 81
+SIG_EXPR_LIST_DECL_SESG(C11, SDA5, I2C5, SIG_DESC_SET(SCU418, 17));
+PIN_DECL_1(C11, GPIOK1, SDA5);
+
+FUNC_GROUP_DECL(I2C5, A11, C11);
+
+#define D12 82
+SIG_EXPR_LIST_DECL_SESG(D12, SCL6, I2C6, SIG_DESC_SET(SCU418, 18));
+PIN_DECL_1(D12, GPIOK2, SCL6);
+
+#define E13 83
+SIG_EXPR_LIST_DECL_SESG(E13, SDA6, I2C6, SIG_DESC_SET(SCU418, 19));
+PIN_DECL_1(E13, GPIOK3, SDA6);
+
+FUNC_GROUP_DECL(I2C6, D12, E13);
+
+#define D11 84
+SIG_EXPR_LIST_DECL_SESG(D11, SCL7, I2C7, SIG_DESC_SET(SCU418, 20));
+PIN_DECL_1(D11, GPIOK4, SCL7);
+
+#define E11 85
+SIG_EXPR_LIST_DECL_SESG(E11, SDA7, I2C7, SIG_DESC_SET(SCU418, 21));
+PIN_DECL_1(E11, GPIOK5, SDA7);
+
+FUNC_GROUP_DECL(I2C7, D11, E11);
+
+#define F13 86
+SIG_EXPR_LIST_DECL_SESG(F13, SCL8, I2C8, SIG_DESC_SET(SCU418, 22));
+PIN_DECL_1(F13, GPIOK6, SCL8);
+
+#define E12 87
+SIG_EXPR_LIST_DECL_SESG(E12, SDA8, I2C8, SIG_DESC_SET(SCU418, 23));
+PIN_DECL_1(E12, GPIOK7, SDA8);
+
+FUNC_GROUP_DECL(I2C8, F13, E12);
+
+#define D15 88
+SIG_EXPR_LIST_DECL_SESG(D15, SCL9, I2C9, SIG_DESC_SET(SCU418, 24));
+PIN_DECL_1(D15, GPIOL0, SCL9);
+
+#define A14 89
+SIG_EXPR_LIST_DECL_SESG(A14, SDA9, I2C9, SIG_DESC_SET(SCU418, 25));
+PIN_DECL_1(A14, GPIOL1, SDA9);
+
+FUNC_GROUP_DECL(I2C9, D15, A14);
+
+#define E15 90
+SIG_EXPR_LIST_DECL_SESG(E15, SCL10, I2C10, SIG_DESC_SET(SCU418, 26));
+PIN_DECL_1(E15, GPIOL2, SCL10);
+
+#define A13 91
+SIG_EXPR_LIST_DECL_SESG(A13, SDA10, I2C10, SIG_DESC_SET(SCU418, 27));
+PIN_DECL_1(A13, GPIOL3, SDA10);
+
+FUNC_GROUP_DECL(I2C10, E15, A13);
+
+#define C15 92
+SSSF_PIN_DECL(C15, GPIOL4, TXD3, SIG_DESC_SET(SCU418, 28));
+
+#define F15 93
+SSSF_PIN_DECL(F15, GPIOL5, RXD3, SIG_DESC_SET(SCU418, 29));
+
+#define B14 94
+SSSF_PIN_DECL(B14, GPIOL6, VGAHS, SIG_DESC_SET(SCU418, 30));
+
+#define C14 95
+SSSF_PIN_DECL(C14, GPIOL7, VGAVS, SIG_DESC_SET(SCU418, 31));
+
+#define D14 96
+SSSF_PIN_DECL(D14, GPIOM0, NCTS1, SIG_DESC_SET(SCU41C, 0));
+
+#define B13 97
+SSSF_PIN_DECL(B13, GPIOM1, NDCD1, SIG_DESC_SET(SCU41C, 1));
+
+#define A12 98
+SSSF_PIN_DECL(A12, GPIOM2, NDSR1, SIG_DESC_SET(SCU41C, 2));
+
+#define E14 99
+SSSF_PIN_DECL(E14, GPIOM3, NRI1, SIG_DESC_SET(SCU41C, 3));
+
+#define B12 100
+SSSF_PIN_DECL(B12, GPIOM4, NDTR1, SIG_DESC_SET(SCU41C, 4));
+
+#define C12 101
+SSSF_PIN_DECL(C12, GPIOM5, NRTS1, SIG_DESC_SET(SCU41C, 5));
+
+#define C13 102
+SSSF_PIN_DECL(C13, GPIOM6, TXD1, SIG_DESC_SET(SCU41C, 6));
+
+#define D13 103
+SSSF_PIN_DECL(D13, GPIOM7, RXD1, SIG_DESC_SET(SCU41C, 7));
+
+#define P25 104
+SSSF_PIN_DECL(P25, GPION0, NCTS2, SIG_DESC_SET(SCU41C, 8));
+
+#define N23 105
+SSSF_PIN_DECL(N23, GPION1, NDCD2, SIG_DESC_SET(SCU41C, 9));
+
+#define N25 106
+SSSF_PIN_DECL(N25, GPION2, NDSR2, SIG_DESC_SET(SCU41C, 10));
+
+#define N24 107
+SSSF_PIN_DECL(N24, GPION3, NRI2, SIG_DESC_SET(SCU41C, 11));
+
+#define P26 108
+SSSF_PIN_DECL(P26, GPION4, NDTR2, SIG_DESC_SET(SCU41C, 12));
+
+#define M23 109
+SSSF_PIN_DECL(M23, GPION5, NRTS2, SIG_DESC_SET(SCU41C, 13));
+
+#define N26 110
+SSSF_PIN_DECL(N26, GPION6, TXD2, SIG_DESC_SET(SCU41C, 14));
+
+#define M26 111
+SSSF_PIN_DECL(M26, GPION7, RXD2, SIG_DESC_SET(SCU41C, 15));
+
+#define AD26 112
+SSSF_PIN_DECL(AD26, GPIOO0, PWM0, SIG_DESC_SET(SCU41C, 16));
+
+#define AD22 113
+SSSF_PIN_DECL(AD22, GPIOO1, PWM1, SIG_DESC_SET(SCU41C, 17));
+
+#define AD23 114
+SSSF_PIN_DECL(AD23, GPIOO2, PWM2, SIG_DESC_SET(SCU41C, 18));
+
+#define AD24 115
+SSSF_PIN_DECL(AD24, GPIOO3, PWM3, SIG_DESC_SET(SCU41C, 19));
+
+#define AD25 116
+SSSF_PIN_DECL(AD25, GPIOO4, PWM4, SIG_DESC_SET(SCU41C, 20));
+
+#define AC22 117
+SSSF_PIN_DECL(AC22, GPIOO5, PWM5, SIG_DESC_SET(SCU41C, 21));
+
+#define AC24 118
+SSSF_PIN_DECL(AC24, GPIOO6, PWM6, SIG_DESC_SET(SCU41C, 22));
+
+#define AC23 119
+SSSF_PIN_DECL(AC23, GPIOO7, PWM7, SIG_DESC_SET(SCU41C, 23));
+
+#define AB22 120
+SIG_EXPR_LIST_DECL_SEMG(AB22, PWM8, PWM8G1, PWM8, SIG_DESC_SET(SCU41C, 24));
+SIG_EXPR_LIST_DECL_SESG(AB22, THRUIN0, THRU0, SIG_DESC_SET(SCU4BC, 24));
+PIN_DECL_2(AB22, GPIOP0, PWM8, THRUIN0);
+GROUP_DECL(PWM8G1, AB22);
+FUNC_DECL_2(PWM8, PWM8G0, PWM8G1);
+
+#define W24 121
+SIG_EXPR_LIST_DECL_SEMG(W24, PWM9, PWM9G1, PWM9, SIG_DESC_SET(SCU41C, 25));
+SIG_EXPR_LIST_DECL_SESG(W24, THRUOUT0, THRU0, SIG_DESC_SET(SCU4BC, 25));
+PIN_DECL_2(W24, GPIOP1, PWM9, THRUOUT0);
+
+FUNC_GROUP_DECL(THRU0, AB22, W24);
+
+GROUP_DECL(PWM9G1, W24);
+FUNC_DECL_2(PWM9, PWM9G0, PWM9G1);
+
+#define AA23 122
+SIG_EXPR_LIST_DECL_SEMG(AA23, PWM10, PWM10G1, PWM10, SIG_DESC_SET(SCU41C, 26));
+SIG_EXPR_LIST_DECL_SESG(AA23, THRUIN1, THRU1, SIG_DESC_SET(SCU4BC, 26));
+PIN_DECL_2(AA23, GPIOP2, PWM10, THRUIN1);
+GROUP_DECL(PWM10G1, AA23);
+FUNC_DECL_2(PWM10, PWM10G0, PWM10G1);
+
+#define AA24 123
+SIG_EXPR_LIST_DECL_SEMG(AA24, PWM11, PWM11G1, PWM11, SIG_DESC_SET(SCU41C, 27));
+SIG_EXPR_LIST_DECL_SESG(AA24, THRUOUT1, THRU1, SIG_DESC_SET(SCU4BC, 27));
+PIN_DECL_2(AA24, GPIOP3, PWM11, THRUOUT1);
+GROUP_DECL(PWM11G1, AA24);
+FUNC_DECL_2(PWM11, PWM11G0, PWM11G1);
+
+FUNC_GROUP_DECL(THRU1, AA23, AA24);
+
+#define W23 124
+SIG_EXPR_LIST_DECL_SEMG(W23, PWM12, PWM12G1, PWM12, SIG_DESC_SET(SCU41C, 28));
+SIG_EXPR_LIST_DECL_SESG(W23, THRUIN2, THRU2, SIG_DESC_SET(SCU4BC, 28));
+PIN_DECL_2(W23, GPIOP4, PWM12, THRUIN2);
+GROUP_DECL(PWM12G1, W23);
+FUNC_DECL_2(PWM12, PWM12G0, PWM12G1);
+
+#define AB23 125
+SIG_EXPR_LIST_DECL_SEMG(AB23, PWM13, PWM13G1, PWM13, SIG_DESC_SET(SCU41C, 29));
+SIG_EXPR_LIST_DECL_SESG(AB23, THRUOUT2, THRU2, SIG_DESC_SET(SCU4BC, 29));
+PIN_DECL_2(AB23, GPIOP5, PWM13, THRUOUT2);
+GROUP_DECL(PWM13G1, AB23);
+FUNC_DECL_2(PWM13, PWM13G0, PWM13G1);
+
+FUNC_GROUP_DECL(THRU2, W23, AB23);
+
+#define AB24 126
+SIG_EXPR_LIST_DECL_SEMG(AB24, PWM14, PWM14G1, PWM14, SIG_DESC_SET(SCU41C, 30));
+SIG_EXPR_LIST_DECL_SESG(AB24, THRUIN3, THRU3, SIG_DESC_SET(SCU4BC, 30));
+PIN_DECL_2(AB24, GPIOP6, PWM14, THRUIN3);
+GROUP_DECL(PWM14G1, AB24);
+FUNC_DECL_2(PWM14, PWM14G0, PWM14G1);
+
+#define Y23 127
+SIG_EXPR_LIST_DECL_SEMG(Y23, PWM15, PWM15G1, PWM15, SIG_DESC_SET(SCU41C, 31));
+SIG_EXPR_LIST_DECL_SESG(Y23, THRUOUT3, THRU3, SIG_DESC_SET(SCU4BC, 31));
+PIN_DECL_2(Y23, GPIOP7, PWM15, THRUOUT3);
+GROUP_DECL(PWM15G1, Y23);
+FUNC_DECL_2(PWM15, PWM15G0, PWM15G1);
+
+FUNC_GROUP_DECL(THRU3, AB24, Y23);
+
+#define AA25 128
+SSSF_PIN_DECL(AA25, GPIOQ0, TACH0, SIG_DESC_SET(SCU430, 0));
+
+#define AB25 129
+SSSF_PIN_DECL(AB25, GPIOQ1, TACH1, SIG_DESC_SET(SCU430, 1));
+
+#define Y24 130
+SSSF_PIN_DECL(Y24, GPIOQ2, TACH2, SIG_DESC_SET(SCU430, 2));
+
+#define AB26 131
+SSSF_PIN_DECL(AB26, GPIOQ3, TACH3, SIG_DESC_SET(SCU430, 3));
+
+#define Y26 132
+SSSF_PIN_DECL(Y26, GPIOQ4, TACH4, SIG_DESC_SET(SCU430, 4));
+
+#define AC26 133
+SSSF_PIN_DECL(AC26, GPIOQ5, TACH5, SIG_DESC_SET(SCU430, 5));
+
+#define Y25 134
+SSSF_PIN_DECL(Y25, GPIOQ6, TACH6, SIG_DESC_SET(SCU430, 6));
+
+#define AA26 135
+SSSF_PIN_DECL(AA26, GPIOQ7, TACH7, SIG_DESC_SET(SCU430, 7));
+
+#define V25 136
+SSSF_PIN_DECL(V25, GPIOR0, TACH8, SIG_DESC_SET(SCU430, 8));
+
+#define U24 137
+SSSF_PIN_DECL(U24, GPIOR1, TACH9, SIG_DESC_SET(SCU430, 9));
+
+#define V24 138
+SSSF_PIN_DECL(V24, GPIOR2, TACH10, SIG_DESC_SET(SCU430, 10));
+
+#define V26 139
+SSSF_PIN_DECL(V26, GPIOR3, TACH11, SIG_DESC_SET(SCU430, 11));
+
+#define U25 140
+SSSF_PIN_DECL(U25, GPIOR4, TACH12, SIG_DESC_SET(SCU430, 12));
+
+#define T23 141
+SSSF_PIN_DECL(T23, GPIOR5, TACH13, SIG_DESC_SET(SCU430, 13));
+
+#define W26 142
+SSSF_PIN_DECL(W26, GPIOR6, TACH14, SIG_DESC_SET(SCU430, 14));
+
+#define U26 143
+SSSF_PIN_DECL(U26, GPIOR7, TACH15, SIG_DESC_SET(SCU430, 15));
+
+#define R23 144
+SIG_EXPR_LIST_DECL_SESG(R23, MDC1, MDIO1, SIG_DESC_SET(SCU430, 16));
+PIN_DECL_1(R23, GPIOS0, MDC1);
+
+#define T25 145
+SIG_EXPR_LIST_DECL_SESG(T25, MDIO1, MDIO1, SIG_DESC_SET(SCU430, 17));
+PIN_DECL_1(T25, GPIOS1, MDIO1);
+
+FUNC_GROUP_DECL(MDIO1, R23, T25);
+
+#define T26 146
+SSSF_PIN_DECL(T26, GPIOS2, PEWAKE, SIG_DESC_SET(SCU430, 18));
+
+#define R24 147
+SSSF_PIN_DECL(R24, GPIOS3, OSCCLK, SIG_DESC_SET(SCU430, 19));
+
+#define R26 148
+SIG_EXPR_LIST_DECL_SESG(R26, TXD10, UART10, SIG_DESC_SET(SCU430, 20));
+PIN_DECL_1(R26, GPIOS4, TXD10);
+
+#define P24 149
+SIG_EXPR_LIST_DECL_SESG(P24, RXD10, UART10, SIG_DESC_SET(SCU430, 21));
+PIN_DECL_1(P24, GPIOS5, RXD10);
+
+FUNC_GROUP_DECL(UART10, R26, P24);
+
+#define P23 150
+SIG_EXPR_LIST_DECL_SESG(P23, TXD11, UART11, SIG_DESC_SET(SCU430, 22));
+PIN_DECL_1(P23, GPIOS6, TXD11);
+
+#define T24 151
+SIG_EXPR_LIST_DECL_SESG(T24, RXD11, UART11, SIG_DESC_SET(SCU430, 23));
+PIN_DECL_1(T24, GPIOS7, RXD11);
+
+FUNC_GROUP_DECL(UART11, P23, T24);
+
+#define AD20 152
+SIG_EXPR_LIST_DECL_SESG(AD20, GPIT0, GPIT0, SIG_DESC_SET(SCU430, 24));
+SIG_EXPR_LIST_DECL_SESG(AD20, ADC0, ADC0);
+PIN_DECL_(AD20, SIG_EXPR_LIST_PTR(AD20, GPIT0), SIG_EXPR_LIST_PTR(AD20, ADC0));
+FUNC_GROUP_DECL(GPIT0, AD20);
+FUNC_GROUP_DECL(ADC0, AD20);
+
+#define AC18 153
+SIG_EXPR_LIST_DECL_SESG(AC18, GPIT1, GPIT1, SIG_DESC_SET(SCU430, 25));
+SIG_EXPR_LIST_DECL_SESG(AC18, ADC1, ADC1);
+PIN_DECL_(AC18, SIG_EXPR_LIST_PTR(AC18, GPIT1), SIG_EXPR_LIST_PTR(AC18, ADC1));
+FUNC_GROUP_DECL(GPIT1, AC18);
+FUNC_GROUP_DECL(ADC1, AC18);
+
+#define AE19 154
+SIG_EXPR_LIST_DECL_SESG(AE19, GPIT2, GPIT2, SIG_DESC_SET(SCU430, 26));
+SIG_EXPR_LIST_DECL_SESG(AE19, ADC2, ADC2);
+PIN_DECL_(AE19, SIG_EXPR_LIST_PTR(AE19, GPIT2), SIG_EXPR_LIST_PTR(AE19, ADC2));
+FUNC_GROUP_DECL(GPIT2, AE19);
+FUNC_GROUP_DECL(ADC2, AE19);
+
+#define AD19 155
+SIG_EXPR_LIST_DECL_SESG(AD19, GPIT3, GPIT3, SIG_DESC_SET(SCU430, 27));
+SIG_EXPR_LIST_DECL_SESG(AD19, ADC3, ADC3);
+PIN_DECL_(AD19, SIG_EXPR_LIST_PTR(AD19, GPIT3), SIG_EXPR_LIST_PTR(AD19, ADC3));
+FUNC_GROUP_DECL(GPIT3, AD19);
+FUNC_GROUP_DECL(ADC3, AD19);
+
+#define AC19 156
+SIG_EXPR_LIST_DECL_SESG(AC19, GPIT4, GPIT4, SIG_DESC_SET(SCU430, 28));
+SIG_EXPR_LIST_DECL_SESG(AC19, ADC4, ADC4);
+PIN_DECL_(AC19, SIG_EXPR_LIST_PTR(AC19, GPIT4), SIG_EXPR_LIST_PTR(AC19, ADC4));
+FUNC_GROUP_DECL(GPIT4, AC19);
+FUNC_GROUP_DECL(ADC4, AC19);
+
+#define AB19 157
+SIG_EXPR_LIST_DECL_SESG(AB19, GPIT5, GPIT5, SIG_DESC_SET(SCU430, 29));
+SIG_EXPR_LIST_DECL_SESG(AB19, ADC5, ADC5);
+PIN_DECL_(AB19, SIG_EXPR_LIST_PTR(AB19, GPIT5), SIG_EXPR_LIST_PTR(AB19, ADC5));
+FUNC_GROUP_DECL(GPIT5, AB19);
+FUNC_GROUP_DECL(ADC5, AB19);
+
+#define AB18 158
+SIG_EXPR_LIST_DECL_SESG(AB18, GPIT6, GPIT6, SIG_DESC_SET(SCU430, 30));
+SIG_EXPR_LIST_DECL_SESG(AB18, ADC6, ADC6);
+PIN_DECL_(AB18, SIG_EXPR_LIST_PTR(AB18, GPIT6), SIG_EXPR_LIST_PTR(AB18, ADC6));
+FUNC_GROUP_DECL(GPIT6, AB18);
+FUNC_GROUP_DECL(ADC6, AB18);
+
+#define AE18 159
+SIG_EXPR_LIST_DECL_SESG(AE18, GPIT7, GPIT7, SIG_DESC_SET(SCU430, 31));
+SIG_EXPR_LIST_DECL_SESG(AE18, ADC7, ADC7);
+PIN_DECL_(AE18, SIG_EXPR_LIST_PTR(AE18, GPIT7), SIG_EXPR_LIST_PTR(AE18, ADC7));
+FUNC_GROUP_DECL(GPIT7, AE18);
+FUNC_GROUP_DECL(ADC7, AE18);
+
+#define AB16 160
+SIG_EXPR_LIST_DECL_SEMG(AB16, SALT9, SALT9G1, SALT9, SIG_DESC_SET(SCU434, 0),
+			SIG_DESC_CLEAR(SCU694, 16));
+SIG_EXPR_LIST_DECL_SESG(AB16, GPIU0, GPIU0, SIG_DESC_SET(SCU434, 0),
+			SIG_DESC_SET(SCU694, 16));
+SIG_EXPR_LIST_DECL_SESG(AB16, ADC8, ADC8);
+PIN_DECL_(AB16, SIG_EXPR_LIST_PTR(AB16, SALT9), SIG_EXPR_LIST_PTR(AB16, GPIU0),
+	  SIG_EXPR_LIST_PTR(AB16, ADC8));
+GROUP_DECL(SALT9G1, AB16);
+FUNC_DECL_2(SALT9, SALT9G0, SALT9G1);
+FUNC_GROUP_DECL(GPIU0, AB16);
+FUNC_GROUP_DECL(ADC8, AB16);
+
+#define AA17 161
+SIG_EXPR_LIST_DECL_SEMG(AA17, SALT10, SALT10G1, SALT10, SIG_DESC_SET(SCU434, 1),
+			SIG_DESC_CLEAR(SCU694, 17));
+SIG_EXPR_LIST_DECL_SESG(AA17, GPIU1, GPIU1, SIG_DESC_SET(SCU434, 1),
+			SIG_DESC_SET(SCU694, 17));
+SIG_EXPR_LIST_DECL_SESG(AA17, ADC9, ADC9);
+PIN_DECL_(AA17, SIG_EXPR_LIST_PTR(AA17, SALT10), SIG_EXPR_LIST_PTR(AA17, GPIU1),
+	  SIG_EXPR_LIST_PTR(AA17, ADC9));
+GROUP_DECL(SALT10G1, AA17);
+FUNC_DECL_2(SALT10, SALT10G0, SALT10G1);
+FUNC_GROUP_DECL(GPIU1, AA17);
+FUNC_GROUP_DECL(ADC9, AA17);
+
+#define AB17 162
+SIG_EXPR_LIST_DECL_SEMG(AB17, SALT11, SALT11G1, SALT11, SIG_DESC_SET(SCU434, 2),
+			SIG_DESC_CLEAR(SCU694, 18));
+SIG_EXPR_LIST_DECL_SESG(AB17, GPIU2, GPIU2, SIG_DESC_SET(SCU434, 2),
+			SIG_DESC_SET(SCU694, 18));
+SIG_EXPR_LIST_DECL_SESG(AB17, ADC10, ADC10);
+PIN_DECL_(AB17, SIG_EXPR_LIST_PTR(AB17, SALT11), SIG_EXPR_LIST_PTR(AB17, GPIU2),
+	  SIG_EXPR_LIST_PTR(AB17, ADC10));
+GROUP_DECL(SALT11G1, AB17);
+FUNC_DECL_2(SALT11, SALT11G0, SALT11G1);
+FUNC_GROUP_DECL(GPIU2, AB17);
+FUNC_GROUP_DECL(ADC10, AB17);
+
+#define AE16 163
+SIG_EXPR_LIST_DECL_SEMG(AE16, SALT12, SALT12G1, SALT12, SIG_DESC_SET(SCU434, 3),
+			SIG_DESC_CLEAR(SCU694, 19));
+SIG_EXPR_LIST_DECL_SESG(AE16, GPIU3, GPIU3, SIG_DESC_SET(SCU434, 3),
+			SIG_DESC_SET(SCU694, 19));
+SIG_EXPR_LIST_DECL_SESG(AE16, ADC11, ADC11);
+PIN_DECL_(AE16, SIG_EXPR_LIST_PTR(AE16, SALT12), SIG_EXPR_LIST_PTR(AE16, GPIU3),
+	  SIG_EXPR_LIST_PTR(AE16, ADC11));
+GROUP_DECL(SALT12G1, AE16);
+FUNC_DECL_2(SALT12, SALT12G0, SALT12G1);
+FUNC_GROUP_DECL(GPIU3, AE16);
+FUNC_GROUP_DECL(ADC11, AE16);
+
+#define AC16 164
+SIG_EXPR_LIST_DECL_SEMG(AC16, SALT13, SALT13G1, SALT13, SIG_DESC_SET(SCU434, 4),
+			SIG_DESC_CLEAR(SCU694, 20));
+SIG_EXPR_LIST_DECL_SESG(AC16, GPIU4, GPIU4, SIG_DESC_SET(SCU434, 4),
+			SIG_DESC_SET(SCU694, 20));
+SIG_EXPR_LIST_DECL_SESG(AC16, ADC12, ADC12);
+PIN_DECL_(AC16, SIG_EXPR_LIST_PTR(AC16, SALT13), SIG_EXPR_LIST_PTR(AC16, GPIU4),
+	  SIG_EXPR_LIST_PTR(AC16, ADC12));
+GROUP_DECL(SALT13G1, AC16);
+FUNC_DECL_2(SALT13, SALT13G0, SALT13G1);
+FUNC_GROUP_DECL(GPIU4, AC16);
+FUNC_GROUP_DECL(ADC12, AC16);
+
+#define AA16 165
+SIG_EXPR_LIST_DECL_SEMG(AA16, SALT14, SALT14G1, SALT14, SIG_DESC_SET(SCU434, 5),
+			SIG_DESC_CLEAR(SCU694, 21));
+SIG_EXPR_LIST_DECL_SESG(AA16, GPIU5, GPIU5, SIG_DESC_SET(SCU434, 5),
+			SIG_DESC_SET(SCU694, 21));
+SIG_EXPR_LIST_DECL_SESG(AA16, ADC13, ADC13);
+PIN_DECL_(AA16, SIG_EXPR_LIST_PTR(AA16, SALT14), SIG_EXPR_LIST_PTR(AA16, GPIU5),
+	  SIG_EXPR_LIST_PTR(AA16, ADC13));
+GROUP_DECL(SALT14G1, AA16);
+FUNC_DECL_2(SALT14, SALT14G0, SALT14G1);
+FUNC_GROUP_DECL(GPIU5, AA16);
+FUNC_GROUP_DECL(ADC13, AA16);
+
+#define AD16 166
+SIG_EXPR_LIST_DECL_SEMG(AD16, SALT15, SALT15G1, SALT15, SIG_DESC_SET(SCU434, 6),
+			SIG_DESC_CLEAR(SCU694, 22));
+SIG_EXPR_LIST_DECL_SESG(AD16, GPIU6, GPIU6, SIG_DESC_SET(SCU434, 6),
+			SIG_DESC_SET(SCU694, 22));
+SIG_EXPR_LIST_DECL_SESG(AD16, ADC14, ADC14);
+PIN_DECL_(AD16, SIG_EXPR_LIST_PTR(AD16, SALT15), SIG_EXPR_LIST_PTR(AD16, GPIU6),
+	  SIG_EXPR_LIST_PTR(AD16, ADC14));
+GROUP_DECL(SALT15G1, AD16);
+FUNC_DECL_2(SALT15, SALT15G0, SALT15G1);
+FUNC_GROUP_DECL(GPIU6, AD16);
+FUNC_GROUP_DECL(ADC14, AD16);
+
+#define AC17 167
+SIG_EXPR_LIST_DECL_SEMG(AC17, SALT16, SALT16G1, SALT16, SIG_DESC_SET(SCU434, 7),
+			SIG_DESC_CLEAR(SCU694, 23));
+SIG_EXPR_LIST_DECL_SESG(AC17, GPIU7, GPIU7, SIG_DESC_SET(SCU434, 7),
+			SIG_DESC_SET(SCU694, 23));
+SIG_EXPR_LIST_DECL_SESG(AC17, ADC15, ADC15);
+PIN_DECL_(AC17, SIG_EXPR_LIST_PTR(AC17, SALT16), SIG_EXPR_LIST_PTR(AC17, GPIU7),
+	  SIG_EXPR_LIST_PTR(AC17, ADC15));
+GROUP_DECL(SALT16G1, AC17);
+FUNC_DECL_2(SALT16, SALT16G0, SALT16G1);
+FUNC_GROUP_DECL(GPIU7, AC17);
+FUNC_GROUP_DECL(ADC15, AC17);
+
+#define AB15 168
+SSSF_PIN_DECL(AB15, GPIOV0, SIOS3, SIG_DESC_SET(SCU434, 8));
+
+#define AF14 169
+SSSF_PIN_DECL(AF14, GPIOV1, SIOS5, SIG_DESC_SET(SCU434, 9));
+
+#define AD14 170
+SSSF_PIN_DECL(AD14, GPIOV2, SIOPWREQ, SIG_DESC_SET(SCU434, 10));
+
+#define AC15 171
+SSSF_PIN_DECL(AC15, GPIOV3, SIOONCTRL, SIG_DESC_SET(SCU434, 11));
+
+#define AE15 172
+SSSF_PIN_DECL(AE15, GPIOV4, SIOPWRGD, SIG_DESC_SET(SCU434, 12));
+
+#define AE14 173
+SIG_EXPR_LIST_DECL_SESG(AE14, LPCPD, LPCPD, SIG_DESC_SET(SCU434, 13));
+SIG_EXPR_LIST_DECL_SESG(AE14, LHPD, LHPD, SIG_DESC_SET(SCU4D4, 13));
+PIN_DECL_2(AE14, GPIOV5, LPCPD, LHPD);
+FUNC_GROUP_DECL(LPCPD, AE14);
+FUNC_GROUP_DECL(LHPD, AE14);
+
+#define AD15 174
+SSSF_PIN_DECL(AD15, GPIOV6, LPCPME, SIG_DESC_SET(SCU434, 14));
+
+#define AF15 175
+SSSF_PIN_DECL(AF15, GPIOV7, LPCSMI, SIG_DESC_SET(SCU434, 15));
+
+#define AB7 176
+SIG_EXPR_LIST_DECL_SESG(AB7, LAD0, LPC, SIG_DESC_SET(SCU434, 16),
+			  SIG_DESC_CLEAR(SCU510, 6));
+SIG_EXPR_LIST_DECL_SESG(AB7, ESPID0, ESPI, SIG_DESC_SET(SCU434, 16),
+			  SIG_DESC_SET(SCU510, 6));
+PIN_DECL_2(AB7, GPIOW0, LAD0, ESPID0);
+
+#define AB8 177
+SIG_EXPR_LIST_DECL_SESG(AB8, LAD1, LPC, SIG_DESC_SET(SCU434, 17),
+			  SIG_DESC_CLEAR(SCU510, 6));
+SIG_EXPR_LIST_DECL_SESG(AB8, ESPID1, ESPI, SIG_DESC_SET(SCU434, 17),
+			  SIG_DESC_SET(SCU510, 6));
+PIN_DECL_2(AB8, GPIOW1, LAD1, ESPID1);
+
+#define AC8 178
+SIG_EXPR_LIST_DECL_SESG(AC8, LAD2, LPC, SIG_DESC_SET(SCU434, 18),
+			  SIG_DESC_CLEAR(SCU510, 6));
+SIG_EXPR_LIST_DECL_SESG(AC8, ESPID2, ESPI, SIG_DESC_SET(SCU434, 18),
+			  SIG_DESC_SET(SCU510, 6));
+PIN_DECL_2(AC8, GPIOW2, LAD2, ESPID2);
+
+#define AC7 179
+SIG_EXPR_LIST_DECL_SESG(AC7, LAD3, LPC, SIG_DESC_SET(SCU434, 19),
+			  SIG_DESC_CLEAR(SCU510, 6));
+SIG_EXPR_LIST_DECL_SESG(AC7, ESPID3, ESPI, SIG_DESC_SET(SCU434, 19),
+			  SIG_DESC_SET(SCU510, 6));
+PIN_DECL_2(AC7, GPIOW3, LAD3, ESPID3);
+
+#define AE7 180
+SIG_EXPR_LIST_DECL_SESG(AE7, LCLK, LPC, SIG_DESC_SET(SCU434, 20),
+			  SIG_DESC_CLEAR(SCU510, 6));
+SIG_EXPR_LIST_DECL_SESG(AE7, ESPICK, ESPI, SIG_DESC_SET(SCU434, 20),
+			  SIG_DESC_SET(SCU510, 6));
+PIN_DECL_2(AE7, GPIOW4, LCLK, ESPICK);
+
+#define AF7 181
+SIG_EXPR_LIST_DECL_SESG(AF7, LFRAME, LPC, SIG_DESC_SET(SCU434, 21),
+			  SIG_DESC_CLEAR(SCU510, 6));
+SIG_EXPR_LIST_DECL_SESG(AF7, ESPICS, ESPI, SIG_DESC_SET(SCU434, 21),
+			  SIG_DESC_SET(SCU510, 6));
+PIN_DECL_2(AF7, GPIOW5, LFRAME, ESPICS);
+
+#define AD7 182
+SIG_EXPR_LIST_DECL_SESG(AD7, LSIRQ, LSIRQ, SIG_DESC_SET(SCU434, 22),
+			  SIG_DESC_CLEAR(SCU510, 6));
+SIG_EXPR_LIST_DECL_SESG(AD7, ESPIALT, ESPIALT, SIG_DESC_SET(SCU434, 22),
+			  SIG_DESC_SET(SCU510, 6));
+PIN_DECL_2(AD7, GPIOW6, LSIRQ, ESPIALT);
+FUNC_GROUP_DECL(LSIRQ, AD7);
+FUNC_GROUP_DECL(ESPIALT, AD7);
+
+#define AD8 183
+SIG_EXPR_LIST_DECL_SESG(AD8, LPCRST, LPC, SIG_DESC_SET(SCU434, 23),
+			  SIG_DESC_CLEAR(SCU510, 6));
+SIG_EXPR_LIST_DECL_SESG(AD8, ESPIRST, ESPI, SIG_DESC_SET(SCU434, 23),
+			  SIG_DESC_SET(SCU510, 6));
+PIN_DECL_2(AD8, GPIOW7, LPCRST, ESPIRST);
+
+FUNC_GROUP_DECL(LPC, AB7, AB8, AC8, AC7, AE7, AF7, AD8);
+FUNC_GROUP_DECL(ESPI, AB7, AB8, AC8, AC7, AE7, AF7, AD8);
+
+#define AE8 184
+SIG_EXPR_LIST_DECL_SEMG(AE8, SPI2CS0, SPI2, SPI2, SIG_DESC_SET(SCU434, 24));
+PIN_DECL_1(AE8, GPIOX0, SPI2CS0);
+
+#define AA9 185
+SSSF_PIN_DECL(AA9, GPIOX1, SPI2CS1, SIG_DESC_SET(SCU434, 25));
+
+#define AC9 186
+SSSF_PIN_DECL(AC9, GPIOX2, SPI2CS2, SIG_DESC_SET(SCU434, 26));
+
+#define AF8 187
+SIG_EXPR_LIST_DECL_SEMG(AF8, SPI2CK, SPI2, SPI2, SIG_DESC_SET(SCU434, 27));
+PIN_DECL_1(AF8, GPIOX3, SPI2CK);
+
+#define AB9 188
+SIG_EXPR_LIST_DECL_SEMG(AB9, SPI2MOSI, SPI2, SPI2, SIG_DESC_SET(SCU434, 28));
+PIN_DECL_1(AB9, GPIOX4, SPI2MOSI);
+
+#define AD9 189
+SIG_EXPR_LIST_DECL_SEMG(AD9, SPI2MISO, SPI2, SPI2, SIG_DESC_SET(SCU434, 29));
+PIN_DECL_1(AD9, GPIOX5, SPI2MISO);
+
+GROUP_DECL(SPI2, AE8, AF8, AB9, AD9);
+
+#define AF9 190
+SIG_EXPR_LIST_DECL_SEMG(AF9, SPI2DQ2, QSPI2, SPI2, SIG_DESC_SET(SCU434, 30));
+SIG_EXPR_LIST_DECL_SEMG(AF9, TXD12, UART12G1, UART12, SIG_DESC_SET(SCU4D4, 30));
+PIN_DECL_2(AF9, GPIOX6, SPI2DQ2, TXD12);
+
+#define AB10 191
+SIG_EXPR_LIST_DECL_SEMG(AB10, SPI2DQ3, QSPI2, SPI2, SIG_DESC_SET(SCU434, 31));
+SIG_EXPR_LIST_DECL_SEMG(AB10, RXD12, UART12G1, UART12,
+			SIG_DESC_SET(SCU4D4, 31));
+PIN_DECL_2(AB10, GPIOX7, SPI2DQ3, RXD12);
+
+GROUP_DECL(QSPI2, AE8, AF8, AB9, AD9, AF9, AB10);
+FUNC_DECL_2(SPI2, SPI2, QSPI2);
+
+GROUP_DECL(UART12G1, AF9, AB10);
+FUNC_DECL_2(UART12, UART12G0, UART12G1);
+
+#define AF11 192
+SIG_EXPR_LIST_DECL_SESG(AF11, SALT5, SALT5, SIG_DESC_SET(SCU438, 0));
+SIG_EXPR_LIST_DECL_SESG(AF11, WDTRST1, WDTRST1, SIG_DESC_SET(SCU4D8, 0));
+PIN_DECL_2(AF11, GPIOY0, SALT5, WDTRST1);
+FUNC_GROUP_DECL(SALT5, AF11);
+FUNC_GROUP_DECL(WDTRST1, AF11);
+
+#define AD12 193
+SIG_EXPR_LIST_DECL_SESG(AD12, SALT6, SALT6, SIG_DESC_SET(SCU438, 1));
+SIG_EXPR_LIST_DECL_SESG(AD12, WDTRST2, WDTRST2, SIG_DESC_SET(SCU4D8, 1));
+PIN_DECL_2(AD12, GPIOY1, SALT6, WDTRST2);
+FUNC_GROUP_DECL(SALT6, AD12);
+FUNC_GROUP_DECL(WDTRST2, AD12);
+
+#define AE11 194
+SIG_EXPR_LIST_DECL_SESG(AE11, SALT7, SALT7, SIG_DESC_SET(SCU438, 2));
+SIG_EXPR_LIST_DECL_SESG(AE11, WDTRST3, WDTRST3, SIG_DESC_SET(SCU4D8, 2));
+PIN_DECL_2(AE11, GPIOY2, SALT7, WDTRST3);
+FUNC_GROUP_DECL(SALT7, AE11);
+FUNC_GROUP_DECL(WDTRST3, AE11);
+
+#define AA12 195
+SIG_EXPR_LIST_DECL_SESG(AA12, SALT8, SALT8, SIG_DESC_SET(SCU438, 3));
+SIG_EXPR_LIST_DECL_SESG(AA12, WDTRST4, WDTRST4, SIG_DESC_SET(SCU4D8, 3));
+PIN_DECL_2(AA12, GPIOY3, SALT8, WDTRST4);
+FUNC_GROUP_DECL(SALT8, AA12);
+FUNC_GROUP_DECL(WDTRST4, AA12);
+
+#define AE12 196
+SIG_EXPR_LIST_DECL_SEMG(AE12, FWSPIDQ2, FWQSPID, FWSPID,
+			SIG_DESC_SET(SCU438, 4));
+SIG_EXPR_LIST_DECL_SESG(AE12, GPIOY4, GPIOY4);
+PIN_DECL_(AE12, SIG_EXPR_LIST_PTR(AE12, FWSPIDQ2),
+	  SIG_EXPR_LIST_PTR(AE12, GPIOY4));
+
+#define AF12 197
+SIG_EXPR_LIST_DECL_SEMG(AF12, FWSPIDQ3, FWQSPID, FWSPID,
+			SIG_DESC_SET(SCU438, 5));
+SIG_EXPR_LIST_DECL_SESG(AF12, GPIOY5, GPIOY5);
+PIN_DECL_(AF12, SIG_EXPR_LIST_PTR(AF12, FWSPIDQ3),
+	  SIG_EXPR_LIST_PTR(AF12, GPIOY5));
+
+#define AC12 198
+SSSF_PIN_DECL(AC12, GPIOY6, FWSPIABR, SIG_DESC_SET(SCU438, 6));
+
+#define AB12 199
+SSSF_PIN_DECL(AB12, GPIOY7, FWSPIWP, SIG_DESC_SET(SCU438, 7));
+
+#define AC10 200
+SSSF_PIN_DECL(AC10, GPIOZ0, SPI1CS1, SIG_DESC_SET(SCU438, 8));
+
+#define AD10 201
+SSSF_PIN_DECL(AD10, GPIOZ1, SPI1ABR, SIG_DESC_SET(SCU438, 9));
+
+#define AE10 202
+SSSF_PIN_DECL(AE10, GPIOZ2, SPI1WP, SIG_DESC_SET(SCU438, 10));
+
+#define AB11 203
+SIG_EXPR_LIST_DECL_SEMG(AB11, SPI1CK, SPI1, SPI1, SIG_DESC_SET(SCU438, 11));
+PIN_DECL_1(AB11, GPIOZ3, SPI1CK);
+
+#define AC11 204
+SIG_EXPR_LIST_DECL_SEMG(AC11, SPI1MOSI, SPI1, SPI1, SIG_DESC_SET(SCU438, 12));
+PIN_DECL_1(AC11, GPIOZ4, SPI1MOSI);
+
+#define AA11 205
+SIG_EXPR_LIST_DECL_SEMG(AA11, SPI1MISO, SPI1, SPI1, SIG_DESC_SET(SCU438, 13));
+PIN_DECL_1(AA11, GPIOZ5, SPI1MISO);
+
+GROUP_DECL(SPI1, AB11, AC11, AA11);
+
+#define AD11 206
+SIG_EXPR_LIST_DECL_SEMG(AD11, SPI1DQ2, QSPI1, SPI1, SIG_DESC_SET(SCU438, 14));
+SIG_EXPR_LIST_DECL_SEMG(AD11, TXD13, UART13G1, UART13,
+			SIG_DESC_SET(SCU438, 14));
+PIN_DECL_2(AD11, GPIOZ6, SPI1DQ2, TXD13);
+
+#define AF10 207
+SIG_EXPR_LIST_DECL_SEMG(AF10, SPI1DQ3, QSPI1, SPI1, SIG_DESC_SET(SCU438, 15));
+SIG_EXPR_LIST_DECL_SEMG(AF10, RXD13, UART13G1, UART13,
+			SIG_DESC_SET(SCU438, 15));
+PIN_DECL_2(AF10, GPIOZ7, SPI1DQ3, RXD13);
+
+GROUP_DECL(QSPI1, AB11, AC11, AA11, AD11, AF10);
+FUNC_DECL_2(SPI1, SPI1, QSPI1);
+
+GROUP_DECL(UART13G1, AD11, AF10);
+FUNC_DECL_2(UART13, UART13G0, UART13G1);
+
+#define C6 208
+SIG_EXPR_LIST_DECL_SESG(C6, RGMII1TXCK, RGMII1, SIG_DESC_SET(SCU400, 0),
+			  SIG_DESC_SET(SCU500, 6));
+SIG_EXPR_LIST_DECL_SESG(C6, RMII1RCLKO, RMII1, SIG_DESC_SET(SCU400, 0),
+			  SIG_DESC_CLEAR(SCU500, 6));
+PIN_DECL_2(C6, GPIO18A0, RGMII1TXCK, RMII1RCLKO);
+
+#define D6 209
+SIG_EXPR_LIST_DECL_SESG(D6, RGMII1TXCTL, RGMII1, SIG_DESC_SET(SCU400, 1),
+			  SIG_DESC_SET(SCU500, 6));
+SIG_EXPR_LIST_DECL_SESG(D6, RMII1TXEN, RMII1, SIG_DESC_SET(SCU400, 1),
+			  SIG_DESC_CLEAR(SCU500, 6));
+PIN_DECL_2(D6, GPIO18A1, RGMII1TXCTL, RMII1TXEN);
+
+#define D5 210
+SIG_EXPR_LIST_DECL_SESG(D5, RGMII1TXD0, RGMII1, SIG_DESC_SET(SCU400, 2),
+			  SIG_DESC_SET(SCU500, 6));
+SIG_EXPR_LIST_DECL_SESG(D5, RMII1TXD0, RMII1, SIG_DESC_SET(SCU400, 2),
+			  SIG_DESC_CLEAR(SCU500, 6));
+PIN_DECL_2(D5, GPIO18A2, RGMII1TXD0, RMII1TXD0);
+
+#define A3 211
+SIG_EXPR_LIST_DECL_SESG(A3, RGMII1TXD1, RGMII1, SIG_DESC_SET(SCU400, 3),
+			  SIG_DESC_SET(SCU500, 6));
+SIG_EXPR_LIST_DECL_SESG(A3, RMII1TXD1, RMII1, SIG_DESC_SET(SCU400, 3),
+			  SIG_DESC_CLEAR(SCU500, 6));
+PIN_DECL_2(A3, GPIO18A3, RGMII1TXD1, RMII1TXD1);
+
+#define C5 212
+SIG_EXPR_LIST_DECL_SESG(C5, RGMII1TXD2, RGMII1, SIG_DESC_SET(SCU400, 4),
+			  SIG_DESC_SET(SCU500, 6));
+PIN_DECL_1(C5, GPIO18A4, RGMII1TXD2);
+
+#define E6 213
+SIG_EXPR_LIST_DECL_SESG(E6, RGMII1TXD3, RGMII1, SIG_DESC_SET(SCU400, 5),
+			  SIG_DESC_SET(SCU500, 6));
+PIN_DECL_1(E6, GPIO18A5, RGMII1TXD3);
+
+#define B3 214
+SIG_EXPR_LIST_DECL_SESG(B3, RGMII1RXCK, RGMII1, SIG_DESC_SET(SCU400, 6),
+			  SIG_DESC_SET(SCU500, 6));
+SIG_EXPR_LIST_DECL_SESG(B3, RMII1RCLKI, RMII1, SIG_DESC_SET(SCU400, 6),
+			  SIG_DESC_CLEAR(SCU500, 6));
+PIN_DECL_2(B3, GPIO18A6, RGMII1RXCK, RMII1RCLKI);
+
+#define A2 215
+SIG_EXPR_LIST_DECL_SESG(A2, RGMII1RXCTL, RGMII1, SIG_DESC_SET(SCU400, 7),
+			  SIG_DESC_SET(SCU500, 6));
+PIN_DECL_1(A2, GPIO18A7, RGMII1RXCTL);
+
+#define B2 216
+SIG_EXPR_LIST_DECL_SESG(B2, RGMII1RXD0, RGMII1, SIG_DESC_SET(SCU400, 8),
+			  SIG_DESC_SET(SCU500, 6));
+SIG_EXPR_LIST_DECL_SESG(B2, RMII1RXD0, RMII1, SIG_DESC_SET(SCU400, 8),
+			  SIG_DESC_CLEAR(SCU500, 6));
+PIN_DECL_2(B2, GPIO18B0, RGMII1RXD0, RMII1RXD0);
+
+#define B1 217
+SIG_EXPR_LIST_DECL_SESG(B1, RGMII1RXD1, RGMII1, SIG_DESC_SET(SCU400, 9),
+			  SIG_DESC_SET(SCU500, 6));
+SIG_EXPR_LIST_DECL_SESG(B1, RMII1RXD1, RMII1, SIG_DESC_SET(SCU400, 9),
+			  SIG_DESC_CLEAR(SCU500, 6));
+PIN_DECL_2(B1, GPIO18B1, RGMII1RXD1, RMII1RXD1);
+
+#define C4 218
+SIG_EXPR_LIST_DECL_SESG(C4, RGMII1RXD2, RGMII1, SIG_DESC_SET(SCU400, 10),
+			  SIG_DESC_SET(SCU500, 6));
+SIG_EXPR_LIST_DECL_SESG(C4, RMII1CRSDV, RMII1, SIG_DESC_SET(SCU400, 10),
+			  SIG_DESC_CLEAR(SCU500, 6));
+PIN_DECL_2(C4, GPIO18B2, RGMII1RXD2, RMII1CRSDV);
+
+#define E5 219
+SIG_EXPR_LIST_DECL_SESG(E5, RGMII1RXD3, RGMII1, SIG_DESC_SET(SCU400, 11),
+			  SIG_DESC_SET(SCU500, 6));
+SIG_EXPR_LIST_DECL_SESG(E5, RMII1RXER, RMII1, SIG_DESC_SET(SCU400, 11),
+			  SIG_DESC_CLEAR(SCU500, 6));
+PIN_DECL_2(E5, GPIO18B3, RGMII1RXD3, RMII1RXER);
+
+FUNC_GROUP_DECL(RGMII1, C6, D6, D5, A3, C5, E6, B3, A2, B2, B1, C4, E5);
+FUNC_GROUP_DECL(RMII1, C6, D6, D5, A3, B3, B2, B1, C4, E5);
+
+#define D4 220
+SIG_EXPR_LIST_DECL_SESG(D4, RGMII2TXCK, RGMII2, SIG_DESC_SET(SCU400, 12),
+			  SIG_DESC_SET(SCU500, 7));
+SIG_EXPR_LIST_DECL_SESG(D4, RMII2RCLKO, RMII2, SIG_DESC_SET(SCU400, 12),
+			  SIG_DESC_CLEAR(SCU500, 7));
+PIN_DECL_2(D4, GPIO18B4, RGMII2TXCK, RMII2RCLKO);
+
+#define C2 221
+SIG_EXPR_LIST_DECL_SESG(C2, RGMII2TXCTL, RGMII2, SIG_DESC_SET(SCU400, 13),
+			  SIG_DESC_SET(SCU500, 7));
+SIG_EXPR_LIST_DECL_SESG(C2, RMII2TXEN, RMII2, SIG_DESC_SET(SCU400, 13),
+			  SIG_DESC_CLEAR(SCU500, 7));
+PIN_DECL_2(C2, GPIO18B5, RGMII2TXCTL, RMII2TXEN);
+
+#define C1 222
+SIG_EXPR_LIST_DECL_SESG(C1, RGMII2TXD0, RGMII2, SIG_DESC_SET(SCU400, 14),
+			  SIG_DESC_SET(SCU500, 7));
+SIG_EXPR_LIST_DECL_SESG(C1, RMII2TXD0, RMII2, SIG_DESC_SET(SCU400, 14),
+			  SIG_DESC_CLEAR(SCU500, 7));
+PIN_DECL_2(C1, GPIO18B6, RGMII2TXD0, RMII2TXD0);
+
+#define D3 223
+SIG_EXPR_LIST_DECL_SESG(D3, RGMII2TXD1, RGMII2, SIG_DESC_SET(SCU400, 15),
+			  SIG_DESC_SET(SCU500, 7));
+SIG_EXPR_LIST_DECL_SESG(D3, RMII2TXD1, RMII2, SIG_DESC_SET(SCU400, 15),
+			  SIG_DESC_CLEAR(SCU500, 7));
+PIN_DECL_2(D3, GPIO18B7, RGMII2TXD1, RMII2TXD1);
+
+#define E4 224
+SIG_EXPR_LIST_DECL_SESG(E4, RGMII2TXD2, RGMII2, SIG_DESC_SET(SCU400, 16),
+			  SIG_DESC_SET(SCU500, 7));
+PIN_DECL_1(E4, GPIO18C0, RGMII2TXD2);
+
+#define F5 225
+SIG_EXPR_LIST_DECL_SESG(F5, RGMII2TXD3, RGMII2, SIG_DESC_SET(SCU400, 17),
+			  SIG_DESC_SET(SCU500, 7));
+PIN_DECL_1(F5, GPIO18C1, RGMII2TXD3);
+
+#define D2 226
+SIG_EXPR_LIST_DECL_SESG(D2, RGMII2RXCK, RGMII2, SIG_DESC_SET(SCU400, 18),
+			  SIG_DESC_SET(SCU500, 7));
+SIG_EXPR_LIST_DECL_SESG(D2, RMII2RCLKI, RMII2, SIG_DESC_SET(SCU400, 18),
+			  SIG_DESC_CLEAR(SCU500, 7));
+PIN_DECL_2(D2, GPIO18C2, RGMII2RXCK, RMII2RCLKI);
+
+#define E3 227
+SIG_EXPR_LIST_DECL_SESG(E3, RGMII2RXCTL, RGMII2, SIG_DESC_SET(SCU400, 19),
+			  SIG_DESC_SET(SCU500, 7));
+PIN_DECL_1(E3, GPIO18C3, RGMII2RXCTL);
+
+#define D1 228
+SIG_EXPR_LIST_DECL_SESG(D1, RGMII2RXD0, RGMII2, SIG_DESC_SET(SCU400, 20),
+			  SIG_DESC_SET(SCU500, 7));
+SIG_EXPR_LIST_DECL_SESG(D1, RMII2RXD0, RMII2, SIG_DESC_SET(SCU400, 20),
+			  SIG_DESC_CLEAR(SCU500, 7));
+PIN_DECL_2(D1, GPIO18C4, RGMII2RXD0, RMII2RXD0);
+
+#define F4 229
+SIG_EXPR_LIST_DECL_SESG(F4, RGMII2RXD1, RGMII2, SIG_DESC_SET(SCU400, 21),
+			  SIG_DESC_SET(SCU500, 7));
+SIG_EXPR_LIST_DECL_SESG(F4, RMII2RXD1, RMII2, SIG_DESC_SET(SCU400, 21),
+			  SIG_DESC_CLEAR(SCU500, 7));
+PIN_DECL_2(F4, GPIO18C5, RGMII2RXD1, RMII2RXD1);
+
+#define E2 230
+SIG_EXPR_LIST_DECL_SESG(E2, RGMII2RXD2, RGMII2, SIG_DESC_SET(SCU400, 22),
+			  SIG_DESC_SET(SCU500, 7));
+SIG_EXPR_LIST_DECL_SESG(E2, RMII2CRSDV, RMII2, SIG_DESC_SET(SCU400, 22),
+			  SIG_DESC_CLEAR(SCU500, 7));
+PIN_DECL_2(E2, GPIO18C6, RGMII2RXD2, RMII2CRSDV);
+
+#define E1 231
+SIG_EXPR_LIST_DECL_SESG(E1, RGMII2RXD3, RGMII2, SIG_DESC_SET(SCU400, 23),
+			  SIG_DESC_SET(SCU500, 7));
+SIG_EXPR_LIST_DECL_SESG(E1, RMII2RXER, RMII2, SIG_DESC_SET(SCU400, 23),
+			  SIG_DESC_CLEAR(SCU500, 7));
+PIN_DECL_2(E1, GPIO18C7, RGMII2RXD3, RMII2RXER);
+
+FUNC_GROUP_DECL(RGMII2, D4, C2, C1, D3, E4, F5, D2, E3, D1, F4, E2, E1);
+FUNC_GROUP_DECL(RMII2, D4, C2, C1, D3, D2, D1, F4, E2, E1);
+
+#define AB4 232
+SIG_EXPR_LIST_DECL_SESG(AB4, SD3CLK, SD3, SIG_DESC_SET(SCU400, 24));
+PIN_DECL_1(AB4, GPIO18D0, SD3CLK);
+
+#define AA4 233
+SIG_EXPR_LIST_DECL_SESG(AA4, SD3CMD, SD3, SIG_DESC_SET(SCU400, 25));
+PIN_DECL_1(AA4, GPIO18D1, SD3CMD);
+
+#define AC4 234
+SIG_EXPR_LIST_DECL_SESG(AC4, SD3DAT0, SD3, SIG_DESC_SET(SCU400, 26));
+PIN_DECL_1(AC4, GPIO18D2, SD3DAT0);
+
+#define AA5 235
+SIG_EXPR_LIST_DECL_SESG(AA5, SD3DAT1, SD3, SIG_DESC_SET(SCU400, 27));
+PIN_DECL_1(AA5, GPIO18D3, SD3DAT1);
+
+#define Y5 236
+SIG_EXPR_LIST_DECL_SESG(Y5, SD3DAT2, SD3, SIG_DESC_SET(SCU400, 28));
+PIN_DECL_1(Y5, GPIO18D4, SD3DAT2);
+
+#define AB5 237
+SIG_EXPR_LIST_DECL_SESG(AB5, SD3DAT3, SD3, SIG_DESC_SET(SCU400, 29));
+PIN_DECL_1(AB5, GPIO18D5, SD3DAT3);
+
+#define AB6 238
+SIG_EXPR_LIST_DECL_SESG(AB6, SD3CD, SD3, SIG_DESC_SET(SCU400, 30));
+PIN_DECL_1(AB6, GPIO18D6, SD3CD);
+
+#define AC5 239
+SIG_EXPR_LIST_DECL_SESG(AC5, SD3WP, SD3, SIG_DESC_SET(SCU400, 31));
+PIN_DECL_1(AC5, GPIO18D7, SD3WP);
+
+FUNC_GROUP_DECL(SD3, AB4, AA4, AC4, AA5, Y5, AB5, AB6, AC5);
+
+#define Y1 240
+SIG_EXPR_LIST_DECL_SEMG(Y1, FWSPIDCS, FWSPID, FWSPID, SIG_DESC_SET(SCU500, 3));
+SIG_EXPR_LIST_DECL_SESG(Y1, VBCS, VB, SIG_DESC_SET(SCU500, 5));
+SIG_EXPR_LIST_DECL_SESG(Y1, SD3DAT4, SD3DAT4, SIG_DESC_SET(SCU404, 0));
+PIN_DECL_3(Y1, GPIO18E0, FWSPIDCS, VBCS, SD3DAT4);
+FUNC_GROUP_DECL(SD3DAT4, Y1);
+
+#define Y2 241
+SIG_EXPR_LIST_DECL_SEMG(Y2, FWSPIDCK, FWSPID, FWSPID, SIG_DESC_SET(SCU500, 3));
+SIG_EXPR_LIST_DECL_SESG(Y2, VBCK, VB, SIG_DESC_SET(SCU500, 5));
+SIG_EXPR_LIST_DECL_SESG(Y2, SD3DAT5, SD3DAT5, SIG_DESC_SET(SCU404, 1));
+PIN_DECL_3(Y2, GPIO18E1, FWSPIDCK, VBCK, SD3DAT5);
+FUNC_GROUP_DECL(SD3DAT5, Y2);
+
+#define Y3 242
+SIG_EXPR_LIST_DECL_SEMG(Y3, FWSPIDMOSI, FWSPID, FWSPID,
+			SIG_DESC_SET(SCU500, 3));
+SIG_EXPR_LIST_DECL_SESG(Y3, VBMOSI, VB, SIG_DESC_SET(SCU500, 5));
+SIG_EXPR_LIST_DECL_SESG(Y3, SD3DAT6, SD3DAT6, SIG_DESC_SET(SCU404, 2));
+PIN_DECL_3(Y3, GPIO18E2, FWSPIDMOSI, VBMOSI, SD3DAT6);
+FUNC_GROUP_DECL(SD3DAT6, Y3);
+
+#define Y4 243
+SIG_EXPR_LIST_DECL_SEMG(Y4, FWSPIDMISO, FWSPID, FWSPID,
+			SIG_DESC_SET(SCU500, 3));
+SIG_EXPR_LIST_DECL_SESG(Y4, VBMISO, VB, SIG_DESC_SET(SCU500, 5));
+SIG_EXPR_LIST_DECL_SESG(Y4, SD3DAT7, SD3DAT7, SIG_DESC_SET(SCU404, 3));
+PIN_DECL_3(Y4, GPIO18E3, FWSPIDMISO, VBMISO, SD3DAT7);
+FUNC_GROUP_DECL(SD3DAT7, Y4);
+
+GROUP_DECL(FWSPID, Y1, Y2, Y3, Y4);
+GROUP_DECL(FWQSPID, Y1, Y2, Y3, Y4, AE12, AF12);
+FUNC_DECL_2(FWSPID, FWSPID, FWQSPID);
+FUNC_GROUP_DECL(VB, Y1, Y2, Y3, Y4);
+
+/*
+ * FIXME: Confirm bits and priorities are the right way around for the
+ * following 4 pins
+ */
+#define AF25 244
+SIG_EXPR_LIST_DECL_SEMG(AF25, I3C3SCL, I3C3, I3C3, SIG_DESC_SET(SCU438, 20),
+			SIG_DESC_SET(SCU4D8, 20));
+SIG_EXPR_LIST_DECL_SESG(AF25, FSI1CLK, FSI1, SIG_DESC_CLEAR(SCU438, 20),
+			SIG_DESC_SET(SCU4D8, 20));
+PIN_DECL_(AF25, SIG_EXPR_LIST_PTR(AF25, I3C3SCL),
+	  SIG_EXPR_LIST_PTR(AF25, FSI1CLK));
+
+#define AE26 245
+SIG_EXPR_LIST_DECL_SEMG(AE26, I3C3SDA, I3C3, I3C3, SIG_DESC_SET(SCU438, 21),
+			SIG_DESC_SET(SCU4D8, 21));
+SIG_EXPR_LIST_DECL_SESG(AE26, FSI1DATA, FSI1, SIG_DESC_CLEAR(SCU438, 21),
+			SIG_DESC_SET(SCU4D8, 21));
+PIN_DECL_(AE26, SIG_EXPR_LIST_PTR(AE26, I3C3SDA),
+	  SIG_EXPR_LIST_PTR(AE26, FSI1DATA));
+
+GROUP_DECL(I3C3, AF25, AE26);
+FUNC_DECL_2(I3C3, HVI3C3, I3C3);
+FUNC_GROUP_DECL(FSI1, AF25, AE26);
+
+#define AE25 246
+SIG_EXPR_LIST_DECL_SEMG(AE25, I3C4SCL, I3C4, I3C4, SIG_DESC_SET(SCU438, 22),
+			SIG_DESC_SET(SCU4D8, 22));
+SIG_EXPR_LIST_DECL_SESG(AE25, FSI2CLK, FSI2, SIG_DESC_CLEAR(SCU438, 22),
+			SIG_DESC_SET(SCU4D8, 22));
+PIN_DECL_(AE25, SIG_EXPR_LIST_PTR(AE25, I3C4SCL),
+	  SIG_EXPR_LIST_PTR(AE25, FSI2CLK));
+
+#define AF24 247
+SIG_EXPR_LIST_DECL_SEMG(AF24, I3C4SDA, I3C4, I3C4, SIG_DESC_SET(SCU438, 23),
+			SIG_DESC_SET(SCU4D8, 23));
+SIG_EXPR_LIST_DECL_SESG(AF24, FSI2DATA, FSI2, SIG_DESC_CLEAR(SCU438, 23),
+			SIG_DESC_SET(SCU4D8, 23));
+PIN_DECL_(AF24, SIG_EXPR_LIST_PTR(AF24, I3C4SDA),
+	  SIG_EXPR_LIST_PTR(AF24, FSI2DATA));
+
+GROUP_DECL(I3C4, AE25, AF24);
+FUNC_DECL_2(I3C4, HVI3C4, I3C4);
+FUNC_GROUP_DECL(FSI2, AE25, AF24);
+
+/* Pins, groups and functions are sort(1):ed alphabetically for sanity */
+
+static struct pinctrl_pin_desc aspeed_g6_pins[ASPEED_G6_NR_PINS] = {
+	ASPEED_PINCTRL_PIN(A11),
+	ASPEED_PINCTRL_PIN(A12),
+	ASPEED_PINCTRL_PIN(A13),
+	ASPEED_PINCTRL_PIN(A14),
+	ASPEED_PINCTRL_PIN(A15),
+	ASPEED_PINCTRL_PIN(A16),
+	ASPEED_PINCTRL_PIN(A17),
+	ASPEED_PINCTRL_PIN(A18),
+	ASPEED_PINCTRL_PIN(A19),
+	ASPEED_PINCTRL_PIN(A2),
+	ASPEED_PINCTRL_PIN(A20),
+	ASPEED_PINCTRL_PIN(A21),
+	ASPEED_PINCTRL_PIN(A22),
+	ASPEED_PINCTRL_PIN(A23),
+	ASPEED_PINCTRL_PIN(A24),
+	ASPEED_PINCTRL_PIN(A25),
+	ASPEED_PINCTRL_PIN(A3),
+	ASPEED_PINCTRL_PIN(AA11),
+	ASPEED_PINCTRL_PIN(AA12),
+	ASPEED_PINCTRL_PIN(AA23),
+	ASPEED_PINCTRL_PIN(AA24),
+	ASPEED_PINCTRL_PIN(AA25),
+	ASPEED_PINCTRL_PIN(AA26),
+	ASPEED_PINCTRL_PIN(AA4),
+	ASPEED_PINCTRL_PIN(AA5),
+	ASPEED_PINCTRL_PIN(AA9),
+	ASPEED_PINCTRL_PIN(AB10),
+	ASPEED_PINCTRL_PIN(AB11),
+	ASPEED_PINCTRL_PIN(AB12),
+	ASPEED_PINCTRL_PIN(AB15),
+	ASPEED_PINCTRL_PIN(AB18),
+	ASPEED_PINCTRL_PIN(AB19),
+	ASPEED_PINCTRL_PIN(AB22),
+	ASPEED_PINCTRL_PIN(AB23),
+	ASPEED_PINCTRL_PIN(AB24),
+	ASPEED_PINCTRL_PIN(AB25),
+	ASPEED_PINCTRL_PIN(AB26),
+	ASPEED_PINCTRL_PIN(AB4),
+	ASPEED_PINCTRL_PIN(AB5),
+	ASPEED_PINCTRL_PIN(AB6),
+	ASPEED_PINCTRL_PIN(AB7),
+	ASPEED_PINCTRL_PIN(AB8),
+	ASPEED_PINCTRL_PIN(AB9),
+	ASPEED_PINCTRL_PIN(AC10),
+	ASPEED_PINCTRL_PIN(AC11),
+	ASPEED_PINCTRL_PIN(AC12),
+	ASPEED_PINCTRL_PIN(AC15),
+	ASPEED_PINCTRL_PIN(AC17),
+	ASPEED_PINCTRL_PIN(AC18),
+	ASPEED_PINCTRL_PIN(AC19),
+	ASPEED_PINCTRL_PIN(AC22),
+	ASPEED_PINCTRL_PIN(AC23),
+	ASPEED_PINCTRL_PIN(AC24),
+	ASPEED_PINCTRL_PIN(AC26),
+	ASPEED_PINCTRL_PIN(AC4),
+	ASPEED_PINCTRL_PIN(AC5),
+	ASPEED_PINCTRL_PIN(AC7),
+	ASPEED_PINCTRL_PIN(AC8),
+	ASPEED_PINCTRL_PIN(AC9),
+	ASPEED_PINCTRL_PIN(AD10),
+	ASPEED_PINCTRL_PIN(AD11),
+	ASPEED_PINCTRL_PIN(AD12),
+	ASPEED_PINCTRL_PIN(AD14),
+	ASPEED_PINCTRL_PIN(AD15),
+	ASPEED_PINCTRL_PIN(AD19),
+	ASPEED_PINCTRL_PIN(AD20),
+	ASPEED_PINCTRL_PIN(AD22),
+	ASPEED_PINCTRL_PIN(AD23),
+	ASPEED_PINCTRL_PIN(AD24),
+	ASPEED_PINCTRL_PIN(AD25),
+	ASPEED_PINCTRL_PIN(AD26),
+	ASPEED_PINCTRL_PIN(AD7),
+	ASPEED_PINCTRL_PIN(AD8),
+	ASPEED_PINCTRL_PIN(AD9),
+	ASPEED_PINCTRL_PIN(AE10),
+	ASPEED_PINCTRL_PIN(AE11),
+	ASPEED_PINCTRL_PIN(AE12),
+	ASPEED_PINCTRL_PIN(AE14),
+	ASPEED_PINCTRL_PIN(AE15),
+	ASPEED_PINCTRL_PIN(AE18),
+	ASPEED_PINCTRL_PIN(AE19),
+	ASPEED_PINCTRL_PIN(AE7),
+	ASPEED_PINCTRL_PIN(AE8),
+	ASPEED_PINCTRL_PIN(AF10),
+	ASPEED_PINCTRL_PIN(AF11),
+	ASPEED_PINCTRL_PIN(AF12),
+	ASPEED_PINCTRL_PIN(AF14),
+	ASPEED_PINCTRL_PIN(AF15),
+	ASPEED_PINCTRL_PIN(AF7),
+	ASPEED_PINCTRL_PIN(AF8),
+	ASPEED_PINCTRL_PIN(AF9),
+	ASPEED_PINCTRL_PIN(B1),
+	ASPEED_PINCTRL_PIN(B12),
+	ASPEED_PINCTRL_PIN(B13),
+	ASPEED_PINCTRL_PIN(B14),
+	ASPEED_PINCTRL_PIN(B16),
+	ASPEED_PINCTRL_PIN(B17),
+	ASPEED_PINCTRL_PIN(B18),
+	ASPEED_PINCTRL_PIN(B2),
+	ASPEED_PINCTRL_PIN(B20),
+	ASPEED_PINCTRL_PIN(B21),
+	ASPEED_PINCTRL_PIN(B22),
+	ASPEED_PINCTRL_PIN(B24),
+	ASPEED_PINCTRL_PIN(B25),
+	ASPEED_PINCTRL_PIN(B26),
+	ASPEED_PINCTRL_PIN(B3),
+	ASPEED_PINCTRL_PIN(C1),
+	ASPEED_PINCTRL_PIN(C11),
+	ASPEED_PINCTRL_PIN(C12),
+	ASPEED_PINCTRL_PIN(C13),
+	ASPEED_PINCTRL_PIN(C14),
+	ASPEED_PINCTRL_PIN(C15),
+	ASPEED_PINCTRL_PIN(C16),
+	ASPEED_PINCTRL_PIN(C17),
+	ASPEED_PINCTRL_PIN(C18),
+	ASPEED_PINCTRL_PIN(C19),
+	ASPEED_PINCTRL_PIN(C2),
+	ASPEED_PINCTRL_PIN(C20),
+	ASPEED_PINCTRL_PIN(C21),
+	ASPEED_PINCTRL_PIN(C22),
+	ASPEED_PINCTRL_PIN(C23),
+	ASPEED_PINCTRL_PIN(C24),
+	ASPEED_PINCTRL_PIN(C25),
+	ASPEED_PINCTRL_PIN(C26),
+	ASPEED_PINCTRL_PIN(C4),
+	ASPEED_PINCTRL_PIN(C5),
+	ASPEED_PINCTRL_PIN(C6),
+	ASPEED_PINCTRL_PIN(D1),
+	ASPEED_PINCTRL_PIN(D11),
+	ASPEED_PINCTRL_PIN(D12),
+	ASPEED_PINCTRL_PIN(D13),
+	ASPEED_PINCTRL_PIN(D14),
+	ASPEED_PINCTRL_PIN(D15),
+	ASPEED_PINCTRL_PIN(D16),
+	ASPEED_PINCTRL_PIN(D17),
+	ASPEED_PINCTRL_PIN(D18),
+	ASPEED_PINCTRL_PIN(D19),
+	ASPEED_PINCTRL_PIN(D2),
+	ASPEED_PINCTRL_PIN(D20),
+	ASPEED_PINCTRL_PIN(D21),
+	ASPEED_PINCTRL_PIN(D22),
+	ASPEED_PINCTRL_PIN(D23),
+	ASPEED_PINCTRL_PIN(D24),
+	ASPEED_PINCTRL_PIN(D26),
+	ASPEED_PINCTRL_PIN(D3),
+	ASPEED_PINCTRL_PIN(D4),
+	ASPEED_PINCTRL_PIN(D5),
+	ASPEED_PINCTRL_PIN(D6),
+	ASPEED_PINCTRL_PIN(E1),
+	ASPEED_PINCTRL_PIN(E11),
+	ASPEED_PINCTRL_PIN(E12),
+	ASPEED_PINCTRL_PIN(E13),
+	ASPEED_PINCTRL_PIN(E14),
+	ASPEED_PINCTRL_PIN(E15),
+	ASPEED_PINCTRL_PIN(E16),
+	ASPEED_PINCTRL_PIN(E17),
+	ASPEED_PINCTRL_PIN(E18),
+	ASPEED_PINCTRL_PIN(E19),
+	ASPEED_PINCTRL_PIN(E2),
+	ASPEED_PINCTRL_PIN(E20),
+	ASPEED_PINCTRL_PIN(E21),
+	ASPEED_PINCTRL_PIN(E22),
+	ASPEED_PINCTRL_PIN(E23),
+	ASPEED_PINCTRL_PIN(E24),
+	ASPEED_PINCTRL_PIN(E25),
+	ASPEED_PINCTRL_PIN(E26),
+	ASPEED_PINCTRL_PIN(E3),
+	ASPEED_PINCTRL_PIN(E4),
+	ASPEED_PINCTRL_PIN(E5),
+	ASPEED_PINCTRL_PIN(E6),
+	ASPEED_PINCTRL_PIN(F13),
+	ASPEED_PINCTRL_PIN(F15),
+	ASPEED_PINCTRL_PIN(F22),
+	ASPEED_PINCTRL_PIN(F23),
+	ASPEED_PINCTRL_PIN(F24),
+	ASPEED_PINCTRL_PIN(F25),
+	ASPEED_PINCTRL_PIN(F26),
+	ASPEED_PINCTRL_PIN(F4),
+	ASPEED_PINCTRL_PIN(F5),
+	ASPEED_PINCTRL_PIN(G22),
+	ASPEED_PINCTRL_PIN(G23),
+	ASPEED_PINCTRL_PIN(G24),
+	ASPEED_PINCTRL_PIN(G26),
+	ASPEED_PINCTRL_PIN(H22),
+	ASPEED_PINCTRL_PIN(H23),
+	ASPEED_PINCTRL_PIN(H24),
+	ASPEED_PINCTRL_PIN(H25),
+	ASPEED_PINCTRL_PIN(H26),
+	ASPEED_PINCTRL_PIN(J22),
+	ASPEED_PINCTRL_PIN(J23),
+	ASPEED_PINCTRL_PIN(J24),
+	ASPEED_PINCTRL_PIN(J25),
+	ASPEED_PINCTRL_PIN(J26),
+	ASPEED_PINCTRL_PIN(K23),
+	ASPEED_PINCTRL_PIN(K24),
+	ASPEED_PINCTRL_PIN(K25),
+	ASPEED_PINCTRL_PIN(K26),
+	ASPEED_PINCTRL_PIN(L23),
+	ASPEED_PINCTRL_PIN(L24),
+	ASPEED_PINCTRL_PIN(L26),
+	ASPEED_PINCTRL_PIN(M23),
+	ASPEED_PINCTRL_PIN(M24),
+	ASPEED_PINCTRL_PIN(M25),
+	ASPEED_PINCTRL_PIN(M26),
+	ASPEED_PINCTRL_PIN(N23),
+	ASPEED_PINCTRL_PIN(N24),
+	ASPEED_PINCTRL_PIN(N25),
+	ASPEED_PINCTRL_PIN(N26),
+	ASPEED_PINCTRL_PIN(P23),
+	ASPEED_PINCTRL_PIN(P24),
+	ASPEED_PINCTRL_PIN(P25),
+	ASPEED_PINCTRL_PIN(P26),
+	ASPEED_PINCTRL_PIN(R23),
+	ASPEED_PINCTRL_PIN(R24),
+	ASPEED_PINCTRL_PIN(R26),
+	ASPEED_PINCTRL_PIN(T23),
+	ASPEED_PINCTRL_PIN(T24),
+	ASPEED_PINCTRL_PIN(T25),
+	ASPEED_PINCTRL_PIN(T26),
+	ASPEED_PINCTRL_PIN(U24),
+	ASPEED_PINCTRL_PIN(U25),
+	ASPEED_PINCTRL_PIN(U26),
+	ASPEED_PINCTRL_PIN(V24),
+	ASPEED_PINCTRL_PIN(V25),
+	ASPEED_PINCTRL_PIN(V26),
+	ASPEED_PINCTRL_PIN(W23),
+	ASPEED_PINCTRL_PIN(W24),
+	ASPEED_PINCTRL_PIN(W26),
+	ASPEED_PINCTRL_PIN(Y1),
+	ASPEED_PINCTRL_PIN(Y2),
+	ASPEED_PINCTRL_PIN(Y23),
+	ASPEED_PINCTRL_PIN(Y24),
+	ASPEED_PINCTRL_PIN(Y25),
+	ASPEED_PINCTRL_PIN(Y26),
+	ASPEED_PINCTRL_PIN(Y3),
+	ASPEED_PINCTRL_PIN(Y4),
+	ASPEED_PINCTRL_PIN(Y5),
+	ASPEED_PINCTRL_PIN(AB16),
+	ASPEED_PINCTRL_PIN(AA17),
+	ASPEED_PINCTRL_PIN(AB17),
+	ASPEED_PINCTRL_PIN(AE16),
+	ASPEED_PINCTRL_PIN(AC16),
+	ASPEED_PINCTRL_PIN(AA16),
+	ASPEED_PINCTRL_PIN(AD16),
+	ASPEED_PINCTRL_PIN(AF25),
+	ASPEED_PINCTRL_PIN(AE26),
+	ASPEED_PINCTRL_PIN(AE25),
+	ASPEED_PINCTRL_PIN(AF24),
+};
+
+static const struct aspeed_pin_group aspeed_g6_groups[] = {
+	ASPEED_PINCTRL_GROUP(ADC0),
+	ASPEED_PINCTRL_GROUP(ADC1),
+	ASPEED_PINCTRL_GROUP(ADC10),
+	ASPEED_PINCTRL_GROUP(ADC11),
+	ASPEED_PINCTRL_GROUP(ADC12),
+	ASPEED_PINCTRL_GROUP(ADC13),
+	ASPEED_PINCTRL_GROUP(ADC14),
+	ASPEED_PINCTRL_GROUP(ADC15),
+	ASPEED_PINCTRL_GROUP(ADC2),
+	ASPEED_PINCTRL_GROUP(ADC3),
+	ASPEED_PINCTRL_GROUP(ADC4),
+	ASPEED_PINCTRL_GROUP(ADC5),
+	ASPEED_PINCTRL_GROUP(ADC6),
+	ASPEED_PINCTRL_GROUP(ADC7),
+	ASPEED_PINCTRL_GROUP(ADC8),
+	ASPEED_PINCTRL_GROUP(ADC9),
+	ASPEED_PINCTRL_GROUP(BMCINT),
+	ASPEED_PINCTRL_GROUP(ESPI),
+	ASPEED_PINCTRL_GROUP(ESPIALT),
+	ASPEED_PINCTRL_GROUP(FSI1),
+	ASPEED_PINCTRL_GROUP(FSI2),
+	ASPEED_PINCTRL_GROUP(FWSPIABR),
+	ASPEED_PINCTRL_GROUP(FWSPID),
+	ASPEED_PINCTRL_GROUP(FWQSPID),
+	ASPEED_PINCTRL_GROUP(FWSPIWP),
+	ASPEED_PINCTRL_GROUP(GPIT0),
+	ASPEED_PINCTRL_GROUP(GPIT1),
+	ASPEED_PINCTRL_GROUP(GPIT2),
+	ASPEED_PINCTRL_GROUP(GPIT3),
+	ASPEED_PINCTRL_GROUP(GPIT4),
+	ASPEED_PINCTRL_GROUP(GPIT5),
+	ASPEED_PINCTRL_GROUP(GPIT6),
+	ASPEED_PINCTRL_GROUP(GPIT7),
+	ASPEED_PINCTRL_GROUP(GPIU0),
+	ASPEED_PINCTRL_GROUP(GPIU1),
+	ASPEED_PINCTRL_GROUP(GPIU2),
+	ASPEED_PINCTRL_GROUP(GPIU3),
+	ASPEED_PINCTRL_GROUP(GPIU4),
+	ASPEED_PINCTRL_GROUP(GPIU5),
+	ASPEED_PINCTRL_GROUP(GPIU6),
+	ASPEED_PINCTRL_GROUP(GPIU7),
+	ASPEED_PINCTRL_GROUP(HVI3C3),
+	ASPEED_PINCTRL_GROUP(HVI3C4),
+	ASPEED_PINCTRL_GROUP(I2C1),
+	ASPEED_PINCTRL_GROUP(I2C10),
+	ASPEED_PINCTRL_GROUP(I2C11),
+	ASPEED_PINCTRL_GROUP(I2C12),
+	ASPEED_PINCTRL_GROUP(I2C13),
+	ASPEED_PINCTRL_GROUP(I2C14),
+	ASPEED_PINCTRL_GROUP(I2C15),
+	ASPEED_PINCTRL_GROUP(I2C16),
+	ASPEED_PINCTRL_GROUP(I2C2),
+	ASPEED_PINCTRL_GROUP(I2C3),
+	ASPEED_PINCTRL_GROUP(I2C4),
+	ASPEED_PINCTRL_GROUP(I2C5),
+	ASPEED_PINCTRL_GROUP(I2C6),
+	ASPEED_PINCTRL_GROUP(I2C7),
+	ASPEED_PINCTRL_GROUP(I2C8),
+	ASPEED_PINCTRL_GROUP(I2C9),
+	ASPEED_PINCTRL_GROUP(I3C3),
+	ASPEED_PINCTRL_GROUP(I3C4),
+	ASPEED_PINCTRL_GROUP(I3C5),
+	ASPEED_PINCTRL_GROUP(I3C6),
+	ASPEED_PINCTRL_GROUP(JTAGM),
+	ASPEED_PINCTRL_GROUP(LHPD),
+	ASPEED_PINCTRL_GROUP(LHSIRQ),
+	ASPEED_PINCTRL_GROUP(LPC),
+	ASPEED_PINCTRL_GROUP(LPCHC),
+	ASPEED_PINCTRL_GROUP(LPCPD),
+	ASPEED_PINCTRL_GROUP(LPCPME),
+	ASPEED_PINCTRL_GROUP(LPCSMI),
+	ASPEED_PINCTRL_GROUP(LSIRQ),
+	ASPEED_PINCTRL_GROUP(MACLINK1),
+	ASPEED_PINCTRL_GROUP(MACLINK2),
+	ASPEED_PINCTRL_GROUP(MACLINK3),
+	ASPEED_PINCTRL_GROUP(MACLINK4),
+	ASPEED_PINCTRL_GROUP(MDIO1),
+	ASPEED_PINCTRL_GROUP(MDIO2),
+	ASPEED_PINCTRL_GROUP(MDIO3),
+	ASPEED_PINCTRL_GROUP(MDIO4),
+	ASPEED_PINCTRL_GROUP(NCTS1),
+	ASPEED_PINCTRL_GROUP(NCTS2),
+	ASPEED_PINCTRL_GROUP(NCTS3),
+	ASPEED_PINCTRL_GROUP(NCTS4),
+	ASPEED_PINCTRL_GROUP(NDCD1),
+	ASPEED_PINCTRL_GROUP(NDCD2),
+	ASPEED_PINCTRL_GROUP(NDCD3),
+	ASPEED_PINCTRL_GROUP(NDCD4),
+	ASPEED_PINCTRL_GROUP(NDSR1),
+	ASPEED_PINCTRL_GROUP(NDSR2),
+	ASPEED_PINCTRL_GROUP(NDSR3),
+	ASPEED_PINCTRL_GROUP(NDSR4),
+	ASPEED_PINCTRL_GROUP(NDTR1),
+	ASPEED_PINCTRL_GROUP(NDTR2),
+	ASPEED_PINCTRL_GROUP(NDTR3),
+	ASPEED_PINCTRL_GROUP(NDTR4),
+	ASPEED_PINCTRL_GROUP(NRI1),
+	ASPEED_PINCTRL_GROUP(NRI2),
+	ASPEED_PINCTRL_GROUP(NRI3),
+	ASPEED_PINCTRL_GROUP(NRI4),
+	ASPEED_PINCTRL_GROUP(NRTS1),
+	ASPEED_PINCTRL_GROUP(NRTS2),
+	ASPEED_PINCTRL_GROUP(NRTS3),
+	ASPEED_PINCTRL_GROUP(NRTS4),
+	ASPEED_PINCTRL_GROUP(OSCCLK),
+	ASPEED_PINCTRL_GROUP(PEWAKE),
+	ASPEED_PINCTRL_GROUP(PWM0),
+	ASPEED_PINCTRL_GROUP(PWM1),
+	ASPEED_PINCTRL_GROUP(PWM10G0),
+	ASPEED_PINCTRL_GROUP(PWM10G1),
+	ASPEED_PINCTRL_GROUP(PWM11G0),
+	ASPEED_PINCTRL_GROUP(PWM11G1),
+	ASPEED_PINCTRL_GROUP(PWM12G0),
+	ASPEED_PINCTRL_GROUP(PWM12G1),
+	ASPEED_PINCTRL_GROUP(PWM13G0),
+	ASPEED_PINCTRL_GROUP(PWM13G1),
+	ASPEED_PINCTRL_GROUP(PWM14G0),
+	ASPEED_PINCTRL_GROUP(PWM14G1),
+	ASPEED_PINCTRL_GROUP(PWM15G0),
+	ASPEED_PINCTRL_GROUP(PWM15G1),
+	ASPEED_PINCTRL_GROUP(PWM2),
+	ASPEED_PINCTRL_GROUP(PWM3),
+	ASPEED_PINCTRL_GROUP(PWM4),
+	ASPEED_PINCTRL_GROUP(PWM5),
+	ASPEED_PINCTRL_GROUP(PWM6),
+	ASPEED_PINCTRL_GROUP(PWM7),
+	ASPEED_PINCTRL_GROUP(PWM8G0),
+	ASPEED_PINCTRL_GROUP(PWM8G1),
+	ASPEED_PINCTRL_GROUP(PWM9G0),
+	ASPEED_PINCTRL_GROUP(PWM9G1),
+	ASPEED_PINCTRL_GROUP(QSPI1),
+	ASPEED_PINCTRL_GROUP(QSPI2),
+	ASPEED_PINCTRL_GROUP(RGMII1),
+	ASPEED_PINCTRL_GROUP(RGMII2),
+	ASPEED_PINCTRL_GROUP(RGMII3),
+	ASPEED_PINCTRL_GROUP(RGMII4),
+	ASPEED_PINCTRL_GROUP(RMII1),
+	ASPEED_PINCTRL_GROUP(RMII2),
+	ASPEED_PINCTRL_GROUP(RMII3),
+	ASPEED_PINCTRL_GROUP(RMII4),
+	ASPEED_PINCTRL_GROUP(RXD1),
+	ASPEED_PINCTRL_GROUP(RXD2),
+	ASPEED_PINCTRL_GROUP(RXD3),
+	ASPEED_PINCTRL_GROUP(RXD4),
+	ASPEED_PINCTRL_GROUP(SALT1),
+	ASPEED_PINCTRL_GROUP(SALT10G0),
+	ASPEED_PINCTRL_GROUP(SALT10G1),
+	ASPEED_PINCTRL_GROUP(SALT11G0),
+	ASPEED_PINCTRL_GROUP(SALT11G1),
+	ASPEED_PINCTRL_GROUP(SALT12G0),
+	ASPEED_PINCTRL_GROUP(SALT12G1),
+	ASPEED_PINCTRL_GROUP(SALT13G0),
+	ASPEED_PINCTRL_GROUP(SALT13G1),
+	ASPEED_PINCTRL_GROUP(SALT14G0),
+	ASPEED_PINCTRL_GROUP(SALT14G1),
+	ASPEED_PINCTRL_GROUP(SALT15G0),
+	ASPEED_PINCTRL_GROUP(SALT15G1),
+	ASPEED_PINCTRL_GROUP(SALT16G0),
+	ASPEED_PINCTRL_GROUP(SALT16G1),
+	ASPEED_PINCTRL_GROUP(SALT2),
+	ASPEED_PINCTRL_GROUP(SALT3),
+	ASPEED_PINCTRL_GROUP(SALT4),
+	ASPEED_PINCTRL_GROUP(SALT5),
+	ASPEED_PINCTRL_GROUP(SALT6),
+	ASPEED_PINCTRL_GROUP(SALT7),
+	ASPEED_PINCTRL_GROUP(SALT8),
+	ASPEED_PINCTRL_GROUP(SALT9G0),
+	ASPEED_PINCTRL_GROUP(SALT9G1),
+	ASPEED_PINCTRL_GROUP(SD1),
+	ASPEED_PINCTRL_GROUP(SD2),
+	ASPEED_PINCTRL_GROUP(SD3),
+	ASPEED_PINCTRL_GROUP(SD3DAT4),
+	ASPEED_PINCTRL_GROUP(SD3DAT5),
+	ASPEED_PINCTRL_GROUP(SD3DAT6),
+	ASPEED_PINCTRL_GROUP(SD3DAT7),
+	ASPEED_PINCTRL_GROUP(SGPM1),
+	ASPEED_PINCTRL_GROUP(SGPS1),
+	ASPEED_PINCTRL_GROUP(SIOONCTRL),
+	ASPEED_PINCTRL_GROUP(SIOPBI),
+	ASPEED_PINCTRL_GROUP(SIOPBO),
+	ASPEED_PINCTRL_GROUP(SIOPWREQ),
+	ASPEED_PINCTRL_GROUP(SIOPWRGD),
+	ASPEED_PINCTRL_GROUP(SIOS3),
+	ASPEED_PINCTRL_GROUP(SIOS5),
+	ASPEED_PINCTRL_GROUP(SIOSCI),
+	ASPEED_PINCTRL_GROUP(SPI1),
+	ASPEED_PINCTRL_GROUP(SPI1ABR),
+	ASPEED_PINCTRL_GROUP(SPI1CS1),
+	ASPEED_PINCTRL_GROUP(SPI1WP),
+	ASPEED_PINCTRL_GROUP(SPI2),
+	ASPEED_PINCTRL_GROUP(SPI2CS1),
+	ASPEED_PINCTRL_GROUP(SPI2CS2),
+	ASPEED_PINCTRL_GROUP(TACH0),
+	ASPEED_PINCTRL_GROUP(TACH1),
+	ASPEED_PINCTRL_GROUP(TACH10),
+	ASPEED_PINCTRL_GROUP(TACH11),
+	ASPEED_PINCTRL_GROUP(TACH12),
+	ASPEED_PINCTRL_GROUP(TACH13),
+	ASPEED_PINCTRL_GROUP(TACH14),
+	ASPEED_PINCTRL_GROUP(TACH15),
+	ASPEED_PINCTRL_GROUP(TACH2),
+	ASPEED_PINCTRL_GROUP(TACH3),
+	ASPEED_PINCTRL_GROUP(TACH4),
+	ASPEED_PINCTRL_GROUP(TACH5),
+	ASPEED_PINCTRL_GROUP(TACH6),
+	ASPEED_PINCTRL_GROUP(TACH7),
+	ASPEED_PINCTRL_GROUP(TACH8),
+	ASPEED_PINCTRL_GROUP(TACH9),
+	ASPEED_PINCTRL_GROUP(THRU0),
+	ASPEED_PINCTRL_GROUP(THRU1),
+	ASPEED_PINCTRL_GROUP(THRU2),
+	ASPEED_PINCTRL_GROUP(THRU3),
+	ASPEED_PINCTRL_GROUP(TXD1),
+	ASPEED_PINCTRL_GROUP(TXD2),
+	ASPEED_PINCTRL_GROUP(TXD3),
+	ASPEED_PINCTRL_GROUP(TXD4),
+	ASPEED_PINCTRL_GROUP(UART10),
+	ASPEED_PINCTRL_GROUP(UART11),
+	ASPEED_PINCTRL_GROUP(UART12G0),
+	ASPEED_PINCTRL_GROUP(UART12G1),
+	ASPEED_PINCTRL_GROUP(UART13G0),
+	ASPEED_PINCTRL_GROUP(UART13G1),
+	ASPEED_PINCTRL_GROUP(UART6),
+	ASPEED_PINCTRL_GROUP(UART7),
+	ASPEED_PINCTRL_GROUP(UART8),
+	ASPEED_PINCTRL_GROUP(UART9),
+	ASPEED_PINCTRL_GROUP(VB),
+	ASPEED_PINCTRL_GROUP(VGAHS),
+	ASPEED_PINCTRL_GROUP(VGAVS),
+	ASPEED_PINCTRL_GROUP(WDTRST1),
+	ASPEED_PINCTRL_GROUP(WDTRST2),
+	ASPEED_PINCTRL_GROUP(WDTRST3),
+	ASPEED_PINCTRL_GROUP(WDTRST4),
+};
+
+static const struct aspeed_pin_function aspeed_g6_functions[] = {
+	ASPEED_PINCTRL_FUNC(ADC0),
+	ASPEED_PINCTRL_FUNC(ADC1),
+	ASPEED_PINCTRL_FUNC(ADC10),
+	ASPEED_PINCTRL_FUNC(ADC11),
+	ASPEED_PINCTRL_FUNC(ADC12),
+	ASPEED_PINCTRL_FUNC(ADC13),
+	ASPEED_PINCTRL_FUNC(ADC14),
+	ASPEED_PINCTRL_FUNC(ADC15),
+	ASPEED_PINCTRL_FUNC(ADC2),
+	ASPEED_PINCTRL_FUNC(ADC3),
+	ASPEED_PINCTRL_FUNC(ADC4),
+	ASPEED_PINCTRL_FUNC(ADC5),
+	ASPEED_PINCTRL_FUNC(ADC6),
+	ASPEED_PINCTRL_FUNC(ADC7),
+	ASPEED_PINCTRL_FUNC(ADC8),
+	ASPEED_PINCTRL_FUNC(ADC9),
+	ASPEED_PINCTRL_FUNC(BMCINT),
+	ASPEED_PINCTRL_FUNC(ESPI),
+	ASPEED_PINCTRL_FUNC(ESPIALT),
+	ASPEED_PINCTRL_FUNC(FSI1),
+	ASPEED_PINCTRL_FUNC(FSI2),
+	ASPEED_PINCTRL_FUNC(FWSPIABR),
+	ASPEED_PINCTRL_FUNC(FWSPID),
+	ASPEED_PINCTRL_FUNC(FWSPIWP),
+	ASPEED_PINCTRL_FUNC(GPIT0),
+	ASPEED_PINCTRL_FUNC(GPIT1),
+	ASPEED_PINCTRL_FUNC(GPIT2),
+	ASPEED_PINCTRL_FUNC(GPIT3),
+	ASPEED_PINCTRL_FUNC(GPIT4),
+	ASPEED_PINCTRL_FUNC(GPIT5),
+	ASPEED_PINCTRL_FUNC(GPIT6),
+	ASPEED_PINCTRL_FUNC(GPIT7),
+	ASPEED_PINCTRL_FUNC(GPIU0),
+	ASPEED_PINCTRL_FUNC(GPIU1),
+	ASPEED_PINCTRL_FUNC(GPIU2),
+	ASPEED_PINCTRL_FUNC(GPIU3),
+	ASPEED_PINCTRL_FUNC(GPIU4),
+	ASPEED_PINCTRL_FUNC(GPIU5),
+	ASPEED_PINCTRL_FUNC(GPIU6),
+	ASPEED_PINCTRL_FUNC(GPIU7),
+	ASPEED_PINCTRL_FUNC(I2C1),
+	ASPEED_PINCTRL_FUNC(I2C10),
+	ASPEED_PINCTRL_FUNC(I2C11),
+	ASPEED_PINCTRL_FUNC(I2C12),
+	ASPEED_PINCTRL_FUNC(I2C13),
+	ASPEED_PINCTRL_FUNC(I2C14),
+	ASPEED_PINCTRL_FUNC(I2C15),
+	ASPEED_PINCTRL_FUNC(I2C16),
+	ASPEED_PINCTRL_FUNC(I2C2),
+	ASPEED_PINCTRL_FUNC(I2C3),
+	ASPEED_PINCTRL_FUNC(I2C4),
+	ASPEED_PINCTRL_FUNC(I2C5),
+	ASPEED_PINCTRL_FUNC(I2C6),
+	ASPEED_PINCTRL_FUNC(I2C7),
+	ASPEED_PINCTRL_FUNC(I2C8),
+	ASPEED_PINCTRL_FUNC(I2C9),
+	ASPEED_PINCTRL_FUNC(I3C3),
+	ASPEED_PINCTRL_FUNC(I3C4),
+	ASPEED_PINCTRL_FUNC(I3C5),
+	ASPEED_PINCTRL_FUNC(I3C6),
+	ASPEED_PINCTRL_FUNC(JTAGM),
+	ASPEED_PINCTRL_FUNC(LHPD),
+	ASPEED_PINCTRL_FUNC(LHSIRQ),
+	ASPEED_PINCTRL_FUNC(LPC),
+	ASPEED_PINCTRL_FUNC(LPCHC),
+	ASPEED_PINCTRL_FUNC(LPCPD),
+	ASPEED_PINCTRL_FUNC(LPCPME),
+	ASPEED_PINCTRL_FUNC(LPCSMI),
+	ASPEED_PINCTRL_FUNC(LSIRQ),
+	ASPEED_PINCTRL_FUNC(MACLINK1),
+	ASPEED_PINCTRL_FUNC(MACLINK2),
+	ASPEED_PINCTRL_FUNC(MACLINK3),
+	ASPEED_PINCTRL_FUNC(MACLINK4),
+	ASPEED_PINCTRL_FUNC(MDIO1),
+	ASPEED_PINCTRL_FUNC(MDIO2),
+	ASPEED_PINCTRL_FUNC(MDIO3),
+	ASPEED_PINCTRL_FUNC(MDIO4),
+	ASPEED_PINCTRL_FUNC(NCTS1),
+	ASPEED_PINCTRL_FUNC(NCTS2),
+	ASPEED_PINCTRL_FUNC(NCTS3),
+	ASPEED_PINCTRL_FUNC(NCTS4),
+	ASPEED_PINCTRL_FUNC(NDCD1),
+	ASPEED_PINCTRL_FUNC(NDCD2),
+	ASPEED_PINCTRL_FUNC(NDCD3),
+	ASPEED_PINCTRL_FUNC(NDCD4),
+	ASPEED_PINCTRL_FUNC(NDSR1),
+	ASPEED_PINCTRL_FUNC(NDSR2),
+	ASPEED_PINCTRL_FUNC(NDSR3),
+	ASPEED_PINCTRL_FUNC(NDSR4),
+	ASPEED_PINCTRL_FUNC(NDTR1),
+	ASPEED_PINCTRL_FUNC(NDTR2),
+	ASPEED_PINCTRL_FUNC(NDTR3),
+	ASPEED_PINCTRL_FUNC(NDTR4),
+	ASPEED_PINCTRL_FUNC(NRI1),
+	ASPEED_PINCTRL_FUNC(NRI2),
+	ASPEED_PINCTRL_FUNC(NRI3),
+	ASPEED_PINCTRL_FUNC(NRI4),
+	ASPEED_PINCTRL_FUNC(NRTS1),
+	ASPEED_PINCTRL_FUNC(NRTS2),
+	ASPEED_PINCTRL_FUNC(NRTS3),
+	ASPEED_PINCTRL_FUNC(NRTS4),
+	ASPEED_PINCTRL_FUNC(OSCCLK),
+	ASPEED_PINCTRL_FUNC(PEWAKE),
+	ASPEED_PINCTRL_FUNC(PWM0),
+	ASPEED_PINCTRL_FUNC(PWM1),
+	ASPEED_PINCTRL_FUNC(PWM10),
+	ASPEED_PINCTRL_FUNC(PWM11),
+	ASPEED_PINCTRL_FUNC(PWM12),
+	ASPEED_PINCTRL_FUNC(PWM13),
+	ASPEED_PINCTRL_FUNC(PWM14),
+	ASPEED_PINCTRL_FUNC(PWM15),
+	ASPEED_PINCTRL_FUNC(PWM2),
+	ASPEED_PINCTRL_FUNC(PWM3),
+	ASPEED_PINCTRL_FUNC(PWM4),
+	ASPEED_PINCTRL_FUNC(PWM5),
+	ASPEED_PINCTRL_FUNC(PWM6),
+	ASPEED_PINCTRL_FUNC(PWM7),
+	ASPEED_PINCTRL_FUNC(PWM8),
+	ASPEED_PINCTRL_FUNC(PWM9),
+	ASPEED_PINCTRL_FUNC(RGMII1),
+	ASPEED_PINCTRL_FUNC(RGMII2),
+	ASPEED_PINCTRL_FUNC(RGMII3),
+	ASPEED_PINCTRL_FUNC(RGMII4),
+	ASPEED_PINCTRL_FUNC(RMII1),
+	ASPEED_PINCTRL_FUNC(RMII2),
+	ASPEED_PINCTRL_FUNC(RMII3),
+	ASPEED_PINCTRL_FUNC(RMII4),
+	ASPEED_PINCTRL_FUNC(RXD1),
+	ASPEED_PINCTRL_FUNC(RXD2),
+	ASPEED_PINCTRL_FUNC(RXD3),
+	ASPEED_PINCTRL_FUNC(RXD4),
+	ASPEED_PINCTRL_FUNC(SALT1),
+	ASPEED_PINCTRL_FUNC(SALT10),
+	ASPEED_PINCTRL_FUNC(SALT11),
+	ASPEED_PINCTRL_FUNC(SALT12),
+	ASPEED_PINCTRL_FUNC(SALT13),
+	ASPEED_PINCTRL_FUNC(SALT14),
+	ASPEED_PINCTRL_FUNC(SALT15),
+	ASPEED_PINCTRL_FUNC(SALT16),
+	ASPEED_PINCTRL_FUNC(SALT2),
+	ASPEED_PINCTRL_FUNC(SALT3),
+	ASPEED_PINCTRL_FUNC(SALT4),
+	ASPEED_PINCTRL_FUNC(SALT5),
+	ASPEED_PINCTRL_FUNC(SALT6),
+	ASPEED_PINCTRL_FUNC(SALT7),
+	ASPEED_PINCTRL_FUNC(SALT8),
+	ASPEED_PINCTRL_FUNC(SALT9),
+	ASPEED_PINCTRL_FUNC(SD1),
+	ASPEED_PINCTRL_FUNC(SD2),
+	ASPEED_PINCTRL_FUNC(SD3),
+	ASPEED_PINCTRL_FUNC(SD3DAT4),
+	ASPEED_PINCTRL_FUNC(SD3DAT5),
+	ASPEED_PINCTRL_FUNC(SD3DAT6),
+	ASPEED_PINCTRL_FUNC(SD3DAT7),
+	ASPEED_PINCTRL_FUNC(SGPM1),
+	ASPEED_PINCTRL_FUNC(SGPS1),
+	ASPEED_PINCTRL_FUNC(SIOONCTRL),
+	ASPEED_PINCTRL_FUNC(SIOPBI),
+	ASPEED_PINCTRL_FUNC(SIOPBO),
+	ASPEED_PINCTRL_FUNC(SIOPWREQ),
+	ASPEED_PINCTRL_FUNC(SIOPWRGD),
+	ASPEED_PINCTRL_FUNC(SIOS3),
+	ASPEED_PINCTRL_FUNC(SIOS5),
+	ASPEED_PINCTRL_FUNC(SIOSCI),
+	ASPEED_PINCTRL_FUNC(SPI1),
+	ASPEED_PINCTRL_FUNC(SPI1ABR),
+	ASPEED_PINCTRL_FUNC(SPI1CS1),
+	ASPEED_PINCTRL_FUNC(SPI1WP),
+	ASPEED_PINCTRL_FUNC(SPI2),
+	ASPEED_PINCTRL_FUNC(SPI2CS1),
+	ASPEED_PINCTRL_FUNC(SPI2CS2),
+	ASPEED_PINCTRL_FUNC(TACH0),
+	ASPEED_PINCTRL_FUNC(TACH1),
+	ASPEED_PINCTRL_FUNC(TACH10),
+	ASPEED_PINCTRL_FUNC(TACH11),
+	ASPEED_PINCTRL_FUNC(TACH12),
+	ASPEED_PINCTRL_FUNC(TACH13),
+	ASPEED_PINCTRL_FUNC(TACH14),
+	ASPEED_PINCTRL_FUNC(TACH15),
+	ASPEED_PINCTRL_FUNC(TACH2),
+	ASPEED_PINCTRL_FUNC(TACH3),
+	ASPEED_PINCTRL_FUNC(TACH4),
+	ASPEED_PINCTRL_FUNC(TACH5),
+	ASPEED_PINCTRL_FUNC(TACH6),
+	ASPEED_PINCTRL_FUNC(TACH7),
+	ASPEED_PINCTRL_FUNC(TACH8),
+	ASPEED_PINCTRL_FUNC(TACH9),
+	ASPEED_PINCTRL_FUNC(THRU0),
+	ASPEED_PINCTRL_FUNC(THRU1),
+	ASPEED_PINCTRL_FUNC(THRU2),
+	ASPEED_PINCTRL_FUNC(THRU3),
+	ASPEED_PINCTRL_FUNC(TXD1),
+	ASPEED_PINCTRL_FUNC(TXD2),
+	ASPEED_PINCTRL_FUNC(TXD3),
+	ASPEED_PINCTRL_FUNC(TXD4),
+	ASPEED_PINCTRL_FUNC(UART10),
+	ASPEED_PINCTRL_FUNC(UART11),
+	ASPEED_PINCTRL_FUNC(UART12),
+	ASPEED_PINCTRL_FUNC(UART13),
+	ASPEED_PINCTRL_FUNC(UART6),
+	ASPEED_PINCTRL_FUNC(UART7),
+	ASPEED_PINCTRL_FUNC(UART8),
+	ASPEED_PINCTRL_FUNC(UART9),
+	ASPEED_PINCTRL_FUNC(VB),
+	ASPEED_PINCTRL_FUNC(VGAHS),
+	ASPEED_PINCTRL_FUNC(VGAVS),
+	ASPEED_PINCTRL_FUNC(WDTRST1),
+	ASPEED_PINCTRL_FUNC(WDTRST2),
+	ASPEED_PINCTRL_FUNC(WDTRST3),
+	ASPEED_PINCTRL_FUNC(WDTRST4),
+};
+
+/**
+ * Configure a pin's signal by applying an expression's descriptor state for
+ * all descriptors in the expression.
+ *
+ * @ctx: The pinmux context
+ * @expr: The expression associated with the function whose signal is to be
+ *        configured
+ * @enable: true to enable an function's signal through a pin's signal
+ *          expression, false to disable the function's signal
+ *
+ * Return: 0 if the expression is configured as requested and a negative error
+ * code otherwise
+ */
+static int aspeed_g6_sig_expr_set(const struct aspeed_pinmux_data *ctx,
+				  const struct aspeed_sig_expr *expr,
+				  bool enable)
+{
+	int ret;
+	int i;
+
+	for (i = 0; i < expr->ndescs; i++) {
+		const struct aspeed_sig_desc *desc = &expr->descs[i];
+		u32 pattern = enable ? desc->enable : desc->disable;
+		u32 val = (pattern << __ffs(desc->mask));
+		bool is_strap;
+
+		if (!ctx->maps[desc->ip])
+			return -ENODEV;
+
+		WARN_ON(desc->ip != ASPEED_IP_SCU);
+		is_strap = desc->reg == SCU500 || desc->reg == SCU510;
+
+		if (is_strap) {
+			/*
+			 * The AST2600 has write protection mask registers for
+			 * the hardware strapping in SCU508 and SCU518. Assume
+			 * that if the platform doesn't want the strapping
+			 * values changed that it has set the write mask.
+			 *
+			 * The strapping registers implement write-1-clear
+			 * behaviour. SCU500 is paired with clear writes on
+			 * SCU504, likewise SCU510 is paired with SCU514.
+			 */
+			u32 clear = ~val & desc->mask;
+			u32 w1c = desc->reg + 4;
+
+			if (clear)
+				ret = regmap_update_bits(ctx->maps[desc->ip],
+							 w1c, desc->mask,
+							 clear);
+		}
+
+		ret = regmap_update_bits(ctx->maps[desc->ip], desc->reg,
+					 desc->mask, val);
+		if (ret)
+			return ret;
+	}
+
+	ret = aspeed_sig_expr_eval(ctx, expr, enable);
+	if (ret < 0)
+		return ret;
+
+	if (!ret)
+		return -EPERM;
+	return 0;
+}
+
+static const struct aspeed_pinmux_ops aspeed_g5_ops = {
+	.set = aspeed_g6_sig_expr_set,
+};
+
+static struct aspeed_pinctrl_data aspeed_g6_pinctrl_data = {
+	.pins = aspeed_g6_pins,
+	.npins = ARRAY_SIZE(aspeed_g6_pins),
+	.pinmux = {
+		.ops = &aspeed_g5_ops,
+		.groups = aspeed_g6_groups,
+		.ngroups = ARRAY_SIZE(aspeed_g6_groups),
+		.functions = aspeed_g6_functions,
+		.nfunctions = ARRAY_SIZE(aspeed_g6_functions),
+	},
+};
+
+static const struct pinmux_ops aspeed_g6_pinmux_ops = {
+	.get_functions_count = aspeed_pinmux_get_fn_count,
+	.get_function_name = aspeed_pinmux_get_fn_name,
+	.get_function_groups = aspeed_pinmux_get_fn_groups,
+	.set_mux = aspeed_pinmux_set_mux,
+	.gpio_request_enable = aspeed_gpio_request_enable,
+	.strict = true,
+};
+
+static const struct pinctrl_ops aspeed_g6_pinctrl_ops = {
+	.get_groups_count = aspeed_pinctrl_get_groups_count,
+	.get_group_name = aspeed_pinctrl_get_group_name,
+	.get_group_pins = aspeed_pinctrl_get_group_pins,
+	.pin_dbg_show = aspeed_pinctrl_pin_dbg_show,
+	.dt_node_to_map = pinconf_generic_dt_node_to_map_all,
+	.dt_free_map = pinctrl_utils_free_map,
+};
+
+static struct pinctrl_desc aspeed_g6_pinctrl_desc = {
+	.name = "aspeed-g6-pinctrl",
+	.pins = aspeed_g6_pins,
+	.npins = ARRAY_SIZE(aspeed_g6_pins),
+	.pctlops = &aspeed_g6_pinctrl_ops,
+	.pmxops = &aspeed_g6_pinmux_ops,
+};
+
+static int aspeed_g6_pinctrl_probe(struct platform_device *pdev)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(aspeed_g6_pins); i++)
+		aspeed_g6_pins[i].number = i;
+
+	return aspeed_pinctrl_probe(pdev, &aspeed_g6_pinctrl_desc,
+			&aspeed_g6_pinctrl_data);
+}
+
+static const struct of_device_id aspeed_g6_pinctrl_of_match[] = {
+	{ .compatible = "aspeed,ast2600-pinctrl", },
+	{ },
+};
+
+static struct platform_driver aspeed_g6_pinctrl_driver = {
+	.probe = aspeed_g6_pinctrl_probe,
+	.driver = {
+		.name = "aspeed-g6-pinctrl",
+		.of_match_table = aspeed_g6_pinctrl_of_match,
+	},
+};
+
+static int aspeed_g6_pinctrl_init(void)
+{
+	return platform_driver_register(&aspeed_g6_pinctrl_driver);
+}
+
+arch_initcall(aspeed_g6_pinctrl_init);
-- 
2.20.1

^ permalink raw reply related


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